25/11/2019

מדריך ל Power Shell בעברית חלק 4 - לולאת foreach והפקודה foreach-object.




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

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

באחת התגובות למאמר הקודם קיבלתי בקשה של קורא:


אז לבקשתך, מר "אנונימי" להלן מאמר המסביר על ההבדלים בין foreach-object לבין הללואה Foreach וכיצד לעובד איתן.

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


הלולאה\הצהרה (כל אחד קורא לזה בצורה אחרת) Foreach.


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


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

להבדיל מה foreach-object שעושה את אותו הדבר אבל היא חייבת להיות רק אחרי הפייפליין.

אתן שלושה דוגמאות ל foreach  ונלמד את מבנה הלולאה:



תחילה מבנה הלולאה:
foreach ($variable1 in $variable2) {

Do stuff with $variable1

}

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

החלק המבלבל בכל הסיפור הזה, זאת השורה הזאת (foreach (variable1 in variable2

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


דוגמא ראשונה: 
קודם כל נייצר משתנה עם כמה אובייקטים שיהיה לנו עם מה לעבוד -

$numbers = @(1, 2 , 3, 4)

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

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

בדוגמא הזאת בחרתי להפעיל את המשתנה שניצל שמייצג כל מספר שהלולאה עוברת עליו כרגע, לכן הפלט יהיה:
 "זה מספר השניצלים שאני אוכל ביום:1"
"זה מספר השניצלים שאני אוכל ביום:2"
"זה מספר השניצלים שאני אוכל ביום:3"
"זה מספר השניצלים שאני אוכל ביום:4"

foreach ($shnitzel in $numbers) {


write-host "I eat this number of Shnitzels each day :" $shnitzel


}
פלט של הלולאה הראשונה:




דוגמא שניה:
בדוגמא זאת אני אפעיל את המשתנה numbers אשר מכיל בתוכו כרגע את המערך "1234" (אם נכתוב ב powershell את ה משתנה numbers$ נקבל את מה שהוא מכיל בתוכו) 


$numbers = @(1, 2 , 3, 4)

foreach ($shnitzels in $numbers) {

write-host "I eat $numbers of shnitzel each day"

}



במקרה של הדוגמא הנ"ל, הפלט יהיה:

 "אני אוכל 1234 שניצלים ביום"
 "אני אוכל 1234 שניצלים ביום"
 "אני אוכל 1234 שניצלים ביום"
 "אני אוכל 1234 שניצלים ביום"

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


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


$stuff = Get-Process

foreach ($thing in $stuff){

Write-Host "The name of the process is :" $thing.Name
Write-Host "`n"
Write-Host "The used cpu of the process is:" $thing.cpu
Write-Host "`n"

}

תשימו לב שבתוך מבנה הלולאה רשום thing.Name$ ואתם בטח שואלים את עצמכם מה זה?, אז אני שמח ששאלתם, התשובה מאוד פשוטה ודיי הגיונית, מאחר ואני רוצה לקבל את שם הפרוסס, אז אני אומר למערכת שתציג לי את המשתנה שכרגע נמצא בלולאה ואת העמודה name ואותו דבר גם  בשורה השניה thing.cpu$ וכך הלאה.. מאוד נוח נכון? והאמת שגם מאוד הגיוני כי הפרוש של הפקודה בעצם נראה ככה "process.property " (אני מקווה שאתם זוכרים ש property ב PowerShell הוא בעצם ה"עמודה", אם לא, אז הינה הזכרתי לכם :) ).

ועוד שאלה, מה זה" "Write-Host "`n " ??

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

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

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


הפלט של הלולאה:


תשימו לב שבין השורות יש רווח בלי טקסט - אז זה בעצם מה שעושה :"write-host "`n.



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

cls
#get the csv file
$filepath = import-csv "C:\scriptingstuff\User creation script\users.csv"

#set the variable for the uers
$newusers = $filepath

#start the loop 

foreach ($user in $newusers) {


#get user information
$firstname = $user.'First Name'.Trim()
$lastname = $user.Lastname.Trim()
$loginname= $user.SamAccountName
$securepassword = $user.Pass
$jobtitle = $user.'Job Title'
$Department= $user.Department
$Description = $user.Description
$OuPath= $user.Path
$LoginScript=$user.ScriptPath
$displayname= $user.DisplayName
$email = $user.Email

#creat the users in active directory

New-ADUser -Name "$firstname $lastname" -GivenName $firstname -Surname $lastname -UserPrincipalName $loginname -Path $OuPath -SamAccountName $loginname  -AccountPassword (ConvertTo-SecureString "AccountPassword" -AsPlainText -Force) -ChangePasswordAtLogon $false  -EmailAddress $email -DisplayName $displayname -Enabled $true 

Write-Host "`n"
Write-Host "The account for $firstname $lastname created in $OuPath successfully"

}

