Pro Tips from the Trenches: The Resolve-Path PowerShell cmdlet
You're designing a reusable tool in PowerShell and decide a function is the most appropriate type of
command to accomplish the task at hand. It will accept a FilePath
parameter which will be used to
specify both the path and filename to a destination file. The path should already exist, but the
file may or may not already exist.
For simplicity, I've stripped away the complexity so the problem is more apparent. This function validates that the parent path exists and then returns the absolute path where the output file would be created once the remainder of the function is written:
1function Out-MrFile {
2 [CmdletBinding()]
3 param (
4 [ValidateScript({
5 if (Test-Path -Path (Split-Path -Parent $_ -OutVariable Parent) -PathType Container) {
6 $True
7 }
8 else {
9 Throw "'$Parent' is not a valid directory."
10 }
11 })]
12 [string]$FilePath
13 )
14
15 Join-Path -Path (Resolve-Path -Path (Split-Path -Parent $FilePath)) -ChildPath (Split-Path -Leaf $FilePath)
16
17}
It works great based on the previous results, but when specifying a UNC path, it doesn't return a usable path:
In this scenario, the problem is immediately identifiable, but if the path itself wasn't displayed in the previous set of results and an attempt was made to write to a file in that location, a cryptic error message would be returned.
The solution to this problem is to use the ProviderPath
property of the Resolve-Path
cmdlet:
1function Out-MrFile {
2 [CmdletBinding()]
3 param (
4 [ValidateScript({
5 if (Test-Path -Path (Split-Path -Parent $_ -OutVariable Parent) -PathType Container) {
6 $True
7 }
8 else {
9 Throw "'$Parent' is not a valid directory."
10 }
11 })]
12 [string]$FilePath
13 )
14
15 Join-Path -Path (Resolve-Path -Path (Split-Path -Parent $FilePath)).ProviderPath -ChildPath (Split-Path -Leaf $FilePath)
16
17}
Hours could be spent troubleshooting a problem such as the one demonstrated in this scenario, but the fix for this particular problem is simply choosing the specific property that not only works with local file paths, but also with UNC paths.
A bonus tip which was shown in the first example of this blog article is the Resolve-Path
cmdlet
can be used to generate an absolute path from a relative one. It can also be used to generate an
absolute path from a relative one that contains wildcards as shown in the following example:
1Resolve-Path -Path .\test\file.txt
2Resolve-Path -Path .\te*\file.txt
µ