Security is something that every administrator should take seriously. Clear text passwords in (PowerShell) scripts is not something that is best practice and should be avoided or handled differently.
In this post I am going to encrypt a password (not a username) using 128-bit AES encryption but the first step is to create a key so we can encrypt and unencrypt data.
So let’s start by creating the AES key, this file will be used to encrypt or unencrypt the password file.
$KeyFile = "C:\TMP\AES.key" # You can use 128-bit (16 bytes), 192-bit (24 bytes) or 256-bit key (32 bytes) for AES $Key = New-Object Byte 16 [Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($Key) $Key | out-file $KeyFile
The AES.key in the folder C:\TMP is our key. This key can be used to unencrypt the password so save it to a secure location.
The next step is to create a password file and use they key to encrypt the password value:
$KeyFile = "C:\TMP\AES.key" $Key = Get-Content $KeyFile $Password = "Password01 | ConvertTo-SecureString -AsPlainText -Force $PasswordFile = "C:\TMP\ADMIN_account.pass" $Password | ConvertFrom-SecureString -key $Key | Out-File $PasswordFile
I use the .pass extension but this can be any file extension.
Repeat this step for every password that needs to be encrypted if you have mutiple passwords.
Not we have the AES.key file and the ADMIN_account.pass file. Both files will be read from a PowerShell script to use the password from the file.
I am going to use the credentials in my PowerShell script to create two Microsoft SQL Server users and set the password from the .pass file.
The PowerShell script will look like this:
# Specify Database Login Name $Login_Name = "Admin_ittechlog" # Create an SMO Login object $Login = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Login -ArgumentList $Server, $Login_Name $Login.LoginType = [Microsoft.SqlServer.Management.Smo.LoginType]::SqlLogin # Don't use PasswordPolicyEnforced and PasswordExpirationEnabled. $Login.PasswordExpirationEnabled = $false $Login.PasswordPolicyEnforced = $false # Set the user password $User = "Admin_ittechlog" $PasswordFile = "C:\TMP\ADMIN_account.pass" $KeyFile = "C:\TMP\AES.key" $key = Get-Content $KeyFile $Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Login_Name, (Get-Content $PasswordFile | ConvertTo-SecureString -Key $key) $Login.Create($Credential.Password)
So, when we run the script above the following will happen.
1. The Login_Name wil be the name of the SQL user that is created.
2. The $passwordfile will be the file which contains the encrypted password for Admin_ittechlog
3. The $KeyFile will be the AES.key file which contains the information to unencrypt the ADMIN_account.pass file
4. The SQL account is created with the unencrypted password from the ADMIN_account.pass file.
Now this is great but what if I want to read the password from the encrypted file using the AES.key file to unencrypt it. Use the following PoSH code to unencrypt it:
$Login_Name = "Admin_ittechlog" $PasswordFile = "C:\TMP\ADMIN_account.pass" $KeyFile = "C:\TMP\AES.key" $key = Get-Content $KeyFile $Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Login_Name, (Get-Content $PasswordFile | ConvertTo-SecureString -Key $key) Write-Host $credential.GetNetworkCredential().password
The above PowerShell scripts make it possible to replace clear-text password from PowerShell scripts by AES encrypted passwords.
Remember: Always store the AES.key in a secure location with the correct (NTFS) rights applied. And backup the file.