17/01/2021

מדריך ל PowerShell בעברית חלק 8 - איך ליצא מידע לקובץ CSV מ-PowerShell?

חלק 8 - איך ליצא מידע לקבצי CSV מ PowerShell?

 


כמו תמיד - במידה ולא עברתם על החקלים הקודמים - ראשית עברו על החלקים הקודמים ורק לאחר מכן המשיכו לקרוא:

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

בפרק הקודם למדנו כיצד ליבא קבצי CSV, אך מה לעשות אם אנחנו צריכים ליצא קובץ CSV? ליצא מידע מהמערכת ולהעבירו למישהו וכד', בדיוק לכך נועדה הפקודה export-csv

כמו שכבר ראינו, PowerShell מאוד נוחה ומאוד פשוטה, והכי חשוב מאוד הגיונית, אם יבוא של קובץ נבצע בעזרת הפקודה Import-csv, אז איך בעצם נבצע יצוא? - ניחשתם נכון, בעזרת export-csv.

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

Get-Process notepad| export-csv -Path 'C:\Users\lev\Desktop\PowerShell - CSV post\test.csv'

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

Get-Process notepad|select ProcessName, id, cpu| export-csv -Path 'C:\Users\lev\Desktop\PowerShell - CSV post\test.csv'

וזה התוכן שנקבל בתוך קובץ ה CSV:



בטח אתם שואלים את עצמכם מה זה ה"Еype" הזה שהופיע לנו?

אז בתור התחלה אם תריצו Get-process notepad | get-member, למעלה תקבלו את המידע הזה:


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

Get-Process notepad |export-csv -Path 'C:\Users\lev\Desktop\PowerShell - CSV post\test.csv' -NoTypeInformation

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

תחילה נריץ את הקובץ הקודם ונראה את התוצאה - הקובץ שנוצר:




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

Get-Process taskhostw |export-csv -Path 'C:\Users\lev\Desktop\PowerShell - CSV post\test.csv' -Append  -NoTypeInformation



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


להלן דוגמא "מהחיים" לסקריפט שמיבא את כלל תיבות הדואר מתוך ה-365 ובודק גודל תיבה:

$users = Import-Csv "C:\CSV Test\Alias_test.csv"
 
 foreach ($user in $users) {

 Get-MailboxStatistics -Identity $user.UserName |

 Select-Object @{l="User Name";e="DisplayName"},

  @{l="Mail Box Size";e="TotalItemSize"}, @{l="Total Emails?";e="itemcount"} |

  Export-Csv "C:\CSV Test\Mailboxe_size.csv" -Append -NoTypeInformation
 } #end of ForEach loop



כמו תמיד מדריך מצולם יצורף בהמשך.

לכל שאלה המייל שלי: levl@leidertech.co.il





לעוד מדריכים:

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

מדריך ל PowerShell בעברית חלק 7 - איך לייבא קובץ CSV לתוך PowerShell?






חלק 7



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

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

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

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

ניתן לבצע מגוון רחב של מוניפולציות על קבצי CSV, בעזרת הפקודה import-csv.

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

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

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

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



cls
write-host -BackgroundColor Blue "##########################"
write-host "Network Testing Script"     
write-host "`n"
write-host "Made by:"
write-host "`n"
Write-Host "LeiderTech's It Department"
write-host "`n"
write-host -BackgroundColor Blue "##########################"

write-host "`n"
write-host -BackgroundColor Gray "What this thing do?"
write-host "`n"
write-host "This script will 'Ping' each computer for 2 times 
            `n and write the result in a colorable answer"

write-host "`n"
write-host "Have fun"
write-host "`n"
#Ask user for the computer names or ip's
$orgspc = (Read-Host -Prompt "Please write the computer names of the pc's you want to check, with comma seporated (you can combine IP's and pc's to: 192.168.2.1,pc-01 etc..)").split(',') | ForEach-Object {$_.trim()}

