使用WMI查询和CIM_DataFile进行递归文件搜索

时间:2018-08-16 20:26:12

标签: powershell wmi wmi-query

我希望能够在远程Windows桌面上查询特定文件,但是我有以下限制:

  1. 我无法假设已启用Powershell远程处理。
  2. 我不知道文件的确切位置
  3. 时间是一个因素

这导致我进行以下查询: SELECT * FROM CIM_DataFile WHERE Drive ='C:'AND FileName='Fake' AND Extension='dll'

与powershell中的Get-childitem之类的东西相比,这花费了相对较长的时间,使我可以通过文件夹和子文件夹来优化搜索。

我总是可以做类似的事情: SELECT * FROM CIM_DataFile WHERE Drive ='C:'AND FileName='Fake' AND Extension='dll' AND Path like '\\Windows\\System32\\%',但是此查询会增加遥控器上的负载,并且实际上不会花费任何时间。

我可以使用WMI进行某种类型的递归搜索吗?

1 个答案:

答案 0 :(得分:0)

如果未在目标计算机上启用PowerShell远程处理,则必须使用DCOM连接到WMI。在现代Windows系统上,默认情况下DCOM连接处于关闭状态,因此您必须启用它-在这种情况下,最好启用PowerShell远程处理。

如果您必须使用WMI,则需要这样的东西

function get-wmifile {
[CmdletBinding()]
param (
 [Parameter(Mandatory = $true)]
 [string]$path,
 [string]$file
)

if ($path.IndexOf('\\') -le 0 ){
  $path = $path.replace('\', '\\')
}

if ($path.IndexOf('*') -ge 0 ){
  $path = $path.replace('*', '%')
}

Write-Verbose -Message "Path to search: $path"

$folders = Get-CimInstance -ClassName Win32_Directory -Filter "Name LIKE '$path'" 
foreach ($folder in $folders){
 if ($file) {
   Get-CimAssociatedInstance -InputObject $folder -ResultClassName CIM_DataFile |
   where Name -Like "*$file" |
   Select Name
 }
 else {
   Get-CimAssociatedInstance -InputObject $folder -ResultClassName CIM_DataFile |
   Select Name
 }
}

}

将该功能用作

PS> get-wmifile -path 'c:\test*'

Name                              
----                              
c:\test\counters.csv              
c:\test\p1.txt                    
c:\test\test.md                   
c:\test2\p1.txt                   
c:\test2\test3\p2.txt             
c:\testscripts\eventlogchanges.txt
c:\testscripts\tempfolderlog.csv  
c:\testscripts\test.ps1       

或查找文件

PS> get-wmifile -path 'c:\test*' -file 'p1.txt'

Name           
----           
c:\test\p1.txt 
c:\test2\p1.txt

正如您所说,使用Get-ChildItem比WMI快得多。无法加快WMI的速度-访问文件数据的速度很慢-所以我的建议是坚持使用get-ChildItem