DCSIMG
September 2007 - Posts - שחר.נט

שחר.נט

בלוגים שאני קורא

ספרים מומלצים

September 2007 - Posts

Option Explicit ב Windows Power Shell

שאלו אותי, איך ניתן להגדיר ל PowerShell להתנהג ב Option Explicit, כמו ב vbScript. מי שלא מכיר, המשמעות היא שחובה להצהיר על משתנה לפני השימוש בו. כלומר, נמנע מצב שבו אתה משתמש במשתנה שלא הוגדר ומקבל תוצאות לא צפויות.

כדי לכפות התנהגות זו ב powershell, יש לכתוב: set-psdebug -strict וכדי לכבות לכתוב set-psdebug -off

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

בהצלחה.

PowerShell Profiles

ב Windows Power Shell, ישנו מושג בשם Profile. הפרופיל, מחולק למספר רמות (החל מפרופיל פרטי וכלה בציבורי) ומכיל, למעשה, את ההתאמות האישיות שלך, את הוראות הקיסטום שלך ל Windows Power Shell. בפרופיל ניתן לשים קוד שייטען ביחד עם סביבת ה Windows Power Shell - החל משורת פעולות שבודקות את מצב המערכת, וכלה בלשים שם את הפונקציות שבהם אתה משתמש הרבה, שיהיו לך זמינות וייטענו מיד עם הפרופיל שלך.

הפרופיל הוא למעשה, כמו כל הקבצים הנוגעים ל powershell, קובץ טקסט שנמצא בנתיב שמוגדר במשתנה profile. על-מנת לראות אם הוא קיים אצלך, ניתן להשתמש ב cmdlet ששמו test-path שבודק האם נתיב מסויים חוקי וקיים:

image

 במידה וקיים לנו פרופיל יופיע הערך true, אחרת יופיע false.
כעת, ניתן לגשת ולערוך את ההפרופיל, או ליצור אותו במידה ואינו קיים:

image

 עכשיו, ייפתח ה notepad ובו פשוט נכניס את מה שאנחנו רוצים, פונקציות שאנחנו משתמשים בהם הרבה וכו'.

סתם בשביל הדוגמא, הנה קובץ profile שמתאים לאנשים שמשתמשים ב Windows Vista עם User Account Control מופעל, ורוצים התרעה אם במקרה הפעילו את ה PowerShell שלא בהרשאות Administrator:

image

 

 

 

 

 

 

הקוד הזה בודק האם Windows Power Shell רץ תחת הרשאות Administrator, ואם לא הוא מתריע במשתמש. הסימן הממורקר, דרך אגב, הוא סימן שבירת שורת קוד ב Windows Power Shell.

בהצלחה.

איך להריץ קוד של Power Shell מתוך Class שיורש מ PSCmdlet?

שאלה: בפוסט הקודם, הוסבר איך ניתן להריץ קוד Power Shell מתוך כל אפליקציית דוט.נט - האם באותה צורה מריצים מ Cmdlet שאני כותב שיורש מ PSCmdlet?

תשובה:
כן, זה יעבוד. אבל יש דרך קצרה יותר וחכמה יותר, שמתאפשרת ב classes שיורשים מ PSCmdlet (לא מ Cmdlet). בשביל הדוגמא הזאת, יצרתי PSSnapin, שכל מה שהוא עושה זה להריץ את הפקודה dir ולהדפיס את תוצאותיה, הנה הקוד:

image

 

 

 

במקום dir ניתן לכתוב כל פקודה שרוצים. על מנת שזה יעבוד, הוספתי בראש הקוד את ה usings הבאים:

image

 מירקרתי (בעקמומיות אופיינית) את השורות שבאמת "חידשנו" פה - את System.Management.Automation אתם צריכים כי בו נמצא PSCmdlet - את System.Collections.ObjectModel אתם צריכים כי בו נמצא Collection.

בהצלחה.

ניהול שגיאות מ Windows Power Shell

בעבר, כבר כתבתי על היתרונות והחסרונות ב scripting - היתרון, הוא כמובן ביצוע line by line כשאם יש בעייה באחת מהשורות, נזרקת איזושהי הודעת שגיאה, והשורה הבאה מתבצעת.
אולם, הרבה פעמים נרצה לדעת האם ביצוע של שורה מסויימת עבד בהצלחה ואם לא - אזי למה?
הסיבה העיקרית, היא כדי למנוע טעות שרשרת. טעות בשורה אחת, שמשפיעה על כל שאר הסקריפט. במקרה כזה, נרצה לדעת מה השגיאה, לנסות לטפל בה, או להחליט שאין לנו אפשרות לטפל בה, ולהודיע למשתמש על הפסקת ביצוע הסקריפט.

