מחיקת קבצים יעילה עם 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++.

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

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

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

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

הידעתם שלפקודת ה-cmdlet 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\<computername>\<share>\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

שים לב שמההודעה המפורטת מעלה, הסקריפט מחק רק חמישה קבצים שנוצרו לפני יותר מ- 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 ב־PowerShell

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

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

Microsoft הוציאה לאור פקודות CIM מסוימות ב־PowerShell 3.0. ה־CIM cmdlets שימושיים למחיקת קבצים הם 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

כפי שאתה רואה בתמונה מטה, ה-ReturnValue מציג 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

שימוש בפוורשל ו-WMI כדי למחוק קבצים לפי סיומת

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

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

$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

עד כה במדריך זה, קיבלת סקירה כללית של איך להשתמש בפוורשל כדי למחוק קבצים. למדת על 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.

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

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

קרא עוד:

Source:
https://adamtheautomator.com/powershell-delete-file/