Skip to content
adatum
  • Home
  •  About adatum
  •  Learn Azure Bicep
  •  SCOM Web API
MPAuthoring

SCOM Task to restart Agent – am i complicating…

  • 16/11/201607/01/2025
  • by Martin Ehrnst

As part of planning to migrate a large (3000 + VM) SCOM 2012 R2 environment to 2016 we will need to do a bit of agent configuration. I have created two tasks in Our SCOM console to help us add or delete management Groups from the monitored computers (when moving all agents we probably will use some other orchestration). The problem is that you will have to restart the agents HealthService to save new configuration. Since we execute the task/script through the Health service the task will fail when we attempt to restart. You may experience Your task to work, as in you will have the managment Group added, but you will not see any output.
Over the years People have published a lot of scripts that restarts the agents but unfortunately I have not managed to get them to work properly.

Therfore, i am complicating Things…

I created a script which creates a scheduled task set to run in one minute before it expires and deletes. The Whole thing Works perfectly, but there has to be another way?

<#
NAME: Create-SCOMAgentRestartSchedTask.ps1

.DESCRIPTION
    Creates a scheduled task on the computer which will restart scom health service.
    Script is used as agent task within SCOM as a 'hack' to restart agent through the console.
    
.NOTES
    Martin Ehrnst /Intility AS
    www.adatum.no

    Intial release November 16
    Version 1.0


#>

#Do some logging to the Operations Manager Event Log
$api = new-object -comObject MOM.ScriptAPI
$api.LogScriptEvent("Create-SCOMAgentRestartSchedTask.ps1", 1001, 4, "Creating a scheduled task to restart SCOM health service. Task will expire and delete after it's finished.")

$Service = "HealthService"
$Action = New-ScheduledTaskAction -Execute "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -Argument "Get-Service $Service | restart-service -force"
$run = (Get-Date).AddMinutes(1) # Two minutes from now
$User = 'SYSTEM'
$trigger = New-ScheduledTaskTrigger -Once -At ($run)
$settings = New-ScheduledTaskSettingsSet -DeleteExpiredTaskAfter 00:00:01
Register-ScheduledTask -TaskName "Restart SCOM HealthService" -User $user -InputObject (
  (
    New-ScheduledTask -Action $Action -Trigger $trigger -Settings $settings
) | %{ $_.Triggers[0].EndBoundary = $run.AddMinutes(5).ToString('s') ; $_ })
write-host "created a task to restart $service in one minute"

I know that Microsoft have a recovery action to restart the agent when it is using too much memory and similar, but I haven’t broken Down their code.

taskinfosystemeventlog

Share this:

  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on X (Opens in new window) X
  • Click to share on Reddit (Opens in new window) Reddit
Automation

SCOM 2016 Schedule Maintenance Script

  • 09/11/201607/01/2025
  • by Martin Ehrnst

With Operation Manager 2016 we finally have the ability to Schedule maintenance for Objects.
Doing that in GUI is pretty straitght forward, altough i have seen some blog post on issues With conflicting maintenance schedules. Besides scheduling maintenance mode in the GUI we have gotten some New PS CMDlet’s to manage maintance schedules.

One of them are New-SCOMMaintenanceSchedule.

Based on this i have created the following script wich will take parameters for servername, comments, start and end date before creating a New maintenance Schedule With the supplied server Objects (Linux/Windows)

Feel free to use and please give me feedback on improvements and bugs. Beware that this Version has some limitations and little error handling.

<#

.SYNOPSIS
    System Center Operations Manager 2016 Schedule maintenance mode script.

.DESCRIPTION
    Adding a SCOM 2016 maintencance shedule to specified servers. Works with Linux and Windows servers.

.EXAMPLE
    New-SCOMServerMaintenanceSchedule.ps1 -ServerName SERVER01 -start '01/01/2017 18:30' -end '02/01/2017' -comment "your comment"

    Adds a new maintenance schedule with server SERVER01 starting Jan. 1. 2017 18:30 and ending Jan 2. 2017 00:00

.EXAMPLE
    New-SCOMServerMaintenanceSchedule.ps1 -ServerName SERVER01 -start NOW -end 02/01/2017 -comment "your comment"

    Adds a new maintenance schedule with server SERVER01 starting NOW (adding 30 seconds by default) ending Jan 2. 2017

.EXAMPLE
    New-SCOMServerMaintenanceSchedule.ps1 -ServerName SERVER01 -start NOW -end 02/01/2017 -comment "your comment" -ManagementServer OPSMGR123.DOMAIN

    Adds a new maintenance schedule with server SERVER01 starting NOW (adding 30 seconds by default) ending Jan 2. 2017 connecting to specific management server

.NOTES
    Author: Martin Ehrnst /Intility AS
    Date: November 2016
    Version 0.9 Beta
    This version has a default of non reccuring schedule and has a hard coded reason for maintenance. You can change this by altering the script directly
    Use at own risk

#>