בחלק הראשון של הסקריפט, כפי שניתן לראות, אנחנו מייבאים את קובץ ה CSV בעזרת הפרודה import-csv, ולאחר מכן בתוך הסקריפט אנחנו רושמים על יד כל משתנה, איזו עמודה אנחנו רוצים לייצג בתוך הסקריפט, ככה שבעצם לדוגמא בשדה המייל בפרופיל של המשתמש אנחנו רוצים להוסיף את המייל, אז בפקודה להוספת המשתמש שהיא new-aduser נציג את הפרמטר EmailAddress ולידו נרשום את המשתנה שהגדרנו בו הפניה לעמודה המתאימה בקובץ ה CSV ובעצם בצורה קצרה זה יראה ככה new-aduser -EmailAddress  $email כי לפני כן הגדרנו את זה:
$email = $email.Email


הפקודה Foreach-object.

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

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

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

¿?(במידה ואתם לא מכירים את הסימן הזה "_$" או "psitem$" אני ממליץ לכם להפסיק לקרוא את המדריך ולעבור על החלק השלישי של המדריך כי באיזשהו שלב לא תבינו על מה אני מדבר במדריכים העתידיים וזה מאוד חיוני שתבינו את כל הדוגמא לצורך הבנה ולימוד פשוטים יותר- יש קישור בתחתית הפוסט וגם בתחילתו)¿?

דוגמא ראשונה (עם הסימון psitem$):
$numbers = @(1, 2 , 3, 4)

$numbers | foreach-object {write-host "I eat $numbers of $Psitem each day"}

פלט של הפקודה:





דוגמא שניה ( עם _$):

$numbers = @(1, 2 , 3, 4)

$numbers | foreach-object  {write-host "I eat $numbers of $_ each day"}

פלט של הפקודה:



דוגמא שלישית:


$stuff = Get-Process

$stuff |ForEach-Object {

Write-Host "the name of the procrss is: " $_.Name

}


פלט של הפקודה:



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

למה שלא תרשמו את כל המחשבים מראש ותריצו פקודה אחת שפשוט תעשה את זה עבורכם?

cls

$pcs = "www.google.co.il","www.ynet.co.il"

foreach ($pc in $pcs) {

ping $pc

}

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

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







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

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

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

28/09/2019

איך לעשות חשיפה כפולה עם SnapSeed באנדרואיד?

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

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


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

אז בלי יותר מדי דיבורים:

תהנו :)

(נ"ב - אני מתנצל על הסאונד, לצערי הרב בדיוק בזמן ההקלטה האוזניות שלי החליטו להתקלקל)




כמו תמיד, אל תתביישו להשאיר תגובות - קללות ופרסומות אני מוחק, כל השאר לא.

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


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

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 כאן

06/08/2019

פקודות PowerShell שימושיות

פקודות שיעשו את החיים שלכם הרבה יותר קלים ופרודוקטיביים

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

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

(אצרף גם פקודות שיכולות לעבוד ב CMD למצבים בהם אתם עובדים עם מערכות ישנות יותר מ Windows 8)

מחשבים מקומיים

1) בדיקת תאריך התקנה של מערכת הפעלה:

:PowerShell

Get-CimInstance Win32_OperatingSystem | select Version, InstallDate, OSArchitecture

:CMD
systeminfo | find /i "install date"

2) קבלת מספר סידורי של מחשב עוזר במיוחד למחשבים ניידים :

:PowerShell

