r/PowerShell•
GUTIF

Searching for computer objects (server only) that are NOT a member of certain AD groups.

I'm trying to get all servers that are not a member of any WSUS ad group. There are multiple WSUS ad groups to check and make sure the object isn't in. I'm finding it difficult to get through multiple groups.

My current attempt is by doing this after filtering only windows servers

where-object { $_.memberof -notmatch "example_wsus_group" -and $_.memberof -notmatch "example_wsus_group -and $_.memberof -notmatch "example_wsus_group"

Basically repeating with -and and -notmatch until I've looked at every group. Will this method even work?

The results I get still show objects that are members of some of the AD groups.

I'm not very good at PS so any tips would be appreciated!

Thanks

Posted Aug 19, 2016, 4:24 PM UTC

27
markekraus•

How about something like this:

# Use the Names of the WSUS groups
$WSUSGroups = @(
    'WSUS No Rebbot'
    'WSUS install all the things'
    'WSUS critical only'
)


$WSUSGroupDNs = $WSUSGroups | foreach-object {
    Get-ADGroup $_ | Select-Object -ExpandProperty DistinguishedName
}
$MemberofDNs = Get-ADComputer $ServerSamAccountName -Properties memberof | select-object -ExpandProperty memberof 
$Matches = Compare-Object -ReferenceObject $WSUSGroupDNs  -DifferenceObject $MemberofDNs -IncludeEqual -ExcludeDifferent -PassThru
if(!$Matches){
    Write-Warning "$ServerSamAccountName is not a member of a WSUS Group!"
    #Do stuff...
}
1
GUTIFOP•

i'll give it a shot and let you know how it works! Do I have to define $servesamaccount names before I run this?

1
markekraus•

yes. That's just a place holder. I don't know how you are getting the list of server to check, so this was written for just a oneoff. But it could be modified to something like this:

# Use the Names of the WSUS groups
$WSUSGroups = @(
    'WSUS No Rebbot'
    'WSUS install all the things'
    'WSUS critical only'
)
#Distinguished name f the Base OU where all servers live in AD
$ServersBaseOU = 'OU=Servers,DC=Adatum,DC=Com'

$WSUSGroupDNs = $WSUSGroups | foreach-object {
    Get-ADGroup $_ | Select-Object -ExpandProperty DistinguishedName
}
Get-ADComputer -Filter * -SearchBase $ServersBaseOU -Properties memberof | ForEach-Object {
    $MemberofDNs = $_ | select-object -ExpandProperty memberof 
    $Matches = Compare-Object -ReferenceObject $WSUSGroupDNs  -DifferenceObject $MemberofDNs -IncludeEqual -ExcludeDifferent -PassThru
    if(!$Matches){
        Write-Warning "$($_.Name) is not a member of a WSUS Group!"
        #Do stuff...
    }
}

Which will loop through and check all the computer objects under $serversBaseOU to see if they are members of the groups etc...

1
GUTIFOP•

awesome stuff. thanks so much I'll let you know how it works out! I'm getting the servers by just getting all computer objects and filtering by OS since out sloppy ass AD doesn't have all servers in the server OU.

Thanks!

1
markekraus•

since out sloppy ass AD doesn't have all servers in the server OU

I have been working on a project for our primary AD since December last year to get everything in a decent OU structure. The company is one that grows by acquisition and IT used to be outsourced. The AD had 7 distinct topologies at play. I am so close to being done with everything in the right place... but I definitely feel your pain.

2
GUTIFOP•

Hey!

Looking at this again now. How could I export the matches to a csv? When I add export-csv "place I want it to go" at the end it doesn't seem to like it. Would it be possible to export the matches out into a list somewhere?

Also, I'm assuming if I see this error

Compare-Object : Cannot bind argument to parameter 'DifferenceObject' because it is null.
At C:\wsus3.ps1:23 char:80
+     $Matches = Compare-Object -ReferenceObject $WSUSGroupDNs -DifferenceObject $ ...
+                                                                                ~
    + CategoryInfo          : InvalidData: (:) [Compare-Object], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.CompareObjectCommand

it's because it's checking an object that DOES have the wsus group?

I appreciate the help!

1
markekraus•

How could I export the matches to a csv?

I assume you mean you want to export a list of the ones that are NOT in WSUS groups?

$CSVOutFile = "c:\path\to\file.csv"
# Use the Names of the WSUS groups
$WSUSGroups = @(
    'WSUS No Rebbot'
    'WSUS install all the things'
    'WSUS critical only'
)
#Distinguished name f the Base OU where all servers live in AD
$ServersBaseOU = 'OU=Servers,DC=Adatum,DC=Com'

$WSUSGroupDNs = $WSUSGroups | foreach-object {
    Get-ADGroup $_ | Select-Object -ExpandProperty DistinguishedName
}
Get-ADComputer -Filter * -SearchBase $ServersBaseOU -Properties memberof | ForEach-Object {
    $MemberofDNs = @()
    $MemberofDNs += $_ | select-object -ExpandProperty memberof 
    $Matches = Compare-Object -ReferenceObject $WSUSGroupDNs  -DifferenceObject $MemberofDNs -IncludeEqual -ExcludeDifferent -PassThru
    if(!$Matches){
        Write-Output $_       
    }
} | Export-Csv -NoTypeInformation -Encoding UTF8 -Path $CSVOutFile

Compare-Object : Cannot bind argument to parameter 'DifferenceObject' because it is null.

I guess that is because the the computers are not members of any groups. I think i fixed that in my code in this reply by defining an empty array and adding to it instead of just assigning the result.

2