13/08/2019

מדריך ל Power Shell בעברית חלק 3 - הרחבה של סינונים ומיונים.



חלק 3


שלום - במידה ולא קראת את החלק הראשון והשני של המדריך אין לך טעם להמשיך לקרוא, אנא עבור על החלק הראשון והשני של המדריך:

לכלל הפוסטים והמדריכים בנושא ה PowerShell ניתן למצוא כאן
לפורום בנושא באתר devhub.co.il כאן

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

מאמר זה יתמקד אך ורק ב - 3 פקודות הסינון ב PowerShell

1) select-object
2) where-object
3) group-object


מיונים, מיונים, מיונים

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

לצורך ההדגמה אני צריך פקודה עם הרבה עמודות, אני אקח את get-process שיציג לי את התהליכים של הדפדפן אינטרנט גוגל כרום, אז נבצע את זה בצורה הבאה: get-process -name chrome (שימו לב, ניתן גם לקבל פלט בלי הפרמטר Name אבל מאחר ואתם רק בהתחלה, מאוד ממליץ לא לעשות קיצורי דרך ולהשתמש בכל הפרמטרים שאתם יכולים, על מנת שהמוח שלכם יזכור את הפעולות והפרמטרים בצורה טובה יותר) 


נקבל את הפלט הבא:


get-process -name chrome



לאחר מכן  אני אריץ את אותה הפקודה עם הפרמטר get-member בשביל לבדוק אילו עמודות אני יכול להציג

get-process -name chrome |get-member



