在管理服务器和系统时,保持空闲磁盘空间至关重要。作为管理员,您不希望陷入”磁盘已满”的窘境。为了确保您没有问题,您应该学会如何使用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 Cmdlet删除文件
当您只需要使用PowerShell删除文件时,您可能会立即了解到Remove-Item cmdlet。该cmdlet是使用PowerShell删除文件的事实标准。
使用Remove-Item结合Get-ChildItem cmdlet读取文件和文件夹,以及强大的PowerShell管道,可以让事情变得轻松愉快。
相关:Get-ChildItem:列出文件、注册表、证书等
您知道Remove-Item cmdlet有一个别名叫做del吗?在PowerShell中使用Remove-Item或del将运行相同的命令。
使用PowerShell删除文件
最有用的第一个例子是最基本的——也就是删除单个文件。要删除一个文件,只需要使用下面的命令。下面的代码删除了文件C:\temp\random.txt。
在PowerShell中运行上面的代码不会在屏幕上显示任何内容,除非遇到错误。
使用PowerShell删除文件夹中的所有文件
在这个例子中,下面的代码删除了文件夹中的所有文件。Get-ChildItem
cmdlet使用-Path
参数定位到了C:\temp。-File
参数表示只包括文件类型的项目,Get-ChildItem
忽略文件夹。
输出应该像下面的截图一样。

使用PowerShell递归删除所有文件
前面的例子只删除了C:\temp文件夹中的文件。如果您还需要删除每个子目录中的文件,需要向Get-ChildItem
cmdlet添加-Recurse
开关,以递归获取所有文件。
运行上面的代码会强制PowerShell查看所有子文件夹并获取所有文件的列表。下面的输出显示,该代码能够删除顶层文件夹中的文件,但无法获取子文件夹中的文件。

解决长路径问题
上面显示的错误表明,PowerShell“找不到路径的一部分”。该错误表明,命令正在尝试获取的路径不存在,这是具有误导性的。
在這種情況下,錯誤是因為Get-ChildItem
嘗試讀取的路徑超過了260個字符的最大路徑長度。
下面的截圖顯示了路徑或目錄及其子目錄存在,並且一個名為InTooDeep.txt的文本文件位於最底層的子目錄中。構成嵌套目錄名的所有字符的組合引發了長路徑問題。

在Windows PowerShell 5.1中,有一個解決長路徑名問題的方法。解決方法是使用路徑的Unicode版本。不要像這樣指定路徑 – C:\temp,而是像這樣使用Unicode版本 – ‘\\?\C:\temp’ (如果文件夾位於本地),或者’\\?\UNC\<計算機名>\\<共享>\Temp’(如果文件夾位於UNC路徑)。
使用修改後的代碼,適應長路徑名,下面的輸出顯示PowerShell成功讀取了深層嵌套的路徑名並刪除了文件。

請注意,長路徑名問題不影響PowerShell 7.0。使用PowerShell 7.0,無需使用Unicode版本的路徑,因為它已內建支援長路徑名。
如果需要刪除文件夾,只需從Get-ChildItem
cmdlet中刪除-File
參數,PowerShell應該刪除所有項目,包括文件和文件夾。
使用PowerShell刪除超過x天的文件
磁盤空間整理的另一個典型例子是刪除比特定天數更舊的文件。此例子適用於刪除舊的日誌文件,例如由IIS Web服務器生成的文件,以釋放磁盤空間。
在這個例子中,c:\temp資料夾中有一些比14天更舊的文件。使用下面的腳本,將顯示每個文件的Name
、CreationTIme
和AgeInDays
。
如下圖所示,有一些文件的年齡分別為15天、7天和0天。

現在您已經知道要刪除的文件,可以創建一個腳本只刪除比特定天數更舊的文件-在這個例子中即比14天更舊的文件。
在下面的腳本示例中,將刪除位於C:\temp中CreationTime
值比設定的閾值更舊的文件。
第一行定義了Get-ChildItem
要搜索的路徑。路徑保存在$path
變量中。然後,第二行指定了閾值。變量$threshold
的值為要刪除的文件的年齡(以天為單位)。
在$threshold
變量之後的下一行代碼將:
- 獲取位於
$path
變量指定的文件夾中的文件集合。在這個例子中,路徑為C:\temp。 - 過濾輸出,只包括
CreationTime
值比$threshold
變量保存的天數更舊的文件。在這個例子中,閾值為14天。 - 將篩選後的檔案清單傳送到
Remove-Item
值以執行刪除這些檔案的動作。
執行上述程式碼後,您將看到如下所示的輸出。

從上述的螢幕截圖中可以看出,根據詳細訊息,該指令碼僅刪除了 14 天前的五個檔案。為了確認 14 天內較新的檔案仍然存在,請執行下面的程式碼再次列出它們。
以下結果確認了 Remove-Item
未刪除較新的檔案。

使用 PowerShell 匹配和刪除檔案模式
不論名稱、類型或副檔名,刪除全部檔案並不總是最佳方法。有時候,您需要明確地排除或包含刪除過程中的某些檔案。
下面的範例展示了如何刪除符合 *.LOG 檔案名稱的檔案。一種方法是直接使用 Remove-Item
指令碼搭配 -Include
參數,如下所示。
另一種方式可能是謹慎的做法,先使用 Get-ChildItem
收集要刪除的檔案清單。只有在滿意刪除清單後,才能將收集的內容傳送到 Remove-Item
指令碼。
例如,下面的程式碼在 c:\temp 中取得 *.LOG 檔案。
由於上面的程式碼,Get-ChildItem
會返回符合 *.LOG 檔案名稱的檔案清單。

