Home » Blog » Saving Credentials for Office 365 PowerShell Scripts and Scheduled Tasks

Saving Credentials for Office 365 PowerShell Scripts and Scheduled Tasks

PowerShell is an efficient way to perform management tasks for Office 365, and also allows a great deal of automation through the use of PowerShell scripts to perform routine and repetitive tasks.

One of the challenges when using PowerShell for automation is handling authentication for the connection to various Office 365 services. Running a script as a scheduled task means that it needs to be able to use a set of stored credentials to authenticate to Office 365. Storing passwords in scripts is obviously not a good idea, because the passwords could easily be exposed if the script is obtained by another person who uses the same computer, or by accidentally sharing it online (such as on GitHub) with the creds still included.

Another challenge is constantly need to access the passwords to login. I keep my Office 365 admin credentials in a password database, and hopefully you use one as well (LastPass, 1Password, KeePass, Dashlane, etc). This makes it easy to have multiple credentials (such as admin accounts for different tenants, or for different tiers of administrative privilege) that each have unique, complex passwords. Thanks to web browser plugins for the likes of LastPass and 1Password it’s easy to login to Office 365 web-based portals, but copying and pasting passwords into PowerShell authentication prompts gets quite tedious.

I solve both of those problems by storing credentials on my admin workstation. This requires no special tools; it can achieved by using built-in PowerShell functionality. If the idea of storing credentials on your computer sounds like a security risk, please read on.

First, let’s look at how you might typically connect to Office 365 using PowerShell. The Connect-MsolService cmdlet will connect you to an Office 365 for management tasks such as assigning a license to a user.

The cmdlet will prompt you for credentials to use for authenticating the session.


To avoid that credential prompt for repeat connections, you can use Get-Credential to capture your username and password as a credential object in PowerShell first, and use that for subsequent commands. For example:

That solves part of the issue (repeatedly entering credentials), but doesn’t solve the issue of managing multiple accounts (should you create several credential objects every time you open a PowerShell console?) or running scheduled tasks (since you won’t be there to answer the credential prompt for the script).

But what we can do is store the password from the credential to a file on our computer. The password value is stored in memory as a secure string, and can be encrypted and stored in a text file, for example:

The text file contains the encrypted value, which will look something like this.


Now, at this point you may be concerned that anyone who has access to that file could decrypt the password. Fortunately, that’s not the case. The ConvertFrom-SecureString cmdlet encrypts the password using the Windows Data Protection API. In short, this means that only the user who encrypted the password can decrypt it again, and they can only do so on the same computer that it was encrypted on. If the text file is accessed by another person, or by the same user on a different machine, they’ll be unable to decrypt it.

Of course, you should still protect the files from being accessed by others, in much the same way you’d protect your SSH keys or your password database. For example, store them in a location on the workstation that is not included in cloud storage or backups, and is on a Bitlocker encrypted disk.

The downside of this approach is that you won’t be able to simply copy your stored credentials to another computer. Instead, you’ll need to recreate them on the new computer, which is not a huge hassle since you only need to do it once. There is another approach that avoids this problem, but it has other caveats. I’ll go into that in a separate article some other time.

So now that you can see how passwords can be securely stored and retrieved, how can this technique be used to manage stored credentials for day to day use, as well as for scheduled tasks? I’ve written some PowerShell functions that make it easy.

Preparation Tasks

The two functions that I’ve written use a variable named $KeyPath, and I recommend you add that variable to your PowerShell profile. If you don’t, the functions will prompt you for a path to save or retrieve credentials from, and that’s just going to get annoying.

Download the script containing the two functions, and run it to load the functions in your PowerShell console. I recommend adding them both to your PowerShell profile as well so that you can re-use them in any PowerShell session.

Storing a New Credential

The first function will save a new stored credential. Simply run New-StoredCredential and enter the username and password when prompted.


The credential will be saves as a file named username.cred in the path that you configured for $KeyPath.

Using a Stored Credential

You can list the stored credentials in your $KeyPath folder by running Get-StoredCredential with the -List parameter.

Get-StoredCredential can also be used to retrieve the stored credential and save it as a variable to then use with a cmdlet that requires authentication, for example:

You can also use Get-StoredCredential in a one-liner like this.

