PS: Using Passwords In Your Scripts

2 minute read

Description:

Sometime when using PS, you will have a set of credentials that you want to store for future use. Follow these steps.

To Resolve:

  1. First we need to get our password and pump it to a file:

    Read-Host -Assecurestring | Convertfrom-Securestring | Out-File C:\Scripts\Cred.Txt
    
  2. Then, draw it back into our scripts:

    $Password = Get-Content C:\Scripts\Cred.Txt | Convertto-Securestring
    
  3. Finally, we create a credential object which we pump into other cmdlets:

    $Creds = New-Object -Typename System.Management.Automation.Pscredential -Argumentlist Yourusername, $Password
    
  4. You could store your password in your profile dirctory (usually C:\Users\userName\Documents\WindowsPowerShell) and then place it in your profile script in order to always have it.

References:

http://blogs.technet.com/b/robcost/archive/2008/05/01/powershell-tip-storing-and-using-password-credentials.aspx


Version 2:

At my last job, I wrote PS scripts at least once a month and placed them on various virtual servers throughout or infrastructure. On my second year of employment, I went back to each server and replaced any hard coded passwords with a key file that only myself and the domain admin had access to. This is how I set it up:

To Resolve:

  1. What you can do, is to create a random 32-bit key (the maximum supported by AES) and store it to a file:

    • Create a key file:
    $KeyFile = "C:\Scripts\AES.key"
    $Key = New-Object Byte[] 32
    [Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($Key)
    $Key | out-file $KeyFile
    
  2. Then, invoking the stored key, create the encrypted password:

    $PasswordFile = "C:\Scripts\AESpassword.txt"
    $KeyFile = "C:\Scripts\AES.key"
    $Key = Get-Content $KeyFile
    $Password = "password" | ConvertTo-SecureString -AsPlainText -Force
    $Password | ConvertFrom-SecureString -key $Key | Out-File $PasswordFile
    
  3. Then, in your script call the password and key:

    • Credentials
    $User = "domain\administrator"
    $PasswordFile = "C:\Scripts\AESpassword.txt"
    $KeyFile = "C\:Scripts\AES.key"
    $Key = Get-Content $KeyFile
    $Creds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, (Get-Content $PasswordFile | ConvertTo-SecureString -Key $Key)
    
  4. As you can imagine, this makes scripts portable as you can place the key and password file on a fileserver and share it out.

NOTE: The main thing there is to just set the correct NTFS permissions. Your password is essentially wide open if an attacker were to get the key.

References:

http://www.virtualtothecore.com/en/encrypt-passwords-in-powershell-scripts/


Update 2018-03:

  1. A couple other ways I have seen this is:

    # Encryption
    $credpath = "c:\scripts\MyCredential.xml"
    New-Object System.Management.Automation.PSCredential("mycomputer\gerry", (ConvertTo-SecureString -AsPlainText -Force "Pa$$word")) | Export-CliXml $credpath
    
    # Decryption
    $cred = Import-Clixml -Path $credpath
    

    NOTE: This way seems to be common, but only works if you run as the same user on the same computer. Most of my scripts will touch multiple servers so this does not work.

  2. This one seems just like my way, but they leave the key in the script itself rather than creating a file. Either way, NTFS permissions are king here:

    # Encryption
    $Key = (3,4,2,3,56,34,254,222,1,1,2,23,42,54,33,233,1,34,2,7,6,5,35,43)
    Read-Host -Assecurestring | Convertfrom-Securestring -Key $Key | Out-File 'C:\Scripts\Encrypted_Pw.xml'
    
    # Decryption
    $Key = (3,4,2,3,56,34,254,222,1,1,2,23,42,54,33,233,1,34,2,7,6,5,35,43)
    $Password = Get-Content 'C:\Scripts\Encrypted_Pw.xml' | Convertto-Securestring -Key $Key
    $Username = "gerry"
    $Cred = New-Object -Typename System.Management.Automation.Pscredential -Argumentlist $Username, $Password