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:

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

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

Connect-MsolService -Credential $Credential

How to Create a PSCredential Object

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

$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:

$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Credential.Password)
$ClearTextPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
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:

$Credential.Password | ConvertFrom-SecureString

The output will look similar to this:

PS C:\> $Credential.Password | ConvertFrom-SecureString

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:

$HexPass = Get-Content "c:\Data\Password.txt"
$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)

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

How to Manage Office 365 Without PowerShell

Many admins are frustrated that you need PowerShell, multiple web consoles, and an on-premises Exchange Server in order to manage Office 365.

With Easy365Manager, all daily Office 365 mailbox operations can be done from AD Users & Computers:

Easy365Manager is a small snap-in to AD Users & Computers that extends user properties with two new tabs, so you no longer have to switch between multiple web consoles to perform daily management:

Easy365Manager Office 365 user properties
New user property tab: "Office 365"
Exchange Online Mailbox properties in AD Users & Computers
New user property tab: "Mailbox"

With Easy365Manager, you can perform all daily tasks from AD Users & Computers:

  • Assign Office 365 licenses
  • Manage shared mailbox delegation
  • Configure calendar permissions
  • Configure proxyAddresses (with format and uniqueness check)
  • Replicate Azure AD Connect

And a lot more. See the complete feature list here

Additionally, Easy365Manager lets you remove your on-premises Exchange Server. This will give you 100% protection from future zero-day exploits targeting Exchange Server.

Try the fully functional 30-day trial now. It only takes a few minutes to install, has zero learning curve, and you’re guaranteed to have saved hours of work before the end of the week!