One day I was looking for a certain video file on my computer but I didn’t know where to look, however I new the name (in this case it was a video I posted on YouTube and there I could easily find the original file name).
With the standard search bar in the Windows Explorer window the file could not be found (it was not indexed). I figured: “how hard can it be to use PowerShell to look for a file with a certain name?”. I limited my scope to only search based on the file name. After this I constructed a fairly simple but effective script which did just that. Not only did I find the file, it even appeared multiple times on my 2TB drive (several copies of the same file). It went through the 2TB drive faster then I would expect (benefit is this case was the limited scope which only looked at the names of files).
I wanted to share this simple (and really, it doesn’t get much more straight forward then this) script which enables empowers you to search large amounts of files as long as you know a part of the filename. If you are familiar with regular expressions you can use this in the search. If you are not familiar with them you can still use a part of the file name.
This is the script:
function Find-File { Param( [Parameter(Mandatory=$true)] [ValidateNotNull()] [string]$Path, [Parameter(Mandatory=$true)] [ValidateNotNull()] [string]$regexSearchString ) return Get-ChildItem -Path $Path -Recurse -File -ErrorAction SilentlyContinue | ? {$_.Name -match $regexSearchString}; } New-Alias -Name ff -Value Find-File;
To make the function easier to work with I also created an alias “ff” as you can see in the last line.
Most of the lines consist of the two mandatory parameters: Path and regexSearchString (don’t worry if you do not know much about regular expressions; normal text will also work).
The actual search is basically a one liner. It collects all files below the provided path (as you can see by the switches “-File” and “-Recurse”. In addition if no files are found (or the path is no valid path) the result will be $null, which indicates there are no results for the current patch/search string combination. When all files are collected there is a filter which matches each file name against the regular expression (or search string).
If called directly it will simply write the result to the screen:
ff -Path c:\ -regexSearchString test
It makes more sense to store the result in a variable like this:
$result = ff -Path c:\ -regexSearchString test
Here $result will contain a collection fileInfo objects; if there is only one match it will be no collection but it will be a fileInfo object directly.
If you are only interested in the location of the files you may choose to only collect the FullName (path+filename) property of the objects. You can do this by piping it to a select:
$result = ff -Path c:\ -regexSearchString test | Select FullName
Here $result will be a collection of strings (or a single string if there is only one match).
If you are looking for a directory of which you know the name, the script can easily be modified to look for directories. Simply replace “-File” with “-Directory”, the rest works the same.