Learn What IT Pros Need to Know About Windows 11 - August 26th at 1 PM ET! Learn What IT Pros Need to Know About Windows 11 - August 26th at 1 PM ET!
PowerShell|Windows Server

Where Is the File: Using Get-FileItem

And we’re back with our look at a couple of command line utility items. In part one, I discussed how to use Where.exe, which can locate files and return the full file name. There’s nothing wrong with the utility because it gets the job done efficiently. However, it really is a legacy command line tool and as such has some limitations, especially if you want to do anything with the results.

It is possible to run it in PowerShell, although you have to be explicit to avoid confusing it with the Where alias for Where-Object.

​PS C:\> where.exe calc.exe
C:\Windows\System32\calc.exe

It certainly makes it easier to find and execute the file.

PS C:\> where.exe calc.exe | invoke-item

But anything more complicated, especially once you start adding directories and parameters gets a little messy. If you are going to be using this in PowerShell (and why wouldn’t you?) then it would seem to make sense to use a PowerShell version of WHERE.EXE. So I wrote one for us!

Sponsored Content

Read the Best Personal and Business Tech without Ads

Staying updated on what is happening in the technology sector is important to your career and your personal life but ads can make reading news, distracting. With Thurrott Premium, you can enjoy the best coverage in tech without the annoying ads.

Using Get-FileItem

My version is an advanced function called Get-FileItem. I wanted to stick with a conventional naming scheme, but the script file will also define an alias called pswhere. The where alias is already in use from Where-Object so I had to come up with something else. The function acts just like a cmdlet and includes complete help and examples as you can see in Figure 1.

Help for Get-FileItem
Figure 1 Help for Get-FileItemI tried to stick to the same syntax and features as the original WHERE.EXE, but I tweaked a few parameter names to make them more PowerShell-like and added a few features. The basic syntax and usage is the same.

​PS C:\> pswhere notepad.exe
C:\Windows\system32\notepad.exe
C:\Windows\notepad.exe

Using Regex with pswhere

One new feature is the addition of regular expression support. In the CLI version, you were limited to wildcards. Now you can specify your search pattern as a regular expression.

​PS C:\> pswhere "^\d+\S+\.((txt)|(xml))" -Regex -path c:\work,c:\scripts -recurse
C:\work\12787550.xml
C:\work\2012-01-10_SRV-2.xml
C:\work\2012-01-10_SRV.xml
C:\work\234.txt
C:\work\2507158.xml
C:\work\638242.xml
C:\scripts\1000FemaleNames.txt
C:\scripts\100names.txt
C:\scripts\13ScriptBlocks.txt
C:\scripts\2500names.txt
C:\scripts\5000names.txt

In this expression, I am searching for any .xml or txt file that begins with a number in the C:\work and C:\Scripts directory. I’m even searching recursively, although I don’t have any matching files.

The default output is the full file name, but if you need to compare files or want detailed information, I decided to write the full file object to the pipeline.

​PS C:\> pswhere notepad.exe -full

    Directory: C:\Windows\system32

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         7/13/2009   9:39 PM     193536 notepad.exe

    Directory: C:\Windows

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         7/13/2009   9:39 PM     193536 notepad.exe

Of course, this means you can do further sorting, exporting or filtering as needed.

My PowerShell version of WHERE.EXE uses –Quiet but writes $True or $False, which makes it much easier to work with.

​PS C:\> if (pswhere vboxmanage.exe -quiet) { "Found file" } else {"File not found"}
Found file

Finally, I decided to add one more feature. It is possible that you may search for a pattern and get many results back but perhaps all you care about is if you find at least one result. I added a –First parameter, which will skip searching any other folders as soon as a match is made. This can be helpful if searching a deep directory structure and you know you can stop after the first file is found.

​PS C:\> pswhere winword.exe -path c:\ -recurse -first -EA SilentlyContinue
C:\Program Files\Microsoft Office\Office14\WINWORD.EXE
PS C:\>

There’s no reason to keep searching the C: drive once I’ve found the file. In fact, this is a handy way to create some shortcuts in the shell.

​PS C:\> $wd=pswhere winword.exe -path "c:\program files" -recurse -first -ea silentlycontinue

Now, whenever I need to launch Microsoft Word, I don’t have to take my hands off the keyboard!

​PS C:\> &wd

You can download the script file here: Get-FileItem. Rename it with a .ps1 file extension. You will need to dot source the file in your shell or profile script. The file includes the pswhere alias. Once loaded, be sure to look at full help and examples before you try it out.

I’ll post any future updates on this script to my blog (http://jdhitsolutions.com/blog). If you have questions on how the function is written or other issues, feel free to use my Q&A forum at http://bit.ly/AskJeffHicks.

Related Topics:

Register for Advanced Microsoft 365 Day!

GET-IT: Advanced Microsoft 365 1-Day Virtual Conference - Live August 24th!

Join us on Tuesday, August 24th and hear from Microsoft MVPs and industry experts about how to take advantage of Microsoft 365 at a technical level and dive deep into the features and functionality that will make your environment more secure and compliant.

RSVP Now

Sponsored By