אחד מהמשתנים הקבועים, שקיימים תמיד בסביבת ה Windows Power Shell הוא error$ - שלמעשה הוא collection שמכיל את פרטי כל השגיאות שנזרקו במסגרת ההפעלה הזאת של ה power shell (של ה host המסויים), כשהשגיאה האחרונה שנזרקה, היא הזריקה הראשונה שמופיע ב collection, כלומר, זאת שתופיע ב image_thumb3 , Last In First Out.

למעשה, error$ הוא מסוג System.Collection.ArrayList והשגיאות שבו מסוג System.Management.Automation.ErrorRecord, סוג שלא מוכר לנו מהעבודה הרגילה בדוט.נט, אבל הוא מכיל מתודות שיכולות להחזיר לנו אובייקט System.Exception שאיתו אנחנו כן יכולים לעבוד בקלות ובצורה רגילה.

אנחנו יכולים לדעת האם יש שגיאות ב collection באמצעות ה property ששמו image_thumb5  שיחזיר לנו את מספר השגיאות שנאספו. בשביל לנקות את כל השגיאות, יש להשתמש ב  image_thumb9

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

בשביל הדוגמא, הנה הדפסת מספר הודעות השגיאה בעת הפעלת ה powershell כאשר עוד לא ביצענו פעולות לא חוקיות:

image_thumb13

 

 

כפי שאתם רואים, ישנן 0 שגיאות.

עכשיו, נקליד פקודה לא קיימת, ואז נדפיס את מספר השגיאות ואת קטגוריית השגיאות. זכרו, שפה, בגלל שה host הוא טקסטואלי אנחנו מקבלים הכל בתור טקסטים יפים (שלא ממש נוח לעבוד איתם) אבל מתוך סקריפט, או אפליקציה, אנחנו מקבלים אובייקטים שאיתם הרבה יותר נוח לעבוד:

image_thumb22

 בהתחלה, כתבתי פקודה לא קיימת, ואז ראיתי שיש שגיאה אחת, והדפסתי את הערך של ERROR - שמכיל את כל השגיאות. ואז כתבתי עוד פקודה שלא קיימת - וכבר יש 2 שגיאות, ואז הערך של ERROR הוא שתי השגיאות אחת אחרי השנייה. עכשיו, נקבל את הקטגוריה ואת סוג ה exception של השגיאה האחרונה שאירעה:

image_thumb26

 ה propery ששמו categoryInfo, מחזיר למעשה אובייקט System.Management.Automation.ErrorCategoryInfo. בגלל שה host טקסטואלי, הוא מדפיס לי את הנתונים של אתו אובייקט שחוזר. אנחנ ויכולים לקבל, למשל, את סיבהת השגיאה, מה הפעולה שגרמה לה ומאיזה סוג היה האובייקט שגרם לה.

אם אנחנו רוצים, אנחנו יכולים להשתמש ב property (לקריאה בלבד) ששמו exception, שיחזיר לנו למעשה אובייקט מסוג Exception רגיל שאיתו נוכל לעבוד.

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

בהצלחה.

Providers ב PowerShell

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

לגשת לאיזשהו כונן, להיכנס לאיזושהי תיקייה, ומשם לעוד תת תיקייה וכו' - נראה לנו טריוויאלי - קיים מאז ומעולם. מצד שני, אפשר לחשוב על עוד הרבה מקומות שבהם תופסת אותה שיטה. למה, למשל, אי אפשר לנווט ב Registry באותה הצורה? אז ב Power Shell אפשר.

image

 

 

 

 

 

אם תלחצו על התמונה ותגדילו, תראו שלמעשה מה שעשיתי פה, זה עברתי מניווט ב Provider של התיקיות לניווט ב Registry - פשוט השתמשתי באחד ה providers שמגיעים built-in שמאפשרים לי לנווט ב registry בקלות.

אם מקלידים את הפקודה get-psdrive, מקבלים את רשימת הכוננים שקיימים מבחינת ה powershell. חלק "וירטואליים" ובכלל לא מצביעים למערכת הקבצים הפיזית:

