linuxpowershellssh

Piping large file from Powershell ssh to Linux


I'm trying to use ssh to load a docker image file stored on a Windows 2022 machine to a Linux machine with docker.

From Windows WSL, this command works perfectly:

cat /mnt/c/temp/my_docker_image.tar.gz | ssh -l matt 192.168.1.250 docker image load

However, I don't want to install WSL just for this (I don't need it otherwise); I just want to use PowerShell. I tried this command in PowerShell and it hangs with PowerShell using up large amounts of memory.

Get-Content -Path C:\temp\my_docker_image.tar.gz -Raw -Encoding Byte | ssh -l matt 192.168.1.250 docker image load

Is there a way to get the PowerShell command working? Or a different command other than Get-Content?


Solution


  • Workaround for Windows PowerShell and PowerShell (Core) 7 versions up to v7.3.x:

    Take advantage of the fact that cmd.exe's pipeline is a raw byte conduit (as in POSIX-compatible shells such as bash), so pass an equivalent command line to it:

    cmd /c 'type C:\temp\my_docker_image.tar.gz | ssh -l matt 192.168.1.250 docker image load'
    

    As noted, you may choose to continue to use this approach in PowerShell 7.4+, for performance reasons.


    For detailed background information, see the bottom section of this answer.


    [1] Even if you read the input file as binary data (a [byte[]] array), on sending this data through the pipeline it is treated as text in PowerShell versions before 7.4. (each [byte] instance is converted to its decimal string representation, and the instances are separated with newlines).