In this article, I'm going to discuss a PowerShell script that retrieves the users with the admin role on Azure subscriptions and exports the information to a CSV file. An Azure subscription is like a wallet you use to pay for the services you use in Microsoft's cloud. Thus, managing and maintaining these subscriptions is an important task.

Viewing subscriptions in the Azure Portal ^

If you want to retrieve the role assignments for every subscription, navigate to Azure portal -> Subscriptions. Select the subscription you want to check the assigned roles on and click Access Control (IAM). On this blade, you can see the role assignments.

User role assignments on subscriptions

User role assignments on subscriptions

To check the role assignments for other subscriptions, you need to check every single subscription the same way you did with this one.

Retrieving Azure subscriptions with PowerShell ^

First, you need to log in using the following cmdlet:


Retrieve the subscription admins

After that, you need to run the following command:

$Subscriptions = Get-AzureRmSubscription | ForEach-Object {$_ | Set-AzureRmContext | Out-Null

Get-AzureRMSubscription reads all the subscriptions. To retrieve specific information about each subscription, we have to set the context for each subscription in a loop where $_ represents the subscriptions. This information includes the account used for authentication, the subscription itself, the Active Directory (AD) tenant, the environment (Azure Cloud, Azure Stack, Azure Government, and so on), and the credentials used to identify the account identity. I used Out-Null to delete the output instead of sending it to the pipeline because we only need to store the information in the $Subscriptions variable

The command below will then retrieve all the role assignments in every subscription for subscription owners, including the classic administrators. After that we will select values such as the sign-in name and the corresponding subscription ID. We will store the result in the $Subscriptions variable.

Get-AzureRmRoleAssignment -IncludeClassicAdministrators | Where-Object` {$_.RoleDefinitionName -eq "Owner"} |`
select SignInName, @{N="SubscriptionId";E={$_.Scope.split('/')[2]}

The expression {$_.Scope.split('/')[2]} allows me to remove the "/" between the results of the scope and store it in an array where I can retrieve the subscription ID.

Retrieving the subscription names

The subscription ID is not a very telling property, and you will most likely want to store the subscription name in another variable.

To retrieve the subscription names, you need to run the following for loop:

$SubscriptionNames = foreach ($subid in $Subscriptions)
  Get-AzureRmSubscription -SubscriptionId $subid.SubscriptionId |`
  select @{N= "SubscriptionName”; E= {$_.Name}}

Merging the variables

Next, we merge the information stored in the $Subscriptions and the $SubscriptionNames variables and store everything in a PSObject:

  for ($i=0; $i -lt $Subscriptions.Count; $i++) {
    New-Object -Type PSObject -Property @{
        'SignInName'     = $Subscriptions[$i].SignInName
        'SubscriptionId'   = $Subscriptions[$i].SubscriptionId
        'SubscriptionName'      = $SubscriptionNames[$i].SubscriptionName
    } | Export-Csv <Specify a path> -Append

This part of the script triggers a for loop that will run a number of times according to the number of rows you have in the $Subscriptions variable. In every run, it will create a new row with the properties specified in the hashtable @{}, adding the result to the CSV file in the new row.

Subscribe to 4sysops newsletter!

Conclusion ^

You should regularly check your subscription role assignments to check that only the proper role assignments are in place. Otherwise, neglecting this will expose you to security risks. The script discussed in this post gave you a good overview of all subscriptions and the corresponding role assignments.

  1. JoJo 4 years ago

    For some reason I am only able to view some owners and not all.

    $Subscriptions = Get-AzureRmSubscription | ForEach-Object {$_} | Set-AzureRmContext | Out-Null
    Get-AzureRmRoleAssignment -IncludeClassicAdministrators | Where-Object {$_.RoleDefinitionName -eq “Owner”} |`select SignInName, @{N=”SubscriptionId”;E={$_.Scope.split(‘/’)[2]}}
    $SubscriptionNames = foreach ($subid in $Subscriptions) {Get-AzureRmSubscription -SubscriptionId $subid.SubscriptionId |` select @{N= “SubscriptionName”; E= {$_.Name}}}

    for ($i=0; $i -lt $Subscriptions.Count; $i++) {
    New-Object -Type PSObject -Property @{
    SignInName = $Subscriptions[$i].SignInName
    SubscriptionId = $Subscriptions[$i].SubscriptionId
    SubscriptionName = $SubscriptionNames[$i].SubscriptionName
    } | Export-Csv -path .\namestesting.csv -Append

  2. Bart 1 year ago

    If you use the Az module for PS you don't need to perform a merge:

    $Subscriptions = Get-AzSubscription |
    foreach {$_ | Set-AzContext | Out-Null
    Get-AzRoleAssignment | select DisplayName,SignInName,RoleDefinitionName,@{N="SubId";E={((get-azcontext).Subscription).Id}},@{N="SubName";E={((get-azcontext).Subscription).Name}}


Leave a reply

Your email address will not be published.


© 4sysops 2006 - 2022


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account