פעם אחרי פעם שתתרגלו לכתוב סקריפטים ב־PowerShell, עליכם ללמוד על מודולריזציה של קוד. מודולריזציה היא פשוט מילת פנימה עבור יצירת קוד בבלוקים בניין. בעולם של PowerShell, פונקציות PowerShell הן אחת מהדרכים הטובות ביותר לעשות זאת.
כאשר אתם כותבים סקריפט PowerShell, יש לכם הרבה אפשרויות על כיצד אתם כותבים את הקוד. ניתן לכתוב אלף שורות של קוד שעושות מאות משימות, הכול בבלוק קוד יחיד ולא מופרך. זה יהיה אסון. במקום זאת, עליכם לכתוב פונקציות.
פונקציות מגבירות משמעותית את השימושיות והקריאות של הקוד שלכם, ומקלות מאוד על העבודה עם זה. במדריך הזה, תלמדו לכתוב פונקציות, להוסיף ולנהל את פרמטרי הפונקציות שלכם, ולהגדיר פונקציות כך שיהיה ניתן לקבל קלט מצינור. אך תחילה, בואו נסתכל על קצת מונחים.
הפוסט הזה נלקח מהספר שלי PowerShell for Sysadmins: Workflow Automation Made Easy. אם למדתם משהו במדריך הזה, הקפידו לבדוק את הספר כדי ללמוד עוד על פונקציות ועוד המון פינוקי PowerShell.
פונקציות נגד Cmdlets
המושג של פונקציה עשוי להישמע מוכר כי זה די דומה לפקודות ה- cmdlet שסביר שכבר השתמשת בהן. פקודות כמו Start-Service
ו־Write-Host
, לדוגמה, דומות לפונקציות. אלו פסיקות של קוד בשמות שונים שמטרתן לפתור בעיה ספציפית. ההבדל בין פונקציה ל- cmdlet הוא באופן שבו כל אחד מהם נבנה.
A cmdlet isn’t written with PowerShell. It’s written in another language, typically something like C#. The cmdlet is then compiled and made available inside PowerShell.
פונקציות, מצד שני, כתובות ב־ PowerShell; לא בשפה אחרת.
אפשר לראות אילו פקודות הם cmdlets ואילו הן פונקציות באמצעות ה cmdlet של Get-Command
ואת הפרמטר שלו CommandType
כפי שמוצג למטה
הפקודה הזו מחזירה את כל הפונקציות שכרגע נטענות למהלך ה- PowerShell שלך, או במודולים שזמינים ל־ PowerShell.
קשור: הבנת ובניית מודולי PowerShell
דרישות מוקדמות
אם ברצונך להמשיך לצפות בדוגמאות, נא לוודא שיש לך גירסת PowerShell זמינה. אין דרישות ספציפיות לגרסה לצורך המדריך הזה. כמו כן, נא לוודא שיש לך עורך קוד נחמד כמו Visual Studio Code כדי להעתיק, להדביק ולהריץ קטעי קוד.
בניית פונקציה פשוטה
לפני שניתן להשתמש בפונקציה, עליך להגדיר אותה. כדי להגדיר פונקציה, אתה משתמש במילת המפתח \״function״, לאחריה בשם מיוחד שאתה מגדיר, ואחריו סט של סוגריים מסולסלים. בתוך הסוגריים מסולסלים יש \״סקריפטבלוק״ שאתה רוצה שפוורשל יבצע.
למטה תוכל לראות פונקציה בסיסית ואת הרצת הפונקציה. הפונקציה הזו נקראת Install-Software
, משתמשת ב־Write-Host
כדי להציג הודעה במסוף. פעם שהיא מוגדרת, אתה יכול להשתמש בשם הפונקציה הזו כדי לבצע את הקוד בתוך סקריפטבלוק שלה.
שימות עם פועל־שם
A function’s name is important. You can name your functions whatever you want, but the name should always describe what the function does. The function-naming convention in PowerShell is the Verb-Noun syntax.
תמיד עליך להתחיל את שם הפונקציה עם פועל, לאחריו מקף ותיאור. כדי למצוא את רשימת הפועלים \״מאושרים״, השתמש ב־Get-Verb
cmdlet.
שינוי בהתנהגות הפונקציה
אם ברצונך לשנות את התנהגות הפונקציה, אתה יכול פשוט לשנות את הקוד שהפונקציה מבצעת, כפי שמוצג למטה.
עכשיו ששינית את הקוד בתוך הפונקציה, היא תציג הודעה מעט שונה.
הגדרת פונקציה מתקדמת
אתה יכול להגדיר פונקציות במקומות רבים שונים. בחלק הנ"ל, המדריך מניח שאתה פשוט העתקת והדבקת את הקוד ישירות לקונסולת פוורשל. אך זה אינו הדרך היחידה. תוכל גם להגדיר פונקציות בתוך סקריפט.
בחלק הקודם, עבדת עם פונקציה קטנה, לכן להגדיר אותה בקונסולה לא היה בעיה רבה. ברוב הזמן, אך תהיה לך פונקציות גדולות יותר. יהיה קל יותר להגדיר את הפונקציות האלו בתוך סקריפט או מודול ולאח"כ לקרוא לסקריפט או למודול ההוא כדי לטעון את הפונקציה לזיכרון.
כפי שאתה יכול לדמות לך, הקלדה מחדש של פונקציה גדולה בכל פעם שברצונך לשנות את הפונקציונליות שלה יכולה להיות מעט מעצבנת.
I suggest you now open your favorite editor and store the function in a .ps1 file as you work through the rest of the tutorial.
הוספת פרמטרים לפונקציות
פונקציות ב-PowerShell יכולות לכלול כל מספר של פרמטרים. כשאתה יוצר פונקציות משלך, יש לך את האפשרות לכלול פרמטרים ולהחליט כיצד הם יתנהגו. הפרמטרים יכולים להיות חובה או אופציונליים, והם יכולים לקבל הכל או להיות כפופים לקבל רק אחד מתוך רשימה מוגבלת של ארגומנטים אפשריים.
קשור: הכל שתמיד רצית לדעת על פרמטרים ב-PowerShell
לדוגמה, התוכנה הדמומה שאתה מתקין דרך הפונקציה Install-Software
עשויה להיות בעלת הרבה גרסאות. אך כרגע, הפונקציה Install-Software
אינה מציעה למשתמש דרך לציין איזו גרסה הוא רוצה להתקין.
אם היית השולט היחיד בשימוש בפונקציה, ייתכן שתוכל לשנות את הקוד בתוכנה בתוכנה כל פעם שתרצה גרסה ספציפית, אך זה היה מבלה של זמן. התהליך גם היה נוטה לשגיאות פוטנציאליות, לא לדבר על העובדה שתרצה שאחרים יוכלו להשתמש בקוד שלך.
הכנסת פרמטרים לתוך הפונקציה שלך מאפשרת לה להיות משתנה. כפי שהמשתנים האפשרו לך לכתוב סקריפטים שיכולים להתמודד עם גרסאות רבות של אותו מצב, הפרמטרים מאפשרים לך לכתוב פונקציה יחידה שתעשה דבר אחד בכמה דרכים.
במקרה זה, אתה רוצה שהיא תתקין גרסאות שונות של אותו תוכנה, ולעשות זאת על מספר רב של מחשבים.
בוא נוסיף תחילה פרמטר לפונקציה שמאפשר לך או למשתמש לציין את הגרסה להתקנה.
יצירת פרמטר פשוט
יצירת פרמטר בפונקציה מחייבת בלוק param
. הבלוק param
מחזיק את כל הפרמטרים לפונקציה. כדי להגדיר בלוק param
עם המילה המפתח param
עם סוגריים מרובעים כפי שמוצג למטה.
בנקודה זו, הפונקציונליות האמיתית של הפונקציה שלך לא השתנתה כלל. פשוט התקנת את הארונות, מכינה את הפונקציה לפרמטר.
כרגע, הפונקציה לא מתקינה בפועל שום תוכנה. היא פשוט משתמשת בפקודת
Write-Host
כדי לחקות את ההתקנה של התוכנה כך שתוכל להתמקד בכתיבת הפונקציה.
לאחר שהוספת את בלוק ה- param
, תוכל ליצור את הפרמטר על ידי שימוש בתוך הסוגריים של בלוק ה- param
כפי שמוצג למטה.
בתוך הבלוק param
למעלה, תגדיר את בלוק הפרמטרים תחילה. בשימוש בבלוק Parameter()
כזה זה יהפוך אותו ל"פרמטר מתקדם". בלוק פרמטר ריק כמו שנמצא כאן לא עושה כלום אבל דרוש; אני אסביר כיצד להשתמש בו באיזור הבא.
בואו נתמקד במקום בסוג המחרוזת שבפני השם של הפרמטר. על ידי שימת סוג הפרמטר בין סוגריים מרובעים לפני שם המשתנה של הפרמטר, אתה משנה את ערך הפרמטר לסוג מסוים. PowerShell תנסה תמיד להמיר ערך כלשהו שנשלח לפרמטר זה למחרוזת – אם הוא לא מחרוזת כבר. לעיל, כל דבר שיעבור כ- $Version יטופל תמיד כמחרוזת.
הצבת פרמטר שלך לסוג אינה חובה, אך אני ממליץ בחום על כך. זה מגדיר באופן מפורש את הסוג ויפחית באופן משמעותי את השגיאות לעתיד.
אתה גם מוסיף את $Version להצהרת ה- Write-Host שלך כעת. זה אומר שכאשר אתה מפעיל את פונקציית ה- Install-Software עם הפרמטר Version ומועבר לו מספר גרסה, אתה צריך לקבל הצהרה המציינת זאת כפי שמוצג למטה.
בוא נראה מה אתה יכול לעשות עם הפרמטר הזה כעת.
התכונה החובה של הפרמטר
אתה יכול להשתמש בבלוק הפרמטר כדי לשלוט בתכונות השונות של הפרמטר, שיאפשרו לך לשנות את ההתנהגות של הפרמטר. לדוגמה, אם ברצונך לוודא שכל מי שקורא לפונקציה חייב להעביר פרמטר נתון, תוכל להגדיר את הפרמטר הזה כחובה.
כברירת מחדל, פרמטרים הם אופציונליים. בוא נכפה על המשתמש להעביר גרסה על ידי שימוש במילת המפתח Mandatory בתוך בלוק הפרמטר כפי שמוצג למטה.
אם תפעיל את הפונקציה לעיל, אתה אמור לקבל את העקובה הבאה:

