I am a beginner programmer in PowerHhell. I am trying to create a function that outputs all nested groups of a group. When I run the function, it gives an error:
Get-ADGroupMember : Cannot find an object with identity: "CN=John,OU=Test,OU=Company,DC=klns,DC=ado,DC=com" в "DC=klns,DC=ado,DC=com".
D:\Work\Powershell\Folder\est4.ps1:11 symbol:23
+ $GetObjects = Get-ADGroupMember $Members
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (CN=John,OU=Т...C=ado,DC=com:ADGroup) [Get-ADGroupMember], ADIdentityNotFoundException
+ FullyQualifiedErrorId : ActiveDirectoryCmdlet:Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException,Microsoft.ActiveDirectory.Management.Commands.GetADGroupMember
$Group = "LGR-Test-RWX"
function Get-NestedGroups
{
$script:Groups = @()
$script:ADGroup = (Get-ADGroup -Identity $Group -Properties Name, Member).Member
$script:Groups += $ADGroup
foreach ($Members in $ADGroup)
{
$GetObjects = Get-ADGroupMember $Members
$GetGroups = $GetObjects | Where-Object objectClass -eq "group"
if ($GetGroups)
{
foreach ($Groups in $GetGroups.Member)
{
Get-NestedGroups $Groups
}
}
}
return ($script:Groups.Name | Sort-Object -Unique)
}
Get-NestedGroups $Group
I can't understand why it doesn't work. Please explain what I am doing wrong. Thank you.
Recursion is the best way for traversing nested structures.
This is a function I've provided as solution for a request in the module Carbon.Security
, Get-CPrivilege should have an option for returning the accumelated privileges
function Get-xEffectiveGroup {
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[string[]]$UserPrincipalName,
[switch]$Local,
[switch]$Domain
)
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
function Get-NestedGroups {
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[System.DirectoryServices.AccountManagement.Principal]$Principal
)
$Groups = [System.Collections.ArrayList]@()
$Principal.GetGroups() | foreach {
$Groups.Add($_) | Out-Null
$Groups.Add($(Get-NestedGroups -Principal $_)) | Out-Null
}
return $Groups
}#end priv function
$Context = New-Object System.DirectoryServices.AccountManagement.PrincipalContext(
[System.DirectoryServices.AccountManagement.ContextType]::Domain)
$UserPrincipal = [System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity(
$Context, $UserPrincipalName
)
$NtDomain = (
$userprincipal.DistinguishedName.split(',') |
where {$_.Contains('DC')}
)[0].split('=')[-1]
[System.Collections.ArrayList]$AllPrincipals = @()
if ($Domain -or -not $Local) {#get domain groups
$AllDomainGroups = Get-NestedGroups -Principal $UserPrincipal |
select -Unique Name |
where {-not [string]::IsNullOrEmpty($_.Name)} |
select @{l = 'Name'; e = {"$NtDomain\" + $_.Name} }
if ($AllDomainGroups) {#was found
if (($AllDomainGroups | Measure-Object).Count -eq 1) {
$AllPrincipals.Add($AllDomainGroups) | Out-Null
}
if (($AllDomainGroups | Measure-Object).Count -gt 1) {
$AllPrincipals.AddRange($AllDomainGroups) | Out-Null
}
}#end domain groups found
}
if ($Local -or -not $Domain) {#get local groups
$LocalGroups = Get-LocalGroup | where {
$ThisLocalGroup = $_
$AllPrincipals.Name | where {
$ThisPrincipalName = $_
$ThisPrincipalName -in ($ThisLocalGroup | Get-LocalGroupMember).Name
}
}
if ($LocalGroups) {
if ($LocalGroups.Count -eq 1) {#ArrayLists are faster but picky
[void]$AllPrincipals.Add(($LocalGroups | select Name))
}
else {
[void]$AllPrincipals.AddRange(($LocalGroups | select Name))
}
}
$UserPrincipalGroups = Get-LocalGroup | where {
$ThisLocalGroup = $_
($NtDomain + '\' + $UserPrincipal.SamAccountName) -in ($ThisLocalGroup | Get-LocalGroupMember).Name
}
if ($UserPrincipalGroups) {
if ($UserPrincipalGroups.Count -eq 1) {#ArrayLists are faster but picky
[void]$AllPrincipals.Add(($UserPrincipalGroups | select Name))
}
else {
[void]$AllPrincipals.AddRange(($UserPrincipalGroups | select Name))
}
}
}#end Local groups
return $AllPrincipals
<#
.SYNOPSIS
Get all groups a domain user is member of.
.DESCRIPTION
Get all groups (explicit and inherited and local) that a user principal object is member of.
.PARAMETER UserPrincipalName
Domain name as domain\account to get all groups for.
.PARAMETER Local
Only get implicit local group membership. I.e. membership through a domain group wont show.
.PARAMETER Domain
Only get domain groups.
.EXAMPLE
Get-xEffectiveGroup -UserPrincipalName domain\accountname
.EXAMPLE
Get-xEffectiveGroup -UserPrincipalName domain\accountname -Local
Show all local groups where the UserPrincipalName is an implict member. Inheritied
membership throuhg domain groups will not show.
#>
}