param(
[Parameter(Mandatory=$True)]
[string[]]$ServerName,
[Parameter(Mandatory=$True)]
[string]$ManagementServer = 'localhost',
[Parameter(Mandatory=$True)]
[string]$start,
[Parameter(Mandatory=$True)]
[string]$End,
[Parameter(Mandatory=$True)]
[string]$Comment)

#####FUNCTIONS#######
function Input-Date{
param(
[string]$dateTime)

Do
{    
$Inputdate = $dateTime
if ($Inputdate -eq "NOW"){
    $Inputdate = (Get-Date).AddSeconds(30)}
Else{
$Inputdate = $Inputdate -as [datetime]}

if (!$Inputdate) { "Not A valid date and time"
break}

} while ($Inputdate -isnot [datetime])

$Inputdate
}

Function Get-SCOMServers{
Param(
[STRING[]]$Name
)
#Getting servers from Windows and Linux Computer Class
foreach ($O in $Name){
$Server = Get-ScomClass -id 'e817d034-02e8-294c-3509-01ca25481689','d3344825-d5d1-2656-852e-1053269703c0' | Get-SCOMClassInstance | where {$_.DisplayName -like "$o.*"}
if(!$Server){
Write-Host "Could not find server. Please check input"
break}
else{
$server}
}
}

######END FUNCTIONS####

#Maintenance start time
$InputStart = Input-Date -dateTime $start -ErrorAction Stop

#Maintenance end time
$InputEnd = Input-Date -dateTime $End -ErrorAction Stop

#Checking if module is loaded. if not load and connect to MS
$Module = Get-Module -Name OperationsManager
if (!$Module){
Import-Module OperationsManager}

New-SCOMManagementGroupConnection -ComputerName $ManagementServer

$Object = (Get-SCOMServers -Name $ServerName).ID
[STRING]$SheduleName = $ServerName + ":" + "Created with Script"
$Duration = (New-TimeSpan -Start $InputStart -End $InputEnd).TotalMinutes
$Reason = 'PlannedApplicationMaintenance'
$Frequency = '1' #1 Equals no frequency or 'once'

try{
New-SCOMMaintenanceSchedule -Name $SheduleName -Enabled $true -MonitoringObjects $Object -ActiveStartTime $InputStart -ActiveEndDate $InputEnd -Duration $Duration -ReasonCode $Reason -FreqType 1 -Comments $Comment -ErrorAction Stop
}
catch{
write-host "Something went wrong"
$_.Exception.Message}

 

Share this:

  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on X (Opens in new window) X
  • Click to share on Reddit (Opens in new window) Reddit
MPAuthoring

OpsMgr & External Services PT2

  • 16/10/201607/01/2025
  • by Martin Ehrnst

Continuing the series where i try to season Operations Manager with data from external sources. Where In part one I created a CSV file containing the name and url to yr.no’s open XML API. I created two classes and one relationship and discoveries for these. You can find part one of OpsMgr and External services here

In part two, I will continue with the weather management pack focusing on the Health Model by adding rules and monitors to Our location Objects. Full MP and VSAE Project will be included at the end of this post.

The rules are perf. Collection rules which collects the forecasted and observed temperature from yr.no. The monitor is added to alert when observed temperature is below what is set as alert temperature on each location (Object). For the configurable alert temperature I have added a New property to the weather location class.

  <Property ID="LocationName" Key="true" Type="string" />
  <Property ID="LocationURL" Key="false" Type="string" />
  <Property ID="LocationAlertTemp" Key="false" Type="int" />

Which also means that Our discovery script has changed as well With the following line.

$instance.AddProperty("$MPElement[Name='TheWeatherSolution.WeatherLocation']/LocationAlertTemp$",$LocationAlertTemp)

Temperature (perf.) Collection rules

If you explore the API from yr, you will see that you get forecast for different periods. I noticed that when you Access the forecast XML node the first Object will always be for the period youre in right now which makes it easier to Write the script when we could just use the first Object.

An example of how the response:

from          : 2016-10-16T21:00:00
to            : 2016-10-17T00:00:00
period        : 3
#comment      : { Valid from 2016-10-16T21:00:00 to 2016-10-17T00:00:00 ,  Valid at 2016-10-16T21:00:00 }
symbol        : symbol
precipitation : precipitation
windDirection : windDirection
windSpeed     : windSpeed
temperature   : temperature
pressure      : pressure

As i mentioned in part one of this blog series I have gotten tips from Trond Hindenes for the MP it self and Kevin Holman for the VSAE fragments used in PowerShell  rules and monitors. For this MP I created two collection rules for temperatures. Both observed and forcasted temp. (don’t ask, i know this data is available at www.yr.no).

The rules use the similar PS script, and after adding the OpsMgr Magic around it this is how it ended up.