קיצרתי את הרשימה, לצורך ההדגמה אבל ישנם גם Methods שאילו הם בעצם פעולות שניתן לבצע על האובייקט (זאת אומרת, להפעיל, לסגור, להרוג תהליך וכד'), עמודות כפי שלמדנו במדריכים הקודמים נקראים Properties וגם ה Alias Properties הם עמודות, רק שהחליטו לקצר להם את השם, אז במקרה הזה אני ארצה להציג את ה:
Processname, ID ,Responding:

אז בעצם הפקודה שלנו תראה כך:

get-process -Name chrome |Select-Object Processname,ID,responding

(שימו לב, בחלק השני של הדוגמא - ניתן לראות את הפקודה הנ"ל ללא שימוש ב- Select-object)


האם ניתן לבצע שינוי לשם העמודות? - כן
נצא מנקודת הנחה שאתם רוצים לשנות את שם העמודה שאתם מקבלים כי זה יותר נוח לכם, ניתן לבצע שינויים אומנם הסינטקס יהיה קצת יותר ארוך, לצורך הדוגמא אני אקח את הפקודה שהשתמשתי בא למעלה - get-process עם הפרוסס של כרום:



להלן הפקודה עצמה: 
Get-Process chrome |Select-Object @{label='Shnitzel_levs_test' ; expression='Id'}, ProcessName

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

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

במקרה של הדוגמא הנ"ל ביצעתי שינוי לעמודה Id וקראתי לה בשם Shnitzel_levs_test

*  הפרמטר "Label" - מסמן את השם שאנחנו רוצים לתת 
* הפרמטר " Expression" - מסמן את העמודה שאנחנו רוצים לשנות

ניתן לקצר ולכתוב אך ורק את האותיות ההתחלתיות "l" ו האות " e" מה שיגרום לפקודה להיראות ככה:

Get-Process chrome |Select-Object @{l='Shnitzel_levs_test' ; e='Id'}, ProcessName

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

ניתן להחליף את האות "l" (האות L בקטן)  בתוך @{l='Shnitzel_levs_test' ; e='Id'} באות "N" (קטנה) או לשם שינוי לכתוב את המילה "name" ותקבלו את אותה התוצאה, כמו כן כמו בכל הפעמים את ה סימן "._$" ניתן להחליף במילה Psitem$ וגם כאן תקבלו את אותה התוצאה.

Get-Process chrome |select @{n='Shnizel_levs_test';e={$_.Id}},ProcessName

Get-Process chrome |select @{name='Shnizel_levs_test';e={$PSItem.Id}},ProcessName



התוצאה תהיה זהה.



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

עם הפקודה הזאת ניתן לעשות המון סינונים ולכן ישנם גם המון פרמטרים:




פרמטרים השוואתיים

-eq שווה ל
-ne לא שווה ל
-gt גדול מ
-ge גדול מ או שווה ל
-lt קטן מ
-le קטן מ או שווה ל

פרמטרי התאמה

-like - *.txt הצג תוצאות אשר דומות למחרוזת הכתובה (טקסט) ניתן להתמש ב"וייל קארד" - לדוגמא 

Get-Service bits |Where-Object status -Like running

-notlike - *.txt הצג תוצאות אשר  לא דומות למחרוזת הכתובה (טקסט) ניתן להתמש ב"וייל קארד" - לדוגמא 

Get-Service bits |Where-Object status -NotLike running

-match - הצג תוצאות אשר המחרוזת מתאימה לערך מסויים

Get-Service bits |Where-Object status -Match running

-notmatch - הצג תוצאות אשר המחרוזת לא מאימה לערך מסויים

Get-Service bits |Where-Object status -NotMatch running

¿?יש עוד המון פרמטרים לפקודה הזאת את כולם ניתן לראות באתר של מיקרוסופט כאן¿?

כפי שהזכרנו למעלה, ניתן להשתמש בפקודה הזאת בסינטקס פשוט ובסינטקס "מורכב" יותר 
דוגמא לסינטקס פשוט: 
"Get-Service  bits |Where-Object status -eq "running

דוגמא לסינטקס ה"מורכב" :

{"Get-Service bits |Where-Object {$_.status -eq "running


מה המשמעות של הסימן הזה "._$" בפקודה Where-object? 
 ובכן לצורך ההבנה, אנחנו נפרק את ההסבר על הפרמטר הזה ל-2, החלק הראשון הוא הסבר על הסימן של ה "._$" ולאחר מכן נוסיף את ה "." והמילה "status".

ניקח לדוגמא את הפקודה get-services, הפקודה הזאת מייצרת המון שורות והמון עמודות, במקרה הזה הסימן "_$" מיצג כל שורה שעוברת בתוך הפייפליין, למי שנוח בתור התחלה יכול גם להשתמש במילה psitem$ ואז הפקודה תיראה ככה {"where-object {$psitem.status -eq "running

לאחר הסימן של ה "_$" מתווספת גם ה "." והמילה "Status", המשמעות היא מאוד פשוטה, ועכשיו זה יתחבר לכם עם החלק הראשון, במקרה הזה, אני רוצה לראות אך ורק את העמודה בעלת השם Status מכל התוצאות, ואז בעצם הפקודה תתפרש ככה: "הראה לי מתוך התוצאה של get-service רק את העמודה "Status" בעלת הערך "running", ואם נעשה "Reverse Engineering" נקבל את זה ככה:

{"get-service bits |where-object {$psitem.status -eq "running

לצורך הדוגמא, הרצתי את כל האופציות על מנת שתבינו:



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

לצורך דוגמא - להלן סקריפט שאני משתמש בו לבדוק האם כתובת IP מסוימת נמצאת ב Reservation בשרת ה DHCP שלי:

"Write-Host " this scrip will check if any ip is reserevd on the local DHCP

Get-DhcpServerv4Scope |select Name,@{l='Scope' ; e='ScopeID'}, StartRange, EndRange |ft -AutoSize

"scopes = Read-Host " what is the Ip Adress that you want to search? - enter ipadress$

Get-DhcpServerv4Reservation -ComputerName $env:COMPUTERNAME -ScopeId $scopes |

הפקודה בשילוב הסקריפט ->         {"*Where-Object {$_.IPAddress -like "*$scopes |
        
Select-Object IPAddress, ScopeId, Description |ft -AutoSize

        
        pause




group-object - מאפשר לבצע קיבוץ של התוצאה לפי שמות של עמודות, או שמות האובייקט וכד'.

להלן 2 דוגמאות :

1)  Get-Service -Name bits, wscsvc,winrm |Group-Object status, displayname

2) Get-Service -Name bits, wscsvc,winrm |Group-Object DisplayName, status







מדיך מצולם :





עד כאן להפעם.
המייל שלי לכל שאלה
 :
levl@leidertech.co.il

אל תשכחו לתת לנו לייק בדף הפייסבוק - חפשו LeiderTech.

לכלל הפוסטים והמדריכים בנושא ה PowerShell ניתן למצוא כאן
לפורום בנושא באתר devhub.co.il כאן

13 תגובות:

  1. תודה רבה על המדריך, כמו תמיד מחכה למדריך הבא.

    כמו כן אשמח אם תוכל לתת יותר מדוגמה אחת על שילוב $_. בסקריפט או הסבר על הסקריפט שלך וצירוץ הפלט שלו.

    השבמחק
  2. היי,
    קודם כל תודה רבה :)

    הסקריפט הזה בודק האם מחשב מסויים נמצא ברשימת ה Reservation של שרת ה DHCP, זאת אומרת במידה ואני מכניס כתובת IP מסויימת או כמה כתובות IP, תעבור על כל שורה בעמודה IPAdress ותבדוק האם ה-IP הזה נמצאת ב Scope שאני מבצע עליו את הבדיקה.


    אז המשמעות של "עבור על כל שורה בעמודה IPAdress" הוא בעצם ה "._$", במקום שזה יבלבל אותך תשתמש ב psitem$ - תחשוב על זה של PSitem בפירוש שלו הוא "פריט", ככה יהיה לך יותר קל להבין את הסינטקס ולזכור איך להשתמש בזה נכון.

    בעברית הפקודה הזאת בערך תיראה ככה

    {"*Where-Object {$_.IPAddress -like "*$scopes -

    {"*משתנה-סקופ$*" דומר- עמודה-בשם-כתובת-אייפי.פריט-פאוואר-שלל$} היכן-שהאובייקט

    זה הכי ברור שהצלחתי :)

    אם יש עוד שאלות, אני כאן.

    השבמחק
    תשובות
    1. היי לב ,
      כל הכבוד על ההשקעה בכתיבת מדריך נורמלי בעברית.
      לגבי הדוגמא של ה$_. אני חייב להגיד שמשהו לא ברור לי.
      בדוגמא המסקיפט שלך {"*Where-Object {$_.IPAddress -like "*$scopes
      לא ניתן פשוט לרשום כמו בדוגמא הפשוט פשוט לכתוב ככה:
      "*Where-Object IPAddress -like "*$scopes ?
      אני חפשתי קצת בגוגל ונראה לי שהבנתי שנגיד למשל במצב הבאה באמת לא ניתן לעבוד בצורה הפשוטה למשל ב: Get-Service | foreach { Write-Output $_.Name}
      אם נכתוב את זה ככה זה פשוט לא יעבוד: Get-Service | foreach Write-Output Name

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

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

      במידה ויש לך שרת DHCP לבדוק עליו, עשה בדיקה ועדכן אותי (או שאולי אני אגיע לשרת DHCP יותר מהר ואעדכן אותך בעצמי :), רק השאר לי מייל או שאפשר להגיב כאן.

      מחק
  3. תודה על התושבה זה מספיק מובן.
    אשמח אם תוכל בעתיד לעשות מדריך על foreach/foreach-object

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

      מחק
  4. תודה רבה על ההשקעה שלך.

    השבמחק
  5. היי לב ,
    תודה על ההשקעה , הסברים מאוד ברורים .
    אנחנו משתמשים בPOWERSHELL עבור POWER BI , מחפשים דרך לבצע LOGIN אוטומטי בכחלק מהסקריפט , ז"א ללא PROMPT.

    השבמחק
  6. היי,
    תרשום לי בבקשה למייל מה בדיוק אתה צריך
    levl@leidertech.co.il

    השבמחק

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

תודה :)