Use test-path with powershell to check if a file exists

From Svendsen Tech PowerShell Wiki
Jump to: navigation, search

In this little article I describe how to use the cmdlet Test-Path to check if a file exists. Type Get-Help Test-Path for more information, possibly with the "-online" switch. I also quickly demonstrate the .NET class method Exists() from the System.IO.File class.




How To Check If A File Exists With PowerShell

You can use something like this for verification on the command line:

PS C:\> Test-Path C:\Windows
True

Be aware that you need quotes if the path contains spaces, parentheses - and possibly other characters I can't think of now. PowerShell automatically adds quotes when you tab complete. I recommend using single quotes, because double quotes "expand" variables (mostly relevant if you have "$" in the path).

PS C:\> Test-Path 'C:\Program Files'
True

Otherwise you will see something like this:

PS C:\> Test-Path C:\Program Files
Test-Path : A positional parameter cannot be found that accepts argument 'Files'.

To explicitly make sure it's a file and not a directory, use the -PathType parameter which has the following possible values:

  • Any
  • Leaf (file)
  • Container (directory/folder)
PS C:\> Test-Path C:\Windows\explorer.exe
True
PS C:\> Test-Path C:\Windows\explorer.exe -PathType Leaf
True
PS C:\> Test-Path C:\Windows\explorer.exe -PathType Container
False

Screenshot Example

Powershell-how-to-check-if-file-exists.png

Script Usage

In a script, you would typically use it in an if statement. To negate and check if the folder or file does not exist, use either "!" or "-not", and remember to enclose the Test-Path statement in parentheses.

Also remember that if the path or file name contains a space, you need to surround the entire path in quotes. Single quotes or double quotes will work the same if there are no "expandable" parts in the path or file name, but the slightly safer choice is single quotes. This is what PowerShell defaults to when you auto-complete names with tab at the prompt.

PS C:\> if (Test-Path C:\Windows\explorer.exe -PathType Leaf) { "It's a file/leaf" }
It's a file/leaf
PS C:\> if ( -not (Test-Path 'C:\Windows\explorer.exe' -PathType Container) ) { "It's not a container/directory/folder" }
It's not a container/directory/folder

Enumerating Possible PathType Values

A small "trick" to see the possible enumeration values for -PathType is to use one that doesn't exist, like this:

PS C:\> Test-Path C:\Windows -PathType foo
Test-Path : Cannot bind parameter 'PathType'. Cannot convert value "foo" to type
"Microsoft.PowerShell.Commands.TestPathType" due to invalid enumeration values.
Specify one of the following enumeration values and try again.
The possible enumeration values are "Any, Container, Leaf".
At line:1 char:31
+ Test-Path C:\Windows -PathType <<<<  foo
    + CategoryInfo          : InvalidArgument: (:) [Test-Path], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.TestPathCommand

And we notice the part where it says:

The possible enumeration values are "Any, Container, Leaf".

Using The .NET System.IO.File Class Method "Exists"

You can also use the Exists() method from the .NET System.IO.File class:

PS E:\temp> [System.IO.File]::Exists('E:\temp\csv1.csv')
True

One thing to be aware of, is that with this method, you need a full path. To check if a file is in the current directory with the IO.File Exists() method, you can use something like this, where you would typically use a variable with the file name in place of the here hard-coded "test.ps1":

PS E:\temp> dir .\test.ps1

    Directory: E:\temp

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        09.07.2012     03:51        206 test.ps1


PS E:\temp> [IO.File]::Exists( (Join-Path (Get-Location) 'test.ps1') )
True

PS E:\temp> [IO.File]::Exists('test.ps1')
False