Credentials (PowerShell): Difference between revisions
m (→Store Password Securely: Added "ConvertTo-SecureString : Key not valid for use in specified state") |
(→Store Password Securely: Added "Convert SecureString To Plain Text") |
||
Line 69: | Line 69: | ||
The password file must be created/encrypted as the same logged in user as the account under which the script will run. Therefore if your script will be running from a scheduled task, run from a server using a service account, you must be logged onto the that machine with the service account when you create the file. | The password file must be created/encrypted as the same logged in user as the account under which the script will run. Therefore if your script will be running from a scheduled task, run from a server using a service account, you must be logged onto the that machine with the service account when you create the file. | ||
=== Convert SecureString To Plain Text === | |||
To decrypt a secure string use the following (this must be run from the same user session used to encrypt the string) | |||
<source lang="powershell"> | |||
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($EncryptPass) | |||
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) | |||
</source> | |||
== Logged-In User's Credentials == | == Logged-In User's Credentials == |
Latest revision as of 09:16, 18 December 2014
Get-Credential
When running commands that require a connection to a remote machine its useful to be able to store a user/pass combination so that you aren't repeatedly prompted every time you run a command. Create a credential object, then supply that in place of a username in a command
PS H:\> $cred = Get-Credential
cmdlet Get-Credential at command pipeline position 1
Supply values for the following parameters:
Credential
PS H:\> Get-WMIObject -query "SELECT * FROM Win32_OperatingSystem" -credential $cred -computer 10.10.4.167
SystemDirectory : C:\WINDOWS\system32
Organization : SandfordIT
BuildNumber : 3790
RegisteredUser : Me
SerialNumber : 69712-640-3560061-45009
Version : 5.2.3790
However, this doesn't really help much in a fully scripted situation where you need to supply user and pass in an unattended fashion, for that you also need the help of ConvertTo-SecureString
, but if you want to be secure you need to use Store Password Securely
ConvertTo-SecureString
- http://technet.microsoft.com/en-us/library/dd819512.aspx
- Converts encrypted standard strings to secure strings
The following example creates a Credential object that can be used for in place of Get_Credential
$pass = ConvertTo-SecureString $svr.pass -asplaintext -force
$cred = New-Object -typename System.Management.Automation.PSCredential -argumentlist $svr.user,$pass
$wmiobj = Get-WMIObject -query "SELECT * FROM Win32_BIOS" -credential $cred -computer $svr.ip
Store Password Securely
Adapted (a little) from http://bsonposh.com/archives/338 by Brandon This is a two stage process, 1st you have to create a file with your (encrypted) password in (its encrypted by the currently logged in user - so if its going to be used in a scheduled task, make sure the user that will execute the script creates the password file).
$Credential = Get-Credential
$credential.Password | ConvertFrom-SecureString | Set-Content "Pass.fil"
Then you can use this in a script, the $cred
is a standard credential object.
$pass = Get-Content "Cred.fil" | ConvertTo-SecureString
$cred = New-Object System.Management.Automation.PsCredential("DOMAIN\user",$pass)
For a complete, but simple user/pass caching system use something like the following. I use this script to create a local user/pass file which gets used whenever I need to provide credentials in a script.
$UserFile = "User.fil"
$PassFile = "Pass.fil"
# Check for credential files, create if required
if (!(Test-Path $UserFile) -or !(Test-Path $PassFile)) {
Write-Host "Credential files not found"
$cred = Get-Credential -Credential ($env:userdomain + "\" + $env:username)
$cred.UserName | Set-Content $UserFile -Force
$cred.Password | ConvertFrom-SecureString | Set-Content $PassFile -Force
Write-Host "Credentials saved"
}
# Load password credential from encrypted file
$pass = Get-Content $PassFile | ConvertTo-SecureString
$user = Get-Content $UserFile
$cred = New-Object System.Management.Automation.PsCredential($user, $pass)
...obviously to make the above more useful you'd test that the user/pass combo supplied was correct prior to saving to file.
ConvertTo-SecureString : Key not valid for use in specified state
This is the error you get if you try to decrypt the contents of your password file using a user account other than that which was used to encrypt it.
The password file must be created/encrypted as the same logged in user as the account under which the script will run. Therefore if your script will be running from a scheduled task, run from a server using a service account, you must be logged onto the that machine with the service account when you create the file.
Convert SecureString To Plain Text
To decrypt a secure string use the following (this must be run from the same user session used to encrypt the string)
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($EncryptPass)
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
Logged-In User's Credentials
To use the credentials of the existing logged in session where a CmdLet requires that you specify them use the following...
$cred = [System.Net.CredentialCache]::DefaultCredentials