image

 כפי שאתם רואים, חוץ מהכוננים הפיזיים הרגילים, גם משתני הסביבה (Env) מוגדרים כ provider כמו כן ה functions וכמובן ה aliases.

image

 אבל, אנחנו לא מוגבלים לשימוש רק במה שמגיע מובנה. אנחנו יכולים לבנות providers משלנו, כדי להקל על גישה למידע. למשל, אם אנחנו רוצים גישה למסד נתונים של MSSQL, אנחנו יכולים לכתוב provider שיגדיר איך למעשה עובדת צורת הניווט מולו למנגנון ה power shell ולאחר מכן, ניתן היהיה להתחיל להשתמש בו.

בהצלחה.

גישה ליכולות ה Windows Power Shell מתוך אפליקציית .net

בעבר, הזכרתי כבר שניתן להשתמש ב cmdlets, functions ו providers של Windows Power Shell מכל אפליקציית .net שרוצים.
לצורך העניין, יצרתי פרוייקט Windows Application חדש ופשוט, ושמתי textbox אחד שבו תוכנת הפקודה ששמו cmdTextbox, כפתור שמבצע את הפעולה ו textbox שיציג את התוצאות בשם resultsTextbox.

תחילה, צריך להוסיף reference ל System.Management.Automation - בד"כ הSDK מתקין את הDLL לכאן: C:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0 כדאי להוסיף using System.Management.Automation לראש הקוד, כמו גם ל System.Management.Automation.Runspaces. ול System.Collectiond.ObjectModel

תחילה, בואו נכיר כמה מחלקות:

System.Management.Automation.Runspace - מחלקה זאת, למעשה, מאפשרת לנו ליצור סביבת ריצה של Windows Power Shell מתוך האפליקציה הדוטץנטית שלנו, ולהשתמש בסביבה זאת להרצת פקודות וכו'.

System.Management.Automation.RunspaceFactory - מאפשר לנו ליצור את ה runspace ולהגדיר אותו בפועל, ואז להעביר אותו לשליטת אובייקט Runspace - מכיל מתודה סטאטית בשם CreateRunspace, שיוצרת בפועל את ה runspace.

RunspaceConfiguration - מכילה את ההגדרות של ה runspace, איזה pssnapins יופעלו בו וכו'.

עכשיו, לפני יצירת ה runspace שבו ירוצו הפקודות שלנו, אנחנו ניצור איזושהי קונפיגורציה כללית שניצור את ה runspace ישר איתה (ניתן גם לשנות לאחר מכן) - לצורך העניין, הסתכלו על הקוד הזה:

image

 

 

 

 

בקוד הזה, אנחנו יוצרים את RunspaceConfiguration ואת PSSnapnInException. מטרת הקוד ליצור סט הגדרות שמכיל כבר איזשהו Power Shell Snap In שקיים (במקרה הזה, אנחנו רק עושים Add, מתוך נקודת הנחה שהוא כבר רשום - עבר installutil) ובמידה ומתגלה שהוא לא קיים, אנחנו זורקים Exception. ה PSSnapInException שמועבר בתור out parameter יכיל את פרטי השגיאה.

עכשיו, כדאי שניצור את ה Runspace עצמו - ונעביר לו ב constructor את config, כלומר, שיפעיל את עצמו כבר עם סט ההגדרות שקבענו (ניתן גם לא להעביר כלום):

image

 

עם המתודה Open, אנחנו למעשה פותחים את ה stream של ה runspace.

השלב הבא, הוא ליצור את ה pipeline. ה pipeline הוא למעשה סט הפקודות שאנחנו מעבירים לביצוע ה powershell, מדובר בצינור שלק\ פקודות, שיכולות להיות משורשרות אחת לתוך השנייה, ולהשפיע אחת על השנייה. בדוגמא הזאת, אנחנו פשוט מעבירים את הפרמטר command שמקבלת המתודה שלנו שמכיל את הפקודות להריץ:

image

 

 

בשלב הזה, הפקודה כבר בשלה להרצה. אולם, אחד מהחוזקים של ה powershell הוא שהוא מעביר stream אל אובייקטים בין חלקיו השונים, בניגוד, למשל, ל shell-ים של מערכות אחרות שעובדות עם text streams. לכן, בגלל שמדובר ב stream של אובייקטים, אם נריץ למשל את הפקודה get-process, לא נקבל טקסט עם רשימת הפרוססים, אלא נקבל מערך שלא בוייקטים מסוג System.Diagnostics.Process - דבר שיכול מאד להעיל לנו בעת העבודה (אנחנו מקבלים הרבה מאד מידע, מקבלים אובייקט שלם שכשיר לעבודה ישירות בדוט.נט, בלי צורך להמיר את הטקסט לאובייקט).

