Search code examples
powershellactive-directory-group

detect if computer is not member of at least one group


I have a need to detect computer objects that are not a member of at least one group. I have come up with this script, but instead of listing just the machines that are not a member of at least one group, it returns all workstations. What am I doing wrong?

Get-ADComputer -Filter * -Property * | where {
  $_.memberof -notmatch 'Group1' -and
  $_.memberof -notmatch 'Group2' -and
  $_.memberof -notmatch 'Group3'
} | Format-Table Name

Solution

  • The MemberOf property contains a list of distinguished names. You can't check if it doesn't contain something with the -notmatch operator. Instead get a list of the distinguished names of your groups:

    $groups = 'Group1', 'Group2', 'Group3' |
              ForEach-Object { Get-ADGroup -Filter "Name -eq '$_'" } |
              Select-Object -Expand DistinguishedName
    

    and check if the MemberOf property doesn't contain any of them:

    Get-ADComputer -Filter * -Property * | Where-Object {
      -not (Compare-Object $groups $_.MemberOf -IncludeEqual -ExcludeDifferent)
    } | Format-Table Name
    

    The Compare-Object is required, because you need to check if one array contains any of the elements of another array. Something like $_.MemberOf | Where-Object {$groups -contains $_} would also work.

    Note that the MemberOf property does not include the primary group of a computer. If the primary group must also not be one of the groups from your list you need an additional check in the Where-Object filter:

    Get-ADComputer -Filter * -Property * | Where-Object {
      -not (Compare-Object $groups $_.MemberOf -IncludeEqual -ExcludeDifferent) -and
      $groups -notcontains $_.PrimaryGroup
    } | Format-Table Name