I thought I’d take a moment to publish my SCOM script template.
Whenever I am writing a SCOM script for monitoring, discovery, or automation, there are some “standards” that I want in all my scripts.
1. I personally feel that all script running in SCOM should at the MINIMUM log at script starting event, and a script completed event with runtime in seconds. This helps anyone evaluating the server, or agent, just how many scripts are running and on what kind of frequency.
2. I like to log “who” the script is executed by (what account, whether RunAs or default agent action account.
3. I like to have an examples section for manually assigning script variables, which is very handy when testing/troubleshooting.
4. I assign a ScriptName and EventID variables in the script, for consistency when logging events.
5. I load examples for discovery scripts, propertybags for monitoring scripts, and just remove what isn’t needed. I find this easier and more consistent than going and grabbing an example from some other script I wrote previously.
6. I have a section on connecting to the SCOM SDK, for scripts that will run automation on the SCOM management server. I found this method to be the most reliable, as there are scenarios where commandlets just stop working under the MonitoringHost.exe process.
I don’t have a lot of “fluff” in here…. I never like it when I have to page down 3 or 4 pages to get to what a script is actually doing…. this is mostly just the meat and potatoes.
#================================================================================= # Describe Script Here # # Author: Your Name # v1.3 #================================================================================= param($SourceId,$ManagedEntityId,[string]$ComputerName,[string]$MGName,[string]$DebugLogging,[string]$Param1,[int]$Param2) # Manual Testing section - put stuff here for manually testing script - typically parameters: #================================================================================= # $SourceId = '{00000000-0000-0000-0000-000000000000}' # $ManagedEntityId = '{00000000-0000-0000-0000-000000000000}' # $ComputerName = "computername.domain.com" # $MGName = "MGNAME" # $DebugLogging = "true" # $Param1 = "foo" # $Param2 = "2" #================================================================================= # Constants section - modify stuff here: #================================================================================= # Assign script name variable for use in event logging. # ScriptName should be the same as the ID of the module that the script is contained in $ScriptName = "CompanyID.AppName.UniqueID.RuleMonitorDiscoveryTaskDSWA.ps1" $EventID = "1234" #================================================================================= # Starting Script section - All scripts get this #================================================================================= # Gather the start time of the script $StartTime = Get-Date #Set variable to be used in logging events $whoami = whoami # Load MOMScript API $momapi = New-Object -comObject MOM.ScriptAPI #Log script event that we are starting task $momapi.LogScriptEvent($ScriptName,$EventID,0,"`nScript is starting. `nRunning as ($whoami).") #================================================================================= # Discovery Script section - Discovery scripts get this #================================================================================= # Load SCOM Discovery module $DiscoveryData = $momapi.CreateDiscoveryData(0,$SourceId,$ManagedEntityId) #================================================================================= # PropertyBag Script section - Monitoring scripts get this #================================================================================= # Load SCOM PropertyBag function $bag = $momapi.CreatePropertyBag() #================================================================================= # Connect to local SCOM Management Group Section - If required #================================================================================= # I have found this to be the most reliable method to load SCOM modules for scripts running on Management Servers # Clear any previous errors $Error.Clear() # Import the OperationsManager module and connect to the management group $SCOMPowerShellKey = "HKLM:\SOFTWARE\Microsoft\System Center Operations Manager\12\Setup\Powershell\V2" $SCOMModulePath = Join-Path (Get-ItemProperty $SCOMPowerShellKey).InstallDirectory "OperationsManager" Import-module $SCOMModulePath TRY { New-DefaultManagementGroupConnection -managementServerName "localhost" } CATCH { IF ($Error) { $momapi.LogScriptEvent($ScriptName,$EventID,1,"`n FATAL ERROR: Unable to load OperationsManager module or unable to connect to Management Server. `n Terminating script. `n Error is: ($Error).") EXIT } } #================================================================================= # Begin MAIN script section #================================================================================= #Put your stuff in here #Example for debuglogging IF ($DebugLogging.ToUpper() -eq "TRUE") { $momapi.LogScriptEvent($ScriptName,$EventID,0,"`nThis is an example event to log for debugging.") } #================================================================================= # End MAIN script section # Discovery Script section - Discovery scripts get this #================================================================================= # Example discovery of a class with properties $instance = $DiscoveryData.CreateClassInstance("$MPElement[Name='Your.Custom.Class']$") $instance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $ComputerName) $instance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $ComputerName) $instance.AddProperty("$MPElement[Name='Your.Custom.Class']/Property1$", $Param1) $instance.AddProperty("$MPElement[Name='Your.Custom.Class']/Property2$", $Param2) $DiscoveryData.AddInstance($instance) # Return Discovery Items Normally $DiscoveryData # Return Discovery Bag to the command line for testing (does not work from ISE) # $momapi.Return($DiscoveryData) #================================================================================= # PropertyBag Script section - Monitoring scripts get this #================================================================================= # Output a fixed Result = BAD for a monitor example $bag.AddValue("Result","BAD") # Output other data from script into bag $bag.AddValue("Param1",$Param1) $bag.AddValue("Param2",$Param2) # Return all bags $bag #================================================================================= # End of script section #================================================================================= #Log an event for script ending and total execution time. $EndTime = Get-Date $ScriptTime = ($EndTime - $StartTime).TotalSeconds $momapi.LogScriptEvent($ScriptName,$EventID,0,"`nScript Completed. `nRuntime: ($ScriptTime) seconds.") #================================================================================= # End of script
Do you have stuff you like to place in every script? If so – let me know in the comments!
I have some SCOM related snippets in my VSCode PowerShell Snippet files but might have to add a few of these….
There is now a really nice MP providing a nicer integration with SCOM, made by square up.
Any thoughts on that?
It is fantastic. But you still need a good script template to develop your powershell script on. The SquaredUp adds simple to use powershell script capability in the SCOM console for rules, monitors, tasks, etc.
Hello! I have created a PS-script that first copy a file from a Web server to one of my Management Servers. The PS-script then checking the details for the file and create a event to the eventlog on the Management Server (if neccesary). If i want to run the PS-script on my Management Server eveyday scheduled in a daily basis. What is the best option for that? I have tried the Rule, Time Command but it will not run for me. Maybe Squared up MP can help me with this or is there any better way? The Web server does not have a Scom Agent so that is the reason why copy the file local to MS.
Just want to confirm that Squared Up PS MP did the work perfectly…:)
Hi,
I’ve created a PS Script based on Squared UP PS MP
I was unable to output multiple data : I’ve got the error (0x80020005)
The only way : Only one row with $bag.AddValue
Any tips ?
You are going to have to provide more details and specifics
Hi,
The part oh the script is :
————
#Add values to the bag
#state value for the monitor
$PropertyBag.AddValue(“Status”,$state)
#context for the alert
$PropertyBag.AddValue(“DisksInWarning”,$DisksInWarning)
$PropertyBag.AddValue(“Count”,$counter)
#output to scom
$PropertyBag
———-
$state is a string
$DisksInWarning is an array
$counter is an integer
I’ve the error (0x80020005) – type mismatch
Monitor works fine with only $status in property bag
It seems that all the data in property bag must hav the same type ?
Regards,
You cannot add an array to a propertybag.
https://monitoringguys.com/2018/08/30/how-to-analyze-a-scom-property-bag/
The VariantType describes the type of the value that is returned. The typical variant types are:
0 = Empty
1 = Null
2 = Short
3 = Integer
4 = Single
5 = Double
6 = Currency
7 = Date
8 = String
9 = Object
10 = Error
11 = Boolean
12 = Variant
13 = DataObject
14 = Decimal
15 = Byte
16 = Char
17 = Long
Thx 🙂
Hi Kevin,
can we add persistence to PS script Rule/Monitor for checking file presence (like 2 checks in 20 mins) then trigger alert ?
ABSOLUTELY. I do this in a bunch of my scripts. Check out “MatchCount” parameter in this example: https://github.com/thekevinholman/FragmentLibrary/blob/master/Monitor.TimedScript.PowerShell.WithParams.mpx
Thanks Kevin, will these take consecutive samples or should we use as well ? also if we use these(“matchcount” or “SampleCount” under suppressionsettings tag) in Rules/Monitors then will there be perf impact on Agent/SCOM DB/DW ?
these are consecutive samples.
When you use these (in a condition detection filter) they add a tiny amount of memory load to the agent because it must retain a counter. It is likely not even measurable.