שלט בפרמטר WhatIf של PowerShell

""אני לא תמיד בודק את התסריטים שלי, אך כאשר אני עושה זאת, אני עושה זאת בייצור""

אל תשקר. עשית זאת לפני. כולנו עשינו את זה במקום מסוים בעבר. אך זה לא חייב להיות מסוכן כאשר אתה מריץ תסריטי PowerShell בייצור. פשוט זכור להשתמש בפרמטר המובנה WhatIf של PowerShell!

האם לא היה נחמד לדעת מה הפקודה של PowerShell תעשה לפני שהיא עושה שינויים בסביבתך? דמיין את היכולת לשאול את הפקודה שלך, "מה היית עושה אם היית מריץ?" אתה יכול להשתמש בפרמטר WhatIf.

כל הפקודות המקומפלות של PowerShell כוללות פרמטר בשם WhatIf. הפרמטר הזה עוזר לך להעריך אם פקודה תעבוד כמצופה או אם היא תתחיל מתפרצת גרעון גרעון.

הפרמטר השימושי WhatIf אינו זמין רק עם כל הפקודות המובנות, אלא גם עם התסריטים שלך והפונקציות המתקדמות שלך! אם הקוד שלך ישנה דברים בסביבתך, יש לך את היתרון של מנגנון בטיחותי כאשר אתה בוחר ליישם אותו.

דרישות קדם

מאמר זה יהיה מדריך. אם ברצונך להתעקב אחרי המסע הזה, עליך להכין כמה דברים.

שים לב שבמאמר זה, אני אשתמש בסביבת פיתוח חזותית 1.38 (אוגוסט 2019) על מחשב עם מערכת הפעלה Windows 10.

הפרמטר WhatIf של PowerShell: מוגדר

בגדול, הפרמטר WhatIf הוא פרמטר מובנה switch parameter זמין עם כל הפונקציות המתקדמות וה-cmdlets (על ידי הוספת המילה המפתח PowerShell CmdletBinding לתסריטים ולפונקציות). בשימוש בו, הפקודה מדווחת על השפעתה הצפויה של הפקודה למסוף. אך היא לא מבצעת באמת את הפקודה.

לכל ה-cmdlets והפונקציות המתקדמות קיים פרמטר WhatIf. במאמר זה, נדגים את הפרמטר הזה באמצעות ה-cmdlets Get-Service, Stop-Service ו- New-Item.

בדיקה של תמיכת PowerShell בפרמטר WhatIf

אם אינך בטוח אם פקודה מסוימת תומכת ב- WhatIf, ישנם שני דרכים מהירות לבדוק.

שימוש ב-Get-Command

ניתן להשתמש בפקודת Get-Command כדי להציג את המטא-נתונים של הפקודה באמצעות הפרמטר Syntax כפי שמוצג למטה. אם אתה רואה הפניה ל- -WhatIf, פרמטר ה- WhatIf נתמך.

Get-Command <CommandName> -Syntax

שימוש בהשלמת טאב

ניתן גם לבדוק אם קיימת תמיכה בפרמטר WhatIf על ידי שלימת טאב. פשוט הקלד את הפקודה שברצונך לבדוק במסוף PowerShell ואז רווח, מקף, 'Wh' ואז מקש הטאב.

אם WhatIf מופיע, אתה יודע שהפקודה כוללת את הפרמטר WhatIf.

PS> <CommandName> -Wh[tab]

שימוש בפרמטר ה-PowerShell WhatIf עם Cmdlets

ישנם דרכים רבות שונות בהן ניתן להשתמש בפרמטר WhatIf. בסעיף זה, תלמד כיצד ניתן להתחיל להשתמש בפרמטר WhatIf מיידית באמצעות פקודות cmdlets מובנות.

יצירת קובץ

כמו כל cmdlets אחר, ל- cmdlet New-Item יש פרמטר WhatIf. בדוגמה זו, תשתמש ב- cmdlet New-Item כדי ליצור קובץ בשם newfile1.txt באותו ספריית עבודה.

אם היית מריץ את הפקודה למטה, היא הייתה יוצרת את הקובץ בשם newfile.txt.

PS51> New-Item -ItemType File -Path .\newfile1.txt

אבל מה אם פקודה זו יוצרת קובץ שייתכן שיגרום לבעיה אם ייוצר בהצלחה? אין בעיה. ניתן להוסיף את הפרמטר WhatIf בסופה.

New-Item -ItemType File -Path .\newfile1.txt -WhatIf

עצירת שירות

ניתן גם להשתמש בפרמטר WhatIf עם ה- cmdlet Stop-Service. בדוגמה זו, אתה מקבל רשימה של חמישה שירותים ראשונים ועוצר אותם בעזרת הפקודה Stop-Service. אבל אתה לא.

במקום זאת, אתה רק רואה הודעת פלט לקונסול PowerShell שמודיעה לך אילו שירותים ה- cmdlet Stop-Service היו מעציר.

PS51> (Get-Service)[0..4] | Stop-Service -WhatIf

שינוי התנהגות WhatIf של PowerShell באופן גלובלי

בנקודה זו, עליך לדעת כי בשימוש בפרמטר WhatIf עם cmdlet או פונקציה מתקדמת רק מדמה את הפעולה. אתה משפיע על התנהגות WhatIf ברמת הפקודה.

ההתנהגות WhatIf יכולה גם להיות מוגדרת ברמה גבוהה יותר שמשפיעה על כל הפקודות על ידי שינוי במשתנה האוטומטי $WhatIfPreference.

