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
– Mathias R. Jessen
Aug 16 at 21:19


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.

Popular posts from this blog

Help:Category

How can temperature be calculated given relative humidity and dew point?

I have a recursive function to validate tree graph and need a return condition