#start the foreach loop
         foreach ($pc in $orgspc) {

 #The "if" quastion:         
          $VerbosePreference = 'continue'
          if (Test-Connection -computername $pc -Count 2 -Quiet) 
          {write-host -BackgroundColor green -ForegroundColor Blue "`nThe connection to ->$pc<- is OK :) !!!" }
 #The "Then" condition
          else { Write-Verbose "`nThe Connection to ->$pc<- is not good :( !! "}
          }
          write-host "`n"  
          pause




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

ישנן המון סיבות ומצבים בהם נשתמש בקובץ CSV, להלן שתי הסיבות העיקריות שלי אישית יצא להשתמש בקובץ CSV:
  1. אקטיב דירקטורי (Active Directory) - תתארו לעצמכם שאת כל בניית הדומיין החדש שלכם אתם יכולים לעשות בצורה מאוד נוחה, ובתוך קובץ CSV (לרוב אנחנו נשתמש באקסל למטרה הזאת) ולאחר שביצענו שינויים ועריכה של המשתמשים לדומיין החדש - תתארו לעצמכם שאתם צריכים ליצור אקטיב דירקטורי שלם של 80-90 משתמשים.. עם הסיסמאות והפרטים המלאים שלהם.
  2. אופיס 365 (Office 365) - המון אנשים היום עוברים לאופיס 365, מיקרוסופט מאפשרים לעבוד עם PowerShell מול אופיס 365 בצורה דיי נוחה, מה שמאפשר לנו אנשי המחשוב לעבוד בצורה הרבה יותר פרודוקטיבית, ונוחה.
  3. וירטואליזציה - ניתן להפעיל ולכבות מכונות וירטואליות, לבצע שינויים על מכונות וירטואליות.
  4. כל דבר שמצריך ממכם לבצע פעולות על אובייקטים שונים - כולל הדברים הכי פשוטים, לבדוק תקשורת, לכבות מחשבים וכו' וכו'.


אז ראשית, למי שלא מכיר איך יוצרים קובץ CSV?

במידה ואין לכם מושג איך יוצרים קובץ CSV - לימדו כיצד ליצור את הקובץ וחזרו למדריך מאחר ומדובר בידע מאוד בסיסי חובה עליכם לדעת כיצד עושים זאת - אך ומאחר ואין לכם אותו, למדו כיצד ליצור קובץ CSV ולאחר מכן חזרו להמשך המדריך.

אז איך בעצם ליבא את הקובץ לתוך PowerShell?

את הקובץ אנחנו מיבאים בצורה הכי פשוטה והכי אינטואיטיבית שיכולה להיות, בעזרת הפקודה import-csv בצורה הבאה:

import-csv  ואז את הנתיב המלא של הקובץ - שימו לב שאנחנו משתמשים בגרש "בודד" ולא גרשיים "כפולים" כאשר אנחנו רושים את הנתיב (זאת מעבר לעובדה שאפשר להשתמש ב-TAB לצורך השלמת הנתיב), ובמקרה של הדוגמא שלי, אני רוצה לביא קובץ שנמצא בתוך תיקייהת "PowerShell posts" על שולחן העבודה שלי - שנשמר בשם "users.csv".

מאוד חשוב שתבינו איך נראה הקובץ CSV שלי על מנת שתוכלו להבין מה רואים בפלט של PowerShell

אז אני מציג לפניכם את היצירה האחרונה שלי - קובץ בשם Users.csv






לצורך הנוחות בהדגמה אני אשתמש ב ISE:

ניבא את הקובץ: 'import-csv 'C:\Users\lev\Desktop\PowerShell - CSV post\users.csv

ומיד בקונסול נוכל לראות ש PowerShell מצליח לקרוא את כל המידע רק שהוא מציג לנו את המידע כרשימה - כזאת ברירת המחדל ביבוא.

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


נוסיף את ה format-table בסוף ונקבל את אותו הדבר שאפשר לראות בקובץ ה CSV שבנינו:
import-csv 'C:\Users\lev\Desktop\PowerShell - CSV post\users.csv'| ft -AutoSize

לא הוספתי את כל העמודות - כי התצלום מסך הוא רק בשביל להראות שהמערכת יודעת לקרוא את התוכן כמו שצריך