param([string]$LocationURL, [string]$LocationName)
                  
                  # Add the SCOM API and Propertybag for output
                  $api = New-Object -comObject "MOM.ScriptAPI"
                  $bag = $api.CreatePropertyBag()
                  $ScriptName = "GetTemperatureObservation.ps1"

                  # Logging
                  $api.LogScriptEvent($ScriptName,1234,0,"$ScriptName script is starting")
                  
                  [xml]$yr = Invoke-WebRequest -Uri $LocationURL
                  #Getting the latest observation
                  $Observation = $yr.SelectNodes("//observations").weatherstation | Select-Object -First 1
                  [int]$ObservationTemp = $Observation.temperature.value

                  #Adding the value from the script into the propertybag
                  $bag.AddValue("ObservationTemp",$ObservationTemp)
                  #Logging
                  $api.LogScriptEvent($ScriptName,1235,0,"$ScriptName script is complete")

                  #Outputting the bag
                  $bag
                  ]]>

As you see, the script takes location URL as a parameter which needs to be added to the fragment by Kevin if you use it.

                <Parameters>
                  <Parameter>
                    <Name>LocationURL</Name>
                    <Value>$Target/Property[Type="TheWeatherSolution.WeatherLocation"]/LocationURL$</Value>
                  </Parameter>
                </Parameters>

After a few days you hopefully have a graph like this With observed and forecasted temperature

Observed temp vs forecast

 

Monitor

I don’t like having unmonitored Objects in SCOM so we needed to add a monitor to these locations, dont know why i need to be alerted by SCOM when it’s cold out, but now i can. Again, based on Kevins fragment created a two state PowerShell monitor which grabs the LocationAlertTemp parameter from each location and compares it to the observed temperature by yr.no. Anything less than Our Alert Temp will change the state and rase an alert. As you can imagine, no drastic changes to the PowerShell script we used in the rule, but some changes to the SCOM bits. This scipt/monitor takes two parameters that need to be added. First the location URL and the LocationAlertTemp.

                  param([string]$LocationURL,[string]$LocationName,[int]$LocationAlertTemp)
                  # Load MomScript API and PropertyBag function
                  $api = new-object -comObject 'MOM.ScriptAPI'
                  $bag = $api.CreatePropertyBag()

                  #Log script event that we are starting task
                  $api.LogScriptEvent("TooCold.ps1",6789,0, "Starting toocold.ps1 script")

                  [xml]$yr = Invoke-WebRequest -Uri $LocationURL
                  #Getting the latest observation
                  $Observations = $yr.SelectNodes("//observations").weatherstation | select-object -First 1
                  [int]$Obstemperature = $Observations.temperature.value
                  $temperatureUnit = $Observations.temperature.unit
                  if ($Obstemperature -lt $LocationAlertTemp){
                  $bag.AddValue("Result","BadCondition")
                  #$bag.AddValue("Description", "It is freaking cold observed temperature" + "$obstemperature" + "$temperatureUnit")
                  }
                  else{
                  $bag.addvalue("Result","GoodCondition")
                  }
                  $bag

Below the script body I have added,

 <Parameters>
                  <Parameter>
                    <Name>LocationURL</Name>
                    <Value>$Target/Property[Type="TheWeatherSolution.WeatherLocation"]/LocationURL$</Value>
                  </Parameter>
                  <Parameter>
                    <Name>LocationAlertTemp</Name>
                    <Value>$Target/Property[Type="TheWeatherSolution.WeatherLocation"]/LocationAlertTemp$</Value>
                  </Parameter>
                </Parameters>

If everything is working correctly you should have all Your locations monitored, and depending on observed temperature and the alert temp parameter it’s either healthy or in warning state

locationmonitoredalerttemp

locationmonitoredalerttempwarningstate

I have made my MP and VSAE Project available for download here – please note that i do not take any responsibility for this MP and it’s not something i would sell or add to Our Production environment before i have made more testing and cleaned all displaynames, alert text etc. Key file are also excluded.

 

Share this:

  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on X (Opens in new window) X
  • Click to share on Reddit (Opens in new window) Reddit

Posts pagination

1 … 6 7 8 9 10 … 12

Popular blog posts

  • SCOM Alerts to Microsoft Teams and Mattermost
  • How to move Azure blobs up the path
  • Creating Azure AD Application using Powershell
  • SCOM and OMS: The agents
  • Azure Application registrations, Enterprise Apps, and managed identities

Categories

Automation Azure Azure Active Directory Azure Bicep Azure DevOps Azure Functions Azure Lighthouse Azure Logic Apps Azure Monitor Azure Policy Community Conferences CSP Monitoring DevOps GitHub Guest blogs Infrastructure As Code Kubernetes Microsoft CSP MPAuthoring OMS Operations Manager Podcast Powershell Uncategorised Windows Admin Center Windows Server

Follow Martin Ehrnst

  • X
  • LinkedIn

RSS feed RSS - Posts

RSS feed RSS - Comments

Microsoft Azure MVP

Martin Ehrnst Microsoft Azure MVP
Adatum.no use cookies to ensure that we give you the best experience on our website. If you continue to use this site we will assume that you are happy with it. Cookie Policy
Theme by Colorlib Powered by WordPress