Compare-SecurityGroups.psm1

function Compare-SecurityGroups {
    <#
    .SYNOPSIS
    Compares security group memberships for a list of Active Directory users.
 
    .DESCRIPTION
    The Compare-SecurityGroups function retrieves the security group memberships for the specified users from Active Directory
    and compares their memberships. The output displays a list of unique security groups and indicates whether each user is a
    member of each group.
 
    .PARAMETER SamAccountName
    Specifies one or more SAM account names of the users whose security group memberships will be compared. This parameter is mandatory.
 
    .EXAMPLE
    Compare-SecurityGroups -SamAccountName "jdoe", "asmith"
 
    This example compares the security group memberships for the users "jdoe" and "asmith".
 
    .EXAMPLE
    Get-ADUser -Identity "jdoe" | Compare-SecurityGroups
 
    This example pipes a list of SAM account names to the Compare-SecurityGroups function for comparison.
 
    .NOTES
    - This script requires the Active Directory module to be imported.
    - The user running this script must have permission to query Active Directory for user and group information.
 
    .OUTPUTS
    [PSCustomObject]
    The output is a custom object containing:
    - SecurityGroup: The name of the security group.
    - Columns corresponding to each SAM account name, indicating group membership as True or False.
 
    #>

    [cmdletbinding()]
    param(
        [Alias("Identity")]
        [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [string[]]$SamAccountName
    )

    begin {
        $userAll = [System.Collections.Generic.List[object]]::new()
    }

    process {
        try {
            foreach ($sam in $SamAccountName) {
                $userObj = Get-ADUser -Identity $sam -Properties MemberOf -ErrorAction Stop
                $userAll.Add($userObj)
            }    
        }
        catch { Write-Host $_.Exception.Message -ForegroundColor Red; return}
    }

    end {
        $secGroupAll = $userAll | ForEach-Object {
            $_ | Select-Object -ExpandProperty MemberOf
        } | Select-Object -Unique | Sort-Object

        foreach ($secGroup in $secGroupAll) {
            $outputObj = [PSCustomobject]@{
                SecurityGroup = ($secGroup -split ',')[0] -replace 'cn=',''
            }
            foreach ($user in $userAll) {
                $outputObj | Add-Member -MemberType NoteProperty -Name $user.SamAccountName -Value ($user.MemberOf -contains $secGroup)
            }
            $outputObj
        }
    }
}