אחרי שהצלחנו ליבא את הקובץ, ניתן לעשות איתו בעצם מה שאנחנו רוצים, ניתן להפוך את כל הקובץ למשתנה ולהוציא ממנו אך ורק מידע ספציפי.. בצורה הבאה - פשוט נוסיף את שם המשתמש שאנחנו רוצים בתחילת הקובץ ולאחר מכן נוסיף את כל פקודת יבוא הקובץ וזה מה שנקבל:
'Csvfile = import-csv 'C:\Users\lev\Desktop\PowerShell - CSV post\users.csv$

ובעצם מתחיל להבנות לנו סקריפט:

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

Csv file Import#
import-csv 'C:\Users\lev\Desktop\PowerShell - CSV post\users.csv'| ft -AutoSize

Set file as variable#
'Csvfile = import-csv 'C:\Users\lev\Desktop\PowerShell - CSV post\users.csv$


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

ניצור את הלולאה שלנו:

foreach($haverim in $Csvfile){

write-host "I love to eat פרגיות with": $haverim."Last name" $haverim.'First Name'

}

ונקבל את התוצאה:




אם אני רוצה להציג רק את העמודה של Department, אני אציב את הקובץ שיצרתי במשתנה ואשתמש ב Select-object:

$Csvfile|select Department

והפלט שנקבל: 



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

נוכל להשתמש באחד מ"אופרטורי ההשווה" או באנגלית "Comparison Operators" ששייכים לפקודת ה Where-Object, לצורך סינון מסויים והצגה של מידע ספציפי - או במקרה שלנו, שורה שלמה מתוך קובץ ה CSV - זאת אומרת נקבל את המידע שיש בתוך כל "תא" בקובץ בהתאם לרובריקה שלו - אם בתא "Department" רשום "IT" על עובד מסויים, אז נקבל את הפלט לפי הדוגמא הבאה:

$list = $Csvfile |where {$_."first name" -eq "bruce"} 
$list



אם נרצה שפלט יהיה קצת יותר דומה לקובץ עצמו, נוכל להוסיף בסוף את ft -autosize





(לידע כללי - אם שאלתם את עצמכם מדוע שמתי את ה-First name בתוך גרשיים?
כי יש רווח בין שתי המילים וזה מסביר למערכת שצריך להשתמש בזה כאילו זה ערך אחד)

המידע שנקבל:
אם אני אסיר את הגרשים המערכת לא תבין מה אני רוצה ממנה ונקבל שגיאה:
המערכת מסמנת לנו שהיא לא מבינה מה זה "name" כי אין שדה כזה בקובץ CSV

נצא מנקודת הנחה שיש לנו קובץ עם המון ערכים ואנחנו רוצים להציג ערך מסוים רק שאנחנו לא זוכרים את שמו, במקרה כזה אנחנו נוכל להשתמש באופרטור "like" של הפקודה where-object - אל תשכחו לשים את הערך שאתם צריכים בתוך "כוכביות" על מנת שהיא תחפש את כל המילה ולא רק את ההתחלה או הסוף של הערך שלכם - במקרה הזה bru.

$list = $Csvfile |where {$_."first name" -like "*bru*"} 
$list  |ft -AutoSize



(בדקו את עצמכם - חושבים שהבנתם את החומר? תחשבו על התשובה וענו לי בתגובות..
בשאר הפוסט אני הולך להשתמש אך ורק במשתנה csvfile$ ללא הצורך ביבוא הקובץ מחדש.. למה בעצם?)


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

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

$Csvfile.count

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

$Csvfile[5]|ft -AutoSize

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

$Csvfile[3].SamAccountName


זאת אומרת שבשביל לבחור שדה, אנחנו נשים "נקודה" ולאחריה את השם של העמודה שאנחנו רוצים להוציא ממנה מידע, חשוב לזכור שמדובר בקובץ אקסל, אז השורה של שמות העמודות לא נחשבת, השורה אחריה היא מספר "0" ואחרי היא מספר 1 זאת אומרת :

first name = לא נספר
Bruce = 0
Tami = 1
Adina = 2
Miri = 3

ככה שלפי הדוגמא שלנו נקבל את התוצאה "Miri" - למרות שבאקסל עצמו היא רשומה בשדה מספר 5.