פעם שהגדרת את התכונה החובה, ביצוע הפונקציה בלעדי הפרמטר יעצור ביצוע עד שהמשתמש מזין ערך. הפונקציה ממתינה כעת עד שהמשתמש מציין ערך עבור הפרמטר גרסה
. לאחר הזנתו, PowerShell מבצע את הפונקציה.
כדי למנוע את הופעת הודעת הפרמטר החובה, פשוט מעבירים ערך לפרמטר בעת קריאת הפונקציה כפי שמוצג למטה.
ערכי פרמטר ברירת מחדל
אם, לדוגמה, אתה מבצע את העברת הערך עבור פרמטר פעם אחר פעם, אפשר להגדיר ערך ברירת מחדל. פרמטרים ברירת מחדל שימושיים כאשר ציפית לערך מסוים עבור פרמטר רוב הזמן.
לדוגמה, אם ברצונך להתקין גרסה 2 של התוכנה הזו 90 אחוז מהזמן, ותרצה שלא תצטרך להגדיר את הערך בכל פעם שאתה מפעיל את הפונקציה הזו, תוכל להקצות ערך ברירת מחדל של 2 לפרמטר $גרסה
. באפשרותך לראות את הדוגמה הזו למטה.
קיום פרמטר ברירת מחדל לא מונע ממך להעביר אחד. הערך שאתה מעביר ימחוק את הערך ברירת המחדל.
הוספת מאפייני אימות פרמטר
תמיד רעיון טוב להגביל את הערכים שאתה יכול להעביר לתוך פונקציה באמצעות פרמטרים. הדרך הטובה ביותר לעשות זאת היא בעזרת מאפייני אימות פרמטר.
הגבלת המידע שמשתמשים (או אפילו אתה!) יכולים להעביר לפונקציות או לסקריפטים שלך תילקח קוד לא נדרש בתוך הפונקציה שלך. לדוגמה, נניח שאתה מעביר את הערך 3 לפונקציית ההתקנה התקן-תוכנה
, ידוע שגרסה 3 היא גרסה קיימת.
פונקציתך מניחה שכל משתמש יודע אילו גרסאות קיימות, ולכן היא לא מתחשבת במה קורה כשנכנס לתיק גרסה 4. במקרה כזה, הפונקציה תיכשל למצוא את התיק המתאים מכיוון שהוא לא קיים.
חיים ללא אימות פרמטר
בדוק את הדוגמה למטה כאשר אתה משתמש במחרוזת $Version
בנתיב קובץ. אם מישהו מעביר ערך שלא משלים לשם תיק קיים (לדוגמה, SoftwareV3 או SoftwareV4), הקוד יכשל.

