If you need to validate a path to a file, registry key, certificate, or any other PowerShell drive path, you need the Test-Path cmdlet.
The Test-Path cmdlet is a simple yet useful way to quickly check many attributes of a file and other items. It can check whether a file exists (or other item types), a string is in the proper path format, or even whether or not an item is newer than or older than a specific time.
In this tutorial, you’re going to learn all about the PowerShell Test-Path cmdlet and how you can use it to improve your PowerShell scripts.
Prerequisites
If you’d like to follow along with the examples in this tutorial, you’re going to need one thing; PowerShell. More specifically, the tutorial will be using PowerShell v7.03 on Windows 10, although many of the techniques you’ll learn will apply to older versions too.
What Does the Test-Path Cmdlet Do?
The PowerShell Test-Path cmdlet is one of the simplest commands around. It’s a command that’s been in PowerShell since the beginning and only returns two values; True or False.
But, don’t let the simplicity fool you; it will save you so much time in validating information in your PowerShell scripts.
Think of the PowerShell Test-Path cmdlet as quality control when working with PowerShell providers and drives. When writing a script, you’ll commonly work with various items contained in PowerShell drives. PowerShell drives like C:\, HKLM, Cert, and so on.
Test-Path
does not work with all PS drives. If, for example, you attempt to useTest-Path
against a registry key, it will work. If, you attempt to useTest-Path
against a registry value, it will returnFalse
every time.
If you’re curious, run the Get-PSDrive
cmdlet right now in PowerShel and notice all of the PS drives that show up for you.
All of these drives have paths inside of them like C:\Windows, HKLM:\Software, etc. When working with paths inside of your PowerShell scripts, it’s always good practice to first test whether or not the path is valid or it exists it not. This is what PowerShell’s Test-Path
does.
Test-Path
defines a condition that returns True
or False
depending on if a specific condition is met (typically whether a file/folder, registry key, certificate, or even a variable exists or not).
Test-Path Parameters and Usage
Like many other PowerShell cmdlets, the Test-Path
cmdlet has various parameters that change its behavior. Let’s now cover each parameter and demonstrate how it works and what kind of results you might expect to see.
Path
The Path
parameter is a mandatory parameter you will use with each Test-Path
execution. The Path
parameter defines the PSDrive’s path you’d like to test for the existence of.
If, for example, you’d like to test whether or not the folder C:\Foo exists, you’d provide the appropriate path to the Path
parameter. Then, depending on if C:\Foo actually exists or not, Test-Path
would either return True
or False
.
PS> Test-Path -Path 'C:\Foo'
True
The same technique can be used for any item path as well. Maybe you’d like to test whether or not the registry key HKLM:\Software\Foo exists. Simply use the registry key path with the Path
parameter.
PS> Test-Path -Path 'HKLM:\Software\Foo'
True
Know that all techniques demoed throughout this tutorial will work with any PowerShell drive path.
Using Wildcards
What happens if you don’t necessarily care if a path has a literal value. Instead, you’d just like to check whether or not a path matches a specific pattern. In that case, you can use wildcards in the Path
value.
Perhaps you’d like to check whether or not your C:\Foo folder contains any subfolder that starts with Bar. In that case, you could use a wildcard.
PS> Test-Path -Path 'C:\Foo\Bar*'
Once you execute the above command, Test-Path
will check for the existence of any folder that starts with Bar and return True
or False
depending on if any folder matching that criteria exists or not.
Asterisks (*
) match one or more characters but you can also use question marks (?
) too to get more granular and test for a single character.
Using the above scenario as an example, if the folder C:\Foo\Bar1 exists, you could test for any subfolder of Foo that starts with Bar and is exactly four characters using the command below.
PS> Test-Path -Path 'C:\Foo\Bar?'
If, for some reason, you’d like to use the
Path
parameter using wildcards but want to literally match a wildcard character like*
, you can always escape the wildcard characters with a backtick (`).
LiteralPath
The LiteralPath
parameter is nearly identical to the Path
parameter with one exception; it doesn’t allow wildcards. Using the LiteralPath
will interpret the path’s value literally.
For example, if you attempt to use an asterisk or question mark inside of the path value using LIteralPath
, Test-Path
will completely ignore the wildcard characters and test literally for C:\Foo\Bar? like in the below example.
PS> Test-Path -LiteralPath 'C:\Foo\Bar?'
You should use
LiteralPath
as the default path parameter if you don’t need to use any wildcard characters to ensureTest-Path
tests the path you’re expecting.
PathType
By default, when you run Test-Path
and provide it a path, it will return True
if it finds anything in that path. The item with a path could be a container like a file folder, a registry key, certificate store, and so on, or a leaf like a file, registry value, or certificate.
You can force Test-Path
to get more granular and test specifically for a container or leaf item using the PathType
parameter.
Test-Path uses the
PathType
valueAny
, by default.
If, for example, there’s a folder at C:\Foo\Bar and you’re looking for a file at that path, you could use the PathType
parameter as shown below. You want only to check if a file exists called C:\Foo\Bar.
PS> Test-Path -LiteralPath 'C:\Foo\Bar' -PathType Leaf
Maybe instead, you need to confirm whether or not C:\Foo\Bar is actually a file. In that case, you’d check for a container.
PS> Test-Path -LiteralPath 'C:\Foo\Bar' -PathType Container
Include
If using the Path
parameter and wildcards, you’ll sometimes need to get more specific. In that case, you need to look into the Include
and Exclude
parameters.
Let’s say you have the following folders:
- C:\Foo\Bar1
- C:\Foo\Bar2
- C:\Foo\Bar3
You’d like to check whether any folder that starts with Bar exists that are exactly four characters like Bar1, Bar2, etc.
PS> Test-Path -Path C:\Foo\Bar? -PathType Container
The above command works fine, but now you’d like to only find folders in C:\Foo named Bar2. In that case, you could use the Include
parameter.
PS> Test-Path -Path C:\Foo\Bar? -PathType Container -Include 'Bar2'
The above command now only tests for essentially a single folder C:\Foo\Bar2. You’d probably be better off just using Test-Path -Path 'C:\Foo\Bar2' -PathType Container
instead.
Exclude
The Exclude
parameter works similarly to the Include
parameter except this time it excludes paths matching a string.
Maybe you want to ensure there is at least one file inside of the C:\Foo folder, and you use the following command:
PS> Test-Path -Path C:\Foo\* -PathType Leaf
The above command returns True
or False
if any files are in C:\Foo. But maybe you want to ensure any files besides ones with a file extension of txt
exist. In that case, you could use the Exclude
parameter using a wildcard to exclude all files with the txt
extension from testing.
PS> Test-Path -Path C:\Foo\* -PathType Leaf -Exclude *.txt
Filter
According to Microsoft’s documentation, the Filter
parameter “specifies a filter in the format or language of the provider. The value of this parameter qualifies as the Path
parameter. The syntax of the filter, including the use of wildcard characters, depends on the provider”.
Although the Filter
parameter should be used with other cmdlets like Get-Childitem
, for example, it is rarely if ever used with Test-Path
. If you’ve found a good use for the Filter
parameter, please reach out on Twitter at @adbertram.
Related: Get-ChildItem: Listing Files, Registry, Certificate and More as One
NewerThan
Have you ever needed to check the timestamp on a file and make a decision based on that? If so, the NewerThan
and OlderThan
parameters save a lot of code. The NewerThan
parameter checks whether or not an item’s timestamp is newer than a specific date.
The NewerThan
parameter accepts a string or a DateTime object to represent a timestamp to check against. For example, to check whether or not the file C:\Foo\bar.txt was created after January 20th, 2021, you’d run Test-Path
like below.
Test-Path -LiteralPath 'C:\Foo\bar.txt' -NewerThan 'January 20, 2021'
## or
Test-Path -LiteralPath 'C:\Foo\bar.txt' -NewerThan '1/20/21'
OlderThan
The OlderThan
parameter is exactly the same as the NewerThan
parameter but opposite. This parameter checks whether or not an item is older than a specific date.
Test-Path -LiteralPath 'C:\Foo\bar.txt' -OlderThan 'January 20, 2021'
## or
Test-Path -LiteralPath 'C:\Foo\bar.txt' -OlderThan '1/20/21'
IsValid
If you’ve ever dynamically built a path in a script, you’d know the struggle. Sometimes you may fat-finger a key or somehow get some special character in a path; if so, the IsValid
parameter is for you.
The IsValid
parameter is a unique parameter that turns Test-Path
, not into a cmdlet that checks for an item’s existence but one that checks for path syntax. This parameter confirms whether or not a path is valid only.
For example, perhaps you need to verify whether a path is syntactically valid. You’re working with a couple of variables and concatenate them to build a path.
When concatenating paths, always use the
Join-Path
cmdlet. This is just for example purposes only!
$someVar = 'abc:dff'
$rootPath = 'C:\'
$path = "$someVar$rootPath
Now to ensure the path you’ve dynamically created is valid, use the IsValid
parameter like below. You’d find that Test-Path
returns False
.
PS> Test-Path -LiteralPath $path -IsValid
False
The path abc:dffC:\
is not a valid path now allowing you to create a validation routine from this situation.
If you’re using PowerShell v6.1.2 or earlier and are using the
IsValid
andPathType
parameters together,Test-Path
will ignore thePathType
parameter.
Credential
Even though you’ll find the Credential
parameter on Test-Path
, you may think you can use it to authenticate to PS drives as another user. That’s a valid assumption, but it’s wrong.
Unfortunately, the Credential
parameter doesn’t do much with the Test-Path
cmdlet. Microsoft recommends using the Invoke-Command
cmdlet and using the Credential
parameter there if you want to invoke Test-Path
with alternate credentials.
Invoke-Command -Credential (Get-Credential) -Scriptblock {Test-Path -LiteralPath 'C:\'}