ואיך זה נראה בקובץ ה CSV שלנו?:



ואם נריץ את אותו הדבר ונציב את "תא" מספר 5 נקבל את Ayala:

Alit  = 4
Ayala = 5





כמו שכבר ראינו, PowerShell מאוד נוחה ומאוד פשוטה, והכי חשוב מאוד הגיונית, אם יבוא של קובץ נבצע בעזרת הפקודה Import-csv, אז איך בעצם נבצע יצוא? - ניחשתם נכון, בעזרת export-csv.

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

Get-Process notepad| export-csv -Path 'C:\Users\lev\Desktop\PowerShell - CSV post\test.csv'

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

Get-Process notepad |select ProcessName, id, cpu | export-csv -Path 'C:\Users\lev\Desktop\PowerShell - CSV post\test.csv'

וזה התוכן שנקבל בתוך קובץ ה CSV:



בטח אתם שואלים את עצמכם מה זה ה"Еype" הזה שהופיע לנו?

אז בתור התחלה אם תריצו Get-process notepad | get-member, למעלה תקבלו את המידע הזה:


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

Get-Process notepad |export-csv -Path 'C:\Users\lev\Desktop\PowerShell - CSV post\test.csv' -NoTypeInformation


ועכשיו היא לא תציג לו את ה Type בתחילת הקובץ שלנו.

בחלק הבא נלמד כיצד נבצע את ההפך - ניצא את המידע שקיבלנו ב PowerShell ישירות לתוך קובץ CSV.

כמו תמיד:
המייל שלי לכל שאלה :levl@leidertech.co.il


בהמשך יצורף מדריך מצולם.



לעוד מדריכים:

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

11/11/2020

מדריך ל PowerShell בעברית חלק 6 - עבודה עם רגיסטרי




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

ככה שקודם כל תעברו על המדריכים הקודמים:

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

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

[reg query HKCU\Software\[PATH_TO_MY_DIR] /v [KEY_NAME

ב PowerShell זה נראה כך:

\Get-ItemProperty HKCU:\SOFTWARE\Google\Chrome

ממש כאילו אתם משתמשים בסייר קבצים בשביל לסייר בין תיקיות, ולמה זה? זה תודות ל - Psproviders, ומה זה בעצם?  מדובר ב"מתאם" שהופך חלקים מסויימים של המידע ל"כונן דיסק" ובעצם מיצר PsDrives , ו PsDrive הוא PowerShell Drive - שזה למעשה סוג של מידע - שמותאם\ממופה ונראה כ"כונן דוסק" שאנחנו מכירים ורואים ב CMD, מה שמאפשר לנו לגשת לכל מיני מקומות במערכת הפעלה בצורה של סייר קבצים, כמו לדוגמא אפשרות לגשת לרג'יסטרי בהיררכיה של ספריות או למפות אותו לאות כונן ולהשתמש בפקודה כמו Dir, CD וכד'.

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

מי שרוצה לקרוא יותר על האופציות של ה Providers\PsDrives - מומלץ לקרוא באתר של מיקרוסופט: כאן


איך עובדים עם הריגסטרי ב PowerShell?

1. נתחיל עם השאלה הכי חשובה - איך לסייר ברגיסטרי כאילו זאת תיקייה רגילה ?

אני מאוד שמח ששאלתם, קודם כל בשביל להבין אילו ל Psdrives יש, אפשר לגשת, נריץ בקונסול את הפקודה:
Get-PSDrive



בתוצאה שנקבל, נראה לאילו נתונים ניתן לגשת, אותנו מעניין הרגיסטי, אנחנו יכולים לגשת ל
1) HKEY_LOCAL_MACHINE - בקונסול (חלון ה PowerShell) נשתמש בקיצור - hklm
2) HKEY_CURRENT_USER - בקונסול (חלון ה PowerShell) נשתמש בקיצור hkcu

בכל מפתח ניתן להוסיף את הערכים הרגילים שאנחנו מכירים מהרגיסטרי (כמה לדוגמא):

1) REG_SZ
2) REG_DWORD 
3) REG_MULTI_SZ

להלן דוגמא להגדרה של אחד הלקוחות שאני נוהג להתחבר אליהם בעזרת FortiClient לצורך תמיכה:





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

