Private/GetLocalUserAndGroups.ps1

function GetLocalUserAndGroups {
    [CmdletBinding()]
    Param()

    if (!$PSVersionTable.Platform -or $PSVersionTable.Platform -eq "Win32NT") {
        $AllLocalUsers = Get-LocalUser
        $AllLocalGroups = Get-LocalGroup

        [System.Collections.ArrayList]$AllLocalGroupMembership = @()
        foreach ($Group in $AllLocalGroups) {
            $Users = Get-LocalGroupMember $Group | Where-Object {$_.PrincipalSource -eq "Local"} | foreach {
                if ($_.Name -match '\\') {
                    $($_.Name -split '\\')[-1]
                }
                else {
                    $_.Name
                }
            }
            if ($Users) {
                $PSObject = [pscustomobject]@{
                    Group   = $Group.Name
                    Users   = [System.Collections.ArrayList]@($Users)
                }
                $null = $AllLocalGroupMembership.Add($PSObject)
            }
        }

        [System.Collections.ArrayList]$AllLocalUserGroups = @()
        foreach ($User in $AllLocalUsers) {
            $Groups = $($AllLocalGroupMembership | Where-Object {$_.Users -contains $User.Name}).Group
            if ($Groups) {
                $PSObject = [pscustomobject]@{
                    User   = $User
                    Groups = [System.Collections.ArrayList]@($Groups)
                }
                $null = $AllLocalUserGroups.Add($PSObject)
            }
        }
        
        $AllLocalUserGroups
    }
    
    if ($PSVersionTable.Platform -eq "Unix" -or $PSVersionTable.OS -match "Darwin") {
        $AllUsers =$(bash -c "getent passwd") | foreach {$($_ -split ':')[0]}
        $AllGroups = $(bash -c "getent group") | foreach {$($_ -split ':')[0]}
        [System.Collections.ArrayList]$UserAndGroups = foreach ($User in $AllUsers) {
            $Groups = $(bash -c "getent group | grep $User") | foreach {$($_ -split ':')[0]}
            [pscustomobject]@{
                User    = $User
                Groups  = [System.Collections.ArrayList]@($Groups)
            }
        }

        $HumanUsersPrep = bash -c "awk -F: '`$3 >= 1000 && `$1 != `"nobody`" {print `$1}' /etc/passwd"
        $HumanUsers = $HumanUsersPrep | Where-Object {$_ -notmatch "nobody"}

        $ActualSudoUsersPrep = foreach ($User in $AllUsers) {
            bash -c "sudo -l -U $User"
        }
        $ActualSudoUsers = $ActualSudoUsersPrep -match "User.*may run .*:" | foreach {$($_ -replace 'User ','' -split ' may')[0]}

        foreach ($User in $ActualSudoUsers) {
            foreach ($obj in $UserAndGroups) {
                if ($obj.User -eq $User) {
                    $null = $obj.Groups.Add("sudousers")
                }
            }
        }

        foreach ($User in $HumanUsers) {
            foreach ($obj in $UserAndGroups) {
                if ($obj.User -eq $User) {
                    $null = $obj.Groups.Add("humanusers")
                }
            }
        }

        $UserAndGroups
    }
}