I'm writing a c# cmdlet which copies files from one location to another (similar to rsync). It even supports ToSession and FromSession.
I'd like it to work with PSDrives that use the Filesystem provider but it currently throws an error from System.IO.File.GetAttributes("psdrive:\path")
I'd really like to use calls from System.IO on the PSDrive.
How does something like copy-item do this?
I've performed a search for accessing PSDrives from c# and have returned no results.
This is the equivalent of my code
new-psdrive -name mydrive -psprovider filesystem -root \\aserver\ashare -Credential domain\user
$attributes=[system.io.file]::GetAttributes("mydrive:\path\")
returns
Exception calling "GetAttributes" with "1" argument(s): "The given path's format is not supported."
.NET knows nothing about PowerShell drives (and typically also has a different working directory), so conversion to a filesystem-native path is necessary:
In PowerShell code:
Use
Convert-Path
to convert a PowerShell-drive-based path to a native filesystem path that .NET types understand:By default (positional argument use) and with
-Path
,Convert-Path
performs wildcard resolution; to suppress the latter, use the-LiteralPath
parameter.Caveat:
Convert-Path
only works with existing paths. Lifting that restriction is the subject of the feature request in GitHub issue #2993.In C# code:
In
PSCmdlet
-derived cmdlets:Use
GetUnresolvedProviderPathFromPSPath()
to translate a PS-drive-based path into a native-drive-based path[1] unresolved, which means that, aside from translating the drive part:Use
GetResolvedProviderPathFromPSPath()
to resolve a PS-drive-based path to a native-drive-based one, which means that, aside from translating the drive part:Use the
CurrentProviderLocation()
method with provider ID"FileSystem"
to get the current filesystem location's path as aSystem.Management.Automation.PathInfo
instance; that instance's.Path
property and.ToString()
method return the PS form of the path; use the.ProviderPath
property to get the native representation.Here's a simple ad-hoc compiled cmdlet that exercises both methods:
You can test it as follows:
If your current directory is
C:\Temp
and it happens to contain text filesa.txt
andb.txt
, you'll see the following output:[1] If a PS drive (created with
New-PSDrive
) referenced in the input path is defined in terms of a UNC path, the resulting native path will be a UNC path too.