לאחר מכן נקבל מצב מאוד מוכר לכולנו - כאילו אנחנו נמצאים בכונן מסויים : 
<\:PS HKLM
:בערך כמו
<c:\users\lev
ועכשיו החלק הכי מעניין, אם נריץ את הפקודה שלומדים בכיתה א' לאנשי Microsoft שהיא dir או בהקבצה א' של לינקוס שהיא ls, נקבל את מה שאנחנו מכירים, תצוגה של התיקייה, או במקרה הזה את הרגיסטרי שאנחנו מכירים מהממשק הגרפי של מיקרוסופט (אל תתיחסו להודעת השגיאה): 




השלב הבא, כפי שכבר ניחשתם, יאפשר לנו פשוט להכנס לכל תיקייה כמו שאנחנו רגילים בדוס, או באחת הפקודות של PowerShell, לדוגמא נכנס ל Software (אל תשכחו שניתן להשתמש ב TAB לצורך השלמה אוט'): 

PS HKLM:\> cd .\SOFTWARE
ואם נקיש עכשיו dir, נקבל את התוכן, כמו שאנחנו רגילים בדוס:



בפקודות של PowerShell יש כמה וכמה פקודות שמקבילות ל cd, כמו שלמדנו בפרקים הקודמים ניתן להשתמש בפקודה get-alias בשביל לבדוק מה מקביל לפקודות שאנחנו מכירים:





 זאת אומרת שאם נרצה להציג את הענף software נוכל לכתוב גם set-location .\software ונגיע לאותו המקום:



2. הצגת ערכים של "מפתחות רגיסטרי" רגיסטרי.

ישנם כמה דברים שניתן להציג: 

א. את המפתח (key) עצמו ואת מה שמתחתיו (Subkey) בעזרת הפקודה - Get-Item
לדוגמאGet-item HKLM:\SOFTWARE\7-Zip


ב. ערך של המפתח ואת מה שהערך מחזיק בתוכו בעזרת הפקודה- Get-ItemProperty
לדוגמאGet-ItemProperty HKLM:\SOFTWARE\7-Zip

ג. ערך ספציפי בתוך קי (Key) מסויים בעזרת הפקודה - Get-ItemPropertyValue
לדוגמא: Get-ItemPropertyValue HKLM:\SOFTWARE\7-Zip\ -Name path64



לצורך הדגמא נגיד ונרצה לדעת מה יש תחת הערך 7zip, פשוט נריץ את הפקודה הבאה :


Get-Item HKLM:\SOFTWARE\7-Zip

ונקבל את התוצאה הבאה :


וכמובן שברגיסטרי הרגיל אנחנו נראה את אותו הדבר:


3) הוספת מפתחות וערכים חדשים

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

לדוגמא: ניצור תחת Software את המפתח LeiderTech וניצור ערך מסוג REG_SZ ונרשום בו Lev1 וניצור עוד אחד בשם Lev2 וניצור ערך מסוג dWord וניתן לו את הסיפרה 1

אז נתחיל ביצירת המפתח במקום הרצוח:

New-Item HKLM:\SOFTWARE\LeiderTech

יצרנו את המפתח הרצוי:



לאחר מכן ניצור את הערכים הרצויים בתוך המפתח:

יצירת סטרינג - REG_SZ:

New-ItemProperty HKLM:\SOFTWARE\LeiderTech\ -Name Lev1

יצירת ערך Dword:

"New-ItemProperty HKLM:\SOFTWARE\LeiderTech\ -Name Lev2 -Value 1 -PropertyType "Dword


התוצאה של כלל הפקודות ביחד:


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

שינוים ב PowerShell מתבצעים בעזרת פקודות שמתחילות בפועל "set", מי שקרא את החלקים הראשונים של המדריך (במידה ולא - כדי מאוד לקרוא - ישלים לכם הרבה ידע !)  יודע שניתן להריץ את get-command ולקבל את כלל הפקודות הרלוונטיות אז נריץ את הפקודה הקצת ארוכה הזאת:

Get-Command -Noun Item,ItemProperty,ItemPropertyValue |Sort-Object -Property Name |select name




