SCOM PowerShell Snippets
There are a lot of things you can do with System Center Operations Manager in PowerShell, that you can’t do (Or would be a pain in the butt to do) via the GUI or other methods.
I’ll place all of the snippets that I’ve picked up while in the course of my SCOM time here on this page. You can place these either in your $PROFILE, or do as I have and create a section in your $PROFILE to store certain SCOM variables, and then dot-source your SCOM-specific code. I use “. $ProfileDir\Scom_Snippets.ps1″ to load my snips.
Speaking of SCOM variables in your main $PROFILE, when I write these snippets, I assume you have them set up similar to mine. Eventually I’ll have a tutorial on how to set it all up, but for now this is what I recommend - some I use now, some I have for ‘future expansion’.
Open your PowerShell profile in your editor of choice, and add a section to it. We’ll be dot-sourcing your SCOM snippet file, as well as setting variables for SCOM
# This block holds environment specific information relating
# to the OpsMgr environment, allowing the SCOM Snippets file
# to be dot sourced and made more ‘generic’.
. $ProfileDir\SCOM_Snippets.ps1 # Load snippets script
$omserver = "SCOMServer.mydomain.com" # FQDN of SCOM RMS
$omserverip = "10.10.9.26" # IP Address of the SCOM RMS
$omdbserver = "SCOMSQLDB.mydomain.com" # FQDN of the OpsMgr SQL Server
$omdbinstance = "Default" # Name of SCOM SQL Instance
$omdb = "OperationsManager" # Name of the OpsMgr database, OperationsManager is the default
### End Operations Manager 2007 Variables ###
Once that is done, you can open or edit your SCOM_Snippets.ps1 file and begin entering the functions I show you, as well as ones you come up with on your own.
Begin the Snippets!
Function Get-AgentNameByHSID - This function will take the Health Service ID, most often referenced in the error about agent proxying “Health service ( <Health Service GUID> ) should not generate data about this managed object ( <Object GUID> ).” and return the agent name responsible for it.
(Get-MonitoringObject -id $hsid).DisplayName
}
Function Get-ActiveRules - This function accepts 2 arguments, server name and file name/location. Server name is required, if no file name/location is given, it will by default save it to C:\$server-rules.xml. This function retrieves the currently running workflows on a given server - workflows are rules, monitors, discovery objects, and anything else that is deployed to the remote agent.
If (!$location) { $location = "C:\$server-Rules.xml" }
# Create the Task object
$taskobj = Get-Task | Where-Object {$_.Name -eq "Microsoft.SystemCenter.GetAllRunningWorkflows"}
# Make sure we have it, if not, the MP isn’t installed.
If (!$taskobj) {
Write-Host "Unable to find required monitoring tasks - MS System Center Internal Tasks MP needs to be installed." -ForeGroundColor Magenta;
break;
}
# Grab HealthService class object
$hsobj = Get-MonitoringClass -name "Microsoft.SystemCenter.HealthService"
# Find HealthService object defined for named server
$monobj = Get-MonitoringObject -MonitoringClass $hsobj | Where-Object {$_.DisplayName -match $server}
# Now actually proceed with the task. I have mine formatted like this version, but I’ve added some light
# error checking for the ‘public’ version.
#(Start-Task -task $taskobj -TargetMonitoringObject $monobj).Output | Out-File C:\$server-Rules.xml
$taskOut = Start-Task -Task $taskobj -TargetMonitoringObject $monobj
# See if it worked, if it did, export out the OutPut part and save as an XML file, then display some items.
If ($taskOut.ErrorCode -eq 0) {
[xml]$taskXML = $taskOut.OutPut
$ruleCount = $taskXML.DataItem.Count
Write-Host "Succeeded in gathering rules for $server" -ForeGroundColor Green
Write-Host "Currently $ruleCount rules active." -ForeGroundColor Green
Write-Host "Exporting to $location" -ForeGroundColor Green
$taskOut.OutPut | Out-File $location
} else {
Write-Host "Error gathering rules for $server" -ForeGroundColor Magenta
Write-Host "Error Code: " + $taskOut.ErrorCode -ForeGroundColor Magenta
Write-Host "Error Message: " + $taskOut.ErrorMessage -ForeGroundColor Magenta
}
}
Function Set-Failover looks for agents that do not have anything set for their failover server, and proceeds to set it. Set the primary and failover servers yourself, then it’s good to go.
# Set Primary Management Server
$Primary_MS = Get-ManagementServer | ? {$_.Name -like "SERVERNAME*"}
# Set Failover Management Server
$Failover_MS = Get-ManagementServer | ? {$_.Name -like "BACKUPSERVER*"}
$noFailoverSpecified = Get-Agent | ? {(!$_.GetFailoverManagementServers())}
ForEach ($agent in $noFailoverSpecified) {
Set-ManagementServer -PrimaryManagementServer $Primary_MS -AgentManagedComputer $agent -FailoverServer $Failover_MS | Out-Null
}
}
Function Get-MissingFailovers queries for all agents without a failover server assigned, then prints out a list of what needs fixed.
$noFailover = Get-Agent |? {!$_.GetFailoverManagementServers()}
If ($noFailover.Count -eq $null) {
Write-Host "All agents have a failover server assigned." -ForeGroundColor Green
} else {
Write-Host "Warning! Missing failover agents for the following servers: " -ForeGroundColor Magenta;
foreach ($agent in $noFailover) {
Write-Host $agent.Name -ForeGroundColor Magenta
}
}