אולם, במקרה הזה, אנחנו רוצים להוציא את מהידע בסוף לאיזשהו textbox, ולכן נוסיף ל pipeline שלנו את הפקודה out-text, שלמשל, דרך אגב, ב gui של ה powershell עצמו מתווספת אוטומטית לכל פקודה - כדי שיסגנן לנו את האובייקט שהוא מקבל לטקסט. פה אנחנו אומרים ל powershell שאנחנו לא מעוניינים ב stream של אובייקטים אלא ב stream של טקסט, ושידאג לספק את מבוקשינו.

image

 

עכשיו, הגיע הזמן להריץ את הפקודה ולעשות Invoke ל Pipeline. לשם כך, נשתמש בקוד הבא:

image

 

 

בהתחלה, אנחנו שמים ב try את הקריאה למתודת ה invoke עבור ה pipeline, שאת התוצאות שלו אנחנו מכניסים ל collection. אם הפקודה הזאת לא קיימת (לא נמצא cmdlet, function או provider בשם זה), ייזרק CommandNotFoundException. בכל אופן, בסוף התהליך, אנחנו סוגרים את ה runspace.

 

עכשיו, לנוחותכם, הנה כל קוד המתודה. בסוף, אנחנו עוברים על כל ה collection ומכניסים ל StringBuilder ובסוף מחזירים string.

image

 באירוע הלחיצה על ה button אנחנו קוראים למתודה ומכניסים את הערך שלה לתוך ה textbox, כשבמידה והוא ריק, כותבים הודעה:

image

 אם אנחנו רוצים, לשנות דברים הקשורים ל powershell, כמו להוסיף snapin תוך כדי ריצה לאחר שיצרנו את ה runspace עם ה configuration שלנו, או להוסיף משתנה, ניתן לעשות זאת כך:

image

 

 

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

היות שהוספנו את ה Snap In שכתבתי במהלך ה webcast, אתם יכולים לראות את זה שאני יכול בקלות להוסיף מהאפליקציה הזאת, באמצעות פקודה, website ל IIS:

image image
 

תיבת הפלט ריקה, כי הפקודה לא מחזירה שום פלט, אולם, בIIS באמת התווסף הwebsite, ואתם יכולים לבדוק בעצמכם (אם יש לכם את ה snapin הזה מותקן).

image

הנה התוצאות עבור הפקודה get-service, שחוזרים כטקסט כי ציינו את זה והוספנו פקודה מתאימה ל pipeline, אחרת, היינו יכולים באפליקציה קצת יותר משמעותית, לקבל אותם כמערך ולעבוד עליהם מתוך האפליקציה, כשאנחנו יכולים לשלוט עליהם בקלות.

לנוחותכם, ניתן להוריד את הפרוייקט המלא מכאן.

בהצלחה.

מחשוב לביש

אני רוצה להמליץ לכם על אתר, בנושא מחשוב לביש (ללבוש את הטכנולוגיה עליך, למעשה). מדובר בענף די מתפתח, שמטרתו להעביר כמה שיותר מהטכנולוגיה השימושית שמשמשת אותנו הרבה לבגדים. בינתיים, יש לזה 2 חסרונות עיקריים: או שזה יקר מאד, או שזה לא שיא היופי. למרות, שעם הזמן החסרונות נפתרים, וכבר רואים בגדים ואבזרי לבוש שונים שהם בהחלט מגניבים.

אתם מוזמנים להיכנס לפורטל מחשוב לביש.

[טיפ] קבלת משתני סביבה דרך Power Shell

כדי לקבל משתני סביבה דרך Power Shell, יש לנו דרך ממש פשוטה:

image

 

 במקום <<<VarName>>> מגיע שם המשתנה. למשל, הנה הדפסה של כמה ערכי משתנים:

image

בסופו של דבר, ניתן להשתמש במשתני הסביבה הללו מכל מקום ב powershell, ובקלות.

בהצלחה.

הוספת רפרנס ל DLL דוט.נטי ל Windows Power Shell

