Your basic ITPro blog... What's going on at work, what I'm interested in.

Thursday, September 18, 2008

A More Elegant Solution...

I have blogged before about our new file server and the folder structure we are using. I wrote about the automation I wrote for creating new shared folders, and for deleting them.

I have since made some changes/updates to these scripts. The biggest issue I had to tackle was a problem that cropped up one evening... I was at home and had to set up some shared folders. So, I VPN'ed in to our network and ran my 'Create Folders' Powershell script.

The script created the AD security groups, created the folder, and then promptly failed while trying to apply the security settings to the folder. After some research, I determined that the security groups were created on one DC and the security settings were trying to be applied via another DC. The new security groups had not yet propagated to the second DC, so it was failing. My solution, check all of my DCs to make sure they knew about the new security groups. My first go-around at this (which works fine), was:

function wait_for_replication {
    param($target = "<server>",
fqdn = "<AD Domain>", $ou = $GroupContainer, $remove = $TRUE, [switch]$table ) Write-Host "Checking replication of security groups..." $context = new-object System.DirectoryServices.ActiveDirectory.DirectoryContext("Domain",$fqdn) $dclist = [System.DirectoryServices.ActiveDirectory.DomainController]::findall($context) if($table) { $DCTable = @() $myobj = "" | select Name,Time $myobj.Name = ("$target [SOURCE]").ToUpper() $myobj.Time = 0.00 $DCTable += $myobj } $dn = "CN=" + $ROgroup + "," + $GroupContainer $start = Get-Date $i = 0 $cont = $TRUE while($cont) { $i++ $oldpos = $Host.UI.RawUI.CursorPosition Write-Host " =========== Check $i ===========" -fore white start-Sleep 1 $replicated = $TRUE foreach($dc in $dclist) { if($target -match $dc.Name){continue} $object = [ADSI]"LDAP://$($dc.Name)/$dn" if($object.name) { Write-Host " - $($dc.Name.ToUpper()) Has Object [$dn]" (" "*5) -fore Green if($table -and !($dctable | ?{$_.Name -match $dc.Name})) { $myobj = "" | Select-Object Name,Time $myobj.Name = ($dc.Name).ToUpper() $myobj.Time = ("{0:n2}" -f ((Get-Date)-$start).TotalSeconds) $dctable += $myobj } } else {Write-Host " ! $($dc.Name.ToUpper()) Missing Object [$dn]" -fore Red;$replicated = $FALSE} } if($replicated){$cont = $FALSE}else{$Host.UI.RawUI.CursorPosition = $oldpos} } $end = Get-Date $duration = "{0:n2}" -f ($end.Subtract($start).TotalSeconds) Write-Host "`n Took $duration Seconds `n" -fore Yellow if($table){$dctable | Sort-Object Time | Format-Table -auto} Write-Host "Moving on!" }

I copied a bulk of this from someone on the web (citation unavailable). It works well and keeps my script from failing. But then, while working with the AWESOME Quest AD CMDlets, I thought I would try to do the same thing with them. After some tinkering, I came up with:

function wait_for_replication 
{
    $DCs = Get-QADComputer -ComputerRole DomainController
    foreach ($DC in $DCs)
    {
        $aa = $null
        $bb = $null
        do
        {
            Write-Host "Checking for Security Group on $($DC.Name)..."
            $null = Connect-QADService -Service $DC.Name
            $aa = Get-QADGroup $MODgroup
            $bb = Get-QADGroup $ROgroup
            Disconnect-QADService 
            Start-Sleep -Seconds 1
        }
        until
        (
            $aa -ne $null -and $bb -ne $null
        )
    }
}

I like this a lot better. I am sure it can be further optimized. And, I look at the rest of this script and see changes I can make to improve things. But, I am making progress. As I continue to learn more about Powershell, I can re-visit my scripts and see what tuning I can do.

No comments:

Additional Info

My photo
email: support (AT) mangrumtech (DOT) com
mobile: 480-270-4332