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
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