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.
I made some changes.
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
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
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.
I made some changes.
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
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.
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