How to pass O365 credentials automatically and securely for scheduled tasks

With everything we can do in any O365 Admin Portal possible to do, even easier and better, in PowerShell, I have tried to create scripts to automate as much of my tasks as possible. When I run these manually its fine, I enter my credentials and approve my MFA popup on Authenticator App. 

But what about scripts I want to run regularly, or automatically based on another event happening? Well, basically we need a few things. The first is to have an O365 Admin account, with only the bare minimum role we need, created and NOT enabled for MFA. This is a risk of course but if it can be restricted and controlled (think Conditional Access here) within your environment then this will be more of a benefit than it is a risk.

Once we create this account, we now need to securely save the credentials somewhere so they can be used in an automated/scheduled task.

Storing credentials securely

Step 1: Store your credentials in a variable - for this session only

On the server you are going to run your scripts from, first ensure you have all of your PowerShell addons installed. Once you have this we are going to test saving our credential locally for this session and log in using the saved credential.

$credential = Get-Credential



Step 2: Test connectivity using the variable passing

Now type the following to log into Microsoft Online Services, using the stored credential.

Connect-MsolService -Credential $credential

This should connect with no prompt for MFA:


This shows us that the account is set up correct and no MFA is assigned to the account. Now we can move on to the next step of saving it to the local server for use outside this session.

Step 3: Save the credentials in a secured format in a text file

Now we use the following command:

$credential.Password | ConvertFrom-SecureString | Out-File C:\Credentials\customera.creds



This command saves the credentials securely into a defined folder and file (the .creds extension is not a mandatory one but helps to define what's happening). The saved file will look similar to the following (clipped).



At this point you should note that the ConvertFrom-SecureString cmdlet encrypts the password using the Windows Data Protection API. Only the user who encrypted the password can decrypt it, also they can only do so on the same computer that it was encrypted on first. The file is useless to anyone else or on any other computer.



If we type the variable on this server we can see that the string is securely stored:


Now if we copy the file and run on a different computer we see the following error:

"Key not valid for use in specified state" 
 Meaning it can't get the password from the hash as it won't match on this server. Good news!

Step 4: Write your script to call the credentials

Now on your same server, you need to store the PowerShell script you are going to use in your connection. In your PowerShell script you need to use the following lines, #Description above each line to explain:

# Define a variable with your O365 Admin account you are going to use

$username = "Martin.Gibney@domain.ie"

# Define a variable with the Get-Content pointing to the location of the securely saved credentials we showed earlier

$pwdTxt = Get-Content "C:\Credentials\customera.creds"

# Now we convert this file to a secure string so it can be used when being passed to the server

$securePwd = $pwdTxt | ConvertTo-SecureString

# Here we join both username and password as the credential we are going to pass as a single variable

$credObject = New-Object System.Management.Automation.PSCredential -ArgumentList $username, $securePwd

# Finally we simply pass the credentials (Including the login name and password) to the connection command

Connect-MicrosoftTeams -Credential $credobject

Step 4: Allow running of batch jobs on your local server

Now on the same server we are going to use for Scheduled Tasks, we need to ensure that the domain/local server username has the correct login permissions to Log on as a batch job

In Local Group Policy Editor we go to the following string:
Local Computer Policy >> Computer Configuration >> Windows Settings >> Security Settings >> Local Policies >> User Rights Assignment

In here, under Log on as a batch job, we edit this and Add User or Group and add our local user here.



Step 5: Configure Scheduled Task

Finally, on the server, we open the Scheduled Task window and Create a New Basic Task

On the General tab, we give the Task a Name and under Security Options, we select Run whether user is logged on or not (As we want our task to run every few hours). Very importantly, we must Configure for the correct version of  Windows Server we are on - this is not automatic!!

Next, we move on to the Triggers tab.
In here we click on New so we can then Schedule the times we want the task to run.


Now, we move to the Actions tab, this is the most important section to define where our script is located.

To run a PowerShell script, under the Settings >> Program/Script we type Powershell then under Add arguments (optional) we type -File c:\location\powershellfile.ps1 (Where this is the location of our .ps1 script file)
Once we press OK then OK to finish, we will be prompted for the local user credentials one more time.

Now once the script is run, it is actually run from C:\Windows\System32 location, this is important to note in case your script outputs a result file and you can't find it!



Comments

Popular posts from this blog

Unassigned Numbers in Microsoft Teams using Audiocodes SBC

Communicator ports used for communication

Teams Device Health Monitoring and Reporting