Sophos/Utimaco Safeguard Auto-Sync Script

Those of you who have used Safeguard will know that for reasons known only to the Germans, Utimaco decided not to provide any way to automatically sync Safeguard with your AD domain(s) without resorting to a rather buggy API. They provide some example code for VBScript, but if you want to do it in Powershell instead, look no further:

#Safeguard Directory Synchronisation Tool
#Adam Beardwood 04/02/2010
#v1.0 - Initial Release
 
#Load Safeguard .NET Assembly for use
[void] [System.Reflection.Assembly]::LoadWithPartialName("Utimaco.SafeGuard.AdministrationConsole.Scripting")
 
 
#---Declare Variables---
#DateTime Stamp
$DTS = date -format yyyy-MM-dd--hh-mm
#Root DSN to bind connection to
$dsn = "DC=mydomain,DC=local"
#Location for Log File
$logFileName = "D:\Scripts\SGSync."+$DTS+".log"
#Sync Group Membership
$membership = 1
#Sync Account State
$accountState = 1
#Relocate Move Objects if they have been relocated to another sync'd OU
$takeCareOfMovedObjects = 1
#Debuggery
if($args[0] -ne $null){$Debug = $True}else{$Debug = $False}
#---End Variables---
 
#---Define Functions---
 
#Function to send email alert on Sync completion
Function SendEmail ($Errs){
 
$smtpServer = "smtp.mydomain.local"
$bodytext=@"
The Safeguard Enterprise Automated Sync process ran. The following errors occurred:
 
$(foreach($item in $Errs){$item;"`r"})
"@
 
$msg = new-object Net.Mail.MailMessage
$att = new-object Net.Mail.Attachment($logFileName)
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
 
$msg.From = "SGE AD Sync<_SGSync@mydomain.local>"
$msg.To.Add("Admins<admins@mydomain.local>")
$msg.Subject = "SGE Sync Process"
$msg.Body=$bodytext
$msg.Attachments.Add($att)
 
$smtp.Send($msg)
 
if($Debug){write-host "Email sent, also," $Errs}
 
}
 
 
#Function to actually sync Safeguard
Function SGSync ($OU){
 
$adsStartContainer = $OU+","+$dsn
if($Debug){write-host "Syncing:" $adsStartContainer}
 
[ref] $Outcome = $ScriptingDirectory.SynchronizeDirectory($dsn, $adsStartContainer, 1, $logFileName, $membership, $accountState, $takeCareOfMovedObjects)
if($Debug){write-host "Start OU:" $Result}
 
$Result = $Scripting.GetLastError($Outcome)
if($Debug){write-host "GetLastError returns:" $Result}
}
 
#---End Functions---
 
#Create scripting objects, authenticate to directory and then initialise the sync process
if($Debug){write-host "Synchronization of Users & Computers ... Started"}
 
try{$Scripting = new-object Utimaco.SafeGuard.AdministrationConsole.Scripting.Base}
catch{write-host "An Error Occurred While Attempting To Load Safeguard Directory Synchronisation Libraries. Quitting...";exit 0}
if($Debug){write-host "Created Base Object"}
 
$ScriptingDirectory = $Scripting.CreateDirectoryClassInstance()
if($Debug){write-host "Created Directory Object"}
 
$Result = $Scripting.Initialize()
if($Debug){write-host "Init API:" $Result}
 
$Result = $Scripting.AuthenticateService()
if($Debug){write-host "Authenticate:" $Result}
 
$Result = $ScriptingDirectory.Initialize()
if($Debug){write-host "Init SGD:" $Result}
 
#---Sync the following OUs---
SGSync("OU=An OU")
SGSync("OU=Another OU")
 
#Free up resources
$Result = $ScriptingDirectory.FreeResources()
if($Debug){write-host "Finalize SGD:" $Result}
 
$Result = $Scripting.FreeResources()
if($Debug){write-host "Finalize API:" $Result}
 
#Get errors from the generated log file
$Errs = select-string -pattern "Failure" -path $logFileName
 
#Send email alert
if($Errs -ne $null){SendEmail $Errs}
 
if($Debug){write-host "Synchronization of Users & Computers...End"}

Obviously this has to be run on a machine which has the Safeguard .NET assemblies installed (Management Console or Server packages)