Get-WmiObject win32_bios | fl SerialNumber

:CMD
wmic bios get serialnumber


3) בדיקת דגם של מחשב:

:PowerShell
Get-CimInstance -ClassName Win32_ComputerSystem |select Manufacturer, Model

:CMD
wmic computersystem get model

4) בדיקת גירסת מערכת הפעלה כולל סוג ארכטיקטורה:

:PowerShell
Get-CimInstance Win32_OperatingSystem | select Version,OSArchitecture

:CMD
wmic OS get Caption, OSArchitecture

5) בדיקה - כמה זמן המחשב דלוק?

:PowerShell
(get-date) - (gcim Win32_OperatingSystem).LastBootUpTime |select Days, Hours |ft -AutoSize

:CMD
systeminfo | find "System Boot Time"

6) במידה והמחשב בדומיין ואתם מקבלים הודעה על trust relationship (אני אישית לא בדקתי את זה)

Test-ComputerSecureChannel -Credential domain\admin -Repair



פקודות לשרתים: 

1) ניתוק כל המשתמשים שהסשן שלהם במצב Disconnected (טוב לשרתי טרמינל):

Get-RDUserSession |where sessionstate -like *STATE_DISCONNECTED* |Invoke-RDUserLogoff

2) מציאת משתמש ב Active Directory והצגת הנתיב בו הוא ממוקם (עוזר לעבודה עם נתיבי LDAP):

Get-ADUser -Filter 'Name -like "*lev*"' |select name, DistinguishedName |Format-Table -AutoSize

3) מציאת כל המאפיינים של המשתמש: 

Get-ADUser -Filter 'Name -like "*sus*"' -Properties *|gm

4) מציאת קבצים שנפתחו על ידי משתמש (ניתן לרשום גם את שם הקובץ בעברית):

Get-SmbOpenFile |where {$_.Path –like "*.xls"} |select ClientUserName, path

במידה ורוצים לסגור את הקובץ באותח הפקודה - נוסיף סימן " Pipe" ( נמצא מעל האנטר -> | ) ואז נוסיף את הפקודה 

Close-SMBOpenFile

או שניתן להעתיק את הפקודה כאן:

Get-SmbOpenFile |where {$_.Path –like "*.pdf"} | Close-SMBOpenFile

5) פקודה שתראה לכם את רשימת הפקודות שיש למודול מסויים:

Get-Command -Module hyper-v


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

1) קודם כל אם אתם על windows 7\8\8.1 ביצעו הורדה של של גירסת ה PowerShell האחרונה - כאן

2) פתחו את PowerShell עם משתמש אדמיניסטרטור (לא משנה אם זה ISE או הרגיל) והריצו:
Install-Module -Name AzureAD

3) לאחר מכן התקינו את Microsoft Online Services Sign-In Assistant for IT Professionals (מסיבה לא מובנת ניתן להתקין את זה אך ורק על מערכות 64 ביט): כאן

4) לאחר שביצעתם התקנה - פתחו את PowerShell בתור מנהל (לא משנה אם ISE או הרגיל) והריצו:
Install-Module MSOnline 
* במהלך ההתקנה תצטרכו לענות על שאלות - אני מאמין שתאשרו את הכל.

להלן המקור של המדריך מהאתר של מיקרוסופט : לינק


פקודות לשימוש באופיס 365:

לידע כללי

 לצורך עבודה עם אופיס 365 הכולל בתוכו Exchange, Skype, SharePoint, ActiveDirectory Azure, office 365 ישנן כמה אפשרויות, או להתחבר לכל השירותים ביחד, או להתחבר לשירות ספציפי, בסביבת העובדה שלי יש לי צורך בחיבור אך ורק לכמה שירותים, אבל במידה ואתם רוצים להתחבר להכל ביחד, להלן סקריפט שניתן לבצע בו עריכה כרצונכם - באתר של מיקרוסופט: לינק

לגופו של עניין:

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

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

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

התחברות ראשונית לשירותי מיקרוסופט

(העדיפות כאן היא לעבוד עם ISE - כי פשוט יותר נוח)