משתנה $WhatIfPreference הוא בוליאני. הוא יכול להיות רק True או False. כברירת מחדל, הוא מוגדר כ-False, המשמעות שלו היא שתמיכת WhatIf מושבתת על כל הפקודות אלא אם נמחק ברמת הפקודה. אם מוגדר כ-True, כל הפקודות שתומכות בו, בין אם באופן מפורש באמצעות הפרמטר WhatIf או לא, יהיו במצב "WhatIf".

ניתן לבדוק זאת על ידי שינוי ערך של $WhatIfPreference ל-True דרך $WhatIfPreference = $true. ניתן לראות למטה שפקודת New-Item בלי הפרמטר WhatIf פועלת כאילו הפרמטר עבר.

PS51> $WhatIfPreference = $true

אם שיניתם את $WhatIfPreference ל-True, אל תשכחו לשנות אותו בחזרה ל-False דרך $WhatIfPreference = $false.

בסעיף זה, למדתם כיצד להשתמש בתמיכת WhatIf עם cmdlets קיימים. בפעולה הבאה, תלמדו כיצד לבנות תמיכת WhatIf בתסריטים ובפונקציות מותאמים אישית שלכם.

מיושמת תמיכת Powershell WhatIf בפונקציות

לפני שאתה מנסה ליישם תמיכת WhatIf בתסריטים שלך, חשוב לדעת שיש דרך נכונה ודרך שגויה לעשות זאת. כמו שתראה בקטעים הבאים, תראה מהם הן.

עושים את זה בצורה שגויה: אל תחדש את הגלגל

לא נדיר שפתחי סקריפטים יחדשו את הגלגל ויממשו את תמיכת WhatIf שלהם עם קצת לוגיקת if/then. בהמשך תוכל לראות דוגמה.

שים לב שהמפתח הגדיר את הפרמטר המתג WhatIf שלו. לאחר מכן, באמצעות ערך הפרמטר הזה, הוא השתמש בבניית if/then לטיפול בלוגיקה כאשר נעשה שימוש או לא נעשה שימוש בפרמטר WhatIf.

Function Remove-LogFile {
    param (
        [Parameter(Mandatory)]
        [string]$name,

        [switch]$WhatIf
    )
    
    if ($WhatIf.IsPresent) { # המתג WhatIf פועל.
        Write-Host "WhatIf: I will remove the log file ""$name""" -ForegroundColor Yellow
    } else {
        # המתג WhatIf מכובה.
        Write-Host "Delete log file ""$name""" -ForegroundColor Green
    }
}

כאשר הפונקציה למעלה מופעלת באמצעות הפרמטר WhatIf כפי שמוצג למעלה, זה נראה כאילו עשתה את המשימה שלה. למעשה, הפונקציה לא הסירה דבר והחזירה הודעה לקונסול.

PS51> Remove-LogFile -name log.txt -WhatIf

אם זה עובד, אז מה הבעיה עם השיטה הזו? כי אתה מתעלם מהיכולות המובנות של פונקציה מתקדמת. עליך לבנות את היכולת הזו בכל פונקציה שאתה יוצר במקום לרק להתמקד במה שהפקודה תעשה כאשר היא כבויה.

במקום זאת, אל תחדשו את הגלגל והשתמשו במילת המפתח SupportsShouldProcess בשילוב עם $PSCmdlet.ShouldProcess(). זה עולה.

עושים זאת נכון: שימוש ב־SupportsShouldProcess

כל הפונקציות שמשתמשות ב־[CmdletBinding()] מפתח משתמשות נכון בהן. מילת המפתח הזו מוסיפה יכולות שונות לפונקציה כולל תמיכה ב־WhatIf.

כל הפונקציות המתקדמות תומכות בפונקציונליות של WhatIf, אך זה תלוי בך להשתמש בזה. כדי לעשות זאת, עליך להשתמש במילת המפתח SupportsShouldProcess בין סוגריים הריבועיים של [CmdletBinding()] תחילה כפי שמוצג למטה.

[CmdletBinding(SupportsShouldProcess)]

הפונקציה מאפשרת כעת לך לקרוא לשיטת ShouldProcess() על משתנה הפונקציה $PSCmdlet כדי לקבוע אם הפרמטר WhatIf נשלח לפונקציה או לא. כאשר משתמשים בפרמטר WhatIf, ShouldProcess() מחזיר False. במקרה אחר, זה תמיד יחזיר True.

Function Remove-LogFile {
     [cmdletbinding(SupportsShouldProcess)]
     param (
         [Parameter(Mandatory)]
         [string]$name
     )
     if ($PSCmdlet.ShouldProcess($name)) {
         ## הפרמטר -WhatIf לא נעשה שימוש. הפונקציה צריכה לעבוד כרגיל.
         Write-Host ("Delete log file " + $name) -ForegroundColor Green
     } else {
         ## הפרמטר -WhatIf נעשה שימוש. הפונקציה לא צריכה לעבוד.
     }
 }
WHATIF PARAMETER USED SHOULDPROCESS() RESULT
True False
False True

עכשיו תוכל לראות למטה כאשר Remove-LogFile מופעל עם פרמטר ה-WhatIf; זה מציג את אותו התנהגות כמו cmdlets מובנים.

PS51> Remove-LogFile -name log.txt -WhatIf

סיכום

במאמר זה, למדת על פרמטר ה-WhatIf ב-PowerShell. עכשיו עליך להבין כיצד הוא פועל ואילו יתרונות הוא יכול להביא.

עליך גם לדעת שלא לשחזר את הגלגל בפעם הבאה שתזדקק לאבטחה נוספת עבור פונקציות PowerShell שלך. במקום זאת, השתמש בתמיכה קיימת ב-PowerShell WhatIf!

קריאה נוספת

Source:
https://adamtheautomator.com/powershell-whatif/