0

Encrypting Passwords in Scripts: The Ultimate Best Practice Guide for Powershell

Unencrypted passwords in Scripts?  We all know that it’s a huge security risk and an overall big no no to have your passwords in plain text.  Sometimes we want to run Scheduled tasks without the need to be standing by to enter in the appropriate credentials.  Or if you’re like me you have the need to connect to Azure or Exchange Online 50 million times a day, but don’t like having the session or Powershell Window open when not needed. So what are the best practices to having your passwords in your scripts to automatically connect to services?  We’ll go over that next.

 

Passwords in Scripts for Powershell

Here is my process for when I want to have my passwords in my scripts. The following we’ll only need to do one time every 3 months or when I change my password.

First we need to get our Credentials.

$Creds = Get-Credential

Then I create an obscure random folder and export the credentials to that folder via the Export-Clixml cmdlet. So for example I’ll pick C:\Windows\System32\WindowsPowerShell\v1.0\Modules\SomeFakeModule and export the ps1xml file there.

$Creds | Export-Clixml C:\Windows\System32\WindowsPowerShell\v1.0\Modules\SomeFakeModule\SomeRandomFilename.ps1xml

Now there should be a file SomeRandomFilename.ps1xml in the C:\Windows\System32\WindowsPowerShell\v1.0\Modules\SomeFakeModule folder. Next I’ll convert that path to a secure string and convert it back from a secure string to get a long random hex character string. That would look something like this..

'C:\Windows\System32\WindowsPowerShell\v1.0\Modules\SomeFakeModule\SomeRandomFilename.ps1xml' | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString | Out-File C:\_Scripts\SomeOtherDirectory\AnotherRandomFilename.ps1xml

The AnotherRandomFilename.ps1xml should contain something like this.

01000000d08c9ddf0115d1118c7a00c04fc297eb010000004af7b54b56de384793f6556f9f497f240000000002000000000003660000c0000000100000001a2e14d11a0435bb980161d9141109be0000000004800000a0000000100000008686204fd145b3cb74dbf328cf3dc19d60000000836224a5abf022bff65da641f93be649c221418303c626e626ee299eea9af9028308041a1f364a6294d8c31a8060dd19156f48b8df58f060f5b1025070946d1e390005ef0c0ece3f9127a7830711da7d54665d87f

The above is the only part you need to do every time you change your password.

 

The Code to have in your Scripts.

Below is the part you need to have in your script where you run the script. So for example if i wanted to connect to Azure I would create an Connect-Azure.ps1 script with the following:

$Module = Get-Content C:\Scripts\SomeOtherDirectory\AnotherRandomFilename.ps1xml | ConvertTo-SecureString
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Module)

Connect-MsolService -Credential ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) | Import-Clixml)

This should allow you to connect with your ‘password’ in the script. I know, it’s confusing as hell but it’s that way by design. You can probably get away with the Export-Clixml and Import-Clixml cmdlets since Powershell can only decrypt the credentials from the same user and computer accounts. In other words, if another user on that same computer tried to import the exported credentials, it will fail. Alternatively, if the same user tried to import the credentials from another computer, it will also fail. Sometimes however, a little extra confusion only makes it harder to reverse engineer what someone is trying to do.

Now you can import the clixml in whatever script you wish. If you want to learn more with online video, take a look at our Youtube Channel

Encrypting Passwords in Scripts: The Ultimate Best Practice Guide for Powershell
5 (100%) 9 votes

Paul Contreras

Hi, my name is Paul and I am a Sysadmin who enjoys working on various technologies from Microsoft, VMWare, Cisco and many others. Join me as I document my trials and tribulations of the daily grind of System Administration.