PowerShell Gotcha: UNC paths and Providers

PowerShell's behavior can be a little bit funny when you pass a UNC path to certain cmdlets. PowerShell doesn't recognize these paths as "rooted" because they're not on a PSDrive; as such, whatever provider is associated with PowerShell's current location will attempt to handle them. For example:

Set-Location C:
Get-ChildItem -Path \\$env:COMPUTERNAME\c$

Set-Location HKLM:
Get-ChildItem -Path \\$env:COMPUTERNAME\c$

The first command works fine (assuming you have a c$ share enabled and are able to access it), and the second command gives a "Cannot find path" error, because the Registry provider tried to work with the UNC path instead of the FileSystem provider. You can get around this problem by prefixing the UNC path with "FileSystem::", which will make PowerShell use that provider regardless of your current location.

On top of that, commands like Resolve-Path and $PSCmdlet.GetUnresolvedProviderPathFromPSPath() don't normalize UNC paths properly, even when the FileSystem provider handles them. This annoyed me, so I spent some time investigating different options to get around the quirky behavior. The result is the Get-NormalizedFileSystemPath function, which can be downloaded from the TechNet Gallery. In addition to making UNC paths behave, this had the side effect of also resolving 8.3 short file names to long paths (something else that Resolve-Path doesn't do.)

The function has an "-IncludeProviderPrefix" switch which tells it to include the "FileSystem::" prefix, if desired (so you can reliably use cmdlets like Get-Item, Get-Content, Test-Path, etc., regardless of your current location or whether the path is UNC.) For example:

$path = "\\$env:COMPUTERNAME\c$\SomeFolder\..\.\Whatever\..\PROGRA~1" 
$path = Get-NormalizedFileSystemPath -Path $path -IncludeProviderPrefix 
Set-Location HKLM: 
Get-ChildItem -Path $path | Select-Object -First 1 

FileSystem::\\MYCOMPUTERNAME\c$\Program Files 
    Directory: \\MYCOMPUTERNAME\c$\Program Files 
Mode                LastWriteTime     Length Name 
----                -------------     ------ ---- 
d----         7/30/2013  10:54 AM            7-Zip 
About the Author

Dave Wyatt

Dave Wyatt is a Microsoft MVP (PowerShell) and a member of PowerShell.org's Board of Directors.

One Comment

  1. Dave, you said :Resolve-Path and $PSCmdlet.GetUnresolvedProviderPathFromPSPath() don't normalize UNC paths properly, even when the FileSystem provider handles them." What do you mean, they don't normalize UNC paths properly?