Mastering the Monthly Update for Microsoft Graph Modules
Updated 15 July 2023
I like the Microsoft Graph PowerShell SDK very much and have written many articles about its use, including how to use the SDK cmdlets with Azure Automation. Microsoft generates a new version of the SDK every month using a process called AutoRest. The result is a brand-new Microsoft.Graph module (the SDK) accompanied by the 40 subsidiary modules. The same AutoRest process also generates documentation for the SDK cmdlets, which accounts for some of the oddities you might encounter in the documentation. Overall, generating updated SDK modules monthly is good because it means that changes Microsoft makes across the thousands of Graph APIs become available in SDK cmdlets.
Downloading and installing the SDK module from the PowerShell gallery using a PowerShell window also updates the subsidiary modules. This means that it’s not an onerous task to track and keep the SDK modules in good shape on a workstation.
Update: The script described here handles V2 of the Microsoft Graph PowerShell SDK, including modules installed with beta cmdlets.
Changes and Updates
The situation is different for Azure Automation accounts. As Microsoft explains in its documentation, common AZ modules are installed in each automation account. Developers then add whatever “custom” modules they need for runbooks to process data. When Azure Automation executes a runbook, it downloads the default and custom modules into a sandbox where the runbooks run. If a runbook (PowerShell script) calls a cmdlet that’s not in the set of downloaded modules, the runbook fails.
Because the AZ team updates its modules regularly, Microsoft warns that changes can occur with the cmdlets in these modules. Old cmdlets disappear, new ones appear, and parameters change. It happens. To make it easy for developers to use the latest AZ modules, Microsoft includes an Update Az Modules button in the modules page of an automation account (Figure 1). There’s also a runbook available for this purpose.
So much for the Az modules. Custom modules, like Exchange Online management and the Microsoft Graph PowerShell SDK need separate arrangements to keep them updated. To update these modules, you add them to the runbook resources again. Azure Automation detects that you’re adding a module that already exists and updates it to the latest version. Going through the update process isn’t difficult when modules don’t change frequently. For instance, the generally available Exchange Online management module moved to version 3.0 on 19 September, 2022 and will likely stay at that point for a while. Updating the Exchange Online module for two automation accounts took just a few minutes and that’s an acceptable overhead.
Updating the Microsoft Graph PowerShell SDK Modules
The monthly update cycle of the Microsoft Graph PowerShell SDK creates a different challenge. The problem is that you’re not dealing with a single module. Instead, each Azure Automation account is likely to use a set of different Graph modules, each of which must be updated. Like any repetitive operation this becomes boring after a couple of iterations. The problem is compounded if Microsoft finds that a problem exists in an SDK module that causes them to issue a minor update. This happened three times in October 2022 with the issuing of versions 1.12.2, 1.12.3, and 1.13.0. On the upside, having multiple new versions appear over a short period gave me an excellent target to test against.
Typically, my automation accounts have between five and eight Graph modules. For example. Figure 1 shows that five Graph modules are present in one automation account. The modules include common areas of functionality such as Microsoft.Graph.Teams (Teams cmdlets, like Get-MgTeamChannel) and Microsoft.Graph.Users (cmdlets for Azure AD accounts, like Get-MgUser). If in doubt about which module is needed to access a cmdlet, you’ll find the module name listed on the documentation page for the cmdlet (here’s an example for Get-MgUser).
All automation accounts that use the Graph SDK must include the Microsoft.Graph.Authentication module. It contains the Connect-MgGraph cmdlet that’s used to sign into the Graph. Other Graph modules have a dependency on the authentication module. This dependency means that when you move to a new version, it’s important to update the Microsoft.Graph.Authentication first before attempting to update the others. If you don’t, it’s likely that the module update will fail.
The Microsoft 365 Kill Chain and Attack Path Management
An effective cybersecurity strategy requires a clear and comprehensive understanding of how attacks unfold. Read this whitepaper to get the expert insight you need to defend your organization!
Use PowerShell to Update PowerShell
To avoid the tedium of multiple module updates, I decided to write a PowerShell script to update the Microsoft Graph modules used by the Azure Automation accounts in my tenant. The script makes extensive use of cmdlets from the Azure Az module. The processing sets are as follows:
- Use the Connect-AzAccount cmdlet to connect to Azure Automation with an administrator account that has the right to manage the Azure subscription used by the accounts.
- Define the current version to check modules against (the Microsoft Graph PowerShell SDK is currently at 1.13.0).
- Find the set of Azure Automation accounts with the Get-AzAutomationAccount cmdlet.
- For each account, use the Get-AzAutomationModule cmdlet to find the set of Microsoft Graph modules used by the account.
- Check the version number of the modules to identify if any modules require an update.
- Use the Remove-AzAutomationModule cmdlet to uninstall the modules to be updated from the automation account.
- If the Microsoft.Graph.Authentication module is in the set to be updated, update it with the New-AzAutomationModule cmdlet first so that the dependency is satisfied for other modules. Running New-AzAutomationModule imports the latest available version from the PowerShell Gallery into the automation account.
- Process the other modules with New-AzAutomationModule.
# Only process remaining modules if there are any to update If ($ModulesToUpdate.Count -gt 0 -and $UpgradeNeeded -eq $True) { Write-Host "Adding new version of modules..." ForEach ($Module in $ModulesToUpdate) { [string]$ModuleName = $Module.Name $Uri = "https://www.powershellgallery.com/api/v2/package/$ModuleName/$DesiredVersion" Write-Host ("Updating module {0} from {1}" -f $ModuleName, $Uri) New-AzAutomationModule -AutomationAccountName $AzName -ResourceGroup $AzResourceGroup -Name $ModuleName -ContentLinkUri $Uri } #End ForEach
- Because New-AzAutomationModule only starts the provisioning process, pause until Azure Automation updates the set of modules.
- Declare success!
Figure 2 shows the desired outcome. All the Graph modules in the selected automation account are at the right version. You can download the full script from GitHub.
More to Do
The script doesn’t process other modules like Exchange Online, SharePoint PnP, or Microsoft Teams that might be used with Azure Automation runbooks. It would be easy to extend the code to deal with whatever modules you like. I’ll leave that as a task for the reader. And of course, make sure that you update modules on your workstation. It would be a pity to run outdated cmdlets locally when everything is updated in the cloud.
Update: The latest version of the script updates the Exchange Online Management module for Azure Automation accounts.
Wonderful 🙂 The amount of times I go to start updating a runbook and think “great, this won’t take me long, just a few lines of code to change” and then find myself 30 minutes later just about finishing the laborious manual updating of all modules before I can start testing the updated code.
This’ll save me a ton of time, thanks!!