The estimated reading time 5 minutes
Encrypt passwords with AES256 key
NOTE: before we dive in, make sure you have read my prolog about basics in powershell password encryption.
LINK working with passwords in powershell part 2
Because I love automating things with powershell, I also want to create a script which creates a new aeskey file and also a text file with a password I typed in. Yes I know it is not the best solution, but hundred times better than storing passwords clear inside the script.
You can run this script with the following two parameters:
password-store.ps1 -KeyFilePath C:\temp\aeskey.key -CredFilePath C:\temp\password.txt
>>DOWNLOAD Script password-store.ps1<<
Enough with useless writing, I’ll give you some demos:
my script also supports -verbose common parameter, so you can see better what it does.
After this short introduction we will dive into the script and have a look at some important functions etc…
See my comments between the lines of codes.
Function Create-AESKeyFile
function Create-AESKeyFile { [CmdletBinding(SupportsShouldProcess = $True)] param ( [Parameter(Mandatory= $true)] [string]$keyFile) # Generate a random AES Encryption Key. # https://www.altaro.com/msp-dojo/encrypt-password-powershell/ #what if parameter If ($PSCmdlet.ShouldProcess("Generating AES 256 bit key and write it to file `"$keyFile`"")) { $AESKey = New-Object Byte[] 32 [Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($AESKey) #adding content to the specified key file Write-Verbose "Writing AES key to file $keyFile" Set-Content $Keyfile $AESKey } else{ #generate aes 256 bit key $AESKey = New-Object Byte[] 32 [Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($AESKey) #adding content to the specified key file Write-Verbose "Writing AES key to file $keyFile" Set-Content $Keyfile $AESKey #check if the file exists Write-Verbose "Checking if the encryption file $keyFile could be created" if (Test-Path $keyFile){ Write-Output "writing key in $Keyfile !" #get the content of keyfile to display in verbose output $contentkey = Get-Content "$keyFile" Write-Verbose "this is your private key keep it safe" Write-Verbose "$contentkey" else{ #clearing variable Write-Verbose "Clearing aes key from variable!" $contentkey =$null throw "your file $keyFile could not be created, please check permissions or path!" } } #clearing variable Write-Verbose "Clearing aes key from variable!" $contentkey =$null } }
Function Create-CredFile
function Create-CredFile { [CmdletBinding(SupportsShouldProcess = $True)] param ( [Parameter(Mandatory= $true)] [string] $credfile, [Parameter(Mandatory= $true)] [string] $aesfile ) #getting password from user as secure string #whatif parameter If ($WhatIfPreference) { $passwordsecurestring = Read-Host "Enter a password to store encrypted" -AsSecureString Write-Verbose "Encrypt securepassword string with AES 256 file: $aesfile!" Write-Verbose "Adding encrypted content to local file: $credfile" Write-Output "What if: $passwordsecurestring | ConvertFrom-SecureString -key (get-content "$aesfile") | set-content "$credfile"" } else{ #encrypt password and write in specified file $passwordsecurestring = Read-Host "Enter a password to store encrypted" -AsSecureString Write-Verbose "Encrypt securepassword string with AES 256 file: $aesfile!" Write-Verbose "Adding encrypted content to local file: $credfile" $passwordsecurestring | ConvertFrom-SecureString -key (get-content "$aesfile") | set-content "$credfile" #check if the file exists if (Test-Path "$credfile"){ #getting content from credfile only verbose $contentcred = Get-Content "$credfile" Write-Verbose "Content of ecnrypted file" Write-Verbose "$contentcred" #erase content from variable $contentcred = $null } else { #erase content from variable $contentcred =$null throw "your file $contentcred could does not exist, please check permissions or path!" } } }
If you want to use these functions in your own script, feel free to do this. But there is not much error handling, because my script checks the paths when they where entered in parameter section.
[CmdletBinding(SupportsShouldProcess = $True)] param ( #validating paths https://4sysops.com/archives/validating-file-and-folder-paths-in-powershell-parameters [Parameter(Mandatory = $true)] #test if the file exists, otherwise throw an error.Test if the user provides a full path to the file [ValidateScript({ if(($_ | Test-path -PathType Leaf)){ throw "File exists in path: $KeyfilePath, please provide another path and provide the filename example C:\temp\aes.key!" } if(($_ | Test-Path -PathType Container)){ throw "The path argument has to be a file. Folder paths are not allowed." } return $true })] #check if it is a path [System.IO.FileInfo]$KeyfilePath, #test if the file exists, otherwise throw an error.Test if the user provides a full path to the file [Parameter(Mandatory = $true)] [ValidateScript({ if(($_ | Test-path -PathType Leaf)){ throw "File or Folder does exists in path: $CredFilePath, please provide another path and provide the filename example C:\temp\cred.txt!" } if(($_ | Test-Path -PathType Container)){ throw "The path argument has to be a file. Folder paths are not allowed." } return $true })] #check if it is a path [System.IO.FileInfo]$CredFilePath )
So hopefully there is no way that the functions get wrong path variables.
At the end my script executes the two functions and finally creates these two files.
Create-AESKeyFile -keyFile "$KeyfilePath" Create-CredFile -credfile "$CredFilePath" -aesfile "$KeyfilePath"
If you like the script let me know or press “helpful”.
Have fun with your passwords.
Sorry here is the new version of my script :
#requires -runasadministrator
function Create-NewLocalAdmin {
[CmdletBinding()]
param (
[string] $NewLocalAdmin,
[securestring] $Password
)
begin {
}
process {
New-LocalUser “$NewLocalAdmin” -Password $Password -FullName “$NewLocalAdmin” -Description “Temporary local admin”
Set-LocalUser -Name “$NewLocalAdmin” –PasswordNeverExpires $True
Write-Verbose “$NewLocalAdmin local user created”
Add-LocalGroupMember -Group “Administrateurs” -Member “$NewLocalAdmin”
Write-Verbose “$NewLocalAdmin added to the local administrator group”
}
end {
}
}
$NewLocalAdmin = Read-Host “New local admin username:”
$Password = Read-Host -AsSecureString “Create a password for $NewLocalAdmin”
Create-NewLocalAdmin -NewLocalAdmin $NewLocalAdmin -Password $Password -Verbose
———————-
Everything works fine but i can not use it if i deploy it on one computer because the password is not integrate inside
Hi Jeremy,
did you see my other blogposts? https://blog.it-koehler.com/en/Archive/2355
I think you can use these lines of code at the end of your script:
###
$NewLocalAdmin = Read-Host “New local admin username:”
$aeskeypath = “.\aeskey.key”
$AESKey = New-Object Byte[] 32
[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($AESKey)
Set-Content $aeskeypath $AESKey
$Password = Read-Host -AsSecureString “Create a password for $NewLocalAdmin”
$key = Get-Content .\aeskey.key
$encryptpw = $password | ConvertFrom-SecureString -Key $key
Set-Content .\cred.txt $encryptpw
Create-NewLocalAdmin -NewLocalAdmin $NewLocalAdmin -Password $Password -Verbose
$Password = $null
##
If you would like to generate two files and use the in your script you can use these lines of code
##
$AESKey = Get-Content .\aeskey.key
$pwdTxt = Get-Content .\cred.txt
$securePwd = $pwdTxt | ConvertTo-SecureString -Key $AESKey
Create-NewLocalAdmin -NewLocalAdmin $NewLocalAdmin -Password $Password -Verbose
$Password = $null
Is this the solution you searched for?
Best regards.
Alexander
Hi Team 🙂
I need your help, i need to create a script with powershell to create a local admin account on W10 with this informations :
– id = IT-WKS
– pwd = encrypted pwd
– Account never expire
– If this account already exist please do not execute this script
This script will be deployed on some computers. Actually i dont know how i can insert an encrypted password in my script
Here is my script :
New-LocalUser “IT-WKS” -FullName “IT-WKS” -Description “Admin Local Account”
Set-LocalUser -Name ‘IT-WKS’ –PasswordNeverExpires $True
If Someone can help me 🙂
Regards