Tag: SCOM

Autogrowth on SCOM Operational DB?

This is another of the hot topics I find with differences in opinion among the experts.

The other one we discussed was Windows Agents and Failover – Debunking the Myth!

Should you enable autogrowth on SCOM Operational Database?

I did some some research online and consulted some of the best SCOM experts I know and put together an article that explains why you would NOT want to autogrow your SCOM DB.

The short version is:

DO NOT autogrow your SCOM Operational DB, unless you absolutely need to. Autogrowing DB comes with its own set of disadvantages and might affect the performance of the DB.

So, choose the size of your DB very carefully while you are designing your Management Group!

The longer and more detailed version is here:

Should You Enable Autogrowth on SCOM Operations Database?

Cheers!

PS. Special thanks to Stoyan Chalakov and “SCOM Bob” Cornelissen for reviewing the article and suggesting edits! 🙂

Cyril Azoulay – An expert behind the mask! – [Interview]

I am a regular visitor/contributor to the SCOM Technet Forums and regularly meet many experts from around the globe there. Fortunately for me I eventually became friends/acquaintances with many of them. One of them is Cyril! If you have posted a question in the forums, you may very well have received the solution from a “CyrAz”, that’s him! 😉

I was able to convince Cyril to feature in one of our community experts interview series, and from his answers you can easily guess the knowledge and experience Cyril possesses! Enough chatter from me, I will let Cyril do the talking now:

Q: Hi Cyril! Thanks for agreeing to this. I see you very often on the SCOM Technet forums, and from what I can tell, you really know what you’re talking about! Can you please tell us a little about yourself and your professional journey so far?
A: Thanks for having me 🙂
I’m a system consultant and I almost exclusively work on Microsoft technologies. I work on quite a lot of them (Active Directory, PKI, Exchange, Direct Access, HyperV/Storage Space direct and even Azure Stack these days) but my current field of expertise is System Center, and more specifically SCOM and Orchestrator.
I started working on these two technologies around 6 years ago when my boss wanted me to specialize on something and asked me if I was interested in System Center. I said yes, because I was interested in the whole “everything is integrated together” aspect of the suite, being able to manage every aspect of the datacenter etc. I quickly realized this ideal world only existed in Microsoft’s presentations and that most of these products were actually not designed to run together and were even pretty clunky by themselves, but I still really liked what they allowed to do!
So I went from customer to customer, doing things that were more and more complicated, from daily operator tasks to architecture design and complex MP development; until now where I believe I can call myself an “expert”, even though I’m still learning things every day. I’ve only started using Visual Studio for MP developments a little bit over a year ago!
And I can say that blogs and Technet forums helped me a lot during this journey, it’s really nice to have such a knowledgeable and sharing  community!
Q: What is your opinion about Microsoft’s strategy of 2 different models for System Center products? What do you prefer, the LTSC or SAC model?

A: I’m glad Microsoft is still developing SCOM, and I can’t wait to get the most recent improvements so I definitely prefer SAC. But to be honest, I’m a bit disappointed by what was added in 1801 and 1807… I’m convinced SCOM has great foundations, the Management Pack system is incredibly powerful and flexible, but there is so much that could be done to improve the final product!

Now from my customers point of view, it really depends on how much they can afford in maintaining their environments… if they have a dedicated team that has enough knowledge, they can go for SAC. If they rely exclusively on me coming from time to time to check that everything is running properly, that may not be the best idea.

Q: How do you feel about the whole SCOM vs. OMS argument? Will OMS be a viable “replacement” for SCOM?
A: I must say I really like Log Analytics and what it is becoming, especially since Kusto query language was released. I was already a huge fan of competing products such as Splunk, and that pretty much sums up what I think about the SCOM vs Log Analytics argument : it has no reason to exist since they are not competitors!
Log Analytics is becoming a great tool for… well, ingesting, archiving and analyzing logs of all kind.
But for now it is a terrible replacement for SCOM, regardless of what Microsoft is trying to make us believe! It doesn’t provide any solution to replace the huge list of existing management packs and everything they include, it doesn’t provide an easy solution to develop your own monitoring, it has terrible SLA regarding data ingestion latency…
However, I can very well see how they can work together to provide more information on your environment, and how Log Analytics can become a good monitoring tool someday. But definitely not today, and probably not tomorrow neither.
Q: Given a chance, what would you like to ask or advise to Microsoft?
A: Don’t abandon great tools that can still provide tremendous service to many people just because you believe they are not the future! And maybe try to make them a little bit more usable by non experts…
Q: Lastly, the traditional question! Star Wars or Star Trek?
A: A 4-cheese pizza and a cold beer, thanks 🙂
Awesome! Thanks again for sharing your expertise with us Cyril, and I hope you will continue to help the folks on the forums! 😀
You can also get in touch with him on LinkedIn:
You can also visit his blog (in French) here:
Cheers!
Sam

Authoring PowerShell SCOM Console Tasks in XML – Ruben Zimmermann

Summary:

This post describes how to create PowerShell SCOM Console Tasks in XML along three examples.

Console-ListTopNProcesses

Introduction:

Console Tasks are executed on the SCOM Management Server. Three examples show how to create them using Visual Studio.

  • Task 1: Displaying a Management Server’s Last-Boot-Time [DisplayLastBootTime]
    • Executes a PowerShell script which displays the result in a MessageBox
  • Task 2: Show all new alerts related to selected Computer [ShowNewAlerts]
    • Passes the Computer principal name property (aka FQDN) to the script which then uses a GridView to display the alerts
  • Task 3: Listing the top N processes running on a Management Server [ListTopNProcesses]
    • An InputBox let the user specify the number (N) of top process on the Management server which is retrieved by script and shown via GridView

Requirements:

This blog assumes that you have created already a management pack before. If not, or if you feel difficulties please visit the section ‘Reading’ and go through the links.

The used software is Visual Studio 2017 (2013 and 2015 should work as well) plus the Visual Studio Authoring Extension. Additionally, the ‘PowerShell Tools for Visual Studio 2017’ are installed.

The Community Edition of Visual Studio technically works. – Please check the license terms in advance. – If you are working for a ‘normal company’ you will most likely require Visual Studio Professional.

Realization:

Initial steps in Visual Studio

à Create a new project based on Management Pack / Operations Manager 2012 R2 Management Pack template.

à Name it SCOM.Custom.ConsoleTasks

à Create a folder named Health Model and a sub folder of it named Tasks

à Add an Empty Management Pack Fragment to the root and name it Project.mpx.

Project File Project.mpx Content:

<ManagementPackFragment SchemaVersion="2.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <LanguagePacks>

    <LanguagePack ID="ENU" IsDefault="true">

      <DisplayStrings>

        <DisplayString ElementID="SCOM.Custom.ConsoleTasks">

          <Name>SCOM Custom ConsoleTasks</Name>

        </DisplayString>

      </DisplayStrings>

    </LanguagePack>

  </LanguagePacks>

</ManagementPackFragment>

Your screen should look like this now:

VSAE-ProjectFile

VSAE-ProjectFile.gif

Creating DisplayLastBootTime task

Within the Tasks folder create a class file named ConsoleTasks.mpx and remove all XML insight the file.

ConsoleTasks.mpx firstly only contains the code for the task DisplayLastBootTime and will be successively extended with the other two tasks.

 

Content of ConsoleTasks.mpx :

