Tutorial: Create Automation PowerShell runbook using managed identity
This tutorial walks you through creating a PowerShell runbook in Azure Automation that uses a managed identity, rather than the Run As account to interact with resources. PowerShell runbooks are based on Windows PowerShell. A managed identity from Microsoft Entra ID allows your runbook to easily access other Microsoft Entra protected resources.
In this tutorial, you learn how to:
- Assign permissions to managed identities
- Create a PowerShell runbook
If you don't have an Azure subscription, create a free account before you begin.
Prerequisites
- An Azure Automation account with at least one user-assigned managed identity. For more information, see Using a user-assigned managed identity for an Azure Automation account.
- Az modules:
Az.Accounts
,Az.Automation
,Az.ManagedServiceIdentity
, andAz.Compute
imported into the Automation account. For more information, see Import Az modules. - The Azure Az PowerShell module installed on your machine. To install or upgrade, see How to install the Azure Az PowerShell module.
Az.ManagedServiceIdentity
is a preview module and not installed as part of the Az module. To install it, runInstall-Module -Name Az.ManagedServiceIdentity
. - An Azure virtual machine. Since you stop and start this machine, it shouldn't be a production VM.
- A general familiarity with Automation runbooks.
Assign permissions to managed identities
Assign permissions to the managed identities to allow them to stop and start a virtual machine.
Sign in to Azure interactively using the Connect-AzAccount cmdlet and follow the instructions.
# Sign in to your Azure subscription $sub = Get-AzSubscription -ErrorAction SilentlyContinue if(-not ($sub)) { Connect-AzAccount } # If you have multiple subscriptions, set the one to use # Select-AzSubscription -SubscriptionId <SUBSCRIPTIONID>
Provide an appropriate value for the variables below and then execute the script.
$resourceGroup = "resourceGroupName" # These values are used in this tutorial $automationAccount = "xAutomationAccount" $userAssignedManagedIdentity = "xUAMI"
Use PowerShell cmdlet New-AzRoleAssignment to assign a role to the system-assigned managed identity.
$role1 = "DevTest Labs User" $SAMI = (Get-AzAutomationAccount -ResourceGroupName $resourceGroup -Name $automationAccount).Identity.PrincipalId New-AzRoleAssignment ` -ObjectId $SAMI ` -ResourceGroupName $resourceGroup ` -RoleDefinitionName $role1
The same role assignment is needed for the user-assigned managed identity
$UAMI = (Get-AzUserAssignedIdentity -ResourceGroupName $resourceGroup -Name $userAssignedManagedIdentity).PrincipalId New-AzRoleAssignment ` -ObjectId $UAMI ` -ResourceGroupName $resourceGroup ` -RoleDefinitionName $role1
Additional permissions for the system-assigned managed identity are needed to execute cmdlets
Get-AzUserAssignedIdentity
andGet-AzAutomationAccount
as used in this tutorial.$role2 = "Reader" New-AzRoleAssignment ` -ObjectId $SAMI ` -ResourceGroupName $resourceGroup ` -RoleDefinitionName $role2
Create PowerShell runbook
Create a runbook that will allow execution by either managed identity. The runbook will start a stopped VM, or stop a running VM.
Sign in to the Azure portal, and navigate to your Automation account.
Under Process Automation, select Runbooks.
Select Create a runbook.
- Name the runbook
miTesting
. - From the Runbook type drop-down, select PowerShell.
- From the Runtime version drop-down, select either 7.1 (preview) or 5.1.
- Enter an applicable Description.
- Name the runbook
Click Create to create the runbook.
In the runbook editor, paste the following code:
Param( [string]$ResourceGroup, [string]$VMName, [string]$Method, [string]$UAMI ) $automationAccount = "xAutomationAccount" # Ensures you do not inherit an AzContext in your runbook $null = Disable-AzContextAutosave -Scope Process # Connect using a Managed Service Identity try { $AzureConnection = (Connect-AzAccount -Identity).context } catch { Write-Output "There is no system-assigned user identity. Aborting." exit } # set and store context $AzureContext = Set-AzContext -SubscriptionName $AzureConnection.Subscription -DefaultProfile $AzureConnection if ($Method -eq "SA") { Write-Output "Using system-assigned managed identity" } elseif ($Method -eq "UA") { Write-Output "Using user-assigned managed identity" # Connects using the Managed Service Identity of the named user-assigned managed identity $identity = Get-AzUserAssignedIdentity -ResourceGroupName $ResourceGroup -Name $UAMI -DefaultProfile $AzureContext # validates assignment only, not perms $AzAutomationAccount = Get-AzAutomationAccount -ResourceGroupName $ResourceGroup -Name $automationAccount -DefaultProfile $AzureContext if ($AzAutomationAccount.Identity.UserAssignedIdentities.Values.PrincipalId.Contains($identity.PrincipalId)) { $AzureConnection = (Connect-AzAccount -Identity -AccountId $identity.ClientId).context # set and store context $AzureContext = Set-AzContext -SubscriptionName $AzureConnection.Subscription -DefaultProfile $AzureConnection } else { Write-Output "Invalid or unassigned user-assigned managed identity" exit } } else { Write-Output "Invalid method. Choose UA or SA." exit } # Get current state of VM $status = (Get-AzVM -ResourceGroupName $ResourceGroup -Name $VMName -Status -DefaultProfile $AzureContext).Statuses[1].Code Write-Output "`r`n Beginning VM status: $status `r`n" # Start or stop VM based on current state if ($status -eq "Powerstate/deallocated") { Start-AzVM -Name $VMName -ResourceGroupName $ResourceGroup -DefaultProfile $AzureContext } elseif ($status -eq "Powerstate/running") { Stop-AzVM -Name $VMName -ResourceGroupName $ResourceGroup -DefaultProfile $AzureContext -Force } # Get new state of VM $status = (Get-AzVM -ResourceGroupName $ResourceGroup -Name $VMName -Status -DefaultProfile $AzureContext).Statuses[1].Code Write-Output "`r`n Ending VM status: $status `r`n `r`n" Write-Output "Account ID of current context: " $AzureContext.Account.Id
In the editor, on line 8, revise the value for the
$automationAccount
variable as needed.Select Save and then Test pane.
Populate the parameters
RESOURCEGROUP
andVMNAME
with the appropriate values. EnterSA
for theMETHOD
parameter andxUAMI
for theUAMI
parameter. The runbook will attempt to change the power state of your VM using the system-assigned managed identity.Select Start. Once the runbook completes, the output should look similar to the following:
Beginning VM status: PowerState/deallocated OperationId : 5b707401-f415-4268-9b43-be1f73ddc54b Status : Succeeded StartTime : 8/3/2021 10:52:09 PM EndTime : 8/3/2021 10:52:50 PM Error : Name : Ending VM status: PowerState/running Account ID of current context: MSI@50342
Change the value for the
METHOD
parameter toUA
.Select Start. The runbook will attempt to change the power state of your VM using the named user-assigned managed identity. Once the runbook completes, the output should look similar to the following:
Using user-assigned managed identity Beginning VM status: PowerState/running OperationId : 679fcadf-d0b9-406a-9282-66bc211a9fbf Status : Succeeded StartTime : 8/3/2021 11:06:03 PM EndTime : 8/3/2021 11:06:49 PM Error : Name : Ending VM status: PowerState/deallocated Account ID of current context: 9034f5d3-c46d-44d4-afd6-c78aeab837ea
Clean up Resources
To remove any resources no longer needed, run the following runbook.
#Remove runbook
Remove-AzAutomationRunbook `
-ResourceGroupName $resourceGroup `
-AutomationAccountName $automationAccount `
-Name "miTesting" `
-Force
# Remove role assignments
Remove-AzRoleAssignment `
-ObjectId $UAMI `
-ResourceGroupName $resourceGroup `
-RoleDefinitionName $role1
Remove-AzRoleAssignment `
-ObjectId $SAMI `
-ResourceGroupName $resourceGroup `
-RoleDefinitionName $role2
Remove-AzRoleAssignment `
-ObjectId $SAMI `
-ResourceGroupName $resourceGroup `
-RoleDefinitionName $role1
Next steps
In this tutorial, you created a PowerShell runbook in Azure Automation that used a managed identity, rather than the Run As account to interact with resources. For a look at PowerShell Workflow runbooks, see:
Feedback
https://aka.ms/ContentUserFeedback.
Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see:Submit and view feedback for