1

I'm working on a Powershell Script which reads an ssh keys and known hosts from a file and writes that to another file.

I read the key with

$SshPrivateKey = Get-Content 'ssh-keys\id_rsa'

Then I write the newfile with

New-Item -path $SshKeysDir -Name $SshPrivateKeyFile -Value $SshPrivateKey -ItemType file -force

This works fine with the public key. But for some strange reason it does not work with the private key. The new file ends up with just

System.Object[]

As a workaround I'm currently using

$SshPrivateKey > $testpath

which writes the file correctly. Also writing the content to the console renders the expected private key

Write-Output $SshPrivateKey

What bothers me most is the fact that it works for other files such as the public key or the known host. Just not for the private key file. The working command for the public key looks like this

New-Item -path $SshKeysDir -Name $SshPublicKeyFile -Value $SshPublicKey -ItemType file -force

One difference I see is that the public key is multiline vs. single line in case of the public key.

Can anyone point shed some light on this mistery?

Pascal Mages
  • 177
  • 1
  • 11
  • If you're reading with `Get-Content` why are you not writing it with `Set-Content`? If the intent is to copy the file why not use `Copy-Item` ? – Remko Apr 05 '17 at 20:09
  • Thanks for the hint! I'm pretty new to Powershell and I didn't know about the Set-Content. Copy-Item could be a good solution as long as the input is coming from a file which might actually change in my use case. – Pascal Mages Apr 05 '17 at 20:29

1 Answers1

2

The problem here is solely with the way you're reading the file into a variable.

The way Get-Content works (detailed here) is that it'll read the file as an array of lines. Reference from above link:

It reads the content one line at a time and returns a collection of objects, each of which represents a line of content.

For single line files, this ends up being simplified for ease of use. Printing this array ends up printing the way you would expect because of how printing in Powershell doesn't just cast it to a string the way New-Item does.

An easy way to check is to just call the GetType() method of the object:

PS > $singleLineFileContent.GetType();

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

PS > $multiLineFileContent.GetType();

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

So to solve your actual problem, you just need to make sure you read the file as a string properly. That said, prefer this answer to the accepted one if you're running 3.0 or later.

Community
  • 1
  • 1
Mike Roibu
  • 307
  • 2
  • 13