powershellgoogle-cloud-storagepowershell-provider

Is it possible to use Copy-Item between providers via a custom implementation of CopyItem in a provider?


Background

I am using the google cloud sdk which implements a provider to its storage service. Inside this provider, I can gci and cd around just fine, but when I want to cp an object onto my local filesystem, hoping to emulate a download command like gcloud storage cp <bucket item> <local path>, I get the error Copy-Item: Source and destination path did not resolve to the same provider.

Problem

I am thinking about trying to adapt this provider to support copying using google's .NET client libaries to make the remote call, but I am not sure PowerShell will allow me to do this.

I found the following issue that seems to imply it's an inherent limitation in the Copy-Item cmdlet. Digging deeper, I found the file SessionStateContainer.cs throws the CopyItemSourceAndDestinationNotSameProvider error in the CopyItem internal method of the SessionStateInternal class (line 4280 atm). (This error is resolved in SessionStateStrings.resx to the above error I was receiving).

I'm confused on how damning this is. When I Get-Command Copy-Item, I see it's coming from a different dll, where Copy-Item is defined in Navigation.cs. Here, there's no mention of any limitation on provider crossing.

Question

Would implementing the CopyItem method in a custom provider circumvent whatever the SessionStateInternal implementation is doing, so that I can wrap a remote call to download a file when using Copy-Item on objects in this provider to my local filesystem, or am I just stuck with this limitation?


Solution

  • From what I understand, PowerShell's provider model:

    Separate providers model separate items (entities in their respective namespace), and converting between the item types of different providers isn't part of the provider model, yet it is what would be required to support copying items between different providers via Copy-Item.

    While this limitation may be less understandable in the case of a cloud provider that, like the file system, ultimate stores files, consider an example such as Copy-Item $PROFILE env:/ - what would the semantics of such an operation be, if it were permitted?

    Hypothetically, you could write your own provider that combines the functionality of the Google provider and the file-system provider, which would then have to publish a new custom drive that, say, has two top-level containers (directories), one representing the cloud storage, and the other the local file-system(s).
    Obviously, this would be a substantial undertaking that duplicates existing functionality, and doesn't seem like it's worth the effort.

    The much simpler solution is to use the dedicated cmdlets for transferring files between the local file-system and the cloud offered by Google Cloud Tools for PowerShell (of which the Google Cloud PowerShell provider is a part), namely Read-GcsObject (copy from the cloud to the local file-system) and Write-GcsObject (copy to the cloud from the local file-system) - see the docs.