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

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

解决长路径问题
上面显示的错误表明PowerShell“找不到路径的一部分”。该错误表明命令尝试访问的路径不存在——这是具有误导性的。
在这种情况下,错误是因为Get-ChildItem
尝试读取的路径超过了260个字符的最大路径长度。
下面的截图显示路径或目录及其子目录存在,并且一个名为InTooDeep.txt的文本文件位于最底层的子目录中。所有嵌套目录名中的字符组合造成了长路径问题。

在Windows PowerShell 5.1中,有一种解决长路径名问题的方法。解决方法是使用路径的Unicode版本。而不是像这样指定路径 – C:\temp,使用Unicode版本如下 – ‘\\?\C:\temp’用于位于本地的文件夹,或者‘\\?\UNC\<computername>\<share>\Temp’如果文件夹位于UNC路径中。
使用上述修改后适用于长路径名的代码,下面的输出显示PowerShell成功读取了深层嵌套的路径名并删除了文件。

请注意,长路径名问题不影响PowerShell 7.0。使用PowerShell 7.0,无需使用路径的Unicode版本,因为它已经内置了对长路径名的支持。
如果需要删除文件夹,只需从Get-ChildItem
cmdlet中删除-File
参数,PowerShell应该删除所有项目,包括文件和文件夹。
使用PowerShell删除早于x天的文件
另一个典型的磁盘空间清理示例是删除早于特定天数的文件。此示例适用于删除旧的日志文件,例如由IIS Web服务器生成的日志文件,以释放磁盘空间。
在这个示例中,有些文件在c:\temp目录下已经存在超过14天了。使用下面的脚本,将显示c:\temp目录中每个文件的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
cmdlet,并使用-Include
参数,如下所示。
另一种方法,也许是谨慎的方法,是首先使用Get-ChildItem
收集要删除的文件列表。只有当您对要删除的文件列表感到满意时,才可以最终将集合传递到Remove-Item
cmdlet。
例如,下面的代码获取了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脚本。
Microsoft在PowerShell 3.0中发布了针对WMI的特定CIM cmdlet。将用于删除文件的CIM cmdlet是Get-CimInstance
和Invoke-CimMethod
。
使用 PowerShell 和 WMI 删除文件
此示例假定您知道要删除的特定文件的路径。使用带有 Cim_DataFile
类的 Get-CimInstance
cmdlet 来检索有关要删除的文件的信息,即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 中的所有文件。
user:记住,ReturnValue
代码为0表示成功,并且对于调用删除方法的每个文件都将有其自己的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来删除文件。与使用WMI相比,这些内置cmdlet更灵活、更容易使用,速度更快。
尝试编写一个可以为您执行磁盘空间清理的脚本。当然,已经存在一些用于此目的的脚本;请尽管将它们作为参考,但如果您愿意练习和学习,您应该尝试创建自己的脚本。
进一步阅读
Source:
https://adamtheautomator.com/powershell-to-delete-files/