Recursive file search using WMI Query and CIM_DataFile
Recursive file search using WMI Query and CIM_DataFile
I want to be able to query a remote windows desktop for a particular file however I have the following constraints:
This has led me to the following query:SELECT * FROM CIM_DataFile WHERE Drive ='C:'AND FileName='Fake' AND Extension='dll'
SELECT * FROM CIM_DataFile WHERE Drive ='C:'AND FileName='Fake' AND Extension='dll'
This takes a relatively long time in comparison to something like Get-childitem in powershell which allows me to refine my search by folders and subfolders.
Get-childitem
I could always do something like:SELECT * FROM CIM_DataFile WHERE Drive ='C:'AND FileName='Fake' AND Extension='dll' AND Path like '\Windows\System32\%' however this query increases the load on the remote and doesn't actually take any less time.
SELECT * FROM CIM_DataFile WHERE Drive ='C:'AND FileName='Fake' AND Extension='dll' AND Path like '\Windows\System32\%'
Is there any way I can use WMI to do some type of recursive search?
Get-CimInstance Win32_Directory -Filter "Name = 'C:\Windows\System32'" |Get-CimAssociatedInstance -Association Win32_Subdirectory
You don't say what OS and PS version (source and target). There are cmdlets one can use without PSRemoting enabled. technet.microsoft.com/en-us/library/ff699046.aspx or the Mathias touted route.
– postanote
Aug 16 at 21:35
1 Answer
1
If you don't have PowerShell remoting enabled on the target machine you'll have to use DCOM to connect to WMI. DCOM connectivity is turned off by default on modern windows systems so you'll have to enable it - in which case you'd be better off enabling PowerShell remoting.
If you have to use WMI you'll need something like this
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)
where Name -Like "*$file"
else
Get-CimAssociatedInstance -InputObject $folder -ResultClassName CIM_DataFile
Use the function as
PS> get-wmifile -path 'c:test*'
Name
----
c:testcounters.csv
c:testp1.txt
c:testtest.md
c:test2p1.txt
c:test2test3p2.txt
c:testscriptseventlogchanges.txt
c:testscriptstempfolderlog.csv
c:testscriptstest.ps1
or to find a file
PS> get-wmifile -path 'c:test*' -file 'p1.txt'
Name
----
c:testp1.txt
c:test2p1.txt
As you say using Get-ChildItem would be much quicker than WMI. There isn't a way to speed up the WMI - accessing file data is slow - so my recommendation is to stick with get-ChildItem
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Get-CimInstance Win32_Directory -Filter "Name = 'C:\Windows\System32'" |Get-CimAssociatedInstance -Association Win32_Subdirectory– Mathias R. Jessen
Aug 16 at 21:19