How to use an Encrypted Password File in PowerShell Scripts?

Requirement: Use an encrypted password file in PowerShell scripts.

How to Use a Encrypted Password File in PowerShell Scripts?

How to use an Encrypted Password File to Read/Write Credentials in PowerShell?

PowerShell modules like PnP PowerShell offers a mechanism to use Windows credentials store to Save and retrieve user name and password to use it in scripts. However, for other PowerShell modules like SharePoint Online Management Shell, AzureAD, CSOM., etc., we don’t have any direct ways to suppress the password prompt, other than storing the password in plain text within the script. In situations like we need to schedule the script in Windows task scheduler, for unattended execution of the script without any user intervention, we can use this method:

Here is how we can store and read encrypted passwords from a file in PowerShell scripts.

MFA must be turn-off for the saved credentials to work!
  • Step 1: Create an encrypted password file to store credentials
  • Step 2: Read the encrypted password from the file and use it in scripts.

Create an Encrypted Password File

Basically, we need to get the credentials from the user (once!) and store the encrypted password in a file. Here is the PowerShell script to save the encrypted password to a file.

#function to Save Credentials to a file
Function Save-Credential([string]$UserName, [string]$KeyPath)
{
    #Create directory for Key file
    If (!(Test-Path $KeyPath)) {        
        Try {
            New-Item -ItemType Directory -Path $KeyPath -ErrorAction STOP | Out-Null
        }
        Catch {
            Throw $_.Exception.Message
        }
    }
    #store password encrypted in file
    $Credential = Get-Credential -Message "Enter the Credentials:" -UserName $UserName
    $Credential.Password | ConvertFrom-SecureString | Out-File "$($KeyPath)\$($Credential.Username).cred" -Force
}

#Get credentials and create an encrypted password file
Save-Credential -UserName "salaudeen@crescent.com" -KeyPath "C:\Scripts"

This creates a file with encrypted credentials on a given path.

Get the encrypted password from the File

Once we create the encrypted password file, we can read the file and use the saved credentials in our scripts like:

#function to get credentials from a Saved file
Function Get-SavedCredential([string]$UserName,[string]$KeyPath)
{
    If(Test-Path "$($KeyPath)\$($Username).cred") {
        $SecureString = Get-Content "$($KeyPath)\$($Username).cred" | ConvertTo-SecureString
        $Credential = New-Object System.Management.Automation.PSCredential -ArgumentList $Username, $SecureString
    }
    Else {
        Throw "Unable to locate a credential for $($Username)"
    }
    Return $Credential
}

#Get encrypted password from the file
$Cred = Get-SavedCredential -UserName "salaudeen@crescent.com" -KeyPath "C:\Scripts"

#Connect to Azure AD from saved credentials
Connect-AzureAD -Credential $Cred

Alright, here is how we can use this method to connect to SharePoint Online Management Shell:

#Get encrypted password from the file
$Cred = Get-SavedCredential -UserName "salaudeen@crescent.com" -KeyPath "C:\Scripts"
 
#Connect to SharePoint Online PowerShell
Connect-SPOService -URL "https://Crescent-admin.sharepoint.com" -Credential $Cred
 
#Get all Site Collections
Get-SPOSite

Similarly, to connect to SharePoint Online using CSOM PowerShell, use:

Import-Module Microsoft.Online.SharePoint.PowerShell

#Get encrypted password from the file
$Cred = Get-SavedCredential -UserName "salaudeen@crescent.com" -KeyPath "C:\Scripts"

#Parameter
$SiteUrl = "https://Crescent.sharepoint.com/sites/marketing"
    
#Set up the context
$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteUrl)
$Ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)
 
#Get the Web Object
$Web = $Ctx.web
$Ctx.Load($Web)
$Ctx.ExecuteQuery()
 
#Get the Title of the Web
Write-host $Web.Title 

I used it in automated PowerShell scripts that are scheduled in the Windows task scheduler. E.g., PowerShell to import custom user profile properties from Azure AD to SharePoint Online user profile store.

Export-Import Credentials using Clixml Method

Here is the alternate way to export and import credentials securely.

#Function to Export Credentials to secure File
Function Export-Credential 
{
   param
   (
     [Parameter(Mandatory=$true)]
     $Path,

     [System.Management.Automation.Credential()]
     [Parameter(Mandatory=$true)]
     $Credential
   )
    
  $CredentialObject = $Credential | Select-Object *    
  $CredentialObject.Password = $CredentialObject.Password | ConvertFrom-SecureString    
  $CredentialObject | Export-Clixml $Path
} 

#Import Credentials from Saved File
Function Import-Credential 
{
   param
   (
     [Parameter(Mandatory=$true)]
     $Path
   )
    
  $CredentialObject = Import-Clixml $path    
  $CredentialObject.password = $CredentialObject.Password | ConvertTo-SecureString    
  New-Object system.Management.Automation.PSCredential($CredentialObject.username, $CredentialObject.password)
}