לצורך שינוי הערך, נשתמש בפקודה Set-ItemProperty ובעצם נבצע רק את השינוי המינורי שהוא ההתחלה של הפקודה מ New ל Set, ולאחר מכן נמחק את הערך Dword בסוף מאחר ואנחנו רוצים רק לשנות את הערך:

Set-ItemProperty HKLM:\SOFTWARE\LeiderTech\ -Name Lev2 -Value 258

וכמובן התוצאה בהתאם :





5. מחיקת מפתחות וערכים

המחיקה היא גם כן באותה הצורה, רק לשנות את ההתחלה בהתאם למה שאתם צריכים - במקרה הזה נמשתמש ב Remove בשביל למחוק את כל המפתח LeiderTech מהרגיסטרי:

Remove-Item HKLM:\SOFTWARE\LeiderTech\ -Force

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


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


בדקתי את זה על אופיס 2016 - תהנו:

(ניתן לעשות "העתק" - "הדבק" לתוך ה ISE ולהשתמש)

## ==============================================
 office global Active X configuration##
## ==============================================

new-item "HKCU:\\Software\Microsoft\Office\Common\Security"
New-ItemProperty "HKCU:\\Software\Microsoft\Office\Common\Security" -name UFIControls -value 1  -PropertyType "DWord"
New-ItemProperty "HKCU:\\Software\Microsoft\Office\Common\Security" -name DisableAllActiveX -value 0  -PropertyType "DWord"


## ==============================================
## Excel configuration##
## ==============================================


#Enable macros in Excel##

Set-ItemProperty -Path "HKCU:\\Software\Microsoft\Office\16.0\Excel\Security" -Name "VBAWarnings" -value 1
New-ItemProperty "HKCU:\\Software\Microsoft\Office\16.0\excel\Security" -name AccessVBOM -value 1  -PropertyType "DWord"

#Trusted Locations in Excel:#

Set-ItemProperty -Path "HKCU:\\Software\Microsoft\Office\16.0\Excel\Security\Trusted Locations" -name "AllowNetworkLocations" -value 1


#Disabel protected view in Excel#

New-Item "HKCU:\\Software\Microsoft\Office\16.0\Excel\Security\ProtectedView"
New-ItemProperty "HKCU:\\Software\Microsoft\Office\16.0\Excel\Security\ProtectedView" -name DisableAttachmentsInPV -value 1  -PropertyType "DWord"
New-ItemProperty "HKCU:\\Software\Microsoft\Office\16.0\Excel\Security\ProtectedView" -name DisableInternetFilesInPV -value 1  -PropertyType "DWord"
New-ItemProperty "HKCU:\\Software\Microsoft\Office\16.0\Excel\Security\ProtectedView" -name DisableUnsafeLocationsInPV -value 1  -PropertyType "DWord"


## ==============================================#
## Word Configuration#
## ==============================================#


#Enable macros in Word#

New-ItemProperty "HKCU:\\Software\Microsoft\Office\16.0\word\Security" -name AccessVBOM -value 1  -PropertyType "DWord"
New-ItemProperty "HKCU:\\Software\Microsoft\Office\16.0\word\Security" -name VBAWarnings -value 1  -PropertyType "DWord"

#Trusted Locationsin word:#

Set-ItemProperty "HKCU:\\\Software\Microsoft\Office\16.0\Word\Security\Trusted Locations" -name "AllowNetworkLocations" -value 1


#Disable protected View in Word#

New-Item "HKCU:\\Software\Microsoft\Office\16.0\word\Security\ProtectedView"
New-ItemProperty "HKCU:\\Software\Microsoft\Office\16.0\word\Security\ProtectedView" -name DisableAttachmentsInPV -value 1  -PropertyType "DWord"
New-ItemProperty "HKCU:\\Software\Microsoft\Office\16.0\word\Security\ProtectedView" -name DisableInternetFilesInPV -value 1  -PropertyType "DWord"
New-ItemProperty "HKCU:\\Software\Microsoft\Office\16.0\word\Security\ProtectedView" -name DisableUnsafeLocationsInPV -value 1  -PropertyType "DWord"