בעקבות אחד הפוסטים פה, נשאלתי איך ניתן להוסיף לסקריפטים ב power shell רפרנס לאיזשהו DLL דוט.נטי, בין אם של מיקרוסופט ובין אם לא.
כמו הרבה דברים, גם הפיתרון של זה מצריך פשוט קצת שימוש ב .net ובפונקציונאליות שלו שמובנת ב Windows Power Shell.

אני מניח שרוב המתכנתים פה שמעו על Reflection ועל הניימספייס System.Reflection - אז עכשיו, תוך שימוש פשוט בזה, ניתן להוסיף רפרנס. הסתכלו על הקוד הבא:

[System.Reflection.Assembly]::LoadFile("C:\windows\system32\inetsrv\microsoft.web.administration.dll")

באמצעות הקוד הזה טענתי את הDLL שמכיל את הפונקציונאליות של ניהול הIIS - באותה צורה ניתן לטעון כל DLL, בין שהוא טעון בGAC ובין שלא.

לאחר מכן, ניתן להשתמש בDLL כרגיל:

$a = new-object Microsoft.Web.Administration.ServerManager

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

בהצלחה.

רישום אוטומטי של snap in אחרי כל build מוצלח ב Visual Studio

במדריכים הקודמים שלי בנושא powershell, הטרחתי אתכם כל הזמן כשאתם בונים snapin ללכת ידנית, לעשות להם install util וכו'. רציתי להראות לכם סקריפט קצר ונוח שעושה עבורכם את זה אוטומטית. את הסקריפט אתם יכולים להוריד מפה.

הסקריפט מקבל פרמטר אחד עם כתובת הDLL שאותו אתם רוצים לרשום. את הסקריפט אתם אפילו לא צריכים להריץ ידנית. ב Visual Studio יש אפשרות לקבוע פקודות שיורצו לאחר כל build - אז נלך, ונניח ששמנו את הסקריפט ב root של כונן C - נכתוב את הפקודה הבאה:

image

 מעכשיו, אחרי כל build יורץ הסקריפט הזה על הDLL - שמה שהוא עושה זה להסיר את הרישום ולרשום מחדש. במידה ויש שגיאות, אתם תוכלו לראות אותם בחלון של ה build output ולדעת מה הם - בלי לצאת מה Visual Studio ובלי להפעיל את ה power shell.

בהצלחה.

כשאתם כותבים cmdlet, תשתמשו באפשרויות המובנות עד כמה שאפשר

בדוגמאות הקודמות, הראתי באיזה קלות ניתן לשלב מתודות ומחלקות של דוט.נט ב cmdlets שכותבים. בין השאלות ששאלו אותי, זה איך כדאי לנהוג במקרה שאתה רוצה להשתמש ולבצע פעולה שיש לה מקבילה גם בקרב הדוט.נט וגם במסגרת התשתית שיש לכתיבת cmdlets (כתוצאה מהירושה מ PSCmdlet או מ Cmdlet).

התשובה, לשאלה הזאת, היא די חד משמעית - תשתמשו בפונקציונאליות שנועדה במקור לשמש לכתיבת cmdlets. לשם הדוגמא, איך כדאי להדפיס משהו - האם בתור Console.Write או אם write-host - התשובה תהיה עם write-host.

הסיבה היא ש cmdlets של Power Shell יכולים לשמש גם משורת הפקודה עצמה, וגם מאפליקציות שמשתמשות בה בתור תשתית.
אם אנחנו כותבים באמצעות Console.WriteLine, אנחנו מגבילים למעשה את ה host שלנו ל host שתומך בכתיבה למסך, כלומר, כמעט תמיד רק שורת הפקודה.

כשמשתמשים ב write-host, ה pipeline יודע לאן רצוי להפנות את המידע ובאיזה צורה. אם נכתוב אובייקט, לדוגמא, עם write-host ולא נשתמש באותו cmdlet מה powershell אלא מאפליקציה אחרת, הוא יידע שהוא לא צריך להדפיס את הערך כ string, אלא להעביר את האובייקט [באחד המאמרים הבאים אכתוב על שילוב באמצעות Runspace ואז זה יובהר יותר טוב]. הוא ישתדל להתאים את צורת הכתיבה של המידע והעברתו ל host שמריץ את האפליקציה - לא משנה איזה הוא.

