Help With Server Admin Group Report

Tagged: , ,

This topic contains 4 replies, has 2 voices, and was last updated by Profile photo of Matt McNabb Matt McNabb 3 months, 2 weeks ago.

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
    Posts
  • #42487
    Profile photo of Paul Frankovich
    Paul Frankovich
    Participant

    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?

    #42492
    Profile photo of Paul Frankovich
    Paul Frankovich
    Participant

    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

    #42607
    Profile photo of Matt McNabb
    Matt McNabb
    Participant

    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}
                }
            }
        }
    }
    
    #42697
    Profile photo of Paul Frankovich
    Paul Frankovich
    Participant

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

    #43024
    Profile photo of Matt McNabb
    Matt McNabb
    Participant

    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.

Viewing 5 posts - 1 through 5 (of 5 total)

You must be logged in to reply to this topic.