לאחר שתריצו את הסקריפט תקבלו חלון שבו תתבקשו להכניס הרשאות - אלו הן הרשאות לחיבור עם חשבון מנהל ה 365 שלכם ללא דומיין וללא שום דבר
שם משתמש (לדוגמא) :levadmin@leidertch.co.il
סיסמא: ToLongPassw0rd2Remmber!

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


$creds = Get-Credential

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ `
                         -Credential $creds -Authentication Basic -AllowRedirection

Import-Module MSOnline

Connect-MsolService -Credential $creds

Import-PSSession $Session


רשימת הפקודות:

1) יצירת משתמש חדש - אך ורק במידה ויש רישיונות פנויים (אין אפשרות לרכוש רישיון חדש דרך PowerShell) אלה רק להקצות:

New-MsolUser -UserPrincipalName sararuchama@expattaxcpas.com -DisplayName "Lev It" -FirstName "Lev" -LastName "WhatEver" -LicenseAssignment EXPATTAXCPAS:EXCHANGESTANDARD -UsageLocation IL

2) מציאת משתמש:

Get-MsolUser -SearchString sar

3) איפוס סיסמא:

Set-MsolUserPassword -UserPrincipalName user@yourdomain.com -NewPassword blah123

4) שינוי שם תצוגה:

Set-MsolUser -UserPrincipalName garfield@odie.net -DisplayName "Garfield"

5) שינוי מייל ראשי של משתמש אך ורק בתוך Exchange online:

Set-MsolUserPrincipalName -UserPrincipalName anne.wallace@contoso.onmicrosoft.com -NewUserPrincipalName anne.jones@whatever.com

עבודה עם רשימות תפוצה (Distribution groups) 

1) הצגת כל רשימות התפוצה:
Get-DistributionGroup

2) חיפוש רשימת תפוצה:

Get-DistributionGroup -Identity "Marketing Reports"

3) הצגת רשימת משתמשים בתוך רשימת תפוצה ספציפית:

Get-DistributionGroupmember "group name"

4) הוספת משתמש (מאפשר הוספה של משתמש אחד בלבד - להוספה מרובה, עבור לסעיף 8) לרשימת תפוצה:

Add-DistributionGroupMember -Identity "admin team" -Member moshecohen -BypassSecurityGroupManagerCheck

5) שינוי שם לרשימת תפוצה: 

Set-DistributionGroup -Identity OldGroupName -Name NewGroupName -IgnoreNamingPolicy

6) מציאת כל רשימות התפוצה שמשתמש חבר בהן: 

$Username = "email_adress@OfTheUser.com"

Get-DistributionGroup | where { (Get-DistributionGroupMember $_.Name | foreach {$_.PrimarySmtpAddress}) -contains "$Username"}

7) מחיקת משתמש מרשימת תפוצה:

Remove-DistributionGroupMember -Identity "Group Name" -Member wanteduser -BypassSecurityGroupManagerCheck

8) בדיקת כמות משתמשים בחשבון הנוכחי:

(get-user).count

9) הוספת כמה משתמשים ביחד לרשימת תפוצה (קיימת):

Update-DistributionGroupMember -Identity "Research Reports" -Members
lev@leidertech.co.il,moshe@leidertech.co.il,hava@leidertech.co.il,shula@leidertech.co.il


10) יצירת רשימת תפוצה:

"New-DistributionGroup New-DistributionGroup -Name "Managers" -Type "Distribution


11) יצירת רשימת תפוצה חדשה והוספת משתמש לתוכה:

New-DistributionGroup -Name "Test Distribution Group" -members Damian@leidertech.co.il -type Distribution


סקריפט קצר להוספת כמה משתמשים ביחד לרשימת תפוצה מתוך קובץ CSV:

1) ניצור קובץ CSV - מספיק תא אחד ותקראו לו איך שתרצו (עדיף שיהיה נוח)

2) לאחר מכן, פתחו את ה PowerShell ISE בתור מנהל


$creds = Get-Credential

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ `
                         -Credential $creds -Authentication Basic -AllowRedirection

Import-Module MSOnline

Connect-MsolService -Credential $creds

Import-PSSession $Session