כשמשתמשים ב console.read, אנחנו למעשה יוצרים באיזושהי מידה הגבלה לקריאה מהמקלדת, מה שלא תמיד רצוי - נניח כשאנחנו כותבים cmdlet שאמור לשמש גם מחוץ ל power shell, ואז יקשה על האפליקציות להשתמש בו, כי לא תמיד ה host מסתמך על קריאה מהמקלדת.
במידה ואנחנו בטוחים שאנחנו כותבים רק ל cmdlet, ניתן להשתמש בזה, למרות שברור מראש שזה עלול להגביל ולהקשות לאחר מכן על שימוש ממקורות חיצוניים.

אם אנחנו כותבים cmdlet שאמור לשמש גם אפליקציות שמשתמשות בתשתית של ה PS ולא בו עצמו, רצוי לאמץ את הכלל שאומר שלא להשתמש באף אחת מהמתודות הסטטיות שב class ששמו System.Console מאחר שהללו בד"כ מגבילים את ה hosts שיכולים לשמש את האפליקציה.


ולסיום, שתהיה לכולנו שנה טובה, מלאת הצלחות והנאה בכל התחומים. והעיקר, בריאות.

שנה טובה.

אז מה זה scripting

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

אני לא אכביר במילים, ואתן לכם ישר לראות על מה מדובר. אנא הורידו מפה את קובץ הZIP שכולל את הסקריפט. הדבר היחיד שאתם צריכים לדאוג זה שהקובץ text.txt יהיה ממוקם ב root של כונן C, מכיוון שהנתיב הזה מצויין בקוד עצמו.

הסקריפט הזה פשוט מאד:

image

 

בתחילת הסקריפט, אני משתמש ב cmdlet ששמו write-warning כדי להדפיס הודעה למשתמש ואז משתמש ב System.Console.Read שימתין עד שהמשתמש יואיל בטובו להקיש על המקלדת.

בשורה הבאה, אני יוצר אובייקט COM של Sapi.SpVoice - כלומר, text to speech.

אני משתמש ב new-object בדומה ליצירת מופע לאובייקטים דוט.נטיים, אבל מוסיף את הפרמטר -com, שמזכיר שאחרי הכל מדובר ברכיב COM.

לאחר מכן אני שואב את התוכן של קובץ טקסט, ומשתמש במתודה speak כדי שהוא יגיד את הטקסט.

כדי להראות שזה מתבצע שורה אחרי שורה, עכשיו, תוסיפו איזושהי שגיאת כתיב לשורה הראשונה. כשתריצו את הסקריפט (באמצעות הנתיב, או אם זה באותה תיקייה עם ./ בהתחלה), תראו כך:

image

 אבל אחרי שלוחצים על איזשהו מקש רואים שפתאום הכל ממשיך לעבוד. הלחיצה על המקש, זה בגלל המתודה Console.Read שמתבצעת.

זה המהות הבסיסית של scripting - ביצוע שורה אחר שורה, מה שמאפשר עבודה גמישה יותר לעיתים ומשפיע די הרבה על שיטת העבודה.

בהצלחה.

אל תכתבו APIs - כתבו Cmdlets!

Power Shell נמצא איתנו פה בשוק כבר כמה זמן, אבל עדיין, אנשים לא מאד מודעים לעוצמה האדירה שלו. בפוסטים (ובוובאקסט) הקודם, כתבתי על כתיבת cmdlets שונים. בד"כ, למטרות ביצוע פעולות דרך שורת פקודה, או כדי שאפליקציות אחרות ישתמשו בפקודות הללו לצרכיהן, כתשתית.

הסעיף האחרון, הוא למעשה SDK. אפשר לכתוב cmdlets, מתוך ידיעה, שאפליקציות אחרות יוכלו להשתמש בהם בתור API שלם כאשר אם משתמשים בהם מה Power Shell הן יעבדו בתור אפליקציות command line ומצד שני, ניתן יהיה להשתמש בהם כ classes באפליקציות דוט.נטיות אחרות, בלי קשר כלל ל power shell, ובלי עירובו בביצוע הפעולות - ממש כמו כל API אחר (שימו לב שמדובר על מחלקות שיורשות מ Cmdlet ולא מ PSCmdlet ההבדל מתואר פה).

להרוג 2 ציפורים במכה אחת

בצורה הזאת, אתה מנצח בשתי החזיתות - מצד אחד, מספק את ה API הנחוץ לשכבה נוספת באפליקציה שמשתמשת בAPI הזה, או אף לאפליקציה אחרת שמשתמשת בAPI הזה, שמבוסס על cmdlet שהאפליקציה שלך חושפת.

