# Obtain the main service of SSMCM application $compassApplicationId = "2f734312-2ccf-4c27-8658-c4a1bb937ef1" $compassInventoryServicePrincipal = Get-AzADServicePrincipal -ApplicationId $compassApplicationId if (!$compassInventoryServicePrincipal) { New-AzADServicePrincipal -ApplicationId $compassApplicationId $compassInventoryServicePrincipal = Get-AzADServicePrincipal -ApplicationId $compassApplicationId } # Obtain subscription list $subscriptions = Get-AzSubscription # Obtain or create the role "Virtual Machine Operator". $role = Get-AzRoleDefinition "Virtual Machine Operator" $new = $false if (!$role) { $new = $true $role = [Microsoft.Azure.Commands.Resources.Models.Authorization.PSRoleDefinition]::new() $role.Id = $null $role.Name = "Virtual Machine Operator" $role.IsCustom = $true $role.Description = "Can monitor, start, and restart virtual machines and virtual machines scale set." $role.AssignableScopes= @() } # Actions allowed by the role $role.Actions = @() $role.Actions.Add("Microsoft.Authorization/*/read") $role.Actions.Add("Microsoft.Storage/*/read") $role.Actions.Add("Microsoft.Network/*/read") $role.Actions.Add("Microsoft.Compute/*/read") $role.Actions.Add("Microsoft.Compute/virtualMachines/start/action") $role.Actions.Add("Microsoft.Compute/virtualMachines/powerOff/action") $role.Actions.Add("Microsoft.Compute/virtualMachines/restart/action") $role.Actions.Add("Microsoft.Compute/virtualMachines/deallocate/action") $role.Actions.Add("Microsoft.Compute/virtualMachineScaleSets/start/action") $role.Actions.Add("Microsoft.Compute/virtualMachineScaleSets/powerOff/action") $role.Actions.Add("Microsoft.Compute/virtualMachineScaleSets/restart/action") $role.Actions.Add("Microsoft.Compute/virtualMachineScaleSets/deallocate/action") $role.Actions.Add("Microsoft.Compute/virtualMachineScaleSets/virtualMachines/start/action") $role.Actions.Add("Microsoft.Compute/virtualMachineScaleSets/virtualMachines/powerOff/action") $role.Actions.Add("Microsoft.Compute/virtualMachineScaleSets/virtualMachines/restart/action") $role.Actions.Add("Microsoft.Compute/virtualMachineScaleSets/virtualMachines/deallocate/action") $role.Actions.Add("Microsoft.ClassicCompute/virtualMachines/downloadRemoteDesktopConnectionFile/action") $role.Actions.Add("Microsoft.Resources/subscriptions/resourceGroups/read") $role.Actions.Add("Microsoft.Resources/subscriptions/resourceGroups/resources/read") $role.Actions.Add("Microsoft.Insights/alertRules/*") $role.Actions.Add("Microsoft.Insights/diagnosticSettings/*") $role.Actions.Add("Microsoft.OperationalInsights/workspaces/search/action") $role.Actions.Add("Microsoft.Support/*") # Subscriptions to which the role has permissions $role.AssignableScopes.Clear() ForEach ($vsub in $subscriptions) { $SubscriptionId = $vsub.SubscriptionID if ($vsub.State -eq "Enabled") { $role.AssignableScopes.Add("/subscriptions/$($SubscriptionId)") } } # Save/update the rol if ($new) { New-AzRoleDefinition -Role $role } else { Set-AzRoleDefinition -Role $role } # Wait 30 seconds for Azure to internally synchronize the new role for the next call. Write-Output "Wainting 30 seconds for Azure internal sync..." Start-Sleep -Seconds 30 # Assign rol reader and Virtual Machine Operator to each subscription ForEach ($vsub in $subscriptions) { $SubscriptionId = $vsub.SubscriptionID # Add permissions to the client if ($vsub.State -eq "Enabled") { if (!(Get-AzRoleAssignment -RoleDefinitionName "Reader" -ObjectId $compassInventoryServicePrincipal.Id -Scope "/subscriptions/$($SubscriptionId)")) { New-AzRoleAssignment -RoleDefinitionName "Reader" -ObjectId $compassInventoryServicePrincipal.Id -Scope "/subscriptions/$($SubscriptionId)" } if (!(Get-AzRoleAssignment -RoleDefinitionName $role.Name -ObjectId $compassInventoryServicePrincipal.Id -Scope "/subscriptions/$($SubscriptionId)")) { New-AzRoleAssignment -RoleDefinitionName $role.Name -ObjectId $compassInventoryServicePrincipal.Id -Scope "/subscriptions/$($SubscriptionId)" } } }