Experimenting with PowerShell and role based access control in Azure

Played around with role-based access control this weekend while learning more about Azure and the cloud. Thought I make a short post about the experimentation and some of the learnings a long the way. Came a across a few best practices, learnt more about RBAC, PowerShell, role assignment, along with a few other things.

Best Practices for RBAC

Here are some best practices I found during my experimentation and readings while testing role assignment to resource, subscription and resource groups.

  1. Segregate duties within your team and grant only the amount of access to users that they need to perform their jobs. Instead of giving everybody unrestricted permissions in your Azure subscription or resources, allow only specific actions at a particular scope. Then if they need more they can be given the at least needed permission needed to perform the tasks.
  2. When planning your access control strategy, grant users the lowest privilege level that they need to do their work.
  3. Use Resource Locks to ensure critical resources aren’t modified or deleted. For a user to modify or delete a resource, the Resource Lock must be deleted by an user with enough privilege’s, then make modifications or delete the resource.

Next up, some of my experimentation and testing with RBAC and PowerShell.

Adding users and RBAC access with PowerShell

In conjunction with RBAC, before we can assign permissions we need a user to test upon, and therefore its a great way to learn how to create a user in Azure AD with Azure PowerShell.

Adding users in Azure Active Directory

To add users in Azure Active Directory with PowerShell you can use the following command New-AzADUser. This cmdlet takes a couple of required parameters -DisplayName, -UserPrincipleName, -Password and -MailNickName as you can see below. I created variables for each of the parameter to make the script more reusable, by having one place to edit the values of the variables, instead of editing each cmdlet separately. For the required parameter -Password I used Read-Host as value, which prompts you to create a first time password when the cmdlet is executed. Since I’m using the parameter -ForceChangePasswordNextLogin the user must change password at first logon. I also added the -Verbose parameter, to see what happens in the background when the cmdlet is running.

$DisplayName = "Ola Nordmann"
$UserPrincipleName = "ola@fredrikengseth.com"
$MailNickname = "OlaN"

New-AzADUser -DisplayName $DisplayName `
    -UserPrincipalName $UserPrincipleName `
    -Password(Read-Host -AsSecureString "Type in first timepassword") `
    -MailNickname $MailNickname `
    -ForceChangePasswordNextLogin `
    -Verbose

Sidenote:

If you try to add a test user to Azure AD with PowerShell and you get the message Property UserPrincipleName is invalid. I couldn’t quite figure out why it didn’t work, the reason was that I tried to create a test user with a gmail and hotmail account, which is not a valid domain for my tenant, doh.. Tried a lot of things to make it work from PowerShell, but it ended up with me going to the Azure Portal just to see the step by step process, where I got the error message gmail.com is not a verified domain displayed when I prompted the UserPrincipleName within the Azure Portal.

Adding and removing RBAC permissions to the user

After creating a user, we can start adding some RBAC permission. In the script below I created the necessary variables needed for adding and removing RBAC permission in the top of the script. Same as above, to more easily manage the script, by allowing editing of values in one place.

Furthermore, the way I “structured” the script is that all variables needed is highlighted and loaded into memory (By pressing F8 if you use PS ISE or VS Code), then executed one cmdlet at a time, to see the different results. For instance,

  1. First I added the RBAC role to the user at the Subscription scope, then removed it with the cmdlet removing access from subscription scope.
  2. Then added a new role assignment to the resource group scope, then removed it with the cmdlet removing access from the resource group scope
  3. At last added role assignment for a single resource, then removed it with the cmdlet removing access from single resource scope.

This allowed me to see how the cmdlets worked within the console and the result within the Azure Portal.

#======== Creating variables to easily manage values one place ========#

# Values of the variables

$UserPrincipleName = "ola@fredrikengseth.com"
$Subscription = (Get-AzSubscription).SubscriptionId
$ResourceGroupName = "rg1"
$ResourceName = "vm1"
$RoleDefinitionName = "Contributor"
# Getting the ObjectID for a user
$UserID = (Get-AzADUser -UserPrincipalName $UserPrincipleName).Id
# Getting the Subscription scope
$SubscriptionScope = "/subscriptions/" + (Get-AzSubscription).SubscriptionId
# Getting Resource Type
$ResourceType = "Microsoft.Compute/" + (Get-AzResource -Name $ResourceName).ResourceType

#======== Adding different RBAC permissions to a user ========#

# Create a role assignment for a user to a Subscription
New-AzRoleAssignment -ObjectId $UserID
    -RoleDefinitionName $RoleDefinitionName `
    -Scope $SubscriptionScope `
    -Verbose

# Create a role assignment for at user to a Resource Group
New-AzRoleAssignment -ObjectId $UserID
    -RoleDefinitionName $RoleDefinitionName `
    -ResourceGroupName $ResourceGroupName ` `
    -Verbose

# Create a role assignment for at user to a Resource Group and a specified resource
New-AzRoleAssignment -ObjectId $UserID `
    -RoleDefinitionName $RoleDefinitionName `
    -ResourceGroupName $ResourceGroupName `
    -ResourceName $ResourceName `
    -ResourceType $ResourceType `
    -Verbose

#======== Removing RBAC assignment to a user ========#

# Removing from subscription level
Remove-AzRoleAssignment -ObjectId $UserID
    -RoleDefinitionName $RoleDefinitionName `
    -Scope $SubscriptionScope `
    -Verbose

## Removing from a Resource Group
Remove-AzRoleAssignment -ObjectId $UserID
    -RoleDefinitionName $RoleDefinitionName `
    -ResourceGroupName $ResourceGroupName `
    -Verbose

## Removing from a Resource
Remove-AzRoleAssignment -ObjectId $UserID `
    -RoleDefinitionName $RoleDefinitionName `
    -ResourceGroupName $ResourceGroupName `
    -ResourceName $ResourceName `
    -ResourceType $ResourceType `
    -Verbose

During this little experiment I learned a thing or two which is cool, I hope you did too. Have a great weekend.