<ManagementPackFragment SchemaVersion="2.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Categories>

    <Category ID ="SCOM.Custom.ConsoleTasks.DisplayLastBootTime.ConsoleTaskCategory"  Target="SCOM.Custom.ConsoleTasks.DisplayLastBootTime.ConsoleTask" Value ="System!System.Internal.ManagementPack.ConsoleTasks.MonitoringObject"/>

  </Categories>
  <Presentation>

    <ConsoleTasks>      

      <ConsoleTask ID="SCOM.Custom.ConsoleTasks.DisplayLastBootTime.ConsoleTask" Accessibility="Public" Enabled="true" Target="SC!Microsoft.SystemCenter.RootManagementServer" RequireOutput="false">        <Assembly>SCOM.Custom.ConsoleTasks.DisplayLastBootTime.Assembly</Assembly>

        <Handler>ShellHandler</Handler>

        <Parameters>

          <Argument Name="WorkingDirectory" />

          <Argument Name="Application">powershell.exe</Argument>

          <Argument><![CDATA[-noprofile -Command "& { $IncludeFileContent/Health Model/Tasks/DisplayManagementServerLastBootTime.ps1$ }"]]></Argument>          

        </Parameters>

      </ConsoleTask>    

    </ConsoleTasks>

  </Presentation>
  <LanguagePacks>

    <LanguagePack ID="ENU" IsDefault="true">      

      <DisplayStrings>        

        <DisplayString ElementID="SCOM.Custom.ConsoleTasks.DisplayLastBootTime.ConsoleTask">

          <Name>Custom Console-Tasks: Display LastBootTime</Name>

          <Description></Description>

        </DisplayString>        

      </DisplayStrings>

    </LanguagePack>

  </LanguagePacks>
  <Resources>

    <Assembly ID ="SCOM.Custom.ConsoleTasks.DisplayLastBootTime.Assembly" Accessibility="Public" FileName ="SCOM.Custom.ConsoleTasks.DisplayLastBootTime.Assembly.File" HasNullStream ="true" QualifiedName ="SCOM.Custom.ConsoleTasks.DisplayLastBootTime.Assembly" />

  </Resources>

</ManagementPackFragment>

 

Key points explanation for ConsoleTasks.mpx

Categories

  • Category Value specifies that this element is a console task

Presentation

ConsoleTask Target defines against what this task is launched. In this case it’s the Management Server. You can only see the task if you click on a View that is targeting the corresponding class. E.g.:

Console-ManagementServer-Tasks

