Author Posts

June 9, 2016 at 7:25 pm

I have to report on every user that has access to a server regardless if it is local access or domain access. I have come up with this bit of code

Function Get-LocalGroup
{
    Param ($ComputerName)

    PROCESS
    {
        ForEach ($Computer in $ComputerName)
        {
            $LGroup = [ADSI]"WinNT://$Computer/Administrators,group"

            $Members = @($LGroup.psbase.Invoke("Members"))

            ForEach($Member in $Members)
            {
                $Name=$Member.GetType().InvokeMember("Name", 'GetProperty', $Null, $Member, $Null)
                $Path=$Member.GetType().InvokeMember("ADsPath", 'GetProperty', $Null, $Member, $Null)
                $Class=$Member.GetType().InvokeMember("Class", 'GetProperty', $Null, $Member, $Null)
                If ($Path -like "*$Computer*")
                {
                    $Location = "Local"
                }
                Else
                {
                    $Location = "Domain"
                }
                New-Object -TypeName psobject -Property @{Name=$Name;
                                                          Path=$Path;
                                                          Class=$Class;
                                                          Server=$Computer;
                                                          Host=$Location;
                                                          Group='Administraotrs'
                                                          FullName=$Name;
                                                          Nested=$null;
                                                          ParentGroup=$null}
            }
        }
    }
}

Function Get-DomainGroup
{
    Param ($Groups,$Nested,$ParentGroup)

    PROCESS
    {
        ForEach ($Group in $Groups)
        {

            $Members = Get-ADGroupMember -Identity $Group.Name

            ForEach ($Member in $Members)
            {
                If ($Member.objectClass -eq 'group')
                {
                    Get-DomainGroup -Groups $Member -Nested $true -ParentGroup $Member.Name
                }
                ElseIf ($Member.objectClass -eq 'computer')
                {
                    $Account = Get-ADComputer -Identity $Member.Name -Properties DisplayName
                }
                Else
                {
                    $Account = Get-ADUser -Identity $Member.SamAccountName -Properties DisplayName
                }

                New-Object -TypeName psobject -Property @{Name = $Account.SamAccountName;
                                                            Class = $Account.objectClass;
                                                            Group = $Group.Name;
                                                            Host = 'Domain';
                                                            Path = $Account.DistinguishedName;
                                                            Server = $Computer;
                                                            FullName = $Account.DisplayName;
                                                            Nested = $Nested;
                                                            ParentGroup = $ParentGroup}
            }
        }
    }
}

Function Get-AllServerAdmins
{
    Param ($ComputerName)

    PROCESS
    {
        ForEach ($Computer in $ComputerName)
        {
            $LocalAccess = Get-LocalGroup -ComputerName $Computer
            $DomainGroups = $LocalAccess| Where-Object -FilterScript {$_.Host -eq 'Domain' -and $_.Class -ne 'User'}# | Sort-Object -Property name # | Select-Object -Property Name | Get-Unique -AsString
            $DomainMembers = Get-DomainGroup -Group $DomainGroups -Nested $false -ParentGroup $null
            $LocalAccess 
            $DomainMembers
        }
    }
}

$Computers = 'Server1','Server2'
Get-AllServerAdmins -ComputerName $Computers | Export-CSV InfoText.csv -NoTypeInformation

The problem I am having is when it encounters a nest domain group and has to recurse through it, it's supposed to pass the name of the parent group back to the domain group function, but the report is showing the nested group as the parent group. I need so extra eyes here. What am I missing?

June 9, 2016 at 7:32 pm

PS. Process blocks are because I do intend to make these advanced functions to supply to our Windows team once I get them working correctly

June 11, 2016 at 2:37 am

When you recursively call the Get-DomainGroup function, you are passing in the current group (member) to both the -Groups parameter and the -ParentGroup parameter. If I am reading your post right, I think you want to pass the $Group variable to -ParentGroup:

Function Get-DomainGroup
{
    Param ($Groups,$Nested,$ParentGroup)

    PROCESS
    {
        ForEach ($Group in $Groups)
        {

            $Members = Get-ADGroupMember -Identity $Group.Name

            ForEach ($Member in $Members)
            {
                If ($Member.objectClass -eq 'group')
                {
                    Get-DomainGroup -Groups $Member -Nested $true -ParentGroup $Group.Name
                }
                ElseIf ($Member.objectClass -eq 'computer')
                {
                    $Account = Get-ADComputer -Identity $Member.Name -Properties DisplayName
                }
                Else
                {
                    $Account = Get-ADUser -Identity $Member.SamAccountName -Properties DisplayName
                }

                New-Object -TypeName psobject -Property @{Name = $Account.SamAccountName;
                                                            Class = $Account.objectClass;
                                                            Group = $Group.Name;
                                                            Host = 'Domain';
                                                            Path = $Account.DistinguishedName;
                                                            Server = $Computer;
                                                            FullName = $Account.DisplayName;
                                                            Nested = $Nested;
                                                            ParentGroup = $ParentGroup}
            }
        }
    }
}

June 13, 2016 at 12:08 pm

The bad part is knowing it's something simple and not being able to find it. I really appreciate the help Matt!

June 15, 2016 at 11:58 am

Glad to help!

You have an interesting approach to the problem of reporting on nested groups, which is something I've seen a lot of questions about. I may point others in this direction if I see a similar question in the future.