כמו תמיד, לכל שאלה המייל שלי levl@leidertech.co.il

ומדריך מצולם:




לחלקים הקודמים:

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

19/06/2020

מדריך ל PowerShell בעברית חלק 5 - קבלת קלט ממשתמש והצגתו ב PowerShell



לפני קריאת המדריך חובה לעבור על החלקים הקודמים:

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

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

1) Read-host  - קבלת קלט מהמשתמש - חלון קובץ שמבקש מידע.
2) Write-host - הצגת מידע מותאם, טקסט כזה או אחר, כגון הודעות, הוראות, ניתן גם בצבעים.


ראשית -  הסבר על הפקודה שנשתמש בה לצורך קבלת קלט מהמשתמש - Read-Host.

אז מתי אנחנו בעצם נרצה לעבוד עם קלט כלשהו ממשתמש כזה או אחר? דבר ראשון ברגע שנרצה להכניס בכל פעם שם משתמש אחר, או אולי שם מחשב אחר, או בעצם כל דבר שלא יהיה זהה בכל פעם, הדוגמא הכי טובה לזה, היא עבודה עם סקריפט קצר שבודק תקשורת, במקום שנכתוב כל פעם ping -some ip adress-  -t אפשר פשוט להגיד ל PowerShell שיבקש מאיתנו את כתובת המחשב בכל פעם שנריץ את הסקריפט, הרבה יותר נוח והרבה יותר פרודוקטיבי.

בתור דוגמא אני אצור את הסקריפט הקצר שהצעתי בפיסקה למעלה - סקריפט לבדיקת פינג.

הפקודה ב PowerShell שיודעת לעבוד עם קלט מהמשתמש היא פקודה שנקראת read-host, פקודה מאוד פשוטה, במידה ותריצו עליה help תקבלו כמה שורות של הסבר

פתחו PowerShell והריצו: help Read-Host -ShowWindow.

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

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

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

נכין סקריפט מאוד פשוט לביצוע פינג:

#הוספתי את ה 
#cls
#בשביל שיופי לי רק הסקריפט ולא הנתיב גם כן
#נסו עם הפקודה ובלי הפקודה ותראו את ההבדל.
cls
$pc = read-host "What is the IP address of the computer?"

ping $pc
במידה ונריץ את הסקריפט, נקבל דבר כזה:




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

סקריפט לדוגמא:
cls
$state = Read-Host "Where did you eat Hamburgers?"
$howmuch = Read-Host "How much hamburgers did you eat?"

write-host " you were in $state and you eat $howmuch hamburgers"


במקרה הזה, פקודת read-host היא בתוך משתנה state$ וגם בתוך משתנה howmuch$ ואז כשאנחנו מאחדים את הכל לתוך הפקודה write-host (שהיא בעצם ההפך מהפקודה read-host - מוציאה פלט למסך המחשב שלנו) אנחנו מקבלים את הפלט כש PowerShell מאחד לנו את כל המשתנים ביחד.

שנית - הסבר על הפקודה שנשתמש בה לצורך הצגת פלט על המסך Write-host.


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

$shnitzel = write-host "I love LeiderTech.co.il"

אם נריץ את זה ולאחר מכן נריץ את המשתנה עלידי הקשת shnitzel$ ו ENTER, לא נקבל כלום, כי המשתנה ריק, לעומת זאת אם נעשה את אותו הדבר עם read-host אז נקבל שבתוך המשתנה יש את read-host:

$shnitzel = read-host "Do you like LeiderTech.co.il?"

במידה ועכשיו תקשיו את shnitzel$ ותקישו ENTER, תקבלו שבתוך המשתנה שזה בעצם מה שהצבנו במשתנה "שניצל"

read-host "Do you like LeiderTech.co.il?"

המשמעות היא שניתן להשתמש עכשיו במשתנה לכל מטרה וניתן לשים אותו בכל מקום בסקריפט אך ורק בתור משתנה.

אני משתמש ב write-host לרוב בסקריפטים שלי כשאני רוצה להציג כותרת כמו "This script made by Lev" או משהו בסגנון.