Console-ManagementServer-Tasks.gif
  • Parameters, Argument Name “Application” sets PowerShell.exe to be called for execution
  • Parameters, Argument <![CDATA … defines the file within this Visual Studio project that contains the PowerShell code to be processed when the task is launched ( not handled yet ).

LanguagePack

  • DisplayString maps the Console Task ID to a text that is more user friendly. This will be shown in the SCOM console

Within the Tasks folder create a PowerShell file named DisplayManagementServerLastBootTime.ps1

Content of  DisplayManagementServerLastBootTime.ps1 :
$regPat         = '[0-9]{8}'

$bootInfo       = wmic os get lastbootuptime

$bootDateNumber = Select-String -InputObject $bootInfo -Pattern $regPat | Select-Object -ExpandProperty Matches | Select-Object -ExpandProperty Value

$bootDate       = ([DateTime]::ParseExact($bootDateNumber,'yyyyMMdd',[Globalization.CultureInfo]::InvariantCulture))

$lastBootTime   = $bootDate | Get-Date -Format 'yyyy-MM-dd'




$null = [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')

$null = [Microsoft.VisualBasic.Interaction]::MsgBox($lastBootTime,0,"""Last Boot time of $($env:COMPUTERNAME)""")

 

Deploy this Management Pack to the SCOM Server and test it. The following screenshot shows the expected result:
Console-DisplayLastBootTime

Console-DisplayLastBootTime.gif

Creating ShowNewAlerts task

Keep the content of ConsoleTasks.mpx unchanged. Add the new code into the proper places.

Additional Content for ConsoleTasks.mpx for ShowNewAlerts:

<Category ID ="SCOM.Custom.ConsoleTasks.ShowNewAlerts.ConsoleTaskCategory"  Target="SCOM.Custom.ConsoleTasks.ShowNewAlerts.ConsoleTask" Value ="System!System.Internal.ManagementPack.ConsoleTasks.MonitoringObject"/><ConsoleTask ID="SCOM.Custom.ConsoleTasks.ShowNewAlerts.ConsoleTask" Accessibility="Public" Enabled="true" Target="Windows!Microsoft.Windows.Computer" RequireOutput="false">

        <Assembly>SCOM.Custom.ConsoleTasks.ShowNewAlerts.Assembly</Assembly>

        <Handler>ShellHandler</Handler>

        <Parameters>

          <Argument Name="WorkingDirectory" />

          <Argument Name="Application">powershell.exe</Argument>

          <Argument><![CDATA[-noprofile -noexit -Command "& { $IncludeFileContent/Health Model/Tasks/ShowNewAlertsForThisComputer.ps1$ }"]]></Argument>          <Argument>"$Target/Property[Type='Windows!Microsoft.Windows.Computer']/PrincipalName$"</Argument>

        </Parameters>

      </ConsoleTask>
<DisplayString ElementID="SCOM.Custom.ConsoleTasks.ShowNewAlerts.ConsoleTask">

          <Name>Custom Console-Tasks: Display ShowNewAlertsForThisComputer</Name>

          <Description></Description>

        </DisplayString>

<Assembly ID ="SCOM.Custom.ConsoleTasks.ShowNewAlerts.Assembly" Accessibility="Public" FileName ="SCOM.Custom.ConsoleTasks.ShowNewAlerts.Assembly.File" HasNullStream ="true" QualifiedName ="SCOM.Custom.ConsoleTasks.ShowNewAlerts.Assembly" />

Key points explanation for ConsoleTasks.mpx for ShowNewAlerts

Categories

  • Category Value specifies that this element is a console task

Presentation

  • ConsoleTask Target defines against what this task is launched. In this case it’s the Windows Computer. – This task is visible when in a View that shows Computer objects.
  • Parameters, Argument Name “Application” sets PowerShell.exe to be called for execution
  • Parameters, Argument <![CDATA … defines the file within this Visual Studio project that contains the PowerShell code to be processed when the task is launched ( not handled yet ).
  • Parameters, Argument “$Target/Property […]/PrincipalName$” gets the FQDN (principal name attribute) of the selected computer and makes it available for retrieving it in the script.

 

Content of ShowNewAlertsForThisComputer.ps1 :
param($ComputerName)

$allNewAlerts = Get-SCOMAlert | Select-Object -Property Name, Description, MonitoringObjectDisplayName, IsMonitorAlert, ResolutionState, Severity, PrincipalName, TimeRaised  | Where-Object {$_.PrincipalName -eq $ComputerName -and $_.ResolutionState -eq '0'}




if ($allNewAlerts) {

       $allNewAlerts | Out-GridView

} else {

       Write-Host 'No new alerts available for the computer: ' + $ComputerName

}

 

Deploy this Management Pack to the SCOM Server and test it. The following screenshot shows the expected result:

Console-ShowNewAlerts

Console-ShowNewAlerts

Creating ListTopNProcesses task

Keep the content of ConsoleTasks.mpx unchanged. Add the new code into the proper places.

Additional Content for ConsoleTasks.mpx for ListTopNProcesses:

<Category ID ="SCOM.Custom.ConsoleTasks.ListTopNProcesses.ConsoleTaskCategory"  Target="SCOM.Custom.ConsoleTasks.ListTopNProcesses.ConsoleTask" Value ="System!System.Internal.ManagementPack.ConsoleTasks.MonitoringObject"/>  <ConsoleTask ID="SCOM.Custom.ConsoleTasks.ListTopNProcesses.ConsoleTask" Accessibility="Public" Enabled="true" Target="SC!Microsoft.SystemCenter.RootManagementServer" RequireOutput="false">

        <Assembly>SCOM.Custom.ConsoleTasks.ListTopNProcesses.Assembly</Assembly>

        <Handler>ShellHandler</Handler>

        <Parameters>

          <Argument Name="WorkingDirectory" />

          <Argument Name="Application">powershell.exe</Argument>

          <Argument><![CDATA[-noprofile -noexit -Command "& { $IncludeFileContent/Health Model/Tasks/ListTopNProcesses.ps1$ }"]]></Argument>

        </Parameters>

      </ConsoleTask>

<DisplayString ElementID="SCOM.Custom.ConsoleTasks.ListTopNProcesses.ConsoleTask">

          <Name>Custom Console-Tasks: Display ListTopNProcesses</Name>

          <Description></Description>

        </DisplayString>     

<Assembly ID ="SCOM.Custom.ConsoleTasks.ListTopNProcesses.Assembly" Accessibility="Public" FileName ="SCOM.Custom.ConsoleTasks.ListTopNProcesses.Assembly.File" HasNullStream ="true" QualifiedName ="SCOM.Custom.ConsoleTasks.ListTopNProcesses.Assembly" />

Key points explanation for ConsoleTasks.mpx for ListTopNProcesses

Categories

  • Category Value specifies that this element is a console task

Presentation

  • ConsoleTask Target defines against what this task is launched. In this case it’s the Windows Computer. – This task is visible when in a View that shows Computer objects.
  • Parameters, Argument Name “Application” sets PowerShell.exe to be called for execution
  • Parameters, Argument <![CDATA … defines the file within this Visual Studio project that contains the PowerShell code to be processed when the task is launched ( not handled yet ).

 

Content of ListTopNProcesses.ps1 :
$null          = [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')

$receivedValue = [Microsoft.VisualBasic.Interaction]::InputBox("""Enter the number of top processes to be shown""", """List top processes:""", "10")

Get-Process | Sort-Object -Property CPU -Descending | Select-Object -First $receivedValue  | Out-GridView

 

Deploy this Management Pack to the SCOM Server and test it. The following screenshot shows the expected result:

Console-ListTopNProcesses

Console-ListTopNProcesses.gif

Reading:

If you are new to management pack authoring I suggest the free training material from Brian Wren. – It was made for SCOM 2012 R2 but is still valid until today (current SCOM 1807 in year 2018).

On Microsoft’s Virtual Academy: System Center 2012 R2 Operations Manager Management Pack

On Microsoft’s Wiki: System Center Management Pack Authoring Guide

Closing:

If you have questions, comments or feedback feel free to feedback in our SCOM – Gitter – Community on: https://gitter.im/SCOM-Community/Lobby

The Visual Studio solution file is downloadable here:

SCOM Console Powershell Task

Thanks!

Ruben Zimmermann

 

Know more about Ruben and get in touch with him here:

Ruben Zimmermann (A fantastic person who has a lot of great ideas) [Interview]

SCOM User Session Duration – Powershell

A few days ago, I needed to find out how many users are connecting to SCOM daily/weekly and how long was each user connected. Out-of-the-box SCOM does not provide you a way of doing this. So I started looking around for some hints. I came across this article, which looked pretty convincing.

https://blogs.technet.microsoft.com/dirkbri/2014/10/15/an-approach-of-collecting-and-analyzing-scom-2012-sdk-connections/

This looked all good, except I wanted to do it with Powershell.

Whenever any “client” connects/disconnects to/from the console an event is written in the Operations Manager event log. In each event there is event data which gives you information on the following points:

  • EventID
  • ManagementServer Name
  • Username
  • SessionID
  • UUID – extracted from SessionID
  • ID – extracted from SessionID
  • TimeCreated
  • SessionDuration -calculated Time between log on and log off Event
  • SessionCount – calculated cumulated counter of all current sessions

So, I started working on a script that’d meet my requirements. To be honest, I am still a Powershell student, so I got stuck halfway. So I decided to “get-help” (Powershell pun, get it? ;)) from my friend and guide Stoyan Chalakov. I explained to him my idea and asked whether he would help me script it. Sure enough, I wasn’t disappointed. He liked the idea as well, and came up with a nice script that outputs the data the way we imagined. I’ve linked the link to his script on Technet at the end.

Some important remarks which apply to both methods (the one described in the blog and the script):

“Yes, there are design flaws in this approach:

  1. If you create daily files, you will have an unknown amount of already open sessions at the beginning of the day and a certain amount of not yet closed sessions at the end. So your SessionCount will be lower than the cumulated values from the “Client Connections” performance counters of all Management Servers.
    But when you analyse e.g. weekly data instead of daily, you should get very good results.
  2. The tricky part is , the exact same event is written when a Powershell SDK connection is made. You cannot distinguish between PowerShell SDK connections and Operations console connections. Unfortunately this is by design and I am not aware of a way to mitigate this problem.”

The script parses all the events, which are being logged in regards to the particular user and gathers information in regards to:

  • Open session, where the session has not been closed (presence of the Login event, absence of Logout event)
  • Closed session and their duration (presence of the Login event and Logout event)
  • Closed session without and Login session event, indicating that the Login session event has been overridden and cannot be found.
  • The script should be run directly on a management server. If you need you can enable PSremoting and run this on a multiple management server.
  • The script is in its first version, where you need to enter a domain and username. The second version (currently being worked on) will include a full report on all user session and their duration, without the need of specifying a particular user name.

Sample output of the script:

user session

You can download the script here:

Stoyan has commented thoroughly throughout the script, so there would no issues to understand the way it works.

SCOM User Session Script

Thanks a ton Stoyan!

Cheers!

 

 

 

 

 

 

 

 

 

Management Server Frequently Greying Out?

I have seen this issue happening a number of times now. The cause of this can be a few things going wrong, but as part of the troubleshooting I’ve noticed a way that works almost every time, if it applies.

Problem :

All of the sudden, the management server(s) greys out. You check the services, all the services are running. Still for good measure, you restart the services – but no use. You then also try flushing the health state folder cache on the affected MS. And sure, the MS becomes healthy again.

But again after some time you notice that the MS has greyed out. You repeat the process of flushing the cache, it becomes green, and after some time becomes grey again. This cycle continues.

In the event log you may see several events, but not sure where to start. Now these can be any events that may actually be the cause of the problem, or maybe the consequence of it. That’s why you need to read carefully through each of them and find out what event is exactly the problem and which ones are the consequences.

The event we’re discussing here is one particular event 4502. Now this event ID is logged for a number of different reasons and with different descriptions. The one we’re looking for goes something like this (sample only, your descriptions would change acoordingly):

A module of type "Microsoft.EnterpriseManagement.Mom.Modules.SubscriptionDataSource.InstanceSpaceSubscriptionDataSource" reported an exception System.ArgumentNullException: Value cannot be null.

Parameter name: value

   at System.Collections.CollectionBase.OnValidate(Object value)

   at System.Collections.CollectionBase.System.Collections.IList.Add(Object value)

   at Microsoft.EnterpriseManagement.Mom.Modules.SubscriptionDataSource.HttpRESTClient.PostDataAsync(Byte[] data, Object context)

   at Microsoft.EnterpriseManagement.Mom.Modules.SubscriptionDataSource.SubscriptionDataSource`2.WriteToCloud(List`1 items, DateTime firstTryDateTime)

   at Microsoft.EnterpriseManagement.Mom.Modules.SubscriptionDataSource.SubscriptionDataSource`2.PostAsync(List`1 items, DateTime firstTryDateTime) which was running as part of rule "Microsoft.SystemCenter.CollectInstanceSpace" running for instance "All Management Servers Resource Pool" with id:"{4932D8F0-C8E2-2F4B-288E-3ED98A340B9F}" in management group "MG".

These events may come in conjuncture with several others, but I like to fix this one first, as it solves the problem most of the times.

Analysis : 

The event might seem cryptic at first, especially if you aren’t used to troubleshooting, but it provides a valuable piece of information. Note the last line of the description. It says,

which was running as part of rule "Microsoft.SystemCenter.CollectInstanceSpace" running for instance "All Management Servers Resource Pool" with id:"{4932D8F0-C8E2-2F4B-288E-3ED98A340B9F}" in management group "MG".

Here, you get some interesting information, as to which exact rule/monitor is failing, and running for what instance.

Ok, so we have the rule ID and the target. The rule is “Microsoft.SystemCenter.CollectInstanceSpace”. With a quick glance at the System Center Wiki tells me that the display name of this rule is “Send Instancespace to the Cloud” and it is a “System rule that sends instancespace up to the cloud.”

So what happens here is, the rule runs at it’s scheduled interval, and fails. This causes the MS where it’s running on to go grey. When you re-initialize the cache on the MS, everything is reset, and the MS becomes green. Then again, the rule runs at its interval and fails again, the MS goes grey again, and the cycle goes on.

Resolution :

Ok, so now we have some solid information to work on. Grab the rule name, find it in the Rules in your console. Once you do, take a look at the properties. You’d know what is it exactly doing, any overrides, what MP is it coming from, etc.

Now that you’ve found the rule that is the root of the problem, disable it. Now, go back and flush the cache on the MS again. As it is downloading the configuration again, keep an eye on the event log for any errors.

If the MS becomes and remains green, we’re done! If if goes back to grey, follow the process all over again, until you notice there are no more failing workflows from rules/monitors that are causing the MS to go grey.

One step further, if you notice that all these rules/monitors are from the same MP, chances are that MP has been corrupted and you may want to remove or update the MP.

Note that although this might solve your problem, it may not be the only one causing the issue. E.g., bad performance of your databases can also result in this problem. So if you find the problem is still persisting, look for other relevant events that might give you a hint. 🙂

You can refer to these threads from the Technet forums for further reading:

SCOM Health Service greyed out on Management Server

Management server getting greyed out again and again

Hope this helps someone out there with similar issues.

Cheers!

 

Guest Blog – Authoring a PowerShell Agent Task in XML – By Ruben Zimmermann

It is my absolute pleasure to announce this guest blog today. My good friend Ruben has come up with a fantastic community MP that is going to make all of our lives a lot easier 🙂

I will let him talk about it himself. All yours, Ruben! –


Authoring a PowerShell Agent Task in XML

Summary:

This post describes the code behind a PowerShell Agent Task. With the help of a real-life case ‘Create Log Deletion Job’ the lines in XML and PowerShell are commented.

Introduction:

Create Log Deletion Job is a SCOM – Agent Task which offers the creation of a scheduled task that deletes log files older than N days on the monitored computer. It works on SCOM 2012 R2 and later.

Requirements:

This blog assumes that you have created already management packs before. If not, or if you feel difficulties please visit the section ‘Reading’ and go through the links.

The used software is Visual Studio 2017 (2013 and 2015 work as well) plus the Visual Studio Authoring Extension. Additionally the ‘PowerShell Tools for Visual Studio 2017’ are installed.

The Community Edition of Visual Studio technically works. – Please check the license terms in advance. – If you are working for a ‘normal company’ you will most likely require Visual Studio Professional.

Realization:

The agent task mainly consists of two components.

  1. A PowerShell Script which creates a Scheduled Task and writes another script on the target machine with the parameters specified in the SCOM console.
  2. A custom module that contains a custom write action based on PowerShell Write Action and a task targeting Windows Computer leveraging the write action.
  3. Visual Studio Authoring Extension (VSAE), a free Plugin for Visual Studio is used to bind the XML and PowerShell together and produce a Management Pack.
    The Management Pack itself can be downloaded as Visual Studio solution or as compiled version directly from GitHub.

https://github.com/Juanito99/Windows.Computer.AgentTasks.CreateLogDeletionJob

Steps to do in Visual Studio:

  • Create a new project based on Management Pack / Operations Manager R2 Management Pack.- Name it ‘Windows.Computer.AgentTasks.CreateLogDeletionjob’
  • Create a folder named ‘Health Model’ and a sub folder of it named ‘Tasks’.
  • Add an Empty Management Pack Fragment to the root and name it Project.mpx.

Project File ‘project.mpx’ Content:

<ManagementPackFragment SchemaVersion="2.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <LanguagePacks>




    <LanguagePack ID="ENU" IsDefault="true">

      <DisplayStrings>

        <DisplayString ElementID="Windows.Computer.AgentTasks.CreateLogDeletionJob">

          <Name>Windows Computer AgentTasks CreateLogDeletionJob</Name>

          <Description>Creates a scheduled task on the managed computer which automatically deletes old logs.</Description>

        </DisplayString>

      </DisplayStrings>

    </LanguagePack>

  </LanguagePacks>




</ManagementPackFragment>

The Powershell Script:

Create a file named CreateLogDeletionJob.ps1 in the ‘Tasks'<h3> sub folder and copy the following content inside it.

param($LogFileDirectory,$LogFileType,$DaysToKeepLogs,$ScheduledTasksFolder)

$api = New-Object -ComObject 'MOM.ScriptAPI'

$api.LogScriptEvent('CreateLogDeletionJob.ps1',4000,4,"Script runs. Parameters: LogFileDirectory $($LogFileDirectory), LogFileType: $($LogFileType) DaysToKeepLogs $($DaysToKeepLogs) and scheduled task folder $($scheduledTasksFolder)")           

Write-Verbose -Message "CreateLogDeletionJob.ps1 with these parameters: LogFileDirectory $($LogFileDirectory), LogFileType: $($LogFileType) DaysToKeepLogs $($DaysToKeepLogs) and scheduled task folder $($scheduledTasksFolder)"

$ComputerName          = $env:COMPUTERNAME

$LogFileDirectoryClean = $LogFileDirectory      -Replace('\\','-')

$LogFileDirectoryClean = $LogFileDirectoryClean -Replace(':','')

$scheduledTasksFolder  = $scheduledTasksFolder -replace([char]34,'')

$scheduledTasksFolder  = $scheduledTasksFolder -replace("`"",'')

$taskName              = "Auto-Log-Dir-Cleaner_for_$($LogFileDirectoryClean)_on_$($ComputerName)"

$taskName              = $taskName -replace '\s',''

$scriptFileName        = $taskName + '.ps1'

$scriptPath            = Join-Path -Path $scheduledTasksFolder -ChildPath $scriptFileName

if ($DaysToKeepLogs -notMatch '\d' -or $DaysToKeepLogs -gt 0) {

                $daysToKeepLogs = 7

                $msg = 'Script warning. DayToKeepLogs not defined or not matching a number. Defaulting to 7 Days.'

                $api.LogScriptEvent('CreateLogDeletionJob.ps1',4000,2,$msg)

}

if ($scheduledTasksFolder -eq $null) {

                $scheduledTasksFolder = 'C:\ScheduledTasks'

} else {

                $msg = 'Script warning. ScheduledTasksFolder not defined. Defaulting to C:\ScheduledTasks'

                $api.LogScriptEvent('CreateLogDeletionJob.ps1',4000,2,$msg)

                Write-Warning -Message $msg

}

if ($LogFileDirectory -match 'TheLogFileDirectory') {

                $msg =  'CreateLogDeletionJobs.ps1 - Script Error. LogFileDirectory not defined. Script ends.'

                $api.LogScriptEvent('CreateLogDeletionJob.ps1',4000,1,$msg)

                Write-Warning -Message $msg

                Exit

}

if ($LogFileType -match '\?\?\?') {    

                $msg = 'Script Error. LogFileType not defined. Script ends.'

                $api.LogScriptEvent('CreateLogDeletionJob.ps1',4000,1,$msg)

                Write-Warning -Message $msg

                Exit

}

Function Write-LogDirCleanScript {




                param(

                                [string]$scheduledTasksFolder,

                                [string]$LogFileDirectory,                 

                                [int]$DaysToKeepLogs,                      

                                [string]$LogFileType,

                                [string]$scriptPath

                )

               

                if (Test-Path -Path $scheduledTasksFolder) {

                                $foo = 'folder exists, no action requried'

                } else {

                                & mkdir $scheduledTasksFolder

                }

               

                if (Test-Path -Path $LogFileDirectory) {

                                $foo = 'folder exists, no action requried'

                } else {

                                $msg = "Script function (Write-LogDirCleanScript, scriptPath: $($scriptPath)) failed. LogFileDirectory not found $($LogFileDirectory)"

                                Write-Warning -Message $msg

                                $api.LogScriptEvent('CreateLogDeletionJob.ps1',4001,1,$msg)                

                                Exit

                }




                if ($LogFileType -notMatch '\*\.[a-zA-Z0-9]{3,}') {

                                $LogFileType = '*.' + $LogFileType

                                if ($LogFileType -notMatch '\*\.[a-zA-Z0-9]{3,}') {

                                                $msg = "Script function (Write-LogDirCleanScript, scriptPath: $($scriptPath)) failed. LogFileType: $($LogFileType) seems to be not correct."

                                                Write-Warning -Message $msg

                                                $api.LogScriptEvent('CreateLogDeletionJob.ps1',4001,1,$msg)                

                                                Exit

                                }

                }




$fileContent = @"

Get-ChildItem -Path `"${LogFileDirectory}`" -Include ${LogFileType} -ErrorAction SilentlyContinue | Where-Object { ((Get-Date) - `$_.LastWriteTime).days -gt ${DaysToKeepLogs} } | Remove-Item -Force

"@         

               

                $fileContent | Set-Content -Path $scriptPath -Force

               

                if ($error) {

                                $msg = "Script function (Write-LogDirCleanScript, scriptPath: $($scriptPath)) failed. $($error)"                       

                                $api.LogScriptEvent('CreateLogDeletionJob.ps1',4001,1,$msg)

                                Write-Warning -Message $msg

                } else {

                                $msg = "Script: $($scriptPath) successfully created"   

                                Write-Verbose -Message $msg

                }




} #End Function Write-LogDirCleanScript







Function Invoke-ScheduledTaskCreation {




                param(

                                [string]$ComputerName,                   

                                [string]$taskName

                )                

                               

                $taskRunFile         = "C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe -NoLogo -NonInteractive -File $($scriptPath)"    

                $taskStartTimeOffset = Get-Random -Minimum 1 -Maximum 10

                $taskStartTime       = (Get-Date).AddMinutes($taskStartTimeOffset) | Get-date -Format 'HH:mm'                                                                                                                                                                                     

                $taskSchedule        = 'DAILY'             

                & SCHTASKS /Create /SC $($taskSchedule) /RU `"NT AUTHORITY\SYSTEM`" /TN $($taskName) /TR $($taskRunFile) /ST $($taskStartTime)                

                               

                if ($error) {

                                $msg = "Sript function (Invoke-ScheduledTaskCreation) Failure during task creation! $($error)"

                                $api.LogScriptEvent('CreateLogDeletionJob.ps1',4002,1,$msg)                

                                Write-Warning -Message $msg

                } else {

                                $msg = "Scheduled Tasks: $($taskName) successfully created"

                                Write-Verbose -Message $msg

                }              




} #End Function Invoke-ScheduledTaskCreation







$logDirCleanScriptParams   = @{

                'scheduledTasksFolder' = $ScheduledTasksFolder

                'LogFileDirectory'     = $LogFileDirectory       

                'daysToKeepLogs'       = $DaysToKeepLogs     

                'LogFileType'          = $LogFileType

                'scriptPath'           = $scriptPath

}




Write-LogDirCleanScript @logDirCleanScriptParams







$taskCreationParams = @{

                'ComputerName'  = $ComputerName             

                'taskName'      = $taskName

                'scriptPath'    = $scriptPath

}




Invoke-ScheduledTaskCreation @taskCreationParams

The Custom Module:

Add an Empty Management Pack Fragment in the ‘Tasks’ sub folder name it ‘AgentTasks.mpx’. Copy the content below into it.

<ManagementPackFragment SchemaVersion="2.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">




  <TypeDefinitions>   

    <ModuleTypes>

      <!-- Defining the Write Action Module Type. The name is user-defined and will be used in the task definition below. -->

      <WriteActionModuleType ID="Windows.Computer.AgentTasks.CreateLogDeletionJob.WriteAction" Accessibility="Internal" Batching="false">

        <!-- The items in the Configuration sections are exposed through the SCOM console -->

        <Configuration>

          <xsd:element minOccurs="1" name="LogFileDirectory" type="xsd:string" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />

          <xsd:element minOccurs="1" name="LogFileType" type="xsd:string" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />

          <xsd:element minOccurs="1" name="ScheduledTasksFolder" type="xsd:string" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />

          <xsd:element minOccurs="1" name="DaysToKeepLogs" type="xsd:integer" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />

          <xsd:element minOccurs="1" name="TimeoutSeconds" type="xsd:integer" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />

        </Configuration>

        <!-- To make exposed items editable it is required to specify them in the OverrideableParameters section -->

        <OverrideableParameters>

          <OverrideableParameter ID="LogFileDirectory" Selector="$Config/LogFileDirectory$" ParameterType="string" />

          <OverrideableParameter ID="LogFileType" Selector="$Config/LogFileType$" ParameterType="string" />

          <OverrideableParameter ID="ScheduledTasksFolder" Selector="$Config/ScheduledTasksFolder$" ParameterType="string" />

          <OverrideableParameter ID="DaysToKeepLogs" Selector="$Config/DaysToKeepLogs$" ParameterType="int" />         

        </OverrideableParameters>

        <ModuleImplementation Isolation="Any">

          <Composite>

            <MemberModules>

              <!-- The ID name is user-defined, suggested to keep it similar as the type. The type signals SCOM to initiate the PowerShell engine  -->

              <WriteAction ID="PowerShellWriteAction" TypeID="Windows!Microsoft.Windows.PowerShellWriteAction">

                <!-- To keep the module readable and the script better editable it is referenced below -->

                <ScriptName>CreateLogDeletionJob.ps1</ScriptName>

                <ScriptBody>$IncludeFileContent/Health Model/Tasks/CreateLogDeletionJob.ps1$</ScriptBody>

                <!-- The parameters are the same than in the Configuration section as we want to pass them into the script from the SCOM console -->

                <Parameters>

                  <Parameter>

                    <Name>LogFileDirectory</Name>

                    <Value>$Config/LogFileDirectory$</Value>

                  </Parameter>

                  <Parameter>

                    <Name>LogFileType</Name>

                    <Value>$Config/LogFileType$</Value>

                  </Parameter>

                  <Parameter>

                    <Name>ScheduledTasksFolder</Name>

                    <Value>$Config/ScheduledTasksFolder$</Value>

                  </Parameter>

                  <Parameter>

                    <Name>DaysToKeepLogs</Name>

                    <Value>$Config/DaysToKeepLogs$</Value>

                  </Parameter>

                </Parameters>

                <TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>

              </WriteAction>

            </MemberModules>

            <Composition>

              <Node ID="PowerShellWriteAction" />

            </Composition>

          </Composite>

        </ModuleImplementation>

        <OutputType>System!System.BaseData</OutputType>

        <InputType>System!System.BaseData</InputType>

      </WriteActionModuleType>     

    </ModuleTypes>

  </TypeDefinitions>




  <Monitoring>   

    <Tasks>     

      <!-- The name for the task ID is user-defined. Target is set to 'Windows.Computer' that make this task visible when objects of type Windows.Computer are shown in the console -->

      <Task ID="Windows.Computer.AgentTasks.CreateLogDeletionJob.Task" Accessibility="Public" Enabled="true" Target="Windows!Microsoft.Windows.Computer" Timeout="120" Remotable="true">

        <Category>Custom</Category>

        <!-- The name for the write action is user-defined. The TypeID though must match to the above created one. -->

        <WriteAction ID="PowerShellWriteAction" TypeID="Windows.Computer.AgentTasks.CreateLogDeletionJob.WriteAction">

          <!-- Below the parameters are pre-filled to instruct the users how the values in the overrides are exptected-->

          <LogFileDirectory>C:\TheLogFileDirectory</LogFileDirectory>

          <LogFileType>*.???</LogFileType>

          <ScheduledTasksFolder>C:\ScheduledTasks</ScheduledTasksFolder>

          <DaysToKeepLogs>7</DaysToKeepLogs>         

          <TimeoutSeconds>60</TimeoutSeconds>

        </WriteAction>

      </Task>     

    </Tasks>

  </Monitoring>




  <LanguagePacks>

    <LanguagePack ID="ENU" IsDefault="true">

      <DisplayStrings>       

        <DisplayString ElementID="Windows.Computer.AgentTasks.CreateLogDeletionJob.Task">

          <Name>Create Log Deletion Job</Name>

        </DisplayString>     

      </DisplayStrings>     

      <KnowledgeArticles></KnowledgeArticles>

    </LanguagePack>

  </LanguagePacks>




</ManagementPackFragment>

Reading:

If you are new to management pack authoring I suggest the free training material from Brian Wren.

On Microsoft’s Virtual Academy: https://mva.microsoft.com/en-US/training-courses/system-center-2012-r2-operations-manager-management-pack-8829?l=lSKqLpx2_7404984382

On Microsoft’s Wiki: https://social.technet.microsoft.com/wiki/contents/articles/15251.system-center-management-pack-authoring-guide.aspx

Closing:

If you have questions, comments or feedback feel free to feedback in our SCOM – Gitter – Community on: https://gitter.im/SCOM-Community/Lobby


Awesome! Thanks a lot for all your contribution and for being considerate for others by publishing it for everyone, Ruben 🙂 Wishing to have many more cool guest blogs from you!

You can get to know Ruben better here:

Ruben Zimmermann (A fantastic person who has a lot of great ideas) [Interview]

Cheers!

SCOM Event Based Monitoring – Part 2 – Rules

In the last post we discussed about event based monitoring options SCOM  provides with Monitors. You can find it here:

SCOM Event Based Monitoring – Part 1 – Monitors

In this post we are going to discuss the event based monitoring options using SCOM Rules. Basically the highlighted options in the image below:

1

As we can see, we have 2 kinds of rules for monitoring events. “Alert Generating Rules” and “Collection Rules”. Let’s walk through them one by one.

Alert Generating Rules:

As the name suggests, this type of rules raise an alert if they detect the event ID.

As you’re going through the Rule Creation wizard you will notice that there are several options in “Rule category”, as shown in the pic below. In my experience, there is no difference whatever you choose. These are more like for “Logical Grouping” of these rules, that you can maybe make use of if working on them through Powershell. Since we’re here to create an “alert generating” rule, the most obvious option here would be “Alert”.

1

Now, this step is pretty important and if you’re new to creating this, you’re very likely to miss this. As you reach the final window, on the bottom of “Alert Description” (which you can modify btw), is the box for “Alert Suppression”. This is used to tell SCOM what events should be considered “duplicates” and hence not raise a new alert if there’s already one open in active alerts. “Auto-suppression” happens automatically for monitors – it only increases the repeat count for every new detection – but for rules, you’ll have to do this manually. If you don’t do this, you’re gonna get a new alert every time this event is detected. In this demo, I’m telling SCOM to consider the event as duplicate if it has the same Event ID AND the same Event Source.

I HIGHLY recommend using this since I learned this hard way some time back. I missed out configuring alert suppression for some rule and a couple nights later, woke up to a call from our Command Center guys. They said, “Dude! We’ve received THOUSANDS of  emails in our mailbox since last 15 minutes…and they’re all the same. Help!”

I rushed and turned it off, further investigation brought to light the cause that something had gone wrong on the server and it was writing the same event over and over again, thousands of times in the event log, and since I had not configured the suppression criteria, it created a new alert every time and sent mail as set up in subscription. Now I check for suppression criteria at least 3 times 🙂

1

Now that is set up, I created the event in the logs with a simple PoSh:

Write-EventLog -Logname Application -ID 1000 -Source custom -Message "This is a test message"

And as you can see, the alert was raised.

1

Collection Rules:

Collection rules are used only to collect the events in the SCOM database. They do not create any alert. In fact, you’ll hardly even notice their presence at all. Why create these rules then? Most commonly for reporting/auditing purposes. You can also create a dashboard showing the detection of these events.

1

1

Notice in the left side of the wizard that there’s no “Configure Alerts” tab as we had in the “Alert Generating” rule.

So what this rule is going to do is detect the occurrence of event 500 with source “custom” and if it detects it, just saves it in the database.

I wrote this event in the logs a bunch of times, now let’s see if SCOM is really collecting them or not. We’ll create a simple “Event View” dashboard for this.

1

And yup, we can indeed see that the event is actually being collected by SCOM.

1

Here’s another thing that might be a bit tricky. After you create these 2 types of events, if you open the properties, you’ll see they’re almost identical. If you’ve named them properly, kudos to you but if you (or someone else) hasn’t, how will you find out whether the rule is generating alerts or just collecting events? Take a close look at the content in the yellow boxes below. See the difference?

Alert Generating Rule Properties:

1

Event Collection Rule Properties:

1

You rightly noticed that the response for the alert generating rule is “Alert”, which means this rule is going to respond to the event detection by generating an alert. If you click on the “Edit” option just beside that, you’ll see wizard for alert name change, format change, suppression criteria, etc.

On the other hand, the yellow box in the collection rule is “Event Data Collection Write Action” and “Event data publisher”, which indicates that it is only writing it in the databases. You can also verify this with Powershell:

1

You can also fetch a report for the event collection rule for auditing purposes, but unfortunately I do not have the Reporting feature installed in my lab so can’t show a demo for that. 🙂

Thus concluding the event monitoring options SCOM offers with monitors as well as Rules. Now you know what abilities SCOM has, now it’s up to you to decide which option do you wanna choose 🙂

Cheers!

 

SCOM Event Based Monitoring – Part 1 – Monitors

In this post I’m discussing about the possibilities SCOM provides with event detection monitoring using monitors.

I’ve written a similar blog for creating services, which you can see here:

SCOM BASIC SERVICE MONITOR VS. WINDOWS SERVICE TEMPLATE

Alright, so just go to Authoring -> Expand Management Pack Objects -> Monitors -> Create a Monitor -> Unit monitor. This is the screen that you should have got:

monitors1

The options enclosed in the box is what we’re concerned about at this time. So let’s go through them, one by one. The three “Reset” options, “Manual Reset”, “Timer Reset” and “Windows Event Reset” exist for all the monitors (even though I’ve expanded only the first 2 in the pic above).

  • Manual Reset: Choose this option when you want the alert to stay in the console unless you close/resolve it manually.
  • Timer Reset: Choose this option when you want the alert to close itself automatically after a given period of time.
  • Windows Event Reset: With this option you can choose to automatically close the alert only when a second healthy event is detected in a given time period. So, one bad event raises the alert, and the second good event resolves it. If the healthy event is not detected in the given time, the alert stays in the console until you close it manually.

Simple Event Detection:

This is the option that may know the best. It’s the simplest and does exactly the same as the name suggests – simply detects the occurrence of an event in the specified Event Log and raises an alert.

Examples:

Manual Reset –

monitors2

monitors3

monitors5

Now that we have the monitor set up, let’s test it.

We’ll create a custom event with Powershell and try to detect that. Here’s a simple Posh:

#create a custom source
New-EventLog -LogName Application -Source "Custom"
#write event
Write-EventLog -LogName Application -Source "Custom" -EventId 100 -Message "This is a test event"

Just making sure the event was created:

new event

Right, looks good. Now onto the Ops Console:

cons

As we can see, the alert has been raised. The alert will be resolved when the monitor producing it will be healthy. Since this is a manual reset monitor, it’ll only turn back healthy when you manually reset it.

There’s a good side to this and a bad one.

Good side:

You will always notice when the alert has been raised, and you can take any responsive measures as applicable. After you’re done, reset the monitor to make sure some action has been taken on this.

Bad side:

Unless and until you’re making sure to manually reset the monitor, there won’t be a new alert. As the monitor is critical already, it can’t be critical again and so won’t generate a new alert. It’ll only increase the repeat count, which may or may not be what you want. The work-around for this is to run a scheduled script that resets the monitors periodically to turn them back to healthy to make way for a new alert.

Timer Reset –

The only extra option you have here is to specify the wait time for reset. I’ve created this monitor to detect event 101 in Applications log.

1

With tests similar to the previous one, I get an alert for this.

1

You will have to take my word for it, the alert disappeared after 15 minutes 😉

Windows Event Reset –

Pay attention to the Wizard options here. You have to configure 2 event expressions, one for unhealthy and other for healthy. I set up the unhealthy event as event 102 with source “custom” in Application log while the healthy event is event 102 with source “custom1”.

Unhealthy event:

1

Healthy event:

2

As soon as I created the unhealthy event, I received an alert which was automatically resolved when I triggered the healthy event.
Repeated Event Detection:

Choose this monitor when you want to raise an alert if the specific event is raised repeatedly, with given settings. Here’s where the things get a little tricky.

1

You have a bunch of different (and confusing) options to set up here. Luckily, it’s all very well documented here on Technet : Repeating Events

What I’m doing is to configure the monitor to raise an alert when the event 103 is raised 3 times within 15 seconds. And sure enough, I do get an alert.

1
Missing Event Detection:

Choose this monitor when you’re expecting some event to be written in the Event Log – maybe due some kind of scheduled activity like backup, maintenance, scripted events, etc – at the given time. If the monitor doesn’t detect it, it generates an alert.

1

So what I’m basically telling SCOM is, “I’m expecting the event ID 104 from source “custom” in the Application event log every 15 minutes, let me know if it doesn’t show up, will ya? Thanks!”

To test this, I did NOT create an event with ID 104, and sure enough, I got the alert.

Capture5

(Do not worry about the mismatch in the alert name and the monitor name, I made a typo in the alert name. It should say “anaops – missing event detection – manual reset” instead of the “repeated” as the name of the monitor at bottom suggests)
Correlated Event Detection:

Choose this option if you want an alert based on some correlation between two event ID’s. “Some correlation” can vary, as you can see in the wizard.

3

4

This can be bit confusing. In this demo, what I’m telling SCOM is,”Hey, let me know if event 105 from source “custom” is raised AND within 5 minutes of its occurrence, event ID 105 from source “custom1″ is also raised (in that order). Cool?”

SCOM said “Cool!”, so I tested it with writing these two events mentioned above within the interval of 5 minutes. And yup, I got an alert.

1
Correlated Missing Event Detection:

Choose this one when you need an alert when you have “some correlation” between two events – first one occurs, we’re expecting the other within 5 minutes, but it isn’t raised.

For testing this, I created the event 106 from source “custom” in applications log but did NOT create the other event 106 from source “custom1” within the next 5 minutes. Sure enough, here’s the alert I got:

1

As you can imagine the other two monitor reset strategies “timer reset” and “windows event reset” will have slightly different wizards, but I’m sure you guys can figure it out 😉

Also, As you may have noticed, unlike many other monitors, there’s no “interval” at which the event detection monitors are running. Meaning, it is looking for the events in the log “all the time”. So the event monitoring you get is almost real-time.

This concludes this fairly long blog, but I hope it gives you some clarity about what options you have for event detection monitoring and help you in choosing the right one. 🙂

We’ll talk about the event monitoring options with rules in the next post.

Cheers!

SCOM Basic Service Monitor Vs. Windows Service Template

Every now and then I’ve seen questions regarding this on the Technet forums. The most usual question is “A service XXX failure alert is being generated by a server where this service isn’t even present! What’s going on?”

The Basic Service Monitor:

This is a simple monitor that simply puts an instance of the monitor you create on EVERY server where it’s targeted. Most of the times the class you select is “Windows Server”, and so the monitor is delivered to every Windows server – regardless of whether the service is actually present there or not.

 

BSM

I suggest you to create a brand new MP and save this monitor in it. Now, export it and analyze what you see in the XML. You’ll notice that there aren’t a lot of things, just a single simple monitor.

So what this basically does is to put up an instance of the monitor on EVERY instance of the target class. It does not bother to check whether the service actually even exists on that server or not. And this more often than sometimes causes false alerts stating that the service is “down” on the servers where it isn’t even present! This is why I call this the “dumb” service monitor.

If you want to apply this only on a group of servers, you need to go through the additional step of disabling this monitor and enable it through override explicitly for the group you’ve created.

Windows Service Template:

Now let’s create a service monitor using the Windows Service template. As you’ll notice while creating the monitor, this wizard offers much more than just simple service availability monitoring. You can also specify to get alerts based on how much CPU and memory the service is actually using.

While setting up the target for this monitor, you’d also notice that you need a group to target this against (instead of the whole classes as we did in case of basic service monitor). What this does is to provide the precise targeting for this monitor to where you want to run this. If you want to target this to all Windows servers in your environment, just select the “All Windows Computers” group.

WST

Now, let’s do the same thing – save this in a separate test MP and export it for our analysis. You’ll see some interesting stuff in the XML.

This MP will be considerably larger than the previous one and the first thing you’ll notice is the discovery. This monitor creates it’s own discovery for the service. And when you have a discovery, you also have a class. As you create this monitor, SCOM automatically detects the presence of this service on the servers (in the group provided earlier) and populates the class. Once the class is populated, the monitoring is targeted only to the instances of this class, saving SCOM and you the trouble to narrow down the scope later. Pretty neat, eh? 🙂 This is why I like to call this the “intelligent” service monitor.

You’ll also see that when you create this one monitor, under the hood SCOM creates several monitors as well as rules:

Type Description Enabled?
Monitors Running state of the service Enabled.
CPU utilization of the service Enabled if CPU Usage monitoring is selected in the wizard.
Memory usage of the service Enabled if Memory Usage monitoring is selected in the wizard.
Collection Rules Collection of events indicating a change in service’s running states. Enabled.
Collection of CPU utilization for the service Enabled if CPU Usage monitoring is selected in the wizard.
Collection of memory usage for the service Enabled if Memory Usage monitoring is selected in the wizard.
Collection of Handle Count for the service Disabled. Can be enabled with an override.
Collection of Thread Count for the service Disabled. Can be enabled with an override.
Collection of Working Set for the service Disabled. Can be enabled with an override.

So you see, this one wizard is actually creating THREE different monitors and SIX different performance collection rules. Also another upside of this is, since the class has also been created, you can target this class for any rules or monitors that you may want to create for this particular sub-set of servers where the service is running.

Another great thing about this is that since you have a class for this, you can even pull an availability report against this object to measure the uptime of your service.

OK then, which one should I choose?

After all said and seen, the obvious question you have in mind is probably one of the below:

  1. Cool, so the Windows Service template option looks pretty awesome. I should be using this one all the time, right?
  2. Wow, I never know that. I’ve never created a service monitor with the Windows Template option. Did I make a mistake?
  3. Why would anyone even create the basic service monitor then?

These are all legit questions, and you might be surprised to know my answer if you ask me my preferred way of monitoring a service. Yes, I (and many others) would still prefer the basic service monitor. Why? There are several reasons to do that.

  1. You only want to monitor the availability of the service. You are not concerned about the amount of CPU memory it is consuming. In fact, this is the case most of the times. You’re mainly focused only on the up/down status of the service. And in case you’re worried about CPU and memory utilization being consumed, you do have special dedicated monitors for them anyway.
  2. As the Window Service template creates a lot of things along with the service availability monitoring (1 class, 3 monitors and 6 rules), if you don’t actually need them, they’re just unnecessary overhead for SCOM. Now imagine you creating (1+3+6) 10 objects in SCOM for EACH service out of which 9 are not being used, how much litter you have created in SCOM. Basic service monitor on the other hand only creates 1 object (the actual availability monitor).
  3. It is much more work to disable the Windows Service template monitor than the basic service monitor. As you can imagine, if you no longer want to monitor the service, you’ll have to disable all 10 objects related to this monitor as opposed to just one in basic service monitor.

Hence, always first decide whether you REALLY want all this additional functionality that the Windows Service template provides, and if the answer is “Yes”, go for this way. Else, the good old basic service monitor is your friend 😉

Hopefully this clears up some things for you. 🙂

Cheers!

 

Run Powershell scripts in Console Tasks

I am working on one of the projects and as a part of it I needed to create some console tasks that would run a Powershell script to do the stuff I want. I knew that it was no problem for a script a line of two long, but any more than that and it is a real pain to pass it as the parameter in the console task. The other way I was aware of is you can point the path to your script in the parameters if you have it locally saved on your management servers (each and every one of them, at the exact same path). This didn’t really serve my purpose as I wanted to embed in a re-usable XML so I decided to do something on my own.

After a bit of researching the Internet and a lot of trial-and-error, I finally got it working. The key points to remember here are:

1. CDATA to parse it through xml

2. -command “cmd1;cmd2” to pass the block as a single input

3. Using “;” to break the cmdlets

4. Use the escape character “\” before every double quote (“) to skip the character otherwise the compiler misunderstands it for -command syntax and throws errors.

Here’s an example of the XML, with a simple Powershell code that creates an event in the custom event source:

 

<ManagementPackFragment SchemaVersion="2.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<Categories>
		<Category ID ="Cat.CustomTasks.CreateEvent"  Target ="CustomTasks.CreateEvent" Value ="System!System.Internal.ManagementPack.ConsoleTasks.MonitoringObject"/>
	</Categories>
	<Presentation>

		<ConsoleTasks>

			<ConsoleTask ID="CustomTasks.CreateEvent" Accessibility="Internal" Enabled="true" Target="Windows!Microsoft.Windows.Computer" RequireOutput="true">
				<Assembly>CustomTasks.CTCreateEventAssembly</Assembly>
				<Handler>ShellHandler</Handler>

				<Parameters>
					<Argument Name ="WorkingDirectory"/>
					<Argument Name ="Application">%windir%\system32\windowsPowershell\v1.0\powershell.exe</Argument>
					<Argument>
						<![CDATA[ -command 
						"
#Create a custom source;
New-EventLog -Source 'Task Source Name' -LogName 'Operations Manager';
#Write the event;
Write-EventLog -LogName 'Operations Manager' -Source 'Task Source Name' -EntryType Warning -EventId 1010 -Message 'This is a test event created by task'
"
						]]>
						
					</Argument>
				</Parameters>

			</ConsoleTask>
		</ConsoleTasks>
	</Presentation>

	<LanguagePacks>
		<LanguagePack  ID ="ENU" IsDefault ="true">
			<DisplayStrings>
				<DisplayString  ElementID ="CustomTasks.CreateEvent">
					<Name>CT - Create Test Event</Name>
					<Description>Creates a Warning test event</Description>
				</DisplayString>
			</DisplayStrings>
		</LanguagePack>
	</LanguagePacks>
	<Resources>
		<Assembly ID ="CustomTasks.CTCreateEventAssembly" Accessibility ="Public" FileName ="Res.CustomTasks.CTCreateEventAssembly" HasNullStream ="true" QualifiedName ="Res.CustomTasks.CTCreateEventAssembly" />
	</Resources>  
</ManagementPackFragment>

Here’s the output:

createeventoutput

Hope this helps someone out there with similar need.

For further reading, you can go through this thread:

Powershell script in a console task?

Keep SCOMing 🙂

Cheers