Loop Through Variables

Hello,

I have the following code which lists Azure resource group owners and displays the output in a custom table:

[pre]

$rgName = ‘rg-name’

constructing a custom table for the following 3 elements:

data column, heading, and width

$cusTab1 = @{Expression={$.DisplayName};Label=“Display Name”;width=25}, `
@{Expression={$
.SignInName};Label=“Login Name”;width=40}, `
@{Expression={$_.RoleDefinitionName};Label=“Role”;width=20}, `
@{Expression={$rgName};Label=“Resource Group”;width=30}

$List = Get-AzRoleAssignment -ResourceGroupName $rgName | where {($_.RoleDefinitionName -in “Owner”)} | Select DisplayName,SignInName,RoleDefinitionName
$List | Format-Table $cusTab1

[/pre]

What I would like to do is run this for multiple resource groups and then display the values in the custom table? With this code, I can only run it for one resource group at a time.

Thanks,

Frank

The first thing you should check is if the -ResouceGroupName accepts a string array by checking the documentation. This would allow you to do something like this:

Get-AzRoleAssignment -ResourceGroupName 'rg1','rg2','rg3' ...

This would handle the for loop inside of the cmdlet, however, this parameter only accepts a string which means you need to perform the for loop yourself:

$roleGroups = 'rg1','rg2','rg3'

$results = foreach ($roleGroup in $roleGroups) {
    $cusTab1 = @{Expression={$_.DisplayName};Label="Display Name";width=25}, `
               @{Expression={$_.SignInName};Label="Login Name";width=40}, `
               @{Expression={$_.RoleDefinitionName};Label="Role";width=20}, `
               @{Expression={$roleGroup};Label="Resource Group";width=30}

    Get-AzRoleAssignment -ResourceGroupName $rgName | 
    where {($_.RoleDefinitionName -in "Owner")} | 
    Select -Property $cusTab1
}

$results | Format-Table

Note: Did not test this code, but this should be close.

That almost worked! When I ran the following:

[pre]
$results = foreach ($roleGroup in $roleGroups) {
$cusTab1 = @{Expression={$.DisplayName};Label=“Display Name”;width=25}, `
@{Expression={$
.SignInName};Label=“Login Name”;width=40}, `
@{Expression={$.RoleDefinitionName};Label=“Role”;width=20}, `
@{Expression={$roleGroup};Label=“Resource Group”;width=30}
Get-AzRoleAssignment -ResourceGroupName $roleGroup | where {($
.RoleDefinitionName -in “Owner”)} | Select -Property $cusTab1
}

$results | Format-Table
[/pre]

It returned the error:

[pre]
Select : The width key is not valid.
At line:6 char:104

  • … ere {($_.RoleDefinitionName -in “Owner”)} | Select -Property $cusTab1
  •                                             ~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidArgument: (:slight_smile: [Select-Object], NotSupportedException
    • FullyQualifiedErrorId : DictionaryKeyIllegal,Microsoft.PowerShell.Commands.SelectObjectCommand
      Select : The width key is not valid.
      At line:6 char:104
  • … ere {($_.RoleDefinitionName -in “Owner”)} | Select -Property $cusTab1
  •                                             ~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidArgument: (:slight_smile: [Select-Object], NotSupportedException
    • FullyQualifiedErrorId : DictionaryKeyIllegal,Microsoft.PowerShell.Commands.SelectObjectCommand
      [/pre]

You had $rgName as the variable for -ResourceGroupName? I changed that to $roleGroup. As for the “The width key is not valid” message, I changed the SELECT statement to:

[pre]
Get-AzRoleAssignment -ResourceGroupName $roleGroup | where {($_.RoleDefinitionName -in “Owner”)} | Select DisplayName,SignInName,RoleDefinitionName
[/pre]

It now returns records, but it’s not showing a resource group name (which I understand why). I guess I now need to figure out how to avoid the “width” error message so I can include the $roleGroups values?

Sorry, I didn’t see width in that expression, that is only applicable to Format-Table, try this:

$roleGroups = 'rg1','rg2','rg3'

$results = foreach ($roleGroup in $roleGroups) {

    Get-AzRoleAssignment -ResourceGroupName $rgName | 
    where {($_.RoleDefinitionName -in "Owner")} | 
    Select -Property @{Name='RoleGroup';Expression={$roleGroup}},DisplayName,SignInName,RoleDefinitionName

}

$results | Format-Table -Property @{Expression={$_.DisplayName};Label="Display Name";width=25}, `
                                  @{Expression={$_.SignInName};Label="Login Name";width=40}, `
                                  @{Expression={$_.RoleDefinitionName};Label="Role";width=20}, `
                                  @{Expression={$_.RoleGroup};Label="Resource Group";width=30}

That worked! Thanks for all the help!

Not sure if I should open a new discussion topic, or continue adding to this one since it’s the same piece of code?

This is a 2-part question:

1 - I’m placing an if-else statement inside the custom table to return a predetermined value for a returned value (i.e., returned value = “f873d82f-7491-4045-8dbe”, but want it to be “DEV”. This piece is figured out, but for other values additional items are returned:

Should be: use2-dev-rg
Returned value: {use2-dev-rg, $null}

2 - Eventually I’m going to need to define additional “if-else” statements. Would I continue to add the code like this and is this the best approach?

The code I’m using is:

[pre]
$roleGroups = ‘use2-dev-rg’,‘use2-prd-rg’,‘use2-qa-rg’

$results = foreach ($roleGroup in $roleGroups) {

Get-AzRoleAssignment -ResourceGroupName $roleGroup | 
where {($_.RoleDefinitionName -in "Owner") -and ($_.DisplayName -ne "AZ Administrators")} | 
Select -Property @{Name='RoleGroup';Expression={$roleGroup}},DisplayName,SignInName,RoleDefinitionName,Scope

}

$results | Format-Table -Property @{Expression={$.DisplayName};Label=“Display Name”;width=25}, `
@{Expression={$
.SignInName};Label=“Login Name”;width=40}, `
@{Expression={$.RoleDefinitionName};Label=“Role”;width=20}, `
@{Expression={$
.RoleGroup};Label=“Resource Group”;width=30}, `
@{Expression={if ($.Scope.Split(‘/’)[-1] -eq “f873d82f-7491-4045-8dbe”) { $result = “DEV” } else {$.Scope.Split(‘/’)[-1]} $result };Label=“Scope”;width=150}

[/pre]

You are returning two things if it is not the DEV value, the value and the $result. just change your if you return one or the other:

 @{Expression={if ($_.Scope.Split('/')[-1] -eq "f873d82f-7491-4045-8dbe") { "DEV" } else {$_.Scope.Split('/')[-1]} };Label="Scope";width=150}

Gotcha. So having the $result variable is returning two values?