Creating and Storing PowerShell Credentials

I actually do not understand why I have not put this in a blog post before, but it is about time - because I used it again today.

Sometime you need to store a credential for a number of purposes, be it a scheduled script - or just not having to enter credentials each and every time you would like to connect to a Host or your vCenter.

PowerCLI has it’s own credential store with the New-VICredentialStoreItem and Get-VICredentialStoreItem cmdlets.

Personally - I do not like using this Cmdlet and have another method that I prefer using -System.Management.Automation.PSCredential.

First get the credential and store it in a file.

(Get-Credential).Password | ConvertFrom-SecureString | Out-File -FilePath C:\users\msaidelk\Documents\scripts\maish.cred

Linux Panic

This will give you a string

Get-Content C:\users\msaidelk\Documents\scripts\maish.cred 01000000d08c9ddf0115d1118c7a00c04fc297eb01000000b215c3e1ee044b4286513bf7017abc8f0000000002000000000003660000c000000010000000d6533af1a8d6da153c0bf43713400cb30000000004800000a0000000100000008217a9ea26e47eba311ce8272156a7a2180000004c7047e3ca25bc540078e9dad60b0aff8ba48f37709534a614000000e582d7d6522c111d7101849 a27f8a9c034eb4ab6

To construct the credential again do this:

$vicred = New-Object System.Management.Automation.PsCredential "root", (Get-Content "C:\Users\msaidelk\Documents\scripts\maish.cred" | ConvertTo-SecureString) 

The object accepts two parameters: UserName, Password. They both have to be there and of course the username has to match the the credential that was originally entered for this to work

One other important point that I should point out is that when you import the credential – it has to be done with the same user that stored it in the file in the first place otherwise it will fail - like I tried below with a different user:

PS C:\Users\testa> $vicred = New-Object System.Management.Automation.PsCredential "root", (Get-Content "C:\temp\maish.cred" | ConvertTo-SecureString)
ConvertTo-SecureString : Key not valid for use in specified state. At line:1 char:108 + ... \maish.cred" | ConvertTo-SecureString) + ~~~~~~~~~~~~~~~~~~~~~~ + 
CategoryInfo : InvalidArgument: (:) [ConvertTo-SecureString], C ryptographicException + FullyQualifiedErrorId : ImportSecureString_InvalidArgument_Cryptographic Error,Microsoft.PowerShell.Commands.ConvertToSecureStringCommand

You could do use this method Storing Passwords to Disk in PowerShell with Machine-key Encryption but that is overkill for my use case.

To summarize the process:

  1. Store the password in a file.
  2. Build the credential by providing the correct username and the content of the file and store it in a variable.
  3. Use the variable when connecting to your vCenter / Hosts.

In my Powershell $PROFILE I have the following three lines:

$vcenter = "msaidelk-lab1" $vicred = New-Object System.Management.Automation.PsCredential "MAISHSK\Maish", (Get-Content "C:\Users\msaidelk\Documents\scripts\maish.cred" | ConvertTo-SecureString) Connect-VIServer $vcenter -Credential $vicred

Every time I open a PowerCLI prompt (I usually do that to perform something on my environment), I now have a connection to my vCenter ready for me.