As the FIM Synchronization Service Manager does not have any out of the box scheduling capabilities, I have to create a script which can be run as a scheduled task to do regular synchronizations. There are a lot of examples out there for scripts, one of the examples can be found here: Technet ScriptBox: Using Powershell to start Run Profiles That’s actually where I based my script on. The script is not the subject of this post. Like with all scripts, logging is very important. If your script is going to be ran on a regular base, and production data is involved, logging cannot be let out.
For scripts like that I prefer two logging modes: debug & operational. Debug is switched off by default, but when switched on floods some text based log with as much output possible. Operational on the other side should be clear, concise and easy to check. The idea of receiving a mail when things go wrong is very nice, but I prefer to leverage the System Center Operations Manager (SCOM) tool a customer has to generate alerts based on event log entries. This way the complete IT staff is up to date when things go wrong and not just one mailbox which is flooded by alerts of a 1000 scripts.
You can see I have an “Application and Services Logs” log (FIM Run Profiles Task") where I can write events too. Besides the log I also have a event source so I can know which application/script logged the events. How do we get this? Quit simple, open up regedit and:
- Create a key with the name of your custom event log below HKLM\SYSTEM\CurrentControlSet\Services\eventlog\
- Create a key with the name of your custom event source below HKLM\SYSTEM\CurrentControlSet\Services\eventlog\YourEventLog
- Create a REG_EXPAND_SZ (Expandable String Value) with the following value in it:
- For x64 OS: C:\Windows\Microsoft.NET\Framework64\v2.0.50727\EventLogMessages.dll
- For x86 OS: C:\Windows\Microsoft.NET\Framework\v2.0.50727\EventLogMessages.dll
- Reboot the server. Don’t leave this step out or your events won’t be displayed correct.
The result should look like this:
Don’t worry about the referenced .NET 2.0 folders, I’m pretty sure they’ll stay there for backwards compatibility. I verified the v3.0 and v3.5 folders and they don’t contain this DLL, so it’s absolutely necessary you pick those. You might wonder why you need to reference a DLL which seems to come from the .net framework. This DLL is in fact an easy way to make sure the Event Viewer knows how to translate your events. A lot of applications have their own DLLs so you can see events in a localized language, or when writing event x, you get the message y. However all we want is to write custom messages to the log, and that’s just what this DLL is meant to do: you pass it a string, and it logs that as the event. If you’d leave out the DLL, your messages would look like the screenshot below, stating that “The description for Event Id x from source Y cannot be found. Either the compontent that raises this event is not installed on your computer or…”
And to finalize this post an example how to log to this event log using PowerShell. I’m pretty sure you can easily do this with VBscript or .net as well. First I prepare a string which will contain the message to displayed in the event entry. I mixed ‘ and “ for a specific reason: strings surrounded by ‘ and ‘ will have their PowerShell variables not resolved. String surrounded with “ and “ will resolve. The “`r`n” will make sure the content following will be printed on a new line.
$eventMsg = 'Scheduled Task to run FIM Synchronization Profiles blocked because $maintenanceModeEnabled is set to true.' + "`r`n" `
+ 'Alter the script so that $maintenanceModeEnabled is set to false if regular syncs should be performed again.' + "`r`n"`
+ "The script: $script"
And the we write to the event log:
write-eventlog -logname "FIM Run Profiles Task" -Source "FIM Run Profiles Task" -Message $eventMsg -EntryType "Information" -EventId "1"
The logname and Source are self-explanatory we created them in the registry editing steps. The Message parameter contains the string which will be used in the entry. The EventId can be chosen as you like it. As for the EntryType the following values are valid: Error, Warning, Information, SuccessAudit and FailureAudit.