כל פקודות PowerShell יכולות לכלול פרמטר אחד או יותר, המכונים לפעמים גם ארגומנטים. אם אתה לא משתמש בפרמטרים של PowerShell בפונקציות שלך, אתה לא כותב קוד PowerShell טוב!
במאמר הזה, אתה הולך ללמוד כמעט כל פרט של יצירת ושימוש בפרמטרים או בארגומנטים של PowerShell!
זוהי דוגמה מהספר שלי "PowerShell for SysAdmins". אם אתה רוצה ללמוד PowerShell או ללמוד כמה טריקים מהמקצוע, בדוק את זה!
למה צריך לך פרמטר?
כשאתה מתחיל ליצור פונקציות, יש לך את האפשרות לכלול פרמטרים או לא ולהגדיר איך הם עובדים.
נניח שיש לך פונקציה שמתקינה את Microsoft Office. אולי זה קורא למתקין של Office באופן שקט בתוך הפונקציה. מה שהפונקציה עושה, לא חשוב לצורכינו. הפונקציה הבסיסית נראית כך עם שמה של הפונקציה ובלוק הפקודות.
בדוגמה הזו, רק הרצת את הפקודה Install-Office
ללא פרמטרים והיא עושה את העבודה שלה.
לא הייתה חשיבות אם הפונקציה Install-Office
הייתה כוללת פרמטרים או לא. כנראה שהיא לא כללה פרמטרים חובה; אחרת, PowerShell לא היה מתיר לנו להריץ אותה ללא שימוש בפרמטר.
מתי להשתמש בפרמטר של PowerShell
Office יש לו הרבה גרסאות שונות. אולי עליך להתקין את Office 2013 ו-2016. כרגע, אין לך דרך לציין זאת. תוכל לשנות את קוד הפונקציה בכל פעם שברצונך לשנות את ההתנהגות.
לדוגמה, תוכל ליצור שתי פונקציות נפרדות להתקנת גרסאות שונות.
פעולה זו עובדת, אך אינה נרחבת. היא מכריחה אותך ליצור פונקציה נפרדת עבור כל גרסה של Office שיוצאת. עליך לשכפל הרבה קוד כשאין צורך בכך.
במקום זאת, עליך למצוא דרך להעביר ערכים שונים בזמן ריצה כדי לשנות את התנהגות הפונקציה. איך נעשה זאת?
כן! פרמטרים או מה שחלק מהאנשים קוראים להם ארגומנטים.
מכיוון שאנחנו רוצים להתקין גרסאות שונות של Office מבלי לשנות את הקוד כל פעם, עליך להוסיף לפחות פרמטר אחד לפונקציה זו.
לפני שאתה דומיין להוסיף פרמטר PowerShell, חשוב לשאול את עצמך שאלה ראשונה; "מה השינוי הקטן ביותר או השינויים שאתה מצפה לצרכם בפועל?".
תזכור שעליך להריץ מחדש את הפונקציה הזו מבלי לשנות קוד כלשהו בתוך הפונקציה. בדוגמה זו, הפרמטר כנראה ברור לך; עליך להוסיף פרמטר גרסה
. אך כאשר יש לך פונקציה עם עשרות שורות של קוד, התשובה לא תהיה ממש ברורה. כל עוד תענה על השאלה הזו בצורה מדויקת ככל האפשר, זה ימיד יעזור.
אז אתה יודע שצריך להוסיף פרמטר גרסה
. עכשיו מה? כעת אתה יכול להוסיף אחד, אך כמו כל שפת תכנות גדולה, ישנם מספר רב של דרכים לעשות זאת.
במדריך זה, אני אראה לך את הדרך "הטובה" ביותר ליצירת פרמטרים בהתבסס על כעשור של ניסיון שלי עם PowerShell. אך ידעו כי זו לא הדרך היחידה ליצור פרמטר.
ישנן פרמטרים מיקומיים. פרמטרים אלו מאפשרים לך להעביר ערכים לפרמטרים מבלי לציין את שם הפרמטר. פרמטרים מיקומיים עובדים אך לא נחשבים ל"שיטה הטובה" לכן? משום שהם קשים יותר לקריאה במיוחד כשיש לך רבים מאוד פרמטרים מוגדרים בפונקציה.
יצירת פרמטר פשוט ב־PowerShell
יצירת פרמטר בפונקציה מחייבת שני רכיבים עיקריים; בלוק param והפרמטר עצמו. בלוק param מוגדר על ידי המילה השמורה param
ואחריה סוגריים.
בנקודה זו, פונקציונליות הפונקציה לא שונתה בשום צורה. אנחנו פשוט יצרנו חלק מהתשתיות, כדי להכין את עצמנו לפרמטר הראשון.
לאחר שהכנו את בלוק ה־param, עכשיו תיצר את הפרמטר. השיטה שאני ממליץ עליך ליצור פרמטר כוללת בלוק התכונה Parameter
, ואחריו הסוג של הפרמטר, ובסוף שם המשתנה של הפרמטר.
יצרנו כעת פרמטר ב־PowerShell, אך מה קרה בדיוק כאן?
בלוק ה־Parameter
הוא חלק אופציונלי אך מומלץ של כל פרמטר. כמו בלוק ה־param, זהו "תשתית פונקציה" שמכינה את הפרמטר להוספת פונקציות נוספות. השורה השנייה היא המקום שבו אתה מגדיר את סוג הפרמטר.
במקרה זה, בחרנו להמיר את הפרמטר Version
למחרוזת. הגדרת סוג ברור אומרת שכל ערך שמועבר לפרמטר זה תמיד ינסה "להמיר" אותו למחרוזת אם כבר אינו.
הסוג אינו הכרחי אך מומלץ ביותר. הגדרת ברורות לסוג הפרמטר תפחית באופן משמעותי הרבה מצבים לא רצויים בעתיד. תאמין לי.
עכשיו שהגדרת את הפרמטר, תוכל להריץ את הפקודה Install-Office
עם הפרמטר Version
שמעביר לו מחרוזת גרסה כמו 2013. הערך שמועבר לפרמטר Version
מכונה לפעמים ארגומנטים או ערכי הפרמטרים.
מה קורה כאן ממש? אמרת לו שאתה רוצה להתקין גרסה 2013, אך הוא עדיין אומר לך שהותקנה גרסה 2016. כאשר אתה מוסיף פרמטר, עליך לזכור לשנות את קוד הפונקציה למשתנה. כאשר הפרמטר מועבר לפונקציה, המשתנה הזה יתרחב כדי להיות כל ערך שמועבר.
שנה את הטקסט הסטטי של 2016 והחליף אותו במשתנה של פרמטר Version
והמר את הגרשיים היחידות לגרשיים כפולים כדי שהמשתנה יתרחב.
עכשיו תוכל לראות שכל ערך שאתה מעביר לפרמטר Version
יועבר לפונקציה כמשתנה $Version
.
התכונה של הפרמטר החובה
זכור שציינתי ששורת ה- [Parameter()]
היא רק "צנזורת פונקציה" וצריך להכין את הפונקציה לעבודה נוספת? הוספת תכונות לפרמטר היא העבודה הנוספת שדיברתי עליה קודם.
A parameter doesn’t have to be a placeholder for a variable. PowerShell has a concept called parameter attributes and parameter validation. Parameter attributes change the behavior of the parameter in a lot of different ways.
לדוגמה, אחת התכונות הנפוצות ביותר שתגדיר היא המילה המפתחית Mandatory
. כברירת מחדל, ניתן לקרוא לפונקציה Install-Office
מבלי להשתמש בפרמטר Version
והיא תמשיך לרוץ ללא בעיה. הפרמטר Version יהיה אופציונלי. כמובן, הוא לא ירחיב את משתנה $Version בפנים הפונקציה מכיוון שאין לו ערך, אבל הפונקציה תמשיך להרוץ.
בהרבה מקרים בהם אתה יוצר פרמטר, תרצה שהמשתמש ישתמש בו תמיד. תסתמך על ערך הפרמטר בתוך קוד הפונקציה במקום כלשהו, ואם הפרמטר לא יעבור, הפונקציה תיכשל. במקרים אלו, ברצונך לכפות על המשתמש למסור ערך עבור הפרמטר שלך. ברצונך שהפרמטר הזה יהפוך להיות חובה.
לכפייה על משתמשים להשתמש בפרמטר זה פשוט לאחר שבנית את המסגרת הבסיסית כמו שיש לך כאן. עליך לכלול את המילה המפתחית Mandatory
בתוך הסוגריים של הפרמטר. לאחר שתעשה זאת, ביצוע הפונקציה בלעדיו הפרמטר יעצור את הרצת הפונקציה עד שימסר ערך.
הפונקציה תמתין עד שתציין ערך עבור הפרמטר Version
. לאחר שתעשה זאת ותלחץ Enter, PowerShell יבצע את הפונקציה וימשיך הלאה. אם תספק ערך לפרמטר, PowerShell לא יבקש ממך להזין את הפרמטר בכל פעם.
מאפייני אימות פרמטרים בשפת PowerShell
להגדיר פרמטר כחובה הוא אחד ממאפייני הפרמטרים הנפוצים ביותר שניתן להוסיף, אך ניתן גם להשתמש במאפייני אימות פרמטרים. בתכנות, תמיד חשוב להגביל את הקלט של המשתמש בצורה הכי קפדנית אפשרית. הגבלת המידע שמשתמשים (או אפילו אתה!) יכולים למסור לפונקציות או לתסריטים שלך תפטר מקוד בלתי נחוץ בפונקציה שאתה חייב לקשור לסוגי מצבים שונים.
למידה דרך דוגמה
לדוגמה, בפונקציה Install-Office
, הצגתי העברת הערך 2013
לפונקציה מכיוון שידעתי שזה יעבוד. אני כתבתי את הקוד! אני מניח (אך אף פעם אל תעשה זאת בקוד!) שזה ברור שכל מי שמבין משהו יציין את הגרסה כ-2013 או 2016. טוב, מה שברור לך עשוי לא להיות כל כך ברור לאנשים אחרים.
אם אתה רוצה להתקדם בגרסאות, אז כנראה יהיה נכון יותר לציין את הגרסה 2013 כ-15.0
ואת 2016 כ-16.0
אם מיקרוסופט הייתה משתמשת עדיין בסכמת הגרסאות שהייתה לה בעבר. אך מה אם, מכיוון שאתה מניח שהם יציינו גרסה של 2013 או 2016, יש לך קוד בתוך הפונקציה שמחפש תיקיות עם הגרסאות האלה או משהו אחר?
להלן דוגמה בה אתה עשוי להשתמש במחרוזת $Version
בנתיב של קובץ. אם מישהו מעביר ערך שאינו משלים את שם התיקייה Office2013
או Office2016
, זה יכשל או יעשה משהו גרוע יותר, כמו להסיר תיקיות לא צפויות או לשנות דברים שלא חשבת עליהם.
כדי להגביל את המשתמש להזין רק את מה שמצופה ממנו, ניתן להוסיף תיקון פרמטרים בפוורשל.
שימוש בתכונת הגבלת ValidateSet של פרמטרים
ישנם סוגים שונים של תיקון פרמטרים שניתן להשתמש בהם. לרשימה מלאה, רוץ את Get-Help about_Functions_Advanced_Parameters
. בדוגמה זו, כנראה שהתכונה ValidateSet תהיה הטובה ביותר.
תכונת התיקון ValidateSet מאפשרת לך לציין רשימה של ערכים שמותרים כערך לפרמטר. מכיוון שאנחנו מתייחסים רק למחרוזת 2013 או 2016, אני רוצה לוודא שהמשתמש יכול לציין רק את הערכים הללו. אחרת, הפונקציה תכשל מיד, ותודיע למשתמש למה.
ניתן להוסיף תכונות תיקון פרמטרים ישירות מתחת למילת המפתח המקורית Parameter. בדוגמה זו, בתוך סוגריים מרובעים של תכונת הפרמטר, יש לך מערך של פריטים; 2013 ו-2016. תכונת תיקון פרמטר מודיעה לפוורשל שהערכים המותרים לפרמטר Version הם רק 2013 או 2016. אם תנסה להעביר משהו שאינו חלק מהקבוצה, תקבל שגיאה שתודיע לך שיש לך רק מספר מוגבל של אפשרויות.
המאפיין ValidateSet
הוא מאפיין אימות נפוץ לשימוש. כדי לקבל פירוט מלא של כל האופציות להגברת הערכים של פרמטרים, יש לעיין בנושא העזר Functions_Advanced_Parameters
על ידי הרצת הפקודה Get-Help about_Functions_Advanced_Parameters
.
קבוצות פרמטרים
נניח שרק רוצים שמסווגים מסוימים של פרמטרים בפוּנְקצִיָּה של PowerShell יתאימו רק עם פרמטרים אחרים. אולי הוספנו פרמטר בשם Path
לפונקציה Install-Office
. פרמטר זה יבצע התקנה של הגרסה המתאימה באמצעות התקנת תוכנה. במקרה כזה, לא נרצה שהמשתמש ישתמש בפרמטר בשם Version
.
כלולים נדרשים
ניתן לקבוצה פרמטרים לקבוצות שיכולות להשתמש רק בפרמטרים אחרים שנמצאים באותה הקבוצה. באמצעות הפונקציה שלמטה, ניתן להשתמש כעת בשני הפרמטרים Version
ו־Path
כדי למצוא את הנתיב למתקין.
אך יש לנו בעיה כאן, מכיוון שהמשתמש עדיין יכול להשתמש בשני הפרמטרים. בנוסף, מאחר ושני הפרמטרים הם חובה, המשתמש יהיה מוכרח להשתמש בשניים גם כאשר זה לא מה שרצינו. כדי לתקן זאת, אנחנו יכולים לשים כל פרמטר בקבוצת פרמטרים כמו שמוצג למטה.
על ידי הגדרת שם קבוצת פרמטרים בכל פרמטר, ניתן לשלוט על קבוצות של פרמטרים ביחד.
הקבוצה המוגדרת כברירת מחדל
מה קורה אם המשתמש מנסה להריץ את הפונקציה Install-Office
ללא פרמטרים? המקרה הזה לא נמצא בחשבון, ותקבל הודעת שגיאה ידידותית.

