מחיקת קבצים יעילה עם PowerShell: Remove-Item ו-WMI

הפרטים בתרגום שלך תורגמו לעברית כך:

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

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

בואו להתחיל!

דרישות מוקדמות

מאמר זה מציג דוגמאות בשימוש ב-PowerShell, ואם אתה מתכוון להשתמש, יש צורך בדברים הבאים.

  • A computer that is running Windows 10 or above.
  • Windows PowerShell 5.1 או PowerShell 7.0
  • A script editor such as Visual Studio Code, Atom, or Notepad++.

שימוש בפקודת Remove-Item כדי למחוק קבצים

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

שימוש ב-Remove-Item בשילוב עם הפקודה Get-ChildItem לקריאת קבצים ותיקיות ולקראת הצינור המתקדם של PowerShell יכול להפוך את התהליך לקל.

קשור: Get-ChildItem: מפרט קבצים, רישומים, תעודות ועוד

הידעת של-Remove-Item יש כינוי בשם del? בעת עבודה ב-PowerShell, שימוש ב-Remove-Item או ב-del יריץ את אותה הפקודה.

שימוש ב-PowerShell למחיקת קובץ

הדוגמה הראשונה שתהיה הכי שימושית היא הפשוטה ביותר – כלומר, למחוק קובץ יחיד. כדי למחוק קובץ יחיד רק עליך להשתמש בפקודה למטה. הקוד למטה מוחק את הקובץ C:\temp\random.txt.

Remove-Item -Path C:\temp\random.txt

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

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

בדוגמה זו, הקוד למטה מוחק את כל הקבצים בתיקייה. פקודת ה־Get-ChildItem מתמקדת ב־C:\temp עם הפרמטר -Path. הפרמטר -File מציין שהיחיד סוג של פריטים המתוכלים להיות כלולים הם קבצים. Get-ChildItem מתעלם מתיקיות.

Get-ChildItem -Path C:\temp -File | Remove-Item -Verbose

הפלט צריך להיראות כמו בתמונת המסך למטה.

Successfully deleted all files in a folder

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

הדוגמה הקודמת מחקה רק קבצים בתיקיית C:\temp. אם תרצה למחוק גם את הקבצים בתיקיות המשניות, עליך להוסיף את המתג -Recurse ל־Get-ChildItem כדי לקבל את כל הקבצים באופן רקורסיבי.

Get-ChildItem -Path C:\temp -File -Recurse | Remove-Item -Verbose

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

Failed to retrieve files in sub-folders

עבודה סביב בעיה של נתיב ארוך

השגיאה שמוצגת למעלה מציינת שה־פוורשל לא הצליח למצוא חלק מהנתיב. השגיאה הזו מציינת שהנתיב שבו הפקודה מנסה להגיע אליו אינו קיים – מה שמביא לבלבול.

במקרה זה, השגיאה היתה מאחר והנתיב שבו Get-ChildItem מנסה לקרוא חורג את אורך הנתיב המרבי של 260 תווים.

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

Nested directories creating a long path name

ב-Windows PowerShell 5.1, קיים פתרון חלופי לבעיה של שם נתיב ארוך. הפתרון הוא להשתמש בגרסת Unicode של הנתיב. במקום לציין את הנתיב כך – C:\temp, עליך להשתמש בגרסת Unicode כך – ‘\\?\C:\temp’ לתיקיות שנמצאות מקומית, או ‘\\?\UNC\<שםמחשב>\<שיתוף>\Temp’ אם התיקייה נמצאת בנתיב UNC.

Get-ChildItem -Path '\\?\C:\temp' -File -Recurse | Remove-Item -Verbose

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

Deleted the file with a long path name

שים לב כי בעיה זו של שם נתיב ארוך אינה משפיעה על PowerShell 7.0. ב-PowerShell 7.0, אין צורך להשתמש בגרסת Unicode של הנתיב מאחר ויש לו תמיכה מובנית בשמות נתיב ארוכים.

אם יש צורך למחוק גם את התיקיות, פשוט הסר את הפרמטר -File מפקודת ה-Get-ChildItem, ו-PowerShell אמור למחוק את כל הפריטים, כולל קבצים ותיקיות.

