If you’ve spent time using PowerShell to manage users, computers or Office 365 resources you’ve probably come across the term PSCredential.

But what is PSCredential exactly and how do you use it?

Username and Password in One Packet

The PSCredential is a placeholder for a set of credentials – it basically contains a username and a password.

The PSCredential object offers a safe and convenient way to handle a username and password.

By wrapping your credentials as an object and storing it in a PowerShell variable, e.g. $Credential, you can use it programmatically in any way you see fit.

In most cases you’ll probably use it as an argument to a cmdlet. By supplying the PSCredential object as an argument you can run the cmdlet as “someone else”.

How to Use the PSCredential

A lot of PowerShell cmdlets come with a “-Credential” parameter which allows you to change the security context of your command. There are several use cases for this:

  • Perhaps you follow Microsoft best-practices and log in to your systems with a non-privileged account but you need to run scripts using your admin credentials?
  • Perhaps you’re connecting to an external resource like Office 365 and need to validate in the context of the external resource?

Retrieving all Sales department users from your AD using your admin account might look like this:

  1. Get-ADUser -LdapFilter "{department=sales}" -Credential $Credential

Connecting to Office 365 with the MSOnline module using your Office 365 credentials might look like this:

  1. Connect-MsolService -Credential $Credential

How to Create a PSCredential Object

The simplest way to create a PSCredential object is by using the following command:

  1. $Credential = Get-Credential

This command will generate the following prompt where you can enter your credentials:

PSCredential prompt

As seen in below output you now have a PSCredential object stored in the $Credential variable. As expected, the variable has two attributes, UserName and Password:

PS C:\> $Credential | fl UserName : Password : System.Security.SecureString

The UserName attribute is in clear text but the the Password is stored as a SecureString. A SecureString has better protection when stored in memory relative to a simple string.

You can convert a SecureString back to clear text using the following lines of code:

  1. $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Credential.Password)
  2. $ClearTextPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
  3. Write-Host $ClearTextPassword

How to Save and Reuse PSCredential Across Sessions

If you’re doing a lot of scripting you’ll probably find it tiresome to re-enter your credentials over and over again.

Fortunately, by using the built-in Data Protection API (DPAPI) in Windows you can safely store credentials on your system and reuse it at a later time.

The DPAPI can encrypt and decrypt information (such as a password) by using key material from both the user and system account. This means, effectively, the encrypted information is only accessible if the same user logs in to the same machine:

  • If another user logs in to the same machine the encrypted password file can’t be decrypted
  • If the same user copies the encrypted password file to another machine it can’t be decrypted

As an example, let’s have a look at the PSCredential variable, $Credential, that we created previously. The following command will generate a hex-encoded text string representing the encrypted Password attribute:

  1. $Credential.Password | ConvertFrom-SecureString

The output will look similar to this:

PS C:\> $Credential.Password | ConvertFrom-SecureString 01000000d08c9ddf0115d1118c7a00c04fc297eb01000000b155b49e1a35784e96809015c36241800000000002 0000000000106600000001000020000000baa7c2525c4dd6fb6e93251dd839336760330ddf917edfe610e134b6 b5981544000000000e8000000002000020000000971810461216541e5477d648e537c92eab5982fcd89a9b2a6e edcc5183fd94122000000067029d7226335b98da23727372ce1fa950d9585effc77232e883883cf5dd47394000 00001d93c3b57e62babdc212536d44a39bffd13934b6c90cb3eab2d78a63380e252a8ebb8cc37339b0e4767072 454a032236cdcc60807d742003c08b2d83cc6a0b11

If you save this string to a text file you can reload the password at a later time when you need the credentials. Simply regenerate your PSCredential object using code similar to this:

  1. $HexPass = Get-Content "c:\Data\Password.txt"
  2. $Credential = New-Object -TypeName PSCredential -ArgumentList "", ($HexPass | ConvertTo-SecureString)

As demonstrated in below output the credentials are correct:

PS C:\> $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Credential.Password) PS C:\> [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) somepassword

If you log in to your system with another account and try to generate the PSCredential from the encrypted password saved to disk you’ll get an error that the data is invalid:

ConvertTo-SecureString : The data is invalid. At line:1 char:104 + ... List "", ($HexPass | ConvertTo-SecureString) + ~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [ConvertTo-SecureString], CryptographicException + FullyQualifiedErrorId : ImportSecureString_InvalidArgument_CryptographicError,Microsoft.PowerShell.Commands.ConvertToSecureStringCommand


Hopefully you’ll now feel confident putting the PSCredential object into good use.

PowerShell can easily and safely store credentials on disk allowing you to automate scripts without the need to manually enter credentials.

If you want your admin life to become even more convenient, have a look at Easy365Manager. Our professional Office 365 management tool allows you to manage Office 365 users, Office 365 licenses and Exchange Online mailboxes from inside the AD Users & Computers administration tool:

Easy365Manager user properties
Easy365Manager user properties

This will save you a ton of time by skipping the need to log in to the various Office 365 web portals on most daily tasks.

You can also decommission your on-prem Exchange server after installing Easy365Manager.

Easy365Manager is available as a 30 day fully functional trial with full support.

Did you like this post? Maybe your friends will too!