Powershell in combination with the VI Toolkit are a very nice way to automate tasks in your virtual infastructure. While the most actions are executed via the vCenter, it is very important not to connect with a clear-text password somewhere in your scripts. If you schedule tasks or run scripts without user interaction, this may be not so easy. In the following I describe in a short way how this can be done:
First we have to store our password encrypted. I have done this with the help of this function, which asks for username and password and store them in a xml file (I have found the source on a website, which name I can't remember). The password is encrypted and can only be decrypted with the same user name. Further I have determined that even the computer, on which this file was created initially has to be the same (in a clustered vCenter environment, my scripts never ran on the failover node, because the password can't be decrypted).
function Export-PSCredential {
param ( $Credential = (Get-Credential), $Path = "connect.xml" )
# Look at the object type of the $Credential parameter
switch ( $Credential.GetType().Name ) {
# It is a credential, so continue
PSCredential { continue }
# It is a string, so use that as the username and prompt for the password
String { $Credential = Get-Credential -credential $Credential }# other cases
default { Throw "You must specify a credential object to export to disk." }
}
# Create temporary object to be serialized to disk
$export = "" | Select-Object Username, EncryptedPassword# Give object a type name which can be identified later
$export.PSObject.TypeNames.Insert(0,’ExportedPSCredential’)$export.Username = $Credential.Username
# Encrypt SecureString password using Data Protection API
# Only the current user account can decrypt this cipher
$export.EncryptedPassword = $Credential.Password | ConvertFrom-SecureString
# Export using the Export-Clixml cmdlet
$export | Export-Clixml $Path
Write-Host -foregroundcolor Green "Credentials saved to: " -noNewLine
# Return FileInfo object referring to saved credentials
Get-Item $Path
}
Export-PSCredential
Afterwards you get a xml file with the following content (example):
<Objs Version="1.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<Obj RefId="RefId-0">
<MS>
<S N="Username">mydomain\vcuser</S>
<S N="EncryptedPassword">
01000000d08c9ddf0115d1118c7a00c04fc297eb01000000df2723e2eb2d0f4eb26a1eff9db804b20000000002000000000003660000a8000000100000008201280235881db0152bdcc0cb1e63290000000004800000a000000010000000156ae1be1fb12ede6abee57e1f30cdd2180000006cd8dd44b0178d020ab951125b692e4364d4043c466eaa79140000004dab9e7cf9de199ab0b998160c7686
</S>
</MS>
</Obj>
</Objs>
Store the xml file in the profile of the respective user (for example).
In the following is shown how the connection and authentication in your script has to be done:
function Import-PSCredential {
param ( $Path = "connect.xml" )
# Import credential file
$import = Import-Clixml $Path# Test for valid import
if ( !$import.UserName -or !$import.EncryptedPassword ) {
Throw "Input is not a valid ExportedPSCredential object, exiting."
}
$Username = $import.Username# Decrypt the password and store as a SecureString object for safekeeping
$SecurePass = $import.EncryptedPassword | ConvertTo-SecureString
# Build the new credential object
$Credential = New-Object System.Management.Automation.PSCredential $Username, $SecurePassWrite-Output $Credential
}$Cred = Import-PSCredential 'c:\documents and settings\vcuser\connect.xml'
$Server = Connect-VIServer myvCenter.example.com -credential $Cred