#Export Credential to a File
Export-Credential -Path "C:\Temp\CredFile.Secure" -Credential (Get-Credential)

#Get Credentials from File
$Cred = Import-Credential -Path "C:\Temp\CredFile.Secure"

#Connect to Azure AD
Connect-AzureAD -Credential $Cred

#Connect to SharePoint Online Management Shell
Connect-SPOService -Url "https://Crescet-admin.sharepoint.com" -Credential $Cred

#Connect to PnP Online
Connect-PnPOnline -Url "https://Crescent-admin.sharepoint.com" -Credentials $Cred

In conclusion, using a PowerShell encrypted password file is a secure method for storing sensitive information such as passwords. The encryption process uses a secure algorithm to convert plaintext into ciphertext, making it unreadable. Additionally, by using a PowerShell script, encrypting and decrypting the password file can be automated, making it a convenient and efficient solution for managing sensitive information. However, one of the biggest disadvantages is, if the password file were to fall into the wrong hands, the information stored within it would not protect it from unauthorized access.

Salaudeen Rajack

Salaudeen Rajack - Information Technology Expert with Two-decades of hands-on experience, specializing in SharePoint, PowerShell, Microsoft 365, and related products. He has held various positions including SharePoint Architect, Administrator, Developer and consultant, has helped many organizations to implement and optimize SharePoint solutions. Known for his deep technical expertise, He's passionate about sharing the knowledge and insights to help others, through the real-world articles!

4 thoughts on “How to use an Encrypted Password File in PowerShell Scripts?

  • I have run a PowerShell command mentioned below running successfully( PnP PowerShell to Download a Document Library from SharePoint Online).
    When we run this script it is asking SharePoint Admin Credentials(User name and password), to avoid providing admin credentials manually(Looking for Automation) encrypt the same using any PowerShell command and add the same below
    PowerShell Command successful
    ………………………………………………………………….
    #Parameters
    $SiteURL = https://kgacompany.sharepoint.com/sites/kga-ssc-bist
    $ListName = “Test”
    $DownloadPath =”D:\Time and attandance”

    #Connect to SharePoint Online
    Connect-PnPOnline $SiteURL
    $Web = Get-PnPWeb

    #Get the list
    $List = Get-PnPList -Identity $ListName

    #Get all Items from the Library – with progress bar
    $global:counter = 0
    $ListItems = Get-PnPListItem -List $ListName -PageSize 500 -Fields ID -ScriptBlock { Param($items) $global:counter += $items.Count; Write-Progress -PercentComplete `
    ($global:Counter / ($List.ItemCount) * 100) -Activity “Getting Items from List:” -Status “Processing Items $global:Counter to $($List.ItemCount)”;}
    Write-Progress -Activity “Completed Retrieving Folders from List $ListName” -Completed

    #Get all Subfolders of the library
    $SubFolders = $ListItems | Where {$_.FileSystemObjectType -eq “Folder” -and $_.FieldValues.FileLeafRef -ne “Forms”}
    $SubFolders | ForEach-Object {
    #Ensure All Folders in the Local Path
    $LocalFolder = $DownloadPath + ($_.FieldValues.FileRef.Substring($Web.ServerRelativeUrl.Length)) -replace “/”,”\”
    #Create Local Folder, if it doesn’t exist
    If (!(Test-Path -Path $LocalFolder)) {
    New-Item -ItemType Directory -Path $LocalFolder | Out-Null
    }
    Write-host -f Yellow “Ensured Folder ‘$LocalFolder'”
    }

    #Get all Files from the folder
    $FilesColl = $ListItems | Where {$_.FileSystemObjectType -eq “File”}

    #Iterate through each file and download
    $FilesColl | ForEach-Object {
    $FileDownloadPath = ($DownloadPath + ($_.FieldValues.FileRef.Substring($Web.ServerRelativeUrl.Length)) -replace “/”,”\”).Replace($_.FieldValues.FileLeafRef,”)
    Get-PnPFile -ServerRelativeUrl $_.FieldValues.FileRef -Path $FileDownloadPath -FileName $_.FieldValues.FileLeafRef -AsFile -force
    Write-host -f Green “Downloaded File from ‘$($_.FieldValues.FileRef)'”
    }

    Reply
  • New sharepoint has broken this wonderful report. Any chance we can get an update?

    Reply
  • You forgot to mention that you have to read the file while running the script as the same account that created the file. Otherwise, you’ll get a “Key not valid for use in specified state.” error.

    Reply
    • That’s right! ONLY The account that encrypts the password can decrypt the password from file. In other scenarios like Scheduling the PowerShell in Windows Tash Scheduler, make sure the account you are using us the same.

      Reply

Leave a Reply

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