I would like to validate that a user-provided string is a path to a file or directory.
$Path = 'some input string'
if (!(Test-Path -LiteralPath $Path)) {
Write-Error "${Path}: No such file or directory"
exit 1
}
The problem is that Test-Path
cannot differentiate between for eg. a directory and a registry key...
How can I do it?
You can use Get-Item
, probably with -LiteralPath
instead of -Path
if you do not want it to interpret wildcards. Based on the output you can determine:
SilentlyContinue
to Stop
if you wanted the cmdlet to throw a terminating error instead of you manually throwing the error..PSProvider
property.FileSystem
, you can determine if the path is a file or directory by looking at the .PSIsContainer
property.In summary you could do:
$item = Get-Item -LiteralPath $path -ErrorAction SilentlyContinue
# if the path can't be resolved
if (-not $item) {
throw [System.Management.Automation.ItemNotFoundException]::new(
"Cannot find path '$path' because it does not exist.")
}
# if the path exists but is not a FileSystem path
if ($item.PSProvider.Name -ne 'FileSystem') {
throw [System.ArgumentException]::new(
"The resolved path '$path' is not a FileSystem path but '$($item.PSProvider.Name)'.")
}
# here you know the path exists and belongs to FileSystem,
# you can use `$item.PSIsContainer` to know if its a File or Folder