working with passwords in powershell part 1 – the encryption

working with passwords in powershell part 1 – the encryption

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.

See also working with passwords with powershell part2

Print Friendly, PDF & Email
  • Was this Helpful ?
  • yes   no

3 thoughts on “working with passwords in powershell part 1 – the encryption

  1. Avatar
    Jeremy Menu

    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

    1. A.K.

      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

  2. Avatar
    Jeremy Menu

    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

Leave a Reply

Your email address will not be published. Required fields are marked *