VMware Cloud Community
tdisalvojobs
Contributor
Contributor
Jump to solution

Effective Permissions

Hi,

I am working on some permissions issues which can get very sorted within VMware roles when you have a lot of nested active directory groups.  Logically what I am trying to do is to create a report.  There was a very good script put together on this thread.  It is a great starting point but what I would like to add if possible is for each line that is returned, to check the Principal against AD to see if it is a group.  If it is a group, to go into it and see if there are any groups which are nested within that AD group.  If a nested group is found, then to create a new entry in the report showing the nested group as Principal, or sub principal would even be better, to show who the parent was and how the roles was inherited.

I have found a function Get-NestedAdGroupMembership which I think would be useful in doing this.

What I am not sure is how to handle the call of this to add the fields from the original script.  Also how to make sure that it recurs all the way down, for really nested groups, as that seems to be the issue which I am running into.

Hopefully with this info I will be able to find where the conflicting rights are set.

Many thanks for the guidance.

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

I made some changes.

  • corrected an error in the nested groupname
  • fixed an error with duplicate entries
  • build in a failsafe if the recursive function is called more than 10 times. I don't assume you have AD groups with a nesting deeper than 10

Give this one a try

function Get-AllSubGroups

{

    param(

        [string]$Name,

        [string]$DName

        )

    if((Get-PSCallStack).Count -gt 12){

        return

    }

    else{

        if($Name){

            $filter = {Name -eq $Name}

        }

        else{

            $filter = {DistinguishedName -eq $DName}

        }

   

        $group = Get-ADGroup -Filter $filter -Properties Members

        if($group -and $group.Members){

            $group.Members | %{

                Get-AllSubGroups -DName $_

            }

            if($DName){

                return $group.Name

            }

        }

    }

}

$date = Get-date -Format yyyy-MM-dd

