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?
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?
Share edited Mar 5 at 22:55 Fravadona asked Mar 5 at 17:18 FravadonaFravadona 17.3k1 gold badge28 silver badges47 bronze badges2 Answers
Reset to default 2You 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:
- If the cmdlet produces output you can be sure the path exists. Here you could change error action from
SilentlyContinue
toStop
if you wanted the cmdlet to throw a terminating error instead of you manually throwing the error. - To which provider the item belongs to by looking at the
.PSProvider
property. - If the path belongs to the
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
You can use Resolve-Path
to discover provider information about a given item path:
if(!(Test-Path -LiteralPath $Path) -or (Resolve-Path -LiteralPath $Path).Provider.Name -ne 'FileSystem') {
# path might be valid, but it's not a file system path
}