Using a certificate to encrypt credentials in automated PowerShell scripts – An Update!

Early last year I wrote a post about encrypting script credentials using certificates. At the time, someone (thanks Dave Wyatt!) commented on the post suggesting a couple of alternative methods to encrypt and decrypt the data, in particular I was interested in the Protect-CmsMessage and Unprotect-CmsMessage cmdlets included in PowerShell 5.0. Now that PowerShell 5.0 is more widespread I wanted to post a quick update about how these cmdlets can help simplify the process. The process is similar, but there are less steps and it is important to note that the certificate must contain the Data Encipherment or Key Encipherment key usage, and include the Document Encryption Enhanced Key Usage (1.3.6.1.4.1.311.80.1).

Let’s start by first locating our certificate using the Get-ChildItem cmdlet:

1
2
  $Cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Subject -like "CN=PowerShell Automation*"}
  

Next we encrypt our password using that certificate:

1
2
  $Password = 'MyPassword'
  Protect-CmsMessage -To $Cert -Content $Password

You’ll notice that the encrypted password is presented a little differently. You will need to include the entire block in your script.

Unencrypting the password in your script basically involves repeating this process in reverse:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  $Cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Subject -like 'CN=PowerShell Automation*'}
$EncryptedPwd = @'
-----BEGIN CMS-----
MIIBqAYJKoZIhvcNAQcDoIIBmTCCAZUCAQAxggFQMIIBTAIBADA0MCAxHjAcBgNVBAMMFVBvd2Vy
U2hlbGwgQXV0b21hdGlvbgIQOEd4fYDturxF77V7lEytlDANBgkqhkiG9w0BAQcwAASCAQB0z92N
HrgQ84JxSV7RYpwSMPJRuSXlgVubOIew8KsYXr/E8kd/wOyT/2NPi3d+4xb67CLUM4infqOrt9Q+
ReAtINvfVB5EPc9wU8yDpdz+WKProT4RJ94nzGH5qW5SK4O1Siu0VSPJZaCNb+CmYNFNNvLu6MN4
pDqOiqZnv+j/rUxhrHX+U3E+eJq5P0gsZUwRaXZoAgGyV6SvZdUsbPYZ+hMPG0DruF/83SK6MOZM
yVnGOmeP8e8/b/Rk2Y24JvDcROwRvK2+uj2Oy3ukw1WS4TxMy2V4lkjTYvwIO+bukjFCCtaR4Q63
C6fx9OArx+uMbPmzkFgmG0w3jFVNnjjMMDwGCSqGSIb3DQEHATAdBglghkgBZQMEASoEEPdMffTC
N+IvYDNFmuWKgZqAELsAZyE9I0POh/j64DNTsLI=
-----END CMS-----
'@
$DecryptedPwd = $EncryptedPwd | Unprotect-CmsMessage -To $Cert | ConvertTo-SecureString -AsPlainText -Force

You can now use $DecryptedPwd to generate your credentials similar to the following:

1
2
3
$MSOLUsername = 'serviceAcc@tenant.onmicrosoft.com'
$MSOLCredentials = New-Object System.Management.Automation.PSCredential ($MSOLUsername,$DecryptedPwd)
Connect-MSOLService -Credential $MSOLCredentials