A common problem I have is that the account that runs a powershell script does not have the required rights on a remote computer to do its job. It could be because the remote “thing” only has local accounts or is a windows computer on a different domain. The old way of getting round this was to have a password in the script. This is a very bad idea from a security point of view and just a plain bad idea from a coding point of view. After all, who wants to find and update a password string in x number of scripts every time the details change.
To make things better for us scripters Microsoft has a Credential object. A credential object stores a user ID in plane text and a hash of a password.
This object can be used in most powershell commands that connect to a remote computer (or require credentials). But more importantly, they can be imported and exported.
An exported credential object is just an XML file the UserID is pain text and a hash of the password. The hash is based on well, the password, the computer it was created on and the user. So, to decrypt and use the password you have to be the user that created the Credential object on the computer that created it.
Creating a Credential object
To create a Credential object. Simply run:
$cred = Get-Credential
You will be prompted for credentials, enter them and the object $cred will be created in memory.
You can now use this $cred object of any command that accepts a Credential parameter. eg.
connect-viserver MyVCenter.Prod.local -Credential $cred
New-SSHSession $MySSHTarget -Credential $cred
Get-WmiObject -Class Win32_logicalDisk -ComputerName $ServerName -Credential $cred
But the best thing about Credential objects is that you can save (export) them. Just use the export-clixml command.
$cred | Export-Clixml C:\temp\MyCred.xml
Once exported to disk, another script (same user, same computer) can import them. using the import-clixml command.
$NewCred = Import-Clixml C:\temp\MyCred.xml
At work I do this a lot. I will need to run a scheduled task to scan all my vCenter servers and get some data for whatever. So, I manually create and export the Credential objects for all the vCenters I need to scan (Not a fun job but I only need to do it once). Then I create a CSV file with the vCenter addresses and the paths to each cred file. Then my script will loop through the CSV file logging on to each vCenter and collecting my data.
If you forget the password in a Credential object or a command needs a password (yuck) you can pull it out by doing this.
$NewCred.GetNetworkCredential().password
Now, Credential objects are not perfict. If I wanted the password from a stored credential object that I could not access. Then I could just edit the scheduled script that imports the credential to run the above $NewCred.GetNetworkCredential().password command and dump the result to a text file. Setting ACLs on the script could stop that.
There you go, Credentials. Very handy!