The difference between the examples above and the use of Get-MsolService earlier in this post, is that using the stored credential avoids the need to respond to an authentication prompt. So your passwords can be unique and complex without you needing to remember them or copy/paste them from a password manager.

And it’s not just for connecting to Office 365 services. You can use the stored credentials for pretty much any PowerShell cmdlet that uses credentials.

If you try to use a credential that doesn’t exist, you’ll simply get an error.

Using a Stored Credential for a Scheduled Task

The Get-StoredCredential function can also be easily integrated into scripts that you are running as scheduled tasks. The most important thing to remember is that the password can only be decrypted by the user account that encrypted it in the first place.

If your scheduled tasks run using a service account, you’ll need to log on as that service account to run New-StoredCredential, or use Runas to launch a PowerShell console as the service account. The stored credential file will also need to be located in a folder that the service account can access, and that location needs to be defined as $KeyPath in your script as well.

Download the New-StoredCredential and Get-StoredCredential Functions

The script to load the functions is available on GitHub. Comments and feedback are welcome in the comments below, or you can raise an issue on GitHub if you find a bug or have a suggested improvement to the script.

Paul is a Microsoft MVP for Office Servers and Services. He works as a consultant, writer, and trainer specializing in Office 365 and Exchange Server. Paul is a co-author of Office 365 for IT Pros and several other books, and is also a Pluralsight author.
Category: Blog


  1. Rob de Jong says:

    Hi Paul,

    I noticed you are using the older MSOnline PowerShell module in your examples. It may be useful to start using the newer Azure Active Directory PowerShell V2 module instead, as we will begin deprecating the MSOnline module when we have migrated the functionality of the MSOnline module to the newer module – currently planned for the Spring of 2017.


    Rob de Jong

    • My function works with any cmdlet that has a -Credential switch, so it’s just an example.

      I’ve been playing with the new AzAD PS V2 module. Spring is a long time away here in Australia. Or perhaps you mean Spring in the northern hemisphere. I can never tell with these season-based release timelines.

  2. Markus says:

    Hi Paul,
    great preparation for the follow up article to receive O365 Notifications via mail. However i have issues with the implementation of the required functions. The functions are not available after executing functions-psstoredcredentials.ps1.executed from either “normal” powershell, Azure Active Directory Shell, also AzADv2 Shell – and runas Administrator.
    Do you have a hint / to what this might be related?
    Any idea is appreciated since i want to get the O365 Message center via Mail.T

    Thank you & best regards

  3. Art Alexion says:

    Thanks for this very valuable script. I have a problem using it with full SAM account names. For example, I run some scripts under a service account using

    $AdminUser = ‘Domain\PrivilegedUser’
    $pwd1 = ‘PrivilegedUser password in plain text’
    $pwd = ConvertTo-SecureString -string $pwd1 -AsPlainText -Force
    $AdminCredential = New-Object System.Management.Automation.PSCredential $AdminUser, $pwd
    Start-Process -FilePath powershell_ise.exe -Credential $AdminCredential

    For some reason,
    $AdminUser = ‘PrivilegedUser’
    $AdminUser = ‘PrivilegedUser@domain’

    Don’t work.

    I can’t create credentials for ‘Domain\PrivilegedUser’ because the backslash gets inserted into the path for the stored credential.

    and the following is not working.

    Start-Process -FilePath posershell_ise.exe -Credential (Get-StoredCredential -UserName PrivilegedUser)


    Start-Process -FilePath posershell_ise.exe -Credential (Get-StoredCredential -UserName PrivilegedUser@domain)

    Is there a workaround? I was thinking something like

    Start-Process -FilePath posershell_ise.exe -Credential “Domain\ + (Get-StoredCredential -UserName PrivilegedUser)”

  4. Ahmad yamout says:

    Hello Paul thank you for your valuable work . I am still beginner in using Windows PowerShell with office 365 . The task that I have given is to share my file of windows powershell fully automated to be used with another person and the credentials should be secure “without writing the password by the guy he want only to run my code and get the requirement” .

    • If you want the credentials to be securely stored then you can use my technique demonstrated above for storing the credentials. Any scripts or commands you want to run must then be written to support the use of the stored credentials.

Leave a Reply

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