כדי לתקן זאת, יהיה עליך להגדיר סט פרמטרים ברירת מחדל בתוך האזור CmdletBinding()
. זה אומר לפונקציה לבחור סט פרמטרים לשימוש אם לא היו משתמשים בפרמטרים באופן מפורש על ידי שינוי [CmdletBinding()]
ל [CmdletBinding(DefaultParameterSetName = 'ByVersion')]
עכשיו, בכל פעם שתריץ את הפקודה Install-Office
, תקבל הודעה להזנת הפרמטר Version
מאחר והפקודה תשתמש בסט הפרמטרים הזה.
קלט צינור
בדוגמאות עד כה, יצרת פונקציות עם פרמטר פוורשל שניתן להעברה רק באמצעות התחברות של סוגריים וערך -שם_הפרמטר. אך, כפי שלמדת כבר, PowerShell מאפשר שימוש בצינורות אינטואיטיבי שמאפשר להעביר אובייקטים בין פקודות בצורה חלקה מבלי להשתמש בתחביר "רגיל".
כאשר אתה משתמש בצינור, אתה "מצרף" פקודות יחד עם סמל הצינור |
ומאפשר למשתמש לשלוח את תוצאת הפקודה כמו Get-Service
ל Start-Service
כקיצור דרך להעברת הפרמטר Name
ל Start-Service
.
הדרך "הישנה" באמצעות לולאה
בפונקציה המותאמת שאתה עובד עליה, אתה מתקין את Office ויש לך פרמטר Version
. נניח שיש לך רשימה של שמות מחשבים בקובץ CSV בשורה אחת עם הגרסה של Office שצריך להתקין בהם בשורה השנייה. הקובץ CSV נראה כמו זה:
אתה רוצה להתקין את הגרסה של Office שנמצאת ליד כל מחשב במחשב זה.
ראשית, עליך להוסיף פרמטר ComputerName
לפונקציה כדי להעביר שם מחשב שונה לכל איטרציה של הפונקציה. להלן דוגמת קוד פסאודו שמייצג חלק מהקוד שעשוי להיות בפועל בפונקציה הדמיונית ונוסף דוגמת Write-Host
כדי לראות איך המשתנים מתרכזים בתוך הפונקציה.
כאשר יש לך את הפרמטר ComputerName
שנוסף לפונקציה, תוכל לבצע זאת על ידי קריאה לקובץ CSV והעברת הערכים של שם המחשב והגרסה לפונקצית Install-Office
.
בניית קלט צינורות עבור פרמטרים
שיטה זו של קריאה לשורות ב-CSV ושימוש בלולאת foreach
כדי להעביר את תכונות כל שורה לפונקציה היא הדרך "ישנה" לעשות זאת. במקטע זה, אתה רוצה לוותר על הלולאה foreach
לחלוטין ובמקום זאת להשתמש בצינור.
כפי שהוא, הפונקציה לא תומכת בצינור בכלל. יהיה טבעי להניח שניתן להעביר כל שם מחשב וגרסה לפונקציה באמצעות הצינור. להלן, אנחנו קוראים ל-CSV ומעבירים אותו ישירות ל-Install-Office
, אבל זה לא עובד.
אתה יכול להניח כל מה שתרצה, אבל זה לא יפעל בפועל. אנחנו מקבלים הזמנה לפרמטר Version
כאשר אנחנו יודעים ש-Import-Csv
שולח את זה כתכונה של אובייקט. למה זה לא עובד? כי אתה עדיין לא הוספת תמיכה בצינורות.
קיימות שתי סוגים של קלט צינורות בפונקציה של PowerShell; ByValue (אובייקט שלם) ו-ByPropertyName (תכונה יחידה של אובייקט). איזה דרך חשבת שהיא הכי טובה לסרוג את פלט של Import-Csv
לקלט של Install-Office
?
ללא כל שינוי, ניתן להשתמש בשיטת ByPropertyName
מאחר ו־Import-Csv
כבר מחזיר את התכונות Version
ו־ComputerName
מאחר והם עמודות ב-CSV.
להוסיף תמיכה בצינורות לפונקציה מותאמת אישית הוא פשוט יותר ממה שאתה חושב. זהו רק מאפיין של פרמטר המיוצג באחד משני המילים המפתחות הבאות; ValueFromPipeline
או ValueFromPipelineByPropertyName
.
בדוגמה, אתה רוצה לחבר את התכונות ComputerName
ו־Version
שמוחזרות מ־Import-Csv
לפרמטרים Version
ו־ComputerName
של Install-Office
כך שתשתמש ב־ValueFromPipelineByPropertyName
.
מכיוון שאנחנו רוצים לחבר שני הפרמטרים הללו, עליך להוסיף את המילה המפתח הזו לשני הפרמטרים כמו שמוצג למטה ולהפעיל מחדש את הפונקציה באמצעות הצינור.
זה מוזר. זה רץ רק עבור השורה האחרונה ב-CSV. מה קורה? הפונקציה רצה רק עבור השורה האחרונה כי דילגת על עקרון שאינו דרוש כאשר אתה בונה פונקציות ללא תמיכת צינור.
אל תשכח את לוח התהליך (Process Block)!
כאשר נדרש ליצור פונקציה שכוללת תמיכת צינור, עליך לכלול (מינימום) בלוק "מוטבע" בתוך הפונקציה שנקרא process
. לוח התהליך הזה אומר לפווורשל שכאשר הקלט מגיע מהצינור, להפעיל את הפונקציה בכל תפריטה. כברירת מחדל, זה רק יבצע את האחרון.
בעצם ניתן להוסיף בלוקים נוספים כמו begin
ו- end
גם, אך מפתחי תסריטים לא משתמשים בהם כל כך הרבה פעמים.
כדי להודיע לפווורשל לבצע את הפונקציה הזו עבור כל אובייקט שנכנס, אני אוסיף לוח process
שכולל את הקוד בתוכו.
עכשיו ניתן לראות שמאפייני הגרסה ושם המחשב של כל אובייקט שהוחזר מ־Import-Csv
עברו אל Install-Office
ונקשרו לפרמטרים של Version
ו־ComputerName
.
משאבים
כדי לעזור לך להבין עוד על איך פרמטרים של פונקציות עובדים, ניתן לעיין בפוסט הבלוג שלי על פונקציות PowerShell – קישור לפוסט.
I also encourage you to check my Pluralsight course entitled Building Advanced PowerShell Functions and Modules for an in-depth breakdown of everything there is to know about PowerShell functions, function parameters, and PowerShell modules.