Decision making meme

Use credentials in PowerShell

Credentials are necessary, if you want to access systems or APIs. Credentials can be used interactively and within a script. If you want to use credentials in PowerShell to automate processes, you might have to export your credentials and import them within your automation solution.

In this article I will show you a few ways to make use of credentials, how to export and import credential objects and security considerations.

Functionality

You export the credentials with PowerShell the context the user whith which you are running the cmdlets, also the machine will be considered. So if you copy the credential file to another machine, it won’t work with the same user and you have to re-export the credential file.

Security considerations

Every initialization of credentials (interactive or automated) will lead to a prompt like this. When you export credentials with PowerShell consider following advice:

Be sure, that you do this close to your authentication and do not enter your credentials on client/ servers, which are not trusted.

Credential Prompt

Why?

You might think this is safe. If we try to read the password, it looks like this:

Credential Secure String

But there is still a way to read the password:

Credential Clear String

The risk will be there, when you enter your credentials to a shell, which you are not owner of.

  • Recommendation
    1. If you have to enter it in a Shell, which you do not controll, ensure, that the credential object will be initialized like this $Credential = $null
    2. If possible, try to run your scripts within windows authentication. In PNP.PowerShell it looks like this:
Connect-PNPOnline -Url $Url -UseCurrentCredentials

Using credentials interactively

This will lead to a prompt.

Credential Prompt
$UserName = "[email protected]"
$Credential = Get-Credential ($UPN)

You can than make use of the credentials like this:

Connect-PnPOnline -Url "https://devmodernworkplace.sharepoint.com/sites/sales" -Credentials $Credential

Using credentials non-interactively

For this use case I wrote two ready-to-use functions.

Function Export-CredentialFile 
{
    param(
    [Parameter(Mandatory=$true,Position=0)]
    $Username,
    [Parameter(Mandatory=$true,Position=1)] 
    $Path
    )
    
    
    While ($Path -eq "")
    {
        $Path = Read-Host "The path does not exist. Where should the credentials be exported to?"
    }

    $ParentPath = Split-Path $Path
    If ((Test-Path $ParentPath) -eq $false)
    {
        New-Item -ItemType Directory -Path $ParentPath
    }

    $Credential = Get-Credential($Username)
    $Credential | Export-Clixml -Path $Path
    Return $Credential
}

Function Import-CredentialFile ($Path)
{
    if (! (Test-Path $Path))
    {
        Write-Host "Could not find the credential object at $Path. Please export your credentials first"
        Export-CredentialFile
    }
    Import-Clixml -Path $Path
}

You can call the functions like this:

$Path = "C:\keys\serkar.key"
$UserName = "[email protected]"

Export-CredentialFile -Username $UserName -Path $Path
$Credential = Import-CredentialFile -Path $Path

And afterwards you can connect to SharePoint. If you feel unsure about it, check out this post: Connect to SharePoint Online with PowerShell (sposcripts.com)

Connect-PnPOnline -Url https://devmodernworkplace.sharepoint.com/sites/sales -Credentials $Credential

But be sure to initialize the $Credential afterwards, so the potential security vector is as small as possible when you export credentials with PowerShell.

Additional links

Get-Credential (Microsoft.PowerShell.Security) – PowerShell | Microsoft Docs