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.
The problem is the behavior of
>, the redirection operator, in PowerShell, which is in effect an alias of theOut-Filecmdlet:Character encoding:
In Windows PowerShell (
powershell.exe), it defaults to creating UTF16-LE ("Unicode") files, which most command-line utilities do not recognize.In PowerShell (Core) 7+ (
pwsh), it now - fortunately - defaults to BOM-less UTF-8, which is now the consistent default for all cmdlets, as well as for the PowerShell engine itself with respect to readings source code.As an aside: In Windows PowerShell and PowerShell (Core) up to v7.3.x, the PowerShell pipeline and
>never act as a raw byte conduit for relaying raw data from external programs: such data is invariably decoded into a .NET string first, which>/Out-Filethen write to a file based on their default encoding. See this answer for background.Trailing newline:
-NoNewLineswitch.The simplest solution is to use
New-Iteminstead, as it - surprisingly - creates BOM-less UTF-8 files even in Windows PowerShell, and never appends a trailing newline (-ItemType Fileis implied):[1]Note:
-Forceis needed in order to ensure that a preexisting file by that name is overwritten. However,-Forcealso creates a non-existent target directory on demand, which>/Out-Filewon't do.In Windows PowerShell, using
Out-File(orSet-Content, which is generally preferable for text-only input)[2] with-Encoding Utf8is not an option, because the resulting file is invariably created with a BOM.Given that PowerShell (Core) 7+ defaults to BOM-less UTF-8, there you could alternatively use:
Set-Contentdefaults to the ANSI code page, as determined by the legacy system locale, which is a superset of ASCII.[3][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.