I love Powershell. Unfortunately, as soon as we cross into the realm of trying to grep for a specific string in gigabytes worth of large files, Powershell becomes a bit of a slowpoke.
Thankfully I also use the incredible FileLocator Pro, a highly optimized tool for searching file contents – no matter the size. The search is blazingly fast – and you can easily utilize FileLocator’s magic within Powershell!
For the sake of clarity: I will be using Powershell 7.1.3 for the following example.
# Add the required assembly
Add-Type -Path "C:\Program Files\Mythicsoft\FileLocator Pro\Mythicsoft.Search.Core.dll"
# Prepare the base search engine and criteria
$searchEngine = New-Object Mythicsoft.Search.Core.SearchEngine
$searchCriteria = New-Object Mythicsoft.Search.Core.SearchFileSystemCriteria
$searchCriteria.FileName = "*.log"
$searchCriteria.FileNameExprType = [Mythicsoft.Search.Core.ExpressionType]::Boolean
$searchCriteria.LookIn = "C:\Temp\LogData"
$searchCriteria.LookInExprType = [Mythicsoft.Search.Core.ExpressionType]::Boolean
$searchCriteria.SearchSubDirectory = $true
$searchCriteria.ContainingText = ".*The device cannot perform the requested procedure.*"
$searchCriteria.ContentsExprType = [Mythicsoft.Search.Core.ExpressionType]::RegExp
# Actually perform the search, $false executes it on the same thread as the Powershell session (as in: it's blocking)
$searchEngine.Start($searchCriteria, $false)
foreach($result in $searchEngine.SearchResultItems)
{
# SeachResultItems are on a per-file basis.
foreach($line in $result.FoundLines)
{
"Match in $($result.FileName) on line $($line.LineNumber): $($line.Value)"
}
}
Wowzers, that’s pretty easy! In fact, a lot easier (and quicker, to boot!) than playing around with Get-Contents, StreamReaders and the like.
One thing of note here: Between running this on a loop for every file in a directory, it is actually quicker to process an entire tree of folders/files. The larger the dataset, the larger the gains through invoking FileLocator.
And yeah, you can use FileLocator on the command line through flpsearch.exe – however the results are not as easily digestable as the IEnumerables you get through the assembly.