In my previous articles I described how to use PowerShell to manage various Office 365 services. But we sometimes also need to plan our scripts to run on a schedule. In this scenario, a problem is encountered – how can we safely store passwords for administrative accounts and run scripts with the help of Task Scheduler.
When it comes to safely storing passowrds for PowerShell scripts, we have quite a few methods at our disposal. In this article I will describe which methods are bad and which are suitable for a production environment.
Method 1 – Credentials in the Script
The first method I will show you is one that should be avoided. The only reason I am including it in the article is because I want to show you the bad practice of writing scripts that include a username and password.
#Not cool $user="firstname.lastname@example.org" $pass=ConvertTo-SecureString -AsPlainText -Force 'Pa$$w0rd' $credentials=New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $userName, $Password Connect-MsolService -Credential $credentials
In this case we can see that a new PS Credential object was created from data read directly from the script. This can have dire consequences – anyone with access to the script can read the credentials and potentialy abuse them.
Method 2 – Credentials in an Encrypted File
The second method safely stores the password in an encrypted file. This way we can also ensure that only the account that created the encrypted file can decrypt it.
# Create-EncryptedCredentialFile $credentials = Get-Credential $filename = "C:\temp\CliXml.xml" $credentials | Export-CliXml -Path $filename $xml=Import-Clixml -Path $filename $xml.UserName $xml.Password $credentials=New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $xml.UserName, $xml.Password Connect-MsolService -Credential $credentials
To create an encrypted file, the most important line of code is:
$credentials | Export-CliXml -Path $filename
This line of code writes the “credentials” object into the selected file:
In the screenshot we can see that the username is written in “clear text”, while the password is encrypted. Password encryption is done with the help of the Windows Data Protection API (DAPI) methods. The advantage, or in some cases the disadvantage of these methods, is that only the user that encrypted the password can decrypt it.
Method 3 – Using Windows Credential Manager
The third method, which is actually very similar to the second one, is the use of Windows Credential Manager, which also uses DAPI to encrypt passwords. In this case however, we don’t need to store passwords in a file. To use Windows Credential Manager in our PowerShell environment, we must first install the add-on for PowerShell. You can get it from the PowerShell Gallery webpage:
PowerShell Gallery | CredentialManager 2.0
The installation can also be performed from the PowerShell environment with the following command:
Install-Module -name credentialmanager
The next step is to store credentials in Credential Manager. This can be performed in the following way:
$credentials=Get-Credential New-StoredCredential -Credentials $credentials -Target PikaOktober
To use credentials in a script, we must of course get the credentials from Credential Manager. We can do this easily with the following command:
$managedCred = Get-StoredCredential -Target PikaOktober Connect-msolService -Credential $managedCred
We can of course use Credential Manager to check if our entry exists.
In the screenshot we can see that the script has indeed created a new entry and we can then use these credentials in our scripts without needing to enter the username and password manually. Besides that, this is a very good way to safely use credentials in scripts that run at scheduled times as these credentials are secured with Windows DAPI.
This article concludes my series of Office 365 PowerShell articles. If you have any requests or suggestions, please do not hesitate to contact me.
Office Servers and Services MVP, MCT