[玩转系统] 使用 PowerShell 查找僵尸文件
作者:精品下载站 日期:2024-12-14 20:38:37 浏览:13 分类:玩电脑
使用 PowerShell 查找僵尸文件
在我们深入探讨这个问题之前,让我强调一下。我的许多帖子本质上都是为了教育。我经常以一个场景(例如查找 0 字节文件)作为教授概念和技术的起点。完成一项任务几乎总是有多种方法。我的代码从来不打算按原样在生产中运行。相反,你应该拿走我如何做某事以及为什么。概念和技术比解决表面目标更重要。
使用CIM
对于此任务,我想我应该使用 Get-CimInstance。 您可能没有意识到,但是您可以查询一个 WMI 类来查找名为 CIM_Datafile。在大多数情况下,老实说,我不确定哪种情况不会出现这种情况,所有文件都在 CIM 存储库中注册。以下是其中一个对象的外观:
Status : OK
Name : c:\work\samples\w.txt
Caption : c:\work\samples\w.txt
Description : c:\work\samples\w.txt
InstallDate : 10/9/2020 3:35:49 PM
AccessMask : 18809343
Archive : True
Compressed : False
CompressionMethod :
CreationClassName : CIM_LogicalFile
CreationDate : 10/9/2020 3:35:49 PM
CSCreationClassName : Win32_ComputerSystem
CSName : PROSPERO
Drive : c:
EightDotThreeFileName : c:\work\samples\w.txt
Encrypted : False
EncryptionMethod :
Extension : txt
FileName : w
FileSize : 0
FileType : Text Document
FSCreationClassName : Win32_FileSystem
FSName : NTFS
Hidden : False
InUseCount :
LastAccessed : 10/30/2020 11:49:34 AM
LastModified : 10/9/2020 6:56:31 PM
Path : \work\samples\
Readable : True
System : False
Writeable : True
Manufacturer :
Version :
PSComputerName :
假设我想查找 C:\work\samples 中文件大小为 0 的所有文件。我可以编写一个 WMI 过滤器,如下所示:
"Drive='c:' AND path = '\work\samples\' AND filesize=0"
创建 WMI/CIM 查询时,您需要转义反斜杠,因此路径值 \work\samples\ 变为 \work\samples\。另请记住,WMI/CIM 查询中的运算符是旧版运算符,而不是 PowerShell 运算符。
在PowerShell中,我们强调早期过滤的重要性。如果命令提供了一种过滤方法,那么就使用它。早期过滤几乎总是比获取所有内容然后通过管道传输到 Where-Object 更好。这并不是说使用Where -Object 是一件坏事。有时您别无选择,或者故意需要通过管道传输到Where-Object。只要确保您知道为什么使用Where-Object即可。
这是我的简单测试。
我知道我的基本查询有效并且得到了我期望的结果。现在,我想退后一步,将所有 0 长度的文件归档到 C:\Work 中。
Get-CimInstance -ClassName CIM_Datafile -Filter "Drive='c:' AND path = '\work\' AND filesize=0" | Select-Object Name,FileSize
嗯。该查询在 C:\Work 的根目录中找到了该文件,但没有找到其他文件。 WMI 查询越具体,通常运行速度越快。但是,在这种情况下,我需要使用通配符稍微扩展查询。我想查找路径以 \\work 开头的文件。
Get-CimInstance -ClassName CIM_Datafile -Filter "Drive='c:' AND path LIKE '\work\%' AND filesize=0" | Select-Object Name,FileSize
在 WMI/Cim 查询中,使用 % 作为通配符代替传统的 *。另请注意,我将运算符更改为 LIKE。运算符不区分大小写。我使用大写,这样它们就会脱颖而出。这种方法的一个显着缺点是它比使用“等于”比较慢得多。但它最终应该会起作用。
注意事项和提示
使用 WMI/CIM 查询时,需要记住一些事项。首先,不能保证每个对象(在本例中为文件)都已在 CIM 存储库中注册。理论上,您的查询可能会丢失文件。在此特定用例中,您始终可以使用 Get-ChildItem 枚举文件夹。
当我从事此工作时,我发现如果文件夹实际上使用重新解析点,则查询需要相当长的时间,甚至可能无法按预期工作。例如,我的 C:\Scripts 文件夹实际上是 OneDrive 的链接。
PS C:\> get-item c:\scripts | Select Target
Target
------
{D:\OneDrive\Scripts}
我发现如果我在查询中使用 C:\Scripts,我得到的结果不完整。但如果我使用 D:\OneDrive\Scripts,我会更快地得到预期的结果。
加快该过程的另一种方法是限制 Get-CimInstance 需要获取的属性。这是另一种类型的过滤。我第一次在 C:\Work 中搜索 0 字节文件花了 8 分钟。但由于我只需要一些属性,我可以改进我的命令:
Get-CimInstance -ClassName CIM_Datafile -Filter "Drive='c:' AND path LIKE '\work\%' AND filesize=0" -property Name,FileSize | Select-Object Name,FileSize
我得到了相同的结果,但这次用了 39 秒。我承认大型查询有时会花费很长时间,有时运行速度比您预期的要快。尽管作为规则,使用 LIKE 总是会减慢查询速度。
创建函数
考虑到所有这些,我编写了一个函数来查找给定路径中的 0 字节文件。
Function Get-ZeroLengthFiles {
[CmdletBinding()]
[alias("gzf", "zombie")]
Param(
[Parameter(Position = 0)]
[ValidateScript( { Test-Path -Path $_ })]
[string]$Path = ".",
[switch]$Recurse
)
Begin {
Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Starting $($myinvocation.mycommand)"
#select a subset of properties which speeds things up
$get = "Name", "CreationDate", "LastModified", "FileSize"
$cimParams = @{
Classname = "CIM_DATAFILE"
Property = $get
ErrorAction = "Stop"
Filter = ""
}
} #begin
Process {
Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Using specified path $Path"
#test if folder is using a link or reparse point
if ( (Get-Item -path $Path).Target) {
$target = (Get-Item -path $Path).Target
Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] A reparse point was detected pointing towards $target"
#re-define $path to use the target
$Path = $Target
}
#convert the path to a file system path
Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Converting $Path"
$cPath = Convert-Path $Path
Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Converted to $cPath"
#trim off any trailing \ if cPath is other than a drive root like C:\
if ($cpath.Length -gt 3 -AND $cpath -match "\$") {
$cpath = $cpath -replace "\$", ""
}
#parse out the drive
$drive = $cpath.Substring(0, 2)
Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Using Drive $drive"
#get the folder path from the first \
$folder = $cpath.Substring($cpath.IndexOf("\")).replace("\", "\")
Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Using folder $folder (escaped)"
if ($folder -match "\w+" -AND $PSBoundParameters.ContainsKey("Recurse")) {
#create the filter to use the wildcard for recursing
$filter = "Drive='$drive' AND Path LIKE '$folder\%' AND FileSize=0"
}
elseif ($folder -match "\w+") {
#create an exact path pattern
$filter = "Drive='$drive' AND Path='$folder\' AND FileSize=0"
}
else {
#create a root drive filter for a path like C:\
$filter = "Drive='$drive' AND Path LIKE '\%' AND FileSize=0"
}
#add the filter to the parameter hashtable
$cimParams.filter = $filter
Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Looking for zero length files with filter $filter"
#initialize a counter to keep track of the number of files found
$i=0
Try {
Write-Host "Searching for zero length files in $cpath. This might take a few minutes..." -ForegroundColor magenta
#find files matching the query and create a custom object for each
Get-CimInstance @cimParams | ForEach-Object {
#increment the counter
$i++
#create a custom object
[PSCustomObject]@{
PSTypeName = "cimZeroLengthFile"
Path = $_.Name
Size = $_.FileSize
Created = $_.CreationDate
LastModified = $_.LastModified
}
}
}
Catch {
Write-Warning "Failed to run query. $($_.exception.message)"
}
if ($i -eq 0) {
#display a message if no files were found
Write-Host "No zero length files were found in $cpath." -ForegroundColor yellow
}
else {
Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Found $i matching files"
}
} #process
End {
Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($myinvocation.mycommand)"
} #end
}
我希望这些评论能够解释我在做什么以及为什么。我什至为本赛季添加了一个有趣的命令别名。
在函数中,我将自定义对象写入管道,以便可以在 PowerShell 中使用结果。
我递归地运行 C:\ 的函数,大约花了 41 秒才找到 1774 个文件。这对我来说似乎非常有效!
概括
在处理任何任务时,始终从可以在控制台中运行的简单命令开始。如果您无法从提示符成功运行命令,那么您将很难围绕它编写函数或脚本。即使这个函数不是我先写的。当使用 CIM cmdlet 并尝试提出优雅且高效的查询时尤其如此。
如果您想了解有关 PowerShell 脚本编写的更多信息,请考虑获取《PowerShell 脚本编写和工具制作》的副本。如果您对我的做法或原因有任何疑问,请随时发表评论。
猜你还喜欢
- 03-30 [玩转系统] 如何用批处理实现关机,注销,重启和锁定计算机
- 02-14 [系统故障] Win10下报错:该文件没有与之关联的应用来执行该操作
- 01-07 [系统问题] Win10--解决锁屏后会断网的问题
- 01-02 [系统技巧] Windows系统如何关闭防火墙保姆式教程,超详细
- 12-15 [玩转系统] 如何在 Windows 10 和 11 上允许多个 RDP 会话
- 12-15 [玩转系统] 查找 Exchange/Microsoft 365 中不活动(未使用)的通讯组列表
- 12-15 [玩转系统] 如何在 Windows 上安装远程服务器管理工具 (RSAT)
- 12-15 [玩转系统] 如何在 Windows 上重置组策略设置
- 12-15 [玩转系统] 如何获取计算机上的本地管理员列表?
- 12-15 [玩转系统] 在 Visual Studio Code 中连接到 MS SQL Server 数据库
- 12-15 [玩转系统] 如何降级 Windows Server 版本或许可证
- 12-15 [玩转系统] 如何允许非管理员用户在 Windows 中启动/停止服务
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[影视] 黑道中人 Alto Knights(2025)剧情 犯罪 历史 电影
[古装剧] [七侠五义][全75集][WEB-MP4/76G][国语无字][1080P][焦恩俊经典]
[实用软件] 虚拟手机号 电话 验证码 注册
[电视剧] 安眠书店/你 第五季 You Season 5 (2025) 【全10集】
[电视剧] 棋士(2025) 4K 1080P【全22集】悬疑 犯罪 王宝强 陈明昊
[软件合集] 25年6月5日 精选软件22个
[软件合集] 25年6月4日 精选软件36个
[短剧] 2025年06月04日 精选+付费短剧推荐33部
[短剧] 2025年06月03日 精选+付费短剧推荐25部
[软件合集] 25年6月3日 精选软件44个
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电视剧] 欢乐颂.5部全 (2016-2024)
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[影视] 【稀有资源】香港老片 艺坛照妖镜之96应召名册 (1996)
[剧集] 神经风云(2023)(完结).4K
[剧集] [BT] [TVB] [黑夜彩虹(2003)] [全21集] [粤语中字] [TV-RMVB]
[实用软件] 虚拟手机号 电话 验证码 注册
[资源] B站充电视频合集,包含多位重量级up主,全是大佬真金白银买来的~【99GB】
[影视] 内地绝版高清录像带 [mpg]
[书籍] 古今奇书禁书三教九流资料大合集 猎奇必备珍藏资源PDF版 1.14G
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电影] 美国队长4 4K原盘REMUX 杜比视界 内封简繁英双语字幕 49G
[电影] 死神来了(1-6)大合集!
[软件合集] 25年05月13日 精选软件16个
[精品软件] 25年05月15日 精选软件18个
[绝版资源] 南与北 第1-2季 合集 North and South (1985) /美国/豆瓣: 8.8[1080P][中文字幕]
[软件] 25年05月14日 精选软件57个
[短剧] 2025年05月14日 精选+付费短剧推荐39部
[短剧] 2025年05月15日 精选+付费短剧推荐36部
- 最新评论
-
- 热门tag