שימוש ב-PowerShell כדי למחוק קבצים הישנים יותר מ-x ימים

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

בדוגמה זו, יש קבצים ב- c:\temp שיש בהם יותר מ-14 ימים. באמצעות הסקריפט למטה, ה- Name, CreationTime, ו- AgeInDays של כל קובץ ב- c:\temp מוצגים.

Get-ChildItem c:\temp | Select-Object Name,CreationTime,@{n='AgeInDays';e={(New-TimeSpan -Start $PSItem.CreationTime).Days}}

כפי שניתן לראות בתמונה המסך למטה, יש קבצים שיש להם 15 ימים, 7 ימים ו- 0 ימים.

List of files in c:\temp

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

בסקריפט הזה למטה, קבצים ב- C:\temp שערך ה- CreationTime שלהם ישן מהערך המוגדר ימחקו.

השורה הראשונה מגדירה את הנתיב ל- Get-ChildItem לחיפוש. הנתיב נשמר במשתנה $path. לאחר מכן, השורה השנייה היא המקום שבו מצויין הסף. ערך ה- $threshold הוא גיל היום של הקובץ שיש למחוק.

השורה הבאה אחרי המשתנה $threshold תבצע את הפעולות הבאות:

  • לקבל את אוסף הקבצים הממוקמים בתיקייה המצויה במשתנה $path. בדוגמה זו, הנתיב הוא C:\temp.
  • לסנן את הפלט כך שיוכל להיות כלול רק קבצים שערך ה- CreationTime שלהם ישן ממספר הימים שמור במשתנה $threshold. בדוגמה זו, הסף הוא 14 ימים.
  • העבר את רשימת הקבצים הסוננים לערך Remove-Item כדי לבצע מחיקת הקבצים האלה.
$path = 'C:\Temp'
$threshold = 14
Get-ChildItem -Path $path -File | Where-Object {$PSItem.CreationTime -lt (Get-Date).AddDays(-$threshold)} |Remove-Item -Verbose

כאשר אתה מריץ את הקוד למעלה, תראה פלט כמו שמוצג למטה.

The script deleted the files older than 14 days

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

Get-ChildItem c:\temp | Select-Object Name,CreationTime,@{n='AgeInDays';e={(New-TimeSpan -Start $PSItem.CreationTime).Days}}

התוצאה למטה מאשר כי Remove-Item לא מחק את הקבצים החדשים.

Newer files are left untouched

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

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

הדוגמה הבאה מציגה כיצד למחוק את הקבצים שמתאימים לשם קובץ *.LOG. דרך אחת לעשות זאת היא באמצעות שימוש בפקודת Remove-Item ישירות בשימוש בפרמטר -Include, כפי שמוצג למטה.

Remove-Item -Path C:\temp\* -Include *.log

דרך נוספת היא, אולי, הגישה הזהירה היא להשתמש תחילה ב־Get-ChildItem כדי לאסוף את רשימת הקבצים שיש למחוק. רק כאשר אתה מרוצה מרשימת הקבצים למחיקה, אפשר להעביר את האוסף ל־Remove-Item.

לדוגמה, הקוד למטה מקבל את קבצי ה־*.LOG ב־c:\temp.

Get-ChildItem -Path C:\temp\* -Include *.log

כתוצאה מהקוד למעלה, Get-ChildItem מחזיר רשימת קבצים המתאימים לשם הקובץ *.LOG.

Only files matching the *.log filename is returned

אך מה אם ברצונך להוציא מקובץ את הקובץ שמכיל את המספר 5 בשמו? אתה יכול לעשות זאת על ידי הוספת הפרמטר -Exclude כמו בקוד הבא.

Get-ChildItem -Path C:\temp\* -Include *.log -Exclude *5*

מאחר שהוצאת את הקובץ עם המספר 5, התוצאה שונתה. למעשה, הקובץ File_5.log כבר אינו ברשימה, כפי שמוצג למטה.

The file File_5.log was excluded

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

