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}

resolve-path1b.png

It works great based on the previous results, but when specifying a UNC path, it doesn't return a usable path:

resolve-path2b.png

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}

resolve-path3a.png

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

resolve-path4a.png

µ