powershellcharacter-encodingdrone.io

powershell ignore character escaping with output from a different process


I have a process running powershell commands with input from a config file. (In casu it's a drone CI executor on Windows with a drone YML file). This process sets an environment variable but I think this environment variable contains backticks which are interpreted as escape characters by powershell.

Since it's an OpenSSH key, this corrupts the key. Is there a way to treat the contents of the environment variable entirely as raw? Either during setting or reading (because since I don't know the key I do not know where it happens).

Drone CI config:

  - name: copy to archive on remote host
    commands:
      - Write-Output $env:SSH_KEY > ssh_key
      - scp -i ssh_key file.zip user@host:/path/to/file.zip
      - rm ssh_key
    environment:
      SSH_KEY:
        from_secret: ssh_key

I know it's a functional key because it works on my linux containers. But on Windows the format is deemed invalid.


Solution

  • The problem is the behavior of >, the redirection operator, in PowerShell, which is in effect an alias of the Out-File cmdlet:


    The simplest solution is to use New-Item instead, as it - surprisingly - creates BOM-less UTF-8 files even in Windows PowerShell, and never appends a trailing newline (-ItemType File is implied):[1]

    $env:SSH_KEY | New-Item -Force ssh_key
    

    Note:


    [1] Strictly speaking, this only applies if PowerShell's current location is one backed by the file-system provider - however, in practice it almost always is. If it isn't and you still want to create a file, either specify a full file-system path or prefix a relative one with FileSystem:: in order to target the file-system provider's current directory.

    [2] See this answer for background.

    [3] This implies, unfortunately, that in Windows PowerShell different cmdlets have different default encodings - see the bottom section of this answer for background.