Help with PowerShell - remove an attribute value if a user is not in all 4 groups

M Tran 491 Reputation points
2024-07-19T22:26:40.6633333+00:00

Hi,

I am hoping to get some suggestions on how to do this.

There are 4 defined groups.

I need to get a list of AD users that have adminCount = 1

Then I need to compare. If a user is not in all 4 groups (not just 1 group), then remove the adminCount.

This is my script:

$Groups = "Domain Admins","Enterprise Admins","Schema Admins","Administrators"
foreach ($group in $Groups){
    $members= Get-ADGroupMember $group -Recursive | Select -ExpandProperty SamAccountName
    Get-ADUser -Filter {enabled -eq $true} -Properties name, adminCount, sAmAccountName | where {$_.adminCount -eq '1'} |`
    
    foreach {
        if ($members -contains $_.samaccountname){
                Write-Host ""$_.samaccountname" exists in $group"}
        else {
               Write-Host ""$_.samaccountname" not in $group"
			set-aduser $_.samaccountname -Replace @{adminCount=0}
}
               }
}

But, some users are in one group, two groups, not all; so, based on my if statement, as soon as it sees a user not in a group, it will remove the adminCount. The condition is: A user is not a member of ALL 4 groups, then clear the adminCount.

How do I do this?

Thank you!

PowerShell
PowerShell
A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
2,568 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Marcin Policht 25,285 Reputation points MVP
    2024-07-19T23:14:27.68+00:00

    Try the following

    $Groups = "Domain Admins", "Enterprise Admins", "Schema Admins", "Administrators"
    # Get the members of all groups
    $groupMembers = @{}
    foreach ($group in $Groups) {
        $groupMembers[$group] = Get-ADGroupMember $group -Recursive | Select-Object -ExpandProperty SamAccountName
    }
    # Get users with adminCount = 1
    $adminUsers = Get-ADUser -Filter {enabled -eq $true} -Properties name, adminCount, sAmAccountName | Where-Object {$_.adminCount -eq '1'}
    # Check if each user is in all groups
    foreach ($user in $adminUsers) {
        $isInAllGroups = $true
        foreach ($group in $Groups) {
            if ($groupMembers[$group] -notcontains $user.sAmAccountName) {
                $isInAllGroups = $false
                break
            }
        }
        if ($isInAllGroups) {
            Write-Host "$($user.sAmAccountName) exists in all groups"
        } else {
            Write-Host "$($user.sAmAccountName) is not in all groups"
            Set-ADUser -Identity $user.sAmAccountName -Replace @{adminCount = 0}
        }
    }
    
    

    If the above response helps answer your question, remember to "Accept Answer" so that others in the community facing similar issues can easily find the solution. Your contribution is highly appreciated.

    hth

    Marcin


  2. Rich Matheisen 46,801 Reputation points
    2024-07-27T20:03:17.1266667+00:00

    I used the code from @Marcin Policht as the basis for the code below. This should identify the accounts with a non-zero adminCount that are NOT a member of ANY of the groups in the $Groups array.

    I use distinguishedNames instead of SAMAccount names because they are unique across the entire AD forest, where SAMAccountNames are only unique within a domain.

    $Groups = "Domain Admins", "Enterprise Admins", "Schema Admins", "Administrators"
    
    # not every account with adminCount -ne 0 is obvious
    $ExcludedSamAccounts = 'Administrator', 'krbtgt'
    $ExcludedDNs = foreach ($u in $ExcludedSamAccounts){
        (Get-ADUser $u).distinguishedName
    }
    
    # get all enabled users with an adminCount greater than zero that aren't excluded from the results
    # Note: this uses the ".Where()" method which is about 10 times faster than using a pipe and Where-Object cmdlet
    # N.B. adminCount (in the past) may have been set to a value greater then 1. Maybe that's been fixed?
    $adminUsers = ((get-aduser -Properties admincount -filter {enabled -eq $true -and admincount -ne 0}).distinguishedName).Where({$_ -notin $ExcludedDNs},'First',$_)
    
    $groupMembers = @{}
    foreach ($group in $Groups) {
        (Get-ADGroupMember $group -Recursive).distinguishedName |
            ForEach-Object{
                $groupMembers[$_] = $false      # add DNs to hash. Only one DN will be in hash no matter how many groups it's a member of
            }
    }
    $adminsNotInAnyGroup = @()          # only needed if you want to know who they were
    foreach($admin in $adminUsers){
        if ($groupmembers.ContainsKey($admin)){
            continue
        }
        $adminsNotInAnyGroup += $admin          # see comment following $adminsNotInAnyGroup
        # Uncomment the following line when you're ready to reset the adminCount property
        #Set-ADUser -Identity $admin -Replace @{adminCount = 0}
    }
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.