0
votes

I am fairly new to scripting in Powershell and have been faced with this task. Display a table that identifies the servers in a particular OU and ensure that they are a member of the correct group. There should also be nothing "hard coded" into the script (i.e. server names or group names). Essentially, the script should evaluate the server's name and determine which group it should be a member. If it is in the right group, print it to a table showing it is correct but if is not, also print it to the table indicating it is in the wrong group.
I began by utilizing the Quest ActiveRoles plugin and determining I would need to use nested loops. I would first loop through the security groups and evaluate each server against that group to see if it was a member. I then add the computer and the group to a custom PSObject and am able to print that out as a Correct answer. That part works fine. I run into problems when I try to also print out the incorrect answers. Because of the way I have the loops structured, the majority of the servers will not be in the selected group so they will all come back as incorrect.
My question is, what would be the best way to loop through this information and compare the server name to the group membership and still be able to show which are in the correct group and which are in the incorrect group. My code is below.

#Load Quest Active Roles Snapin
Add-PSSnapin quest.activeroles.admanagement

#Load Active Directory module
Import-Module ActiveDirectory

#Variables
$AccelGroup = Get-QADGroup -SearchRoot 'lumosnet.com/Centrify/Role Groups' -GroupType     'Security' | where {$_.name -like "* Servers"}
$AccelComputer = Get-QADComputer -SearchRoot 'lumosnet.com/Centrify/servers'
$report = @()

$AccelGroup | foreach{$ADN=$_.DN
    $AccelComputer | foreach{$AMember=$_.memberof
        $AComp=$_.name

        If($AMember -like $ADN)
        {
            $ReportObj = New-Object PSObject
            $ReportObj | Add-Member -MemberType NoteProperty -Name Computer_Name -Value     $AComp                        
            $ReportObj | Add-Member -MemberType NoteProperty -Name Group_Name -Value     $($AMember -replace '^CN=([^,]+),OU=.+$','$1')
            $ReportObj | Add-Member -MemberType NoteProperty -Name Correct? -Value "Correct"
            $report += $ReportObj
        }
        Else
        {

        }
    }    
}

write-host ($report | FT -Autosize | Out-String)
1
What version of PowerShell are you using? Is there a reason you're using Quest instead of the ActiveDirectory module? - Simon

1 Answers

0
votes

Instead of trying to do the join yourself, consider using LDAP queries to retrieve the servers in the group, and then another to retrieve those not in the group. It will probably still end up simpler:

$ouPath = "LDAP://OU=Database,OU=Domain Servers,DC=EXAMPLE,DC=LOCAL"
$groupPath = "CN=ITT Testing Servers,OU=Domain Servers,DC=EXAMPLE,DC=LOCAL"

$correctFilter = ("(&(objectClass=computer)(memberof={0}))" -f $groupPath)
$incorrectFilter = ("(&(objectClass=computer)(!(memberof={0})))" -f $groupPath)

# set up the searcher
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $ouPath 
$objSearcher.PageSize = 1000
$objSearcher.SearchScope = "Subtree"
@("name","operatingSystem","lastLogonTimestamp") | %{ $unused = $objSearcher.PropertiesToLoad.Add($_) }

# retrieve the correct items
$objSearcher.Filter = $correctFilter 

Write-Host "Servers correctly in group"
$goodItems = $objSearcher.FindAll()
$goodItems | %{ New-Object PSObject -Property $_.Properties } | ft name,operatingsystem,lastLogonTimestamp

# retrieve the bad items
$objSearcher.Filter = $incorrectFilter 

Write-Host "Servers in wrong group"
$badItems = $objSearcher.FindAll()
$badItems | %{ New-Object PSObject -Property $_.Properties } | ft name,operatingsystem,lastLogonTimestamp

You can, of course, loop over each result to get them to a single list as you are doing currently.