但是,如果您想要排除文件名中包含数字5的文件该如何处理呢?您可以通过添加-Exclude
参数来实现,就像下面的代码所示。
由于您排除了文件名中带有数字5的文件,所以结果现在是不同的。具体来说,文件File_5.log不再在列表中,如下所示。

当您对代码创建的文件集合感到满意时,可以将文件集合传递给Remove-Item
命令来最终删除这些文件。
运行最终的代码后,您将实现仅删除所选文件的目标。

使用PowerShell中的WMI删除文件
现在,您已经很好地了解了如何使用常见的Remove-Item
命令来删除文件,让我们进入一个更高级的用例;使用WMI。
PowerShell支持WMI。支持WMI意味着可以从PowerShell内部调用WMI查询和方法。是的,WMI不仅适用于管理员在Windows早期使用的Visual Basic脚本。
微软在PowerShell 3.0中发布了专门用于WMI的CIM cmdlets。用于删除文件的CIM cmdlets是Get-CimInstance
和Invoke-CimMethod
。
使用PowerShell和WMI刪除文件
此示例假設您知道要刪除的特定文件的路徑。使用Get-CimInstance
cmdlet和Cim_DataFile
類別檢索有關要刪除的文件的信息,該文件是C:\Temp\random.txt
在上面的代碼中,-Filter
參數接受WQL格式的查詢。使用WQL需要對一些字符進行轉義,包括反斜線。而且,由於WQL轉義字符也是反斜線,導致出現雙反斜線字符- \\
運行上面的代碼會產生下面演示中顯示的結果。有關C:\Temp\random.txt的信息保存在$file2delete
變量中

現在已檢索到文件C:\Temp\random.txt的信息,可以將$file2delete
變量中的結果導向Invoke-CimMethod
cmdlet。 Invoke-CimMethod
cmdlet有一個名為-Name
的參數,該參數表示Cim_DataFile
類別的方法名稱。
如下面的屏幕截圖所示,ReturnValue
顯示為0,表示命令成功。

要了解可能的ReturnValue代码,请参考此链接 – CIM_DataFile类的Delete方法
此外,下面的截图显示在运行Invoke-CimMethod
Delete()
方法后,CIM仅删除了C:\Temp\random.txt文件。它没有删除其他文件。

使用PowerShell和WMI删除文件夹中的所有文件
在下一个示例中,将展示如何使用PowerShell和WMI删除文件夹中的所有文件。与前面示例中使用的相同的cmdlet,即Get-CimInstance
和Invoke-CimMethod
,将被使用。但是,这次WQL查询将检索文件夹中的所有文件,而不仅仅是一个特定文件。
在下面的代码中,Get-CimInstance
cmdlet检索位于C:\temp的所有文件。如下所示,查询过滤了Cim_DataFile
类的Drive
和Path
属性。
运行上面的代码将保存有关C:\temp中文件的检索信息在$file2delete
变量中。查看$file2delete
变量的值将显示下面的输出。

现在,将存储在$file2delete
变量中的值通过管道传递给Invoke-CimMethod
,以删除c:\temp中的所有文件。
請記住, ReturnValue
代碼為0表示成功,並且對每個調用delete方法的文件都有自己的 ReturnValue
代碼。

使用PowerShell和WMI按文件擴展名刪除文件
在先前的示例中,您已經看到如何刪除文件夾中的所有文件,而不考慮擴展名。但是,您也可以根據擴展名控制哪些文件被刪除。
您會注意到下面的代碼中,此次查詢添加了條件( Name LIKE%.log
)。此添加的條件意味著只返回與 .LOG 擴展名匹配的文件。百分比(%
)符號是WQL LIKE 運算符,表示“零個或多個字符的字符串”。在編程術語中,%
等同於萬用字符,即星號( *
)字符。
下面的演示顯示,在執行上述代碼之前,有九個* .LOG 文件和一個* .TXT 文件。代碼運行完畢後,* .LOG 文件被刪除,只剩下* .TXT 文件在文件夾中。

比較WMI和Remove-Item
到目前為止,在本教程中,您已經獲得了如何使用PowerShell刪除文件的概述。您已經了解了 Remove-Item
和WMI。兩者執行類似的功能,但方式大不相同。
應該使用哪種方法來刪除文件; Remove-Item
還是WMI?
在PowerShell中使用内置的cmdlet,如Get-ChildItem
和Remove-Item
来检索和删除文件,比使用WMI要快得多。
下面的示例展示了使用WMI和内置的PowerShell cmdlet获取C:\windows\web目录及其子目录下文件列表的比较。
在PowerShell中运行上述代码时,您将看到类似下面的输出。

从上面的输出中可以看出,使用Get-CimInstance
列出C:\windows\web中的文件几乎比使用Get-ChildItem
要慢十倍!
此外,您是否注意到Get-ChildItem
行要比Get-CimInstance
短得多?使用Get-ChildItem
不仅可以获得更快的执行速度,而且还可以获得更简洁和更短的代码。
下一步
在本文中,您已经了解了使用内置的cmdlet和WMI/CIM来删除文件的两种不同方式。
要知道,您应该始终使用Get-ChildItem
和Remove-Item
cmdlet来删除文件。这些内置的cmdlet比使用WMI更灵活、更容易使用,速度更快。
試著撰寫一個可以為您執行磁碟空間清理的腳本。當然,已經存在一些針對此目的的腳本;您可以將它們作為參考,但如果您願意練習和學習,應該嘗試創建自己的腳本。
進一步閱讀
Source:
https://adamtheautomator.com/powershell-to-delete-files/