ניתן גם להוסיף לטקסט צבעים על ידי שימוש בפרמטרים "Background Color" ו "Foregroundcolor" ולאחר מכן בחירת צבע, החלק הכי חשוב כאן, זאת הגמישות שיש ל PowerShell מבחינת המיקום של הפרמטרים, גם אם תרשמו אותם לפני הטקסט וגם אם תרשמו אותם אחרי הטקסט, זה עדיין יעבוד כמו שרואים כאן בתצלום המסך בסקריפט הקטן שמספר אודות כמות ההמבורגרים שאכלתי במוסקבה :)


cls
$state = Read-Host "Where did you eat Hamburgers?"
$howmuch = Read-Host "How much hamburgers did you eat?"

#משתנה לפני הטקסט
write-host -ForegroundColor DarkCyan -BackgroundColor White "you were in $state and you eat $howmuch hamburgers"



#משתנה אחרי הטקסט
write-host  "you were in $state and you eat $howmuch hamburgers" -ForegroundColor DarkCyan -BackgroundColor White


התוצאה:




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

רווחים אנחנו נייצר עלידי שימוש ב "Escape character" (תו יציאה\בריחה), כמו שלמדנו באחד המדריכים (כרגע לא זוכר בעל פה, באיזה מהחלקים) אנחנו נשתמש בגרש מיוחד שנמצא במקש ה"טילדה" לרוב מצד שמאל מעל ה-TAB במקלדת והאות "n" (המשמעות - חדש\חדשה):



ואז הסקריפט שלנו יראה ככה:

cls
$state = Read-Host "Where did you eat Hamburgers?"
$howmuch = Read-Host "How much hamburgers did you eat?"

#משתנה לפני הטקסט
write-host -ForegroundColor DarkCyan -BackgroundColor White "you were in $state and you eat $howmuch hamburgers"


#ביצוע רווח בין שורה לשורה
write-host "`n"


#משתנה אחרי הטקסט
write-host  "you were in $state and you eat $howmuch hamburgers" -ForegroundColor DarkCyan -BackgroundColor White


התוצאה:



איך בעצם ניתן לדעת אילו צבעים יש? אז ראשית ברגע שאתם כותבים את הקוד ב-ISE, אתם תקבלו את הרשימה של כל הצבעים שעומדים לרשותכם, דבר שני, ניתן להריץ את help write-host ותקבלו את הרשימה של הצבעים, דבר שלישי, אני אכתוב לכם את הצבעים כאן:

Black
DarkBlue
DarkGreen
DarkCyan
DarkRed
DarkMagenta
DarkYellow
Gray
DarkGray
Blue
Green
Cyan
Red
Magenta
Yellow
White




בנוסף, ניתן לרשום טקסט בשורה חדשה בצורה דומה, על ידי שימוש באותו ה "Escape character", בעזרת הצבתו בתחילת המילה\משפט שנרצה להציג בשורה חדשה כמו בדוגמא הבאה:

בדוגמא זאת, שמתי את ה "n`" ישר בצמוד למילה שאחרי הפסיק, בשביל שהחלק השני של המשפט יוצג בשורה הבאה ללא רווחים (שימו לב למה שקורה אחרי הפסיק):

write-host -ForegroundColor DarkCyan -BackgroundColor
White "you were in $state ,`nand you eat $howmuch hamburgers"

בתוך סקריפט זה יראה ככה:

cls
$state = Read-Host "Where did you eat Hamburgers?"
$howmuch = Read-Host "How much hamburgers did you eat?"

#שורה חדשה
write-host -ForegroundColor DarkCyan -BackgroundColor
White "you were in $state ,`nand you eat $howmuch hamburgers"


התוצאה:





לידע כללי:
ישנה גם פקודה שנקראת write-output, שהיא יותר מיועדת לשימוש בתוך הסקריפט. בעזרתה  ניתן להציג "תוצאה" של הסקריפט שלכם או ליצא את הנתונים הסופיים של הסקריפט שלכם לקובץ מסויים, אין לה אפשרות להוסיף צבעים או רקעים בצבעים כמו ב Write-host.


לכל שאלה המייל שלי: levl@LeiderTech.co.il.

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