Automated ORCA-report with Powershell & Azure Bicep

Automated ORCA-report with Powershell & Azure Bicep


What is this?


This post describes how you can automate the Office Recommended Configuration Analyzer (ORCA) report using Powershell & IaC automation with Azure Bicep.

During 2022 I got the chance to move into a new role in a new team that has given me the chance to work more closely with the Azure Platform and specifically given me more time to work with DevOps driven teams and do deep-dives on Infrastructure as Code, CICD pipelines and more.

I have been given the chance to work with many smart co-workers that has taught me a lot and the project detailed in this blogpost is my first "own" project I have done a deep-dive on during my private time.

Why would you want this?


While there are user interfaces for administrators to see secure score reports, configuration analysis and more you may not always want to give out more administrative roles than you need.

To try and keep privileged accounts down to a minimum you can use this system to reduce both the number of admins, and what they can see, these are key items in the Zero Trust approach.

Often roles like Security Administrator or Exchange Administrator may give your admin more insight than you wish. You can think of this as a custom role if you want.

You can save all reports and reference back to an earlier date to see what configuration we had if a problem has been identified to try and find the root-cause or answer the question: What has changed?

Technical challenges


ExchangeOnlineManagement v3.0 gave us the ability to use Connect-ExchangeOnline with the -ManagedIdentity switch, but there are limitations:

  • It only works from Azure VMs which means we cannot use Azure Automation or Azure Functions to run code-snippets with the switch
  • My solution was to deploy a Virtual Machine that will "simulate" the sandbox environment that Azure Automation creates when executing runbooks
  • We use an Azure Automation account to power on and off the VM (deallocate) so its only running when required, which in this case is once a month

Implementation


All the infrastructure required for this solution gets deployed with a Bicep Template along with some manual configuration resulting in a solution that consists of:

  • Azure Automation account with two runbooks    
  • Two scripts to start and stop the VM
  • A keyvault
  • I use Sendgrid API to send the HTML-report from the powershell script to a user, the secure API key is stored in Azure Keyvault as a secret
  • RBAC assignment for the automation account, VM contributor, this is so the AA have permission to start & stop the server
  • A managed identity for the VM that receives "Get" permissions to fetch the sendgrid API key secret from the Azure Keyvault
  • The virtual machine

I simply deploy the template and provide a few parameters and Bicep takes care of everything else. I will have to RDP into the machine at a later point and configure a scheduled task to run at system startup that will authenticate to Exchange Online and run the required commands.

I will need to paste in finished scripts into the two runbooks to start and stop the Virtual Machine.

Hopefully the -ManagedIdentity switch will start working on more platforms so we can migrate from using a VM to AA or Azure Functions.

All the source-code for this project is stored in what is currently a private repository I own in Github. My hope is to get the go ahead to make it public and open-source soon. If that happens a follow-up post with some more detailed instructions will be published that helps you implement this.

References & resources

MS Docs: Send an email from an Automation Runbook

Web Dev Zone: How to send an email with an attachment using Powershell and SendGrid API

onprem.wtf: How to connect to Exchange Online powershell with a Managed Identity

MS Docs: Azure Automation Sandbox limitations

MS Docs: Exchange Online Management module

GitHub: ORCA GitHub Repo