维护自由磁盘空间在管理服务器和系统时至关重要。作为管理员,你不希望被‘磁盘已满’的情况所困扰。为了确保你安然无恙,你应该学习如何使用 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 pipeline,使用 Remove-Item
真的可以让事情变得轻松。
相关: 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文件夹中的文件。如果您需要还删除每个子目录中的文件,则需要将-Recurse
开关添加到Get-ChildItem
命令中以递归获取所有文件。
运行上面的代码会强制PowerShell查看所有子文件夹并检索所有文件列表。下面的输出显示该代码能够删除顶层文件夹中的文件;但是,它未能检索子文件夹中的文件。

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

在Windows PowerShell 5.1中,有一种解决长路径名问题的方法。解决方法是使用路径的Unicode版本。不要像这样指定路径 – C:\temp,而是像这样使用Unicode版本 – ‘\\?\C:\temp’,对于位于本地的文件夹,或者如果文件夹位于UNC路径中,则使用‘\\?\UNC\<computername>\<share>\Temp’。
使用上面修改后的代码来处理长路径名,下面的输出显示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脚本。
微软在PowerShell 3.0中发布了特定于WMI的CIM cmdlet。将用于删除文件的CIM cmdlet是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
变量中的值可以传输到 c:\temp 中删除所有文件的 Invoke-CimMethod
。
记住,ReturnValue
代码为0表示成功,对于调用删除方法的每个文件,都会有自己的ReturnValue
代码。

使用PowerShell和WMI按扩展名删除文件
在前面的示例中,您已经看到如何删除文件夹中的所有文件,而不考虑扩展名。但是,您也可以根据扩展名控制要删除的文件。
您会注意到下面的代码中,这次查询增加了一个条件(Name LIKE '%.log
)。这个添加的条件意味着只返回与.LOG扩展名匹配的文件。百分号(%
)符号是WQLLIKE操作符,意思是“零个或多个字符的字符串”。在编程术语中,%
相当于通配符,即星号(*
)字符。
下面的演示显示,在执行上述代码之前,有九个*.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
不仅可以获得更快的执行速度,还可以获得更清洁和更短的代码。
下一步
在本文中,您已经看到了使用PowerShell通过内置cmdlet和WMI/CIM删除文件的两种不同方法。
请注意,您应始终使用Get-ChildItem
和Remove-Item
cmdlet来删除文件。这些内置的cmdlet比使用WMI时更加灵活、易用和快速。
尝试编写一个可以为您执行磁盘空间清理的脚本。当然,已经存在一些用于此目的的脚本;可以参考它们,但如果您愿意练习和学习,应该尝试创建您自己的脚本。
进一步阅读
Source:
https://adamtheautomator.com/powershell-delete-file/