$csvName=("C:\Temp\" + $date +"-" + $global:DefaultVIServer.Name + "-Permissions.csv")

$domain = $env:USERDOMAIN

$report = foreach($vc in $global:DefaultVIServers){

    Write-Verbose "Looking at $vc.Name"

    $si = Get-View ServiceInstance -Server $global:DefaultVIServer

    $authMgr = Get-View -Id $si.Content.AuthorizationManager-Server $global:DefaultVIServer

    foreach($perm in $authMgr.RetrieveAllPermissions()){

        Write-Verbose "`tPrincipal: $($perm.Principal)"

        $perm | Select @{N='Entity';E={Get-View -Id $_.Entity -Property Name -Server $global:DefaultVIServer | select -ExpandProperty Name}},

            @{N='Entity Type';E={$_.Entity.Type}},

            @{N='vCenter';E={$vc.Name}},

            Principal,

            @{N='Nested';E={$false}},

            Propagate,

            @{N='Role';E={$perm = $_; ($authMgr.RoleList | where{$_.RoleId -eq $perm.RoleId}).Info.Label}}

        if($perm.Group -and $perm.Principal -match $domain){

            Get-AllSubGroups -Name $perm.Principal.Split('\')[1] |

            Select @{N='Entity';E={Get-View -Id $perm.Entity -Property Name -Server $global:DefaultVIServer | select -ExpandProperty Name}},

            @{N='Entity Type';E={$perm.Entity.Type}},

            @{N='vCenter';E={$vc.Name}},

            @{N='Principal';E={"$($domain)\$($_)"}},

            @{N='Nested';E={$true}},

            @{N='Propagate';E={$perm.Propagate}},

            @{N='Role';E={($authMgr.RoleList | where{$_.RoleId -eq $perm.RoleId}).Info.Label}}

        }

    }

}

$report | Export-Csv $csvName -NoTypeInformation -UseCulture


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
5 Replies
LucD
Leadership
Leadership
Jump to solution

Try something like this.

The Nested property will indicate if it is a nested group or not.

function Get-AllSubGroups

{

    param(

        [string]$Name,

        [string]$DName

    )

    if($Name){

        $filter = {Name -eq $Name}

    }

    else{

        $filter = {DistinguishedName -eq $DName}

    }

    $group = Get-ADGroup -Filter $filter -Properties Members

    if($group -and $group.Members){

        $group.Members | %{

            Get-AllSubGroups -DName $_

        }

        return $group.Name

    }

}

$domain = $env:USERDOMAIN

$si = Get-View ServiceInstance -Server $global:DefaultVIServer

$authMgr = Get-View -Id $si.Content.AuthorizationManager-Server $global:DefaultVIServer

foreach($perm in $authMgr.RetrieveAllPermissions()){

    $perm | Select @{N='Entity';E={Get-View -Id $_.Entity -Property Name -Server $global:DefaultVIServer | select -ExpandProperty Name}},

        @{N='Entity Type';E={$_.Entity.Type}},

        Principal,

        @{N='Nested';E={$false}},

        Propagate,

        @{N='Role';E={$perm = $_; ($authMgr.RoleList | where{$_.RoleId -eq $perm.RoleId}).Info.Label}}

    if($perm.Group -and $perm.Principal -match $domain){

        Get-AllSubGroups -Name $perm.Principal.Split('\')[1] |

        Select @{N='Entity';E={Get-View -Id $perm.Entity -Property Name -Server $global:DefaultVIServer | select -ExpandProperty Name}},

        @{N='Entity Type';E={$perm.Entity.Type}},

        @{N='Principal';E={$perm.Principal}},

        @{N='Nested';E={$true}},

        @{N='Propagate';E={$perm.Propagate}},

        @{N='Role';E={($authMgr.RoleList | where{$_.RoleId -eq $perm.RoleId}).Info.Label}}

    }

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
tdisalvojobs
Contributor
Contributor
Jump to solution

LucD,

So this is great except that when I try to modify it to report out, like you showed in the reference ticket, I get an error,

The script failed due to call depth overflow.

Which makes me think that we have some seriously nested group issues.  What I added was the following.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

I made some changes.

  • corrected an error in the nested groupname
  • fixed an error with duplicate entries
  • build in a failsafe if the recursive function is called more than 10 times. I don't assume you have AD groups with a nesting deeper than 10

Give this one a try

function Get-AllSubGroups

{

    param(

        [string]$Name,

        [string]$DName

        )

    if((Get-PSCallStack).Count -gt 12){

        return

    }

    else{

        if($Name){

            $filter = {Name -eq $Name}

        }

        else{

            $filter = {DistinguishedName -eq $DName}

        }

   

        $group = Get-ADGroup -Filter $filter -Properties Members

        if($group -and $group.Members){

            $group.Members | %{

                Get-AllSubGroups -DName $_

            }

            if($DName){

                return $group.Name

            }

        }

    }

}

$date = Get-date -Format yyyy-MM-dd

$csvName=("C:\Temp\" + $date +"-" + $global:DefaultVIServer.Name + "-Permissions.csv")

$domain = $env:USERDOMAIN

$report = foreach($vc in $global:DefaultVIServers){

    Write-Verbose "Looking at $vc.Name"

    $si = Get-View ServiceInstance -Server $global:DefaultVIServer

    $authMgr = Get-View -Id $si.Content.AuthorizationManager-Server $global:DefaultVIServer

    foreach($perm in $authMgr.RetrieveAllPermissions()){

        Write-Verbose "`tPrincipal: $($perm.Principal)"

        $perm | Select @{N='Entity';E={Get-View -Id $_.Entity -Property Name -Server $global:DefaultVIServer | select -ExpandProperty Name}},

            @{N='Entity Type';E={$_.Entity.Type}},

            @{N='vCenter';E={$vc.Name}},

            Principal,

            @{N='Nested';E={$false}},

            Propagate,

            @{N='Role';E={$perm = $_; ($authMgr.RoleList | where{$_.RoleId -eq $perm.RoleId}).Info.Label}}

        if($perm.Group -and $perm.Principal -match $domain){

            Get-AllSubGroups -Name $perm.Principal.Split('\')[1] |

            Select @{N='Entity';E={Get-View -Id $perm.Entity -Property Name -Server $global:DefaultVIServer | select -ExpandProperty Name}},

            @{N='Entity Type';E={$perm.Entity.Type}},

            @{N='vCenter';E={$vc.Name}},

            @{N='Principal';E={"$($domain)\$($_)"}},

            @{N='Nested';E={$true}},

            @{N='Propagate';E={$perm.Propagate}},

            @{N='Role';E={($authMgr.RoleList | where{$_.RoleId -eq $perm.RoleId}).Info.Label}}

        }

    }

}

$report | Export-Csv $csvName -NoTypeInformation -UseCulture


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
tdisalvojobs
Contributor
Contributor
Jump to solution

Thanks LucD,

This did the trick.  I am trying to understand this a bit more.

I get that this line calls Get-ADGroup and puts the filter which was one of the two parameters, it pulls back the object AD GRoup with the added property Members and load them into a variable $group

        $group = Get-ADGroup -Filter $filter -Properties Members

I think this checks if there is something in group and distinguished names in $Group.Members

        if($group -and $group.Members){

I think this takes the distinguished names which are in $group.Members and passes that into a for loop

            $group.Members | %{

Here I am confused as to why when it recurses, I get it uses -DName because $group.Members woudl only have the distingushed names

                Get-AllSubGroups -DName $_

            }

Here I dont get what is going on at all.  If $DName was used return the group name?

            if($DName){

                return $group.Name

With this I do not see how it can tell if the things nested within a group are another group or just a user.

Your help is greatly appreciated.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

You're correct on the Get-ADGroup cmdlet, it uses a filter, and that filter can have a Name or DName.

If there is a group returned, this eliminates the fact that a User does not return anything with the Filter, and if there are Members in the group, the if-block is executed.

We then look at all Members in the returned group.

It recurses, becauses you specified you wanted to see all nested groups. Note that there is a fail-safe set at 10 nested groups. If you have more in your environment, you should increase the number 12 accordingly (the calling function + the first call with the Name + 10 nested groups (with Dname) = 12).

That last test on DName is because the first call (with the Name Filter) doesn't need to return anything. We already have that group from the Get-VIPermission cmdlet (Nested -eq $false).

I hope that clarifies it somewhat?
I know, recursive functions can be a pain to read when somebody else wrote them :smileygrin:


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos