PowerShell Genie

Find empty security groups

Script 2 min read Windows PowerShell 5.1 and PowerShell 7

Documentation: Microsoft Learn

Get-ADGroup returns security groups, then ForEach-Object tests each by calling Get-ADGroupMember against it.

The script

1PS> Get-ADGroup -Filter 'GroupCategory -eq "Security"' | ForEach-Object { if(-not (Get-ADGroupMember $_ -ErrorAction SilentlyContinue)){ $_ } } | Select-Object Name,SamAccountName

Script reader

Inspect before you run

Inspection only

Inspect the script below. It does not run in this browser.

Inspection only — no command has run.

    Show reference output
    1 Name SamAccountName objectClass
    2 ---------- -------------- -----------
    3 Jane Smith jsmith user
    4 Alex Jones ajones user
    Inspect this example’s structure

    Read the command and its supplied arguments. This example requires real PowerShell or its module; this diagram does not execute it.

    Get-ADGroup -Filter 'GroupCategory -eq "Security"' | ForEach-Object { if(-not (Get-ADGroupMember $_ -ErrorAction SilentlyContinue)){ $_ } } | Select-Object Name,SamAccountName
    1. Stage 1Get-ADGroup-Filter
    2. Stage 2ForEach-ObjectPositional values or no named parameters
    3. Stage 3Select-ObjectPositional values or no named parameters

      How it works

      Get-ADGroup returns security groups, then ForEach-Object tests each by calling Get-ADGroupMember against it. Groups where that call produces nothing are emitted, and the projection keeps the display name next to the SAM account name.

      Adapting it

      Scope the query with -SearchBase to one OU and add the WhenCreated attribute to the output, which lets you exclude genuinely new groups that simply have not been populated yet.

      Requirements

      ActiveDirectory module.

      If the result is unexpected

      A group appears empty although access through nested groups is expected.

      Direct group membership and recursively resolved user membership answer different questions.

      1. Inspect the direct Members property and then review nested membership where that is relevant.

      Validate the result

      The report states whether empty means no direct members or no resolved users.

      Keep the check reliable

      Keep direct and recursive membership reports separate and retain group-owner review.

      Primary documentation

      ForEach-Object reference

      Continue
      Genie guideFind empty security groups

      Get-ADGroup returns security groups, then ForEach-Object tests each by calling Get-ADGroupMember against it.