אתה יכול לכתוב קוד לטיפול בשגיאה כדי להתמודד עם הבעיה הזו, או תוכל למנוע את הבעיה בזרם על ידי דרישה שהמשתמש יעביר רק גרסה קיימת של התוכנה. כדי להגביל את הקלט של המשתמש, הוסף אימות פרמטר.
הוספת אימות פרמטר
קיימים מגוון סוגים שונים של אימות פרמטר, אך בקשר לפונקציה שלך Install-Software
, המאפשרת הכי טוב היא התכונה [ValidateSet
](https://adamtheautomator.com/powershell-validateset/). עם התכונה ValidateSet תוכל לציין רשימת ערכים שמורשים עבור הפרמטר. אם אתה רק רואה לתת ערכים כמו 1
או 2
, תוודא שהמשתמש יכול לציין רק את הערכים האלו; אחרת, הפונקציה תיכשל מייד ותודיע למשתמש על הסיבה.
הוסף תכונות אימות פרמטר בתוך בלוק param
, ישירות מתחת לבלוק Parameter
המקורי כפי שמוצג למטה.
על ידי הוספת סט של פריטים (1
ו־2
) בתוך הסוגריים האחרונים של התכונה ValidateSet
, זה אומר ל־PowerShell כי הערכים החוקיים למשתנה Version
הם רק 1
או 2
. אם משתמש מנסה להעביר משהו מלבד מה שבקבוצה, הם יקבלו הודעת שגיאה כפי שמוצג למטה שמודיעה להם שיש להם רק מספר מוגבל של אפשרויות.

התכונה ValidateSet
היא תכונת אימות נפוצה, אך ישנן גם תכונות אחרות זמינות. לפירוט מלא של כל הדרכים בהן ניתן להגביל ערכי פרמטרים, ראה את מסמכי Microsoft.
קבלת קלט מצינור
עד כה, יצרת פונקציה עם פרמטר שניתן להעברה רק באמצעות התחביר הנפוץ -ParameterName <Value>. זה עובד, אך יש לך גם אפשרות נוספת להעביר ערכים לפרמטרים באמצעות צינור PowerShell. בוא נוסיף יכולות של צינור לפונקציה שלנו Install-Software.
קשור: קבלת קלט מצינור במאמר הפרמטרים של PowerShell ATA
ראשית, הוסף פרמטר נוסף לקוד שלך שמציין את המחשב שעליו ברצונך להתקין את התוכנה. כמו כן, הוסף את הפרמטר הזה להפניה שלך ל־Write-Host
כדי להדמות את ההתקנה.
לאחר שהוספת את הפרמטר ComputerName
לפונקציה, אתה יכול כעת לעבור על רשימת שמות המחשבים ולהעביר את הערכים עבור שם המחשב והגרסה לפונקציה Install-Software
, כמו שמוצג למטה.
במקום לעשות כל זאת, כדאי ללמוד להשתמש בצינורות במקום זאת.
יעילות בצינורות בפונקציה
למרבה הצער, אין לך את היכולת להשתמש בצינורות של PowerShell עם פונקציה פשוטה בנויה מראש. עליך להחליט על איזה סוג של קלט של צינור אתה רוצה שהפונקציה תקבל וליישם.
A PowerShell function uses two kinds of pipeline input: ByValue
(entire object) and ByPropertyName
(a single object property). Here, because the $computers
array contains only strings, you’ll pass those strings via ByValue
.
כדי להוסיף תמיכת בצינור, הוסף אטריביוט לפרמטר שתרצה על ידי שימוש באחת משתי המילים המפתח: ValueFromPipeline
או ValueFromPipelineByPropertyName
, כפי שמוצג למטה.
לאחר שהוספת את פונקציית ההתקנה מעודכנת, התקשר אליה כך:
הרץ את הסקריפט שוב ואתה צובע לראות משהו דומה לזה:
שים לב ש־Install-Software
מבצעת רק עבור מחרוזת האחרונה במערך. תראה איך לתקן את זה בחלק הבא.
הוספת בלוק תהליך
לספר לפוורשל (PowerShell) לבצע פונקציה זו עבור כל אובייקט שנכנס, עליך לכלול בלוק תהליך (process). בתוך בלוק התהליך, שים את הקוד שברצונך לבצע בכל פעם שהפונקציה מקבלת קלט מצינור. הוסף בלוק תהליך לסקריפט שלך כפי שמוצג למטה.
עכשיו קרא שוב לפונקציה בדיוק כמו שעשית לפני. פונקציית Install-Software
תחזיר כעת שלוש שורות (אחת עבור כל אובייקט).
בלוק התהליך מכיל את הקוד הראשי שברצונך לבצע. תוכל גם להשתמש בבלוקים begin
ו־end
לקוד שיבוצע בתחילה ובסיום של קריאת הפונקציה. ניתן לקרוא עוד על בלוקים אלו, begin
, process
, ו־end
באמצעות מסמכי Microsoft.
שלבים באמצע
פונקציות מאפשרות לך להפריד קוד לבלוקים בנינים ונפרדים. הן לא רק עוזרות לך לפצל את העבודה שלך לחתיכות קטנות וניתנות לניהול יותר, אלא גם כובסות אותך לכתוב קוד קריא ונבדק.
I now challenge you to look through some old scripts and see where you can add a PowerShell function. Look for patterns in code. Build a function from those patterns. Notice where you’re copying/pasting code snippets and turn those into PowerShell functions!