Get-ChildItem -Path C:\temp\* -Include *.log -Exclude *5* | Remove-Item -Verbose

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

Deleting selected files

מחיקת קבצים באמצעות WMI בפוורשל

עכשיו שיש לך הבנה טובה של שימוש בפקודת ה- Remove-Item הנפוצה כדי להסיר קבצים, בוא נקפוץ למקרה שימוש מתקדם יותר; בשימוש ב-WMI.

פוורשל מגיע עם תמיכה ב-WMI. ותמיכה ב-WMI אומרת ששאילתות ושיטות של WMI יכולות להיות קרואות מתוך PowerShell. כן, WMI הוא לא רק לתסריטים של Visual Basic שמנהלים השתמשו בהם בימי הראשונים של Windows.

Microsoft שחררה פקודות CIM ספציפיות ל-WMI ב- PowerShell 3.0. הפקודות CIM שימושיות למחיקת קבצים הן Get-CimInstance ו- Invoke-CimMethod.

שימוש ב־PowerShell וּב־WMI כדי למחוק קובץ

דוגמה זו מניחה שיש לך את הנתיב של הקובץ הספציפי שברצונך למחוק. פקודת ה־Get-CimInstance עם מחלקת ה־Cim_DataFile משמשת לקבלת מידע על הקובץ שברצונך למחוק, שהוא C:\Temp\random.txt.

$file2delete = Get-CimInstance -ClassName Cim_DataFile -Filter "Name = 'C:\Temp\random.txt'"
 $file2delete

בקוד לעיל, הפרמטר של -Filter מקבל שאילתת פורמט WQL. השימוש ב־WQL מחייב שמספר תווים יופיעו בשימוש כמו הבר-אחורי. ובשיעור האם תו הבר-אחורי הוא גם התו המשמש לבר-אחורי ב־WQL, יוביל להופעת התווים של בר-אחורי כפול – \\.

הרצת הקוד למעלה גורמת להצגת התוצאה המוצגת בדגמה למטה. המידע על C:\Temp\random.txt נשמר במשתנה $file2delete

Getting a file using WMI query and PowerShell

עכשיו שהמידע על הקובץ C:\Temp\random.txt נאסף, העצם התוצאה במשתנה $file2delete יכול להיות מועבר לפקודת ה־Invoke-CimMethod. פקודת ה־Invoke-CimMethod כוללת פרמטר בשם -Name, שמייצג את שם השיטה של מחלקת ה־Cim_DataFile.

$file2delete | Invoke-CimMethod -Name Delete

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

File successfully deleted using WMI and PowerShell

כדי לדעת על קודי ההחזרה האפשריים, נא להפנות אל שיטת המחיקה של מחלקת CIM_DataFile

בנוסף, התמונה למטה מראה שאחרי הרצת שיטת Invoke-CimMethod Delete(), CIM הסירה רק את הקובץ C:\Temp\random.txt ולא הסירה את שאר הקבצים.

C:\Temp\random.txt file was deleted

שימוש ב-PowerShell ו-WMI כדי למחוק את כל הקבצים בתיקייה

בדוגמה הבאה, אני מראה לך איך למחוק את כל הקבצים בתיקייה באמצעות PowerShell ו-WMI. הפקודות הקודמות שנמצאות בדוגמה הקודמת, Get-CimInstance ו־Invoke-CimMethod, יועברו. אך, הפעם, שאילתת WQL תאסוף את כל הקבצים בתיקייה במקום קובץ ספציפי אחד בלבד.

בקוד הבא, פקודת Get-CimInstance מביאה את כל הקבצים שנמצאים ב-C:\temp. כפי שאתה רואה למטה, השאילתה מסננת את המאפיינים Drive ו־Path של מחלקת Cim_DataFile.

$file2delete = Get-CimInstance -ClassName Cim_DataFile -Filter "Drive = 'c:' AND Path = '\\temp\\'"

הרצת הקוד מעלה את המידע שנאסף על הקבצים ב-C:\temp למשתנה $file2delete. תצוגת הערכים של משתנה $file2delete מראה את הפלט שבהמשך.