#את החלק הזה צריך לערוך בהתאם למה שאתם צריכים
$users= import-csv "C:\Users\Leidertech\Desktop\Partners.csv" | ForEach {Add-DistributionGroupMember -Identity "Snitzelim Group" -Member $_.Partners}



העברת מייל למשתמש אחר (Email Forwarding):

הגדרת Mail Forword - מומלץ לבצע את הפעולות הבאות על מנת שלא נתבלבל:

  •  מציאת משתמש : *get-mailbox -identety *tsipy
  • לאחר מכן  נעתיק את ה UserPrincipalname
ונדביק באחת מהפקודות הבאות:

¿?במידה ואתם לא רוצים שישאיר עותק אל המשתמש שאליו המייל מגיע¿?:

Set-Mailbox -Identity tsipy -ForwardingSMTPAddress lev@LeiderTech.co.il

¿?במידה ואתם כן רוצים שישאיר עותק אל המשתמש שאליו המייל מגיע¿?:

Set-Mailbox -Identity "User NAme" -DeliverToMailboxAndForward $true -ForwardingSMTPAddress "lev@LeiderTech.co.il"

נבצע בדיקה שהכל עבר כמו שצריך:

Get-Mailbox lev | select UserPrincipalName,ForwardingSmtpAddress,DeliverToMailboxAndForward

8) ביטול Mail Forwarding:

set-mailbox -Identity "User Name" -ForwardingSmtpAddress $Null

עבודה עם Alias:

1) בדיקת  האליאס שמוגדר למשתמש: 

Get-Mailbox lev | select -ExpandProperty emailaddresses | Select-String -Pattern "smtp"

2) הוספת אליאס למשתמש:

Set-Mailbox lev -EmailAddresses @{Add='levvv@leidertech.co.il'}

3) מחיקת אליאס ממשתמש:

Set-Mailbox lev -EmailAddresses @{Remove=’alias@LeideTech.co.il’}

ניהול רשימת תפוצה\קבוצה מסוג"אופיס365" - אשר נקראות בשפת ה Unified Group" Powershell":

1) הצגת כל רשימות תפוצה\קבוצה מסוג "אופיס365":
Get-UnifiedGroup

2) ביצוע שינוי לרשימת תפוצה\קבוצה מסוג" אופיס365":

Set-UnifiedGroup -Identity "HelpDesk Department" -PrimarySmtpAddress helpdesk@leidertech.co.il -RequireSenderAuthenticationEnabled $false


3) הוספת רשימת תפוצה\קבוצה חדשה מסוג "אופיס365":

New-UnifiedGroup -DisplayName "HR Department" -Alias HR

4) מחיקת רשימת תפוצה\קבוצה מסוג "אופיס365":

Remove-UnifiedGroup -Identity "PR Department"

5) הצגת חברות ובעלות של רשימת תפוצה\קבוצה מסוג "אופיס365":

Get-UnifiedGroupLinks -Identity "PR Department" -LinkType Members

6) הוספת חברות לרשימת תפוצה\קבוצה מסוג "אופיס365"

Add-UnifiedGroupLinks -Identity "Management Department" -LinkType Members -Links uri@leidertech.co.il,shula@leidertech.co.il

7) הסרת חברות מרשימת תפוצה\קבוצה מסוג "אופיס365"

Remove-UnifiedGroupLinks -Identity "Management Department" -LinkType Members -Links uri@leidertech.co.il,shula@leidertech.co.il

הוספת תמונות למשתמשים באופיס 365

1) הצגת תמונה של משתמש מסויים:
Get-UserPhoto "Moshe Cohen"

2) תצוגה מקדימה של קובץ שעלה למשתמשת אבל לא נשמר:

Get-UserPhoto "Moshe Cohen" -Preview

3) העלת תמונה למשתמש:

Set-UserPhoto -Identity "Shmuel Cohen" -PictureData ([System.IO.File]::ReadAllBytes("C:\Users\Admin\Desktop\Shmuel.jpg"))

4) מחיקת תמונה של משתמש:

Remove-UserPhoto "Simon Cohen"


במידה ותרצו ללמוד אודות PowerShell עוד - ניתן למצוא ריכוז מדריכים מתעדכן בעברית: כאן