• Post category:Azure
  • Post comments:0 Comments
  • Reading time:4 mins read

Jeff Brown

Cloud and DevOps Engineer specializing in Microsoft 365, Azure, and PowerShell. Twitter | LinkedIn

Azure currently comes with more than 140 built-in roles for assigning role-based access control (RBAC) to your Azure resources. This allows assigning users, groups, service principals, and managed identities granular access on managing your resources, such as virtual machines, log analytics, storage accounts, or networks. If one of the built-in roles doesn’t fit your needs, you can create your own. In this post I will cover how to create a custom Azure role using PowerShell.

First, take a look at the available roles using the Get-AzRoleDefinition cmdlet. In this example, I’m going to focus on the “Virtual Machine Contributor” role.

Here you can view the description, actions, not actions (deny), data actions, and not data actions for the role. The Actions property has quite a few resource providers assigned to it that I can’t currently see, so let’s convert it to JSON using the ConvertTo-Json command.

Outlined in the screenshot are resource providers inside of Azure. This aligns with different resources available in Azure, such as “Microsoft.Network” or “Microsoft.Compute”. These providers then have resource types like networkInterfaces, publicIPAddresses, or virtualMachines. Some of these have wildcards after them, like virtualMachines, meaning this role can perform any action against Microsoft.Compute/virtualMachine resources.

Looking at Microsoft.Network, we can see where it is more limited. For example, this role has permissions to work with networkInterfaces but can only view and add network security groups to the virtual machine but not create network security groups. This is how granularity is applied in these roles.

Let’s export this role definition into a JSON file so we can edit our custom role. To do this I use the following command:

Get-AzRoleDefinition -Name “Virtual Machine Contributor” | ConvertTo-Json | Out-File <filename>.json

Opening the file, it should look exactly like what we see in the PowerShell window. Before modifying any of the Action providers, we need to sanitize and change some properties for our custom role. First, the first three key:value pairs need to be updated. This is what our role looks like before any changes:

I’m going to change Name property as I can’t import this role using a name that already exists. I need to set the Id to null as a new Id will be generated automatically when it is created. Finally, we’ll change the IsCustom to true as this isn’t a built-in role, this is a custom role I’m creating. This is the what the updated file looks like after my changes:

Next there is the Actions section, which I covered above. This is the list of resource providers and actions that the role has permissions to perform. For my custom role, I’m going to give more permissions to allow creating and modifying virtual networks. Here is the before and after of the Microsoft.Network provider:



I removed individual permissions and just used a wildcard to give all permission on the Microsoft.Network resource provider.

Finally, in the bottom of the role definition file, I need to set the AssignableScopes property. For this, I’m going to assign it to the top level of my subscription. If you’re not sure of your subscription GUID, you can use the Get-AzSubscription command to find it.

Finally, going back to PowerShell, I can use the New-AzRoleDefinition command and specify the role definition using the -InputFile parameter.

If I jump back to the Azure portal, I can now go to something like a resource group and assign this role to give an admin permissions to manage both virtual machines and networks.

Finally, I’m going to share a mistake I made and hopefully it helps you in the future. When I first tried to create the custom role in PowerShell, I ran into this error:

The client <> with object id <> does not have authorization to perform action ‘Microsoft.Authorization/roleDefinitions/write’ over scope <> or the scope is invalid.

The solution here was I forgot to change the AssignableScopes. Once I set the assignable scope to my subscription, I was able to import and create the new role.

Questions or comments? If so, drop me a note below or find me on Twitter or LinkedIn to discuss further.


Microsoft Docs: Create custom roles for Azure resources using Azure PowerShell


Microsoft Docs: Resource Providers for Azure services


Microsoft Docs: Azure resource providers and types


Leave a Reply