List of all folders found in c:\temp using WMI

עכשיו, הערכים שמאוחסנים במשתנה $file2delete יכולים להיות מפורקים ל־Invoke-CimMethod כדי למחוק את כל הקבצים ב-c:\temp.

$file2delete | Invoke-CimMethod -Name Delete

זכור, קוד ההחזר הReturnValue של 0 אומר שהפעולה הושלמה בהצלחה, ולכל קובץ שבו הוזמן לשיטת המחיקה יש קוד ReturnValue ייחודי.

All files in c:\temp deleted using WMI

באמצעות PowerShell ו-WMI למחיקת קבצים לפי סיומת

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

תגים נוספים נוספים בקוד מתחת, כאשר השאילתה הפעם כוללת תנאי נוסף (Name LIKE '%.log). התנאי הנוסף הזה אומר שיתקבלו רק קבצים שתואמים את הסיומת .LOG. האחוז (%) הוא אופרטור WQL LIKE המשמש כ-"מחרוזת של אפס או יותר תווים". במונחים של תכנות, ה-% הוא השקול לתו כללי, המסמל את הכוכבית (*).

$file2delete = Get-CimInstance -ClassName cim_datafile `
-Filter "Drive = 'c:' AND Path = '\\temp\\' AND Name LIKE '%.log'"

$file2delete | Invoke-CimMethod -Name Delete

הדגמה למטה מראה שלפני ביצוע הקוד, יש תשעה *.LOG קבצים ורק קובץ *.TXT אחד. לאחר הרצת הקוד, קבצי *.LOG נמחקים והקובץ *.TXT הוא היחיד שנשאר בתיקייה.

Deleting files by extension using WMI

השוואה בין WMI ו-Remove-Item

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

איזו שיטה כדאי לך להשתמש בה למחיקת קבצים; Remove-Item או WMI?

שימוש ב- cmdlet מובנה ב-PowerShell כמו Get-ChildItem ו-Remove-Item כדי לאחזר ולמחוק קבצים הוא הרבה יותר מהיר משימוש ב-WMI.

הדוגמה למטה מראה את ההשוואה בין שימוש ב-WMI וב-cmdlet המובנה של PowerShell לקבלת רשימת הקבצים בתיקיית C:\windows\web ובתתי-תיקיותיה.

## לרשומת כל הקבצים ב- C:\Windows\Web\ באמצעות Get-ChildItem
Measure-Command { Get-ChildItem C:\Windows\Web\ -Recurse}

## לרשומת כל הקבצים ב- C:\Windows\Web\ באמצעות Get-CimInstance ושאילתת WMI
Measure-Command { Get-CimInstance -ClassName Cim_DataFile -Filter "Drive = 'c:' AND Path = '\windows\web\%'"}

כשאתה מפעיל את הקוד לעיל ב-PowerShell, תראה את הפלט הדומה למטה.

Get-ChildItem vs. Get-CimInstance with WMI Query

כפי שאתה יכול לראות מהפלט המוצג למעלה, רשימת הקבצים ב- C:\windows\web לקחה כמעט עשר פעמים יותר זמן בשימוש ב- Get-CimInstance מאשר הזמן שנדרש ל- Get-ChildItem כדי להשלים!

גם שים לב לאיך השורה של Get-ChildItem היא הרבה יותר קצרה מאשר של Get-CimInstance? לא רק שאתה מקבל ביצוע יותר מהיר באמצעות Get-ChildItem, אלא גם תרווד מקוד נקי וקצר יותר.

שלבים הבאים

במאמר זה, ראית את שתי הדרכים השונות שבהן תוכל להשתמש ב-PowerShell כדי למחוק קבצים עם cmdlets מובנים ועם WMI/CIM.

דע שתמיד עליך להשתמש ב- Get-ChildItem וב- Remove-Item cmdlet כדי להסיר קבצים. cmdlets אלו הם יותר גמישים, קלים יותר ומהירים יותר לשימוש מאשר שימוש ב-WMI.

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

קריאה נוספת

Source:
https://adamtheautomator.com/powershell-to-delete-files/