מצד שני, ה API שלך, שכתבת, יכול לשמש כפי שהוא גם בשימוש מתוך power shell, ללא צורך בשינויים - אותו API מאפשר גם סקריפטינג.
אם אתה מוסיף עוד טיפה מאמץ, אתה יכול לבנות GUI שלם לניהול משורת הפקודה, שתומך גם בסקריפטינג וגם מאפשר שימוש כ API רגיל מתוך כל אפליקציה בלי קשר לשאלה האם מותקן או לא מותקן באותו מחשב power shell וגם, בנוסף לכל, במסגרת פקודות מבוססות verb-noun משורת הפקודה.

פעולה אחת, שנותנת לך ניצחון בכל החזיתות. תחשבו על זה.

נ.ב. למיטב ידיעתי, ב Exchange 2007 - הלכו בשיטה הזאת, ורוב אם לא כל ה API שלהם מבוסס cmdlets.

Cmdlet מול PSCmdlet

ב WebCast ובמאמרים הקודמים על כתיבת cmdlets, הדגמתי לכם שימוש וכתיבה באמצעות מחלקה שיורשת מ PSCmdlet. אולם, הראיתי שאפשר גם לרשת מה class ששמו Cmdlet - אולם לא נכנסתי להבדלים.

ההבדל בין cmdlet ו pscmdlet - הוא אחד ויחיד - האם הם תלויים בסביבת ה runtime של power shell או לא. בעוד שמחלקות שיורשות מ System.Managment.Automation.PSCmdlet תלויות בסביבת הריצה של powershell לצורך הפעלתן והרצתן, מחלקות שיורשות מ System.Managment.Automation.Cmdlet - לא זקוקות לסביבת הריצה של power shell לצורך הרצתן, ויכולות גם לרוץ מ power shell וגם שישתמשו בהם מכל קוד דוט.נטי אחר, כמו בכל מחלקה אחרת, כחלק מ class library, למשל.

אז למה לך להשתמש ב System.Managment.Automation.PSCmdlet?
לכאורה, באמת אין סיבה - להיפך, רק חסרונות. אתה מייצר תלות נוספת באיזושהי סביבה.
אולם, למעשה, PSCmdlet יורשת מ Cmdlet ומספקת פונקציונאליות נוספת של עבודה מול ה powershell בצורה יותר עמוקה, למשל, עם PSCmdlet ניתן לקרוא ולהריץ סקריפטים [שפעולתם מבוצעת שורה אחר שורה, כך שאם שורה אחת נכשלת, עדיין השורה הבאה ממשיכה להתבצע], לגשת ל session state הנוכחי של power shell וכו'. כלומר, אינטגרציה יותר עמוקה ל Powershell

ב PSCmdlet תשתמש כשאתה רוצה לכתוב משהו שירוץ בהכרח במחשב שיש בו Windows Power Shell, ואפילו אם הוא מורץ מתוך אפליקציה דוט.נטית אחרת, אתה יודע שהוא יהיה בסביבה המתאימה.

ב Cmdlet, תשתמש כשאתה רוצה להרוג 2 ציפורים במכה אחת, גם לכתוב מחלקה, לא תלוייה, שאפשר להשתמש בה משאר האפליקציות או מאפליקציות אחרות (אם אתה חושף אותה) כרפרנס, וגם, מאפשר לבצע פעולות שונות שאותם אתה מגדיר במתודה מסויימת שדרסת (BeginProcess,ProcessRecord,EndProcessing), בנוסף לתיפקוד בתור מחלקה רגילה. מה שמוגדר באותם מתודות, הוא עבור ה powershell. בשאר, ניתן יהיה להשתמש גם מתוך ה power shell וגם באופן נייטרלי, מתוך כל אפליקציה דוט.נטית אחרת.

בהצלחה.

טיפ - כתיבת output לתוך קובץ

נניח שאתם רוצים להריץ איזושהי פקודה, ולהכניס את הפלט שלה לתוך איזשהו קובץ, ב Power Shell - זה ממש פשוט.
הסימנים < ו- > משמשים להכוונת נתונים. כלומר, אם תכתבו את הפקודה הזאת:

image

הפקודה הזאת תכתוב את הפלט של tracert על microsoft.com לקובץ שציינו. ועכשיו, אם נפתח את הקובץ, נראה את הפלט:

image

בהצלחה.

More Posts Next page »