.\Matthew Long

{An unsorted collection of thoughts}

SCOM 2012: Runbook to get SCOM Group membership in System Center Orchestrator

Posted by Matthew on May 15, 2014

A quick one today sharing a useful runbook that I’ve used a couple of times now – getting the list of SCOM groups that a Monitored SCOM object is a member of.  The runbook is basically a powershell script (isn’t it always!) that recursively parses group membership by navigating the System.Containment Relationships between the given monitored object and anything inheriting from the group class.  This means..

  1. It works on all groups (both from sealed MPs and user created ones).
  2. It works on anything based on a Containment relationship (so anything other than a reference relationship, which meaningfully is all the valid ones for considering group membership)
  3. It supports nested groups and indirect membership (so if a computer is a member of a group, and you query membership for a logical disk in that computer, it is counted as being in the group).

In terms of output, the runbook reports the name of the group, the name of the object that is actually the direct member of the group, and the SCOM class of the object that is the direct member of the group. This is mostly very useful when you are building automated ticketing or notification workflows (if a member of a given group, assign to or alert a specific team), but also useful for automated triage scenarios (i.e. if the computer is a member of the SQL servers group, automated patching should include these extra steps…)

The Script

As is often the case, this script has been written for Orchestrator in mind, so make sure you populate the variables on lines 3,5 and 8.  If your Runbook Server service account already has access to SCOM, you can remove line 3 and take the -Credential $cred off of line 5.


Import-Module "C:\Program Files\System Center 2012\Operations Manager\Powershell\OperationsManager"

$cred = new-object "System.Management.Automation.PSCredential" ("SCOM Username", (ConvertTo-SecureString "SCOM Password" -AsPlainText -Force))

New-SCOMManagementGroupConnection -ComputerName "SCOM Management Server" -Credential $cred

$mg = Get-SCOMManagementGroup
$monitoringObject = Get-ScomClassInstance -Id "Monitoring Object ID"

$groupClass = Get-SCOMClass -Name System.Group
$relationship = $mg.GetmonitoringRelationshipClass([Microsoft.EnterpriseManagement.Configuration.SystemRelationship]::Containment)
$groups = $monitoringObject.GetMonitoringRelationshipObjectsWhereTarget($relationship, [Microsoft.EnterpriseManagement.Configuration.DerivedClassTraversalDepth]::Recursive, [Microsoft.EnterpriseManagement.Common.TraversalDepth]::Recursive) | where {$_.isDeleted -eq $false -and $_.SourceObject.GetLeastDerivedNonAbstractMonitoringClass().IsSubClassOf($groupClass)}
$groupOutput = @()
$groupMember = @()
$memberClass = @()

ForEach ($group in $groups)
{
$groupOutput += $group.SourceObject.DisplayName
$groupMember += $group.TargetObject
$memberClass += $group.TargetObject.GetLeastDerivedNonAbstractClass().DisplayName
}

#Set results into Published Variables.
$Output = $groupOutput
$OutputMemberClass = $memberClass
$OutputMember = $groupMember

The Runbook

The runbook below is designed to be a worker/child runbook that returns multi value data – specifically one object for each group that the object is a member of.  If you need to process this as a single activity, I’d recommend enabling the “Flatten” option on the Behaviour tab of either the Invoke runbook activity used to call this runbook, or on the .net script activity directly if you always want it to return a single string that is delimited by a character.

Runbook

Initialize Data

Init Data

.Net Script Returned Data Tab

Net Script Data

Return Data

Returned Data

Simple but powerful – just what we like around here :)  Hope this helps!

Posted in Computing | Tagged: , , , , , | Leave a Comment »

SCSM 2012 R2: Dynamically replacing AD groups in Review Activities with users

Posted by Matthew on May 14, 2014

Problem

One of the challenges people seem to run into with using Review activities in System Center Service Manager is using Active Directory groups as reviewers.  When you add an AD group as a reviewer the functionality you get is:

  1. Everyone who is a member of that group may vote, via the SCSM Console (if they have access) or via the Self-Service Portal.
  2. The group only has a single vote – if there are 5 members of the group and you need a vote from each person, the moment 1 person votes yes/no the entire group has voted.
  3. Unless the group also has a mail address, group members won’t get a notification as the notification engine doesn’t know who is a member of the group.
  4. Even if you do send out a notification via the group address, if the members reply back to the mail with a vote it won’t be processed by SCSM as only the Group is recognised as a reviewer, not them.

Number 4 is essentially a bug, but a long-standing one.  However for many people this mechanism isn’t suitable for their needs because:

  1. You may want to require an approve vote from everyone in the group, or a % proportion.
  2. If the group is the only reviewer, as soon as one person votes yes, the activity is approved, even if 30 seconds later someone wants to vote declined.
  3. Each group only gets a single vote – there is no room for weighting.  If one group contains 7 people and one contains 3, they both have equal voting share.
  4. When your Service desk is trying to chase or determine who can vote on an activity, it can be difficult to ascertain exactly who can vote.

The alternative is therefore to populate the review activity with the users that make up the group… which can be extremely painful if you’ve got many templates all with individual users that need updating whenever a person joins/leaves a team, nested groups, and must all this must be cross-referenced when building new templates or creating review activities manually.

Solution

In order to address the problem, I’ve put together a powershell script that will replace any Active Directory groups from an instance of a review activity and replace them with SCSM AD Users (assuming they have been imported into the CMDB).  This means you can add groups to your templates (or manually created activities) and once they go in progress the groups are expanded.  Features include:

  1. Recursively parses groups, so nested groups are supported.
  2. Ensures that a user is not added twice if a member of multiple groups (or manually added to the review activity).
  3. Calculates and maintains the highest approval rights a user may be entitled to (Must vote and Veto).
  4. Group is removed once users have been added.
  5. No external PS modules required – uses the native SCSM 2012 R2 module.

This script can be hooked up to service manager in a variety of ways – the primary method being a System Center Orchestrator runbook that is monitoring for created review activities.  You could also utilise this script in a Service Management Automation (SMA) runbook or even using the native SCSM Workflow engine if you use the community PS workflow activities.

As the script has been written to support System Center Orchestrator, it makes use of Powershell remoting to get around the x86 PSv2 only restrictions, but you can remove these elements if you are running it using SMA or natively on the SCSM Management servers.  There are a few variables at the start of the script that contain connection details – these can either be hard coded (not recommended) or populated via SCO Variables.  The Review activity GUID needs to be set using a subscription to a “Monitor Object” activity.


#Create Session that we will re-use for multiple invokes.
$username = "scsmusername"
$password = "scsmpassword" | ConvertTo-SecureString -asPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($username,$password)
$session = New-PSSession -computername 'scsmmanagementservername' -Credential $credential

#Invoke into session to setup variables & structures, parse initial RA membership.
Invoke-Command -Session $session -Scriptblock {
   Import-Module Microsoft.EnterpriseManagement.Core.Cmdlets
   Import-Module Microsoft.EnterpriseManagement.ServiceManager.Cmdlets
   New-SCManagementGroupConnection localhost

   $reviewActivity = Get-SCClassInstance -Id 'Review Activity SC Object Guid'

   $reviewers = $reviewActivity.GetRelatedObjectsWhereSource("System.ReviewActivityHasReviewer")
   $groupQueue = New-Object "System.Collections.Queue"
   $userDictionary = @{}
   $SCADGroupClass = Get-SCClass -name "Microsoft.AD.Group"
   $SCADUserClass = Get-SCClass -name "Microsoft.AD.User"
   $SCReviewerClass = Get-SCClass -Name "System.Reviewer"
   $SCHasReviewerRelationship = Get-SCRelationship -Name "System.ReviewActivityHasReviewer"
   $SCReviewerIsUser = Get-SCRelationship -Name "System.ReviewerIsUser"

   ForEach ($reviewer in $reviewers)
   {
      $psReviewer = $reviewer.ToPSObject()
      $user = @($reviewer.GetRelatedObjectsWhereSource("System.ReviewerIsUser"))[0]
      If ($user -ne $null)
      {
         $dn = $user.EnterpriseManagementObject.Item([guid]'97362a11-e6b1-a352-820e-b1e75d09da66').Value
         If ($dn -ne $null -and $dn.length -gt 0)
         {
            $adReviewer = New-Object PSObject -Property @{MustVote=[Boolean]$psReviewer.MustVote;Veto=[boolean]$psReviewer.Veto;DN=$dn;Id=$reviewer.Enterprisemanagementobject.id}
            If ($user.EnterpriseManagementObject.IsInstanceOf($SCADGroupClass) -eq $true)
            {
               $groupQueue.Enqueue($adReviewer)
            }
            ElseIf ($user.EnterpriseManagementObject.IsInstanceOf($SCADUserClass) -eq $true)
            {
               If ($userDictionary.ContainsKey($dn) -eq $false)
               {
                  $userDictionary[$dn] = $adReviewer
               }
               else
               {
                  $userDictionary[$dn].MustVote = $psReviewer.MustVote -or $userDictionary[$dn].MustVote
                  $userDictionary[$dn].Veto = $psReviewer.Veto -or $userDictionary[$dn].Veto
               }
            }
         }
      }
   }
}

#Return groups to process and existing user reviewers to local machine
$groupQueue = Invoke-Command -Session $session -scriptblock {(,$groupqueue)}
$userDictionary = Invoke-Command -Session $session -scriptblock {$userDictionary}
$processedGroups = New-Object 'System.Collections.Generic.List[System.String]'

#Declare recursive function to process and expand AD groups into SCSM user-based Reviewers
Function ExpandGroup ($ADSIGroup, $hasVeto, $mustVote)
{
   If ($processedGroups.Contains($ADSIGroup.Path) -eq $false)
   {
      $processedGroups.Add( $ADSIGroup.Path)
      $members = $ADSIGroup.Invoke("Members",$null) | % { [ADSI]$_}
      ForEach ($member in $members)
      {
         If ($member.objectClass -match 'group')
         {
            ExpandGroup $member $hasVeto $mustVote
         }
         ElseIf ($member.objectClass -match 'user')
         {
            $userDn = $member.Path.replace("LDAP://",'')
            If ($userDictionary.ContainsKey($userDn) -eq $false)
            {
               $userDictionary[$userDn] += $null
               $newReviewerTargetId = Invoke-Command -Session $session -ArgumentList $userDn,$mustVote,$hasVeto -ScriptBlock {
                  Param($userDn,$mustVote,$hasVeto)
                  $reviewerUser = Get-SCClassInstance -Class $SCADUserClass -filter ("DistinguishedName -eq " + $userDn)
                  If ($reviewerUser -ne $null)
                  {
                     $newReviewRelationship = New-SCRelationshipInstance -RelationshipClass $SCHasReviewerRelationship -Source $reviewActivity.EnterpriseManagementObject -TargetClass $SCReviewerClass -TargetProperty @{ReviewerId="{0}";MustVote=$mustVote;Veto=$hasVeto} -PassThru
                     New-SCRelationshipInstance -RelationshipClass $SCReviewerIsUser -Source $newReviewRelationship.TargetObject -Target $reviewerUser
                     $newReviewRelationship.TargetObject.Id
                  }
               }
               If ($newReviewerTargetId -ne $null)
               {
                  $userDictionary[$userDn] = New-Object PSObject -Property @{MustVote=$mustVote;Veto=$hasVeto;DN=$userDn;Id=$newReviewerTargetId}
               }
            }
            ElseIf($userDictionary[$userDn] -ne $null)
            {
               $changedRights = $false
               If ($userDictionary[$userDn].MustVote -ne $mustVote)
               {
                  $changedRights = $true
                  $userDictionary[$userDn].MustVote = $userDictionary[$userDn].MustVote -or $mustVote
               }
               If ($userDictionary[$userDn].Veto -ne $hasVeto)
               {
                  $changedRights = $true
                  $userDictionary[$userDn].Veto = $userDictionary[$userDn].Veto -or $hasVeto
               }
               If ($changedRights -eq $true)
               {
                  Invoke-Command -Session $session -ArgumentList $userDictionary[$userDn].Id,$userDictionary[$userDn].MustVote,$userDictionary[$userDn].Veto -ScriptBlock {
                     Param($Id,$MustVote,$Veto)
                     $existingUser = Get-SCClassInstance -Id $Id
                     $existingUser.MustVote = $MustVote
                     $existingUser.Veto = $Veto
                     $existingUser | Update-SCClassInstance
                  }
               }
            }
         }
      }
   }
}

#Process Groups using above function.
While ($groupQueue.Count -gt 0)
{
   $group = $groupQueue.Dequeue()
   $adsiGroup = [adsi]("LDAP://" + $group.dn)
   ExpandGroup $adsiGroup $group.Veto $group.MustVote
   Invoke-Command -session $session -scriptblock {Param($Id) Get-SCClassInstance -Id $Id | Remove-SCClassInstance } -ArgumentList $group.Id
}
#Cleanup session
Remove-PSSession $session

With this script we can now

  1. Place groups in our templates at design time, and know that the review activity will contain the correct members of the group.
  2. The service desk can add groups to manually created activities, without having to look up who is a member, find their CIs and deal with nested groups
  3. We can use notification channels to allow the reviewers to vote back via email etc.
  4. Finally, if we only wanted to give the group a single vote share in specific cases, we can still do that by putting a parallel activity in our workflow and putting two review activities in – one with the single vote group and one with the remaining voters.  The group review activity can then have it’s criteria set appropriately (unanimous, %), and if the group rejects the review activity then the Parallel activity will fail and the parent work item will stop as normal.

 Example

In the screenshots below, you can see that I’ve used this script in an Orchestrator Runbook.  The “Monitor for New Review Activities” trigger is just set to monitor for new “Review Activity” work items, with no filters.

Runbook

The script is inserted in the (badly named, i’ll admit) “Delete Group Reviewer” activity, which is actually a Run .Net Script activity.  Hook up all your variables and published data (remember that the ID the script is looking for is the SC Object Guid from “Monitor for..”, NOT the work item ID.

Start the runbook, and then go create a review activity.  Below I’ve got one user with the “Must Vote” right enabled, and one group with the “Has Veto” right.  The user is also a member of the group, so when the runbook executes it should expand the group into users but also give the existing user the “Has Veto” right and maintain their must vote status.

Before

Wait for the runbook to execute, then check back on your review activity – as you can see we now have all users and the group has been removed!

after

Hope you find this script helpful!

Posted in Computing | Tagged: , , , , , | 1 Comment »

Upgrading Systems Center Operations Manager 2012 to R2

Posted by Matthew on October 25, 2013

Rob Kuehfus just posted on his blog his process for upgrading SCOM 2012 to R2 (full disclosure, Rob is one of my colleagues).

Anything that has that many screenshots is always helpful when tackling the process yourself.  Rob does note however (and I feel I should reiterate):

warningThis blog post is intended to be used as a reference when upgrading to System Center 2012 R2 Operations Manager. It is not intended to be used in place of the official Microsoft documentation. Please review the upgrade guidance from Microsoft located here

 

Check out the post (and other useful articles) over at http://itprovssoftware.wordpress.com/2013/10/25/it-pro-vs-scom-2012-r2-upgrade/

Posted in Computing | Tagged: , , | Leave a Comment »

SCOM – Updated Visual Studio Authoring Extensions released

Posted by Matthew on October 21, 2013

Hi Guys,

A new version of the System Center Visual Studio Authoring Extensions has now been released, featuring many bugfixes, improvements and enhancements.  One of these that I’ve long been awaiting is..

Visual Studio 2012 and 2013 are now supported!

This means all of the new VS 2012/3 features that you’ve been waiting to use are now go.  I know items such as previewing files and source control enhancements

Download link : http://www.microsoft.com/en-us/download/details.aspx?id=30169

You’ll need to uninstall the previous version if you’ve already got it installed, as the installer won’t perform an upgrade (at this time, I also uninstalled Visual Studio 2010, as I only had that version installed for MP Authoring, everything else I’m doing has since moved on to more recent versions of VS).

Some of the notable changes are (in no particular order):

  • Support for Visual Studio 2012 and 2013
  • Language packs other than ENU are now built correctly,
  • Picker dialog boxes now traverse Project references properly, as does the Find All references tool.
  • No more access denied error messages when trying to build a 2012 MP that has been auto deployed to a management group.
  • Import wizard can now resolve MP references inside MP bundles
  • Snippet Editor no longer displays duplicate columns when an ID has been used multiple times in the snippet template.
  • Monitor templates now set Auto resolve to “True” by default and Severity to “MatchMonitorHealth”
  • MP Context Parameter replacements can now be used in Module parameters that have non-string data types.
  • MP Simulator can now simulate Agent Task workflows
  • MPBA “Resolve” option now works correctly with generated fragment files

They’ve also changed the Project templates to make it a bit more explicit which versions of Operations Manager each project type supports, and added 2012 SP1 and 2012 R2 explicitly as new project types.  Sadly still no xml  templates provided for datasource, monitortype, probe or condition detection modules.

VSAE Project Types

Full change list: http://social.technet.microsoft.com/wiki/contents/articles/20357.whats-new-in-visual-studio-authoring-extensions-2013.aspx

Remaining Issues:

  • MPBA Tool still doesn’t resolve Alert Strings where the default Language is not the workstation language (switch your machines language and all the missing alert string messages will disappear)
  • No intellisense support when configuring module parameters outside of Template groups (painful when creating custom modules).
  • Go To Definition doesn’t function if you are already previewing an existing item (essentially only works when called from fragments in your projects).
  • Informational schema errors are still logged when you configure module parameters outside of a template group.
  • When creating template snippets, intellisense still only provides snippet specific options, which can make authoring snippets challenging.

Happy Authoring!

Posted in Computing | Tagged: , , , , , , | 5 Comments »

Switch a Visual Studio Authoring Extension MP project between SCOM 2007 and SCOM 2012

Posted by Matthew on February 8, 2013

A couple of times now I’ve started a new MP project in Visual Studio using the Operations Manager Visual Studio Authoring Extensions, and about 45 minutes into my development realized I’ve created the wrong project type.  There have also been a few occasions where requirements change and it makes more sense to change the project from a Core Monitoring (2007) management pack into a 2012 “add-on” pack.

It’s actually quite a simple change to make, providing you know which files to edit.

Project File

  1. Open the .mpproj file that represents your management pack project (NOT the solution file).
  2. Locate the MPFrameworkVersion element in the first PropertyGroup section, and modify it according to the version you want the project to build:
    1. For 2012, use <MpFrameworkVersion>v7.0</MpFrameworkVersion>
    2. For 2007, use <MpFrameworkVersion>v6.1</MpFrameworkVersion>
  3. If downgrading from 2012 to 2007, under the ItemGroup element containing the MP Reference elements, remove any references to MPs that don’t exist in 2007.
  4. Save the file.

Management Pack Fragments

Next, you’ll need to update the SchemaVersion attribute of the ManagementPackFragment element at the start of every .mpx file in your project.  The good news is that you can just use Visual Studio’s find and replace option to replace this in all files in the solution simultaneously!

  1. Open the Project/solution in visual studio.
  2. Open one of the .mpx files, and hit Ctrl+H to open the “Find and Replace” window.
  3. To go from 2007 to 2012, in the “find what” box, enter <ManagementPackFragment SchemaVersion=”1.0″ and in “replace with” enter <ManagementPackFragment SchemaVersion=”2.0″
  4. Otherwise, do the reverse and in the “find what” box, enter <ManagementPackFragment SchemaVersion=”2.0″and in “replace with” enter <ManagementPackFragment SchemaVersion=”1.0″
  5. Make sure “Look in” is set to Current Project.
  6. You can now either click “Find Next” and “Replace” repeatedly if you aren’t comfortable letting VS just replace everything, or hit “Replace All

Save all files in your project, and attempt a build.  If you get any build errors relating to Management pack references or Schema Versions, just look for the reference/file that you missed and update the values.

Needless to say, you should always think carefully before you do this, and thoroughly test the MP to ensure that there aren’t any side effects from now using earlier/later versions of the default SCOM management packs.  Going from 2007 -> 2012 is safer as 2012 is backwards compatible and will support your previous module configurations.

Hope that helps!

Posted in Computing | Tagged: , , , , , | 1 Comment »

Referencing MPBs and other SCOM 2012 Management Packs using Visual Studio Authoring Extensions

Posted by Matthew on January 29, 2013

One of the great features of the SCOM Visual Studio Authoring Extension is the ability to easily view the definitions of content in sealed management packs you are referencing.  Sometimes (especially if you are exporting a MP from the SCOM management group for further customization) you’ll need to reference an MP that is installed in your SCOM management group but that isn’t included in the VSAE package, or isn’t available online.  Most likely this is a system MP or a MP that’s only available as part of a bundle (If your MP contains 2012 dashboards, it’s probably got a reference to Microsoft.SystemCenter.Visualization.Library or Microsoft.SystemCenter.Visualization.Internal).  How can you reference these?

Well if you’ve still got your SCOM installation media to hand you can find all of the MPs imported at installation in the ManagementPacks folder.  This can be great if you’ve got a required reference, or even just want to have a look at how the product group implemented some piece of functionality!

Note however that some of the MPs are wrapped up in MPBs (Management pack bundles).  It’s still perfectly possible to reference these in your project:

  1. Make sure you’re editing a 2012 MP project.  If you’ve chosen an Operations Manager Core MP, you’ll be unable to add a reference to MPBs as they didn’t exist at that time.
  2. In Solution Explorer (by default on the right panel) right click on “References”  and choose “Add References from Management Pack bundle…”
  3. Browse to and select your file (Lets say Microsoft.SystemCenter.Visualization.Internal.mpb from the SCOM 2012 install media)
  4. You’ll be then given a dialog detailing the MP(s) that were added from the bundle into the project.
  5. Now you can view the definition of any module you need from that MP via the Management Pack browser (View -> Management Pack Browser) or by selecting the module in-code and hitting F12 (go to definition hotkey).

Pretty simple procedure!  If you have accidentally created your MP project as a Operations Manager Core (2007) MP, you can modify your solution files to upgrade it.  Think carefully about doing this however – would you be better off including the extra functionality you need in an additional “feature” pack?  If you decide to go ahead and upgrade/downgrade, you can follow the steps in this blogpost.

Oh and one final tip: If you don’t want to find yourself having to constantly keep hold of the 2012 install media, you can just copy the MPs into the VSAE installation folder (they will now automatically be resolved when referenced).  You’ll find them in Program Files (x86)\System Center 2012 Visual Studio Authoring Extensions\References\OM2012.  I’d advise not to overwrite any of the existing MPs (you’ll get some conflicts) to be safe.  Also, be careful about copying updated versions of MPs that come from CU’s/SPs into this location, unless you don’t mind all the MPs you create requiring that updated version of the MP in future.  Not all customers have/can install the latest patches..

Hope that helps!

Posted in Computing | Tagged: , , , | Leave a Comment »

SCOM 2012 – Update Run As Account distribution via Powershell

Posted by Matthew on January 25, 2013

If you’ve ever had to use a Run as Profile with a Run As Account set to “Most Secure” that is used on a large number of agents, you’re probably used to seeing a lot of “System Center Management Health Service Credentials Not Found Alert Message” alerts.

Individually this isn’t too much work to manage, but when you get 120 of these come in at once (new MP imported in a large environment) it’s pretty painful to add them all manually via the console.  So below is a quick script to do this via powershell.

warningWarning: This only works with SCOM 2012.  If you want to do this for SCOM 2007, you can follow Andreas Zuckerhut’s post here –  but be warned, you don’t have the utility class used below so you need to be comfortable with your powershell!

In my example below I only had alerts open for one particular Run As account.  If you have multiple different accounts that you need to add systems to, please make sure you use some additional filtering on the Get-ScomAlerts cmdlet.

And yes I know this could be one horrible one-liner, but that wouldn’t be very nice to read🙂

$alerts = Get-SCOMAlert -ResolutionState 0 -Name "System Center Management Health Service Credentials Not Found Alert Message"
$runas = Get-SCOMRunAsAccount  -Name "RunasAccountNameGoeshere"
$monitoringObjects = $alerts | % {get-ScomMonitoringObject -id $_.MonitoringObjectId}
$monitoringObjects += (Get-SCOMRunAsDistribution $runas).securedistribution
$managementGroup = Get-ScomManagementGroup
[Microsoft.SystemCenter.OperationsManagerV10.Commands.OMV10Utility]::ApproveRunasAccountForDistribution($managementGroup, $runas, $monitoringObjects)

After that, you can check the results by running (Get-SCOMRunAsDistribution $runas).securedistribution or checking in the SCOM Console under the Run As Account’s distribution tab.

Hope that helps!

Posted in Computing | Tagged: , | 1 Comment »

SCOM 2012 – Manually triggering a Discovery via the SCOM Console (On Demand Discovery)

Posted by Matthew on January 24, 2013

We’ve all been there – you’ve just added a new role to a server, installed a new component or got around to updating an expired licence, and now you’ve got to sit there and wait until the next discovery cycle occurs (potentially up to 24 hours in some cases).

However, Operations Manager 2012 includes a nice little Agent task you can run on a health service to manually trigger a discovery attempt!  I haven’t found much documentation for the task or the module (it’s not composite, and I haven’t yet deconstructed it) but I’ve used it a couple of times now and it always works a treat!

warning

Disclaimer: I don’t know exactly how this task interacts with discoveries that don’t feature Probe modules expecting a trigger item somewhere in their cooked down chain.  If your Discovery is based on the presence of a Windows event, this may not function as expected.   Discoveries based on schedules (normally via System.Discovery.Scheduler) should function fine.

The high level steps are:

  1. Locate the “Trigger On Demand Discovery Task” for the health service you need to run the discovery from.
  2. Find the DiscoveryId so that SCOM knows which discovery to run.
  3. Find the TargetInstanceId so SCOM knows which specific object the discovery should run for.
  4. Run the task, overriding with the appropriate IDs.

Run the Task against the appropriate Health Service

So, how do I run this task?  Well you’ll find it targeted at health Services, so the Agent Health State or Management Servers State views under the Operations Manager folder will do the trick.

Operations Manager Agent Views

Select the Agent/Management server that you want the discovery to be triggered on (make sure you select the state view on the right and not the “from health service watcher” items) and you should see the task show up in the task pane on the far right.

On Demand Discovery Task

Don’t run it yet though, because now comes the only tricky part – you MUST specify which discovery the agent should trigger, and which target instance that discovery should be run for.  These have to be specified as the internal GUID that SCOM assigns to entities.  What’s the best way to retrieve that you ask?  Powershell of course!

DiscoveryId

In order to get your DiscoveryId you can use the Get-ScomDiscovery cmdlet with the -Displayname parameter, or if you know it the –Name parameter.  The Displayname is what displays in the SCOM console in the “Object Discoveries” section of the Authoring pane.  The Name is whatever name the MP Author gave the discovery when writing the management pack.

Either way, once you’ve run that cmdlet and found your discovery you want the guid displayed in the Id property.  It will look something along the lines of: 94d82cfb-2644-97ab-b42c-f0438d77b90a

TargetInstanceId

Now to get your TargetInstanceId guid we need to find the unique ID that’s been assigned to the particular instance of the object that your discovery targets.  Most times this is probably going to be a windows computer or server object.  In order to find this we can use the Get-ScomClass and Get-ScomClassInstance cmdlets. If you are comfortable getting this, skip head to the next section (PROTip: The class id is available in the .Target.Id property of the discovery object you returned above).

First we need to get the Class that the discovery targets .  In the authoring pane of the SCOM console where you got the discovery name from, note down the value in the “Target” column.

Next, load up the Discovered Inventory view in the Monitoring Pane, and change the Target Type (via the task pane on the right) to your class you got from the Discovery target column.  Note down the displayname of the object that you want to run the discovery against (for example, a particular computer name).  Finally, run the below command

Get-SCOMClass -DisplayName “Discovery Target name goes here” | Get-SCOMClassInstance -Displayname “Object Displayname goes here” | fl Displayname,Id

This will display another guid, which is your TargetInstanceId.  Almost there!

Override and Run the Task

Head back to the Agent/Management server view, select your health service that you want the discovery to run on, and click on the task.  You’ll see the following screen:

On Demand Discovery Options

Hit the Override button, and in the “New Value” column enter in your TargetInstanceId and DiscoveryId guids that you found in the previous steps.  Hit Override, and then back on the run task screen click Run.  The discovery request will launch and should complete fairly quickly (faster than your discovery will at any rate.  Task completion doesn’t mean the discovery has finished, merely that the trigger request was sent successfully).  If you see any errors listed in the task results pane, then it’s likely you’ve got the wrong guid somewhere.

And that’s it.  Hopefully after a short amount of time your class objects should start to appear in SCOM.  If your discovery finds the root of a hierarchy of objects, you don’t need to submit a trigger for each subsequent object – those will be discovered immediately as normal once your root object is discovered.

Hope that helps you having to wait around for your latest installed component to show up in SCOM, and get back to monitoring!

Posted in Computing | Tagged: , | 2 Comments »

Deleting a SCOM MP which the Microsoft.SystemCenter.SecureReferenceOverride MP depends upon

Posted by Matthew on December 14, 2012

If you’ve ever imported a management pack which contained a Run As profile into SCOM, you will know the pain that awaits you if you ever need to delete it (most commonly when the latest version of the MP doesn’t support an upgrade via import).

The most discussed option I’ve seen for dealing with this is to:

  1. Delete the offending Run As Account(s) from the Run as Profile.
  2. Export the Microsoft.SystemCenter.SecureReferenceOverride MP
  3. Remove the reference that gets left behind when you delete a Run As Profile configuration from the raw xml.
  4. Increment the version number (again in the xml)
  5. Reimport it.

However, there is another way that doesn’t rely on you having to import/export or having to touch any xml, just a bit of Powershell!  The below is for 2012, but the same principle applies for 2007, just use the appropriate cmdlets/methods.

  1. Open a powershell session with the Operations Manager module/snappin loaded.
  2. Type: $MP = Get-SCOMManagementpack -Name Microsoft.SystemCenter.SecureReferenceOverride
  3. Now we can view the referenced management packs by typing $MP.References
  4. From the list of items in the Key column, note down the alias of your MP you wish to delete.  If you are having trouble finding it, the Value column will list the full ID of the MP.
  5. Now that we know the MP alias, we can remove it from the Secure Reference MP by typing $MP.References.Remove(“yourMPAliasGoesHere“)
  6. Now we can verify the MP is valid by entering $MP.Verify()  to ensure there are no orphaned overrides, etc.
  7. Finally, we can save our changes by typing: $MP.AcceptChanges()

powershell_references

If you don’t follow step 7, you won’t actually commit your changes to the MP.  Once this is done, give the SCOM management group a chance to catch up (you might have to wait a minute and then refresh your console).  When you now check the Dependencies tab of the MP you want to delete, you’ll see that the SecureReferenceOverride MP is no longer listed and you’ll be able to remove your MP.

Dependencies

 

Hope that helps!

Posted in Computing | Tagged: , , , , | 7 Comments »

SCOM : Revisiting the DayTimeExpression option of System.ExpressionFilter

Posted by Matthew on August 17, 2012

You may remember a few weeks ago I did an article on the flexibility and power of the System.ExpressionFilter. In that post I commented that I wouldn’t go into any depth on the DayTimeExpression expression type as you could accomplish most of the day/time comparison tasks with a System.ScheduleFilter instead.  Well, no sooner than writing that, I found myself authoring a workflow where that was not the case.

The customer was looking for a three state unit monitor, that had some complex health behavior:

  1. If the result of a scheduled Job was successful, switch to a Healthy state.
  2. If The result of the job is a Failure, switch to a Critical state.
  3. After 15 Minutes since the job has started, if it is not Successful or Failed, switch to a Warning State.
    1. After 30 minutes, if it has still not succeeded, go into a critical State.

Normally this kind of complex logic would be included as part of a custom script, however in this case we were using a built-in module to perform the query of our Job status, so it seemed very inefficient to then have to go into a script just to calculate the time differential (especially if due to the return code, the time calculation is irrelevant).

Why couldn’t we use a System.ScheduleFilter?

The normal approach when doing time comparisons is to use a System.ScheduleFilter to block the workflow from posting items to the appropriate health states in a MonitorType.  However, here we had a combination approach where we needed to use boolean AND and OR operators, which is something that the ScheduleFilter cannot provide, and the SCOM workflow engine only allows a single workflow branch to lead to a given Health State.

Our module didn’t return the current time as an additional property, so in order to get the current date I decided to just use the timestamp found on every Dataitem in a SCOM workflow.  This required a little bit of XPath knowledge however, as nearly all the XPath Query examples I’ve seen documented with SCOM are for accessing the child properties of a DataItem, not its own attributes.

So without further ado here are the Expressions I eventually came up with..

Healthy Expression

    <RegExExpression>
      <ValueExpression>
        <XPathQuery Type="String">//*[local-name()="StdOut"]
      </ValueExpression>
      <Operator>MatchesRegularExpression</Operator>
      <Pattern>^(.*SU)$</Pattern>
    </RegExExpression>

Nothing groundbreaking here, if at any time the result code matches the regular expression “SU” then we know our job succeeded (those of you who have done cross-platform monitoring with SCOM may recognize the XPath Query i’m using, however that’s not really the focus of this article).

Warning Filter

    <And>
      <Expression>
        <RegExExpression>
          <ValueExpression>
            <XPathQuery Type="String">//*[local-name()="StdOut"]
          </ValueExpression>
          <Operator>DoesNotMatchRegularExpression</Operator>
          <Pattern>^(.*SU|.*FA|[\s]*[\s]*)$</Pattern>
        </RegExExpression>
      </Expression>
      <Expression>
        <DayTimeExpression>
          <ValueExpression>
            <XPathQuery Type="DateTime">./@time</ValueExpression>
          <StartTime>79200
          <EndTime>80100
          <Days>62</Days>
          <InRange>true
        </DayTimeExpression>
      </Expression>
    </And>

The first part of our Warning expression (lines 2-9) is just checking that the Job status code is not one which instantly pushes us into another health state (remember, a return code of Failure is an automatic critical health state, regardless of time).  Lines 12-20 are what we are interested in here.  We’ve specified that we want to do a DayTime comparison, and we are going to compare the “./@time” XPath query against a time range.  I’ll come back to the XPath in a second, first let me explain the rest of the parameters.

  • StartTime is the start of the time range, specified in Seconds from Midnight.
  • EndTime is the end of the time range, specified in Seconds from Midnight.
  • Days is the usual Days of the week mask used by SCOM.  To specify which days are in the range, simply add up the corresponding values from the table below (so Mon through Friday is 62).
    • Sunday = 1
    • Monday = 2
    • Tuesday = 4
    • Wednesday = 8
    • Thursday = 16
    • Friday = 32
    • Saturday = 64
  • InRange is a boolean operator that specifies if this expression is TRUE if the input time is inside, or outside the time range specified.

So what i’ve done here is specified that the warning filter will match only for the 15-30 minute period after the job has started (remember this is a scheduled job, so it’s the same time each day), and only if the status code is not SU (Healthy) or FA (Critical).

The XPath Query on line 14 of “./@time” is a little weird, and is to do with the implementation of XPath in the ExpressionFilter module.  Essentially it’s already scoped to look at the elements within a workflow Data item, so we have to explicitly go back up the tree and say we want the Time attribute of the DataItem itself.  The value you use to perform your date time calculation must be in the DateTime format (2012-08-17T14:23:16.291Z) for this to succeed.  Thankfully the Time value on DataItems always is.

Critical Filter

    <Or>
      <Expression>
        <RegExExpression>
          <ValueExpression>
            //*[local-name()="StdOut"]
          </ValueExpression>
          <Operator>MatchesRegularExpression</Operator>
          <Pattern>^(.*FA|[\s]*[\s]*)$</Pattern>
        </RegExExpression>
      </Expression>
      <Expression>
        <And>
          <Expression>
            <RegExExpression>
              <ValueExpression>
                //*[local-name()="StdOut"]
              </ValueExpression>
              <Operator>DoesNotMatchRegularExpression</Operator>
              <Pattern>^(.*SU|[\s]*[\s]*)$</Pattern>
            </RegExExpression>
          </Expression>
          <Expression>
            <DayTimeExpression>
              <ValueExpression>
                <XPathQuery Type="DateTime">./@time</XPathQuery>
              </ValueExpression>
              <StartTime>78300</StartTime>
              <EndTime>80100</EndTime>
              <Days>62</Days>
              <InRange>false</InRange>
            </DayTimeExpression>
          </Expression>
        </And>
      </Expression>
    </Or>

And finally, we have the Critical health state Expression filter.  This uses an OR condition to short-circuit and allow us to instantly go to a critical health state if the job result is a failure without having to check the time.  Otherwise, we carry on and evaluate the AND expression and make sure that the job result isn’t a Success code and we are now outside our 30 minute window since the job started.  Note that the InRange parameter on line 30 is now false, so that the expression will only evaluate to true if the current time is outside our time window of 0-30 minutes since the job started.

And there we have it!  Unfortunately the SCOM 2007 Authoring console doesn’t allow you to use the wizard when trying to use DayTime/Exists expressions, so you’ll need to hit the “edit” button and get your hands dirty with XML yourself.  My suggestion would be to create your logic using the wizard with a placeholder line in place where you want your DayTimeExpression, and then to edit it by hand to include that line afterwards.  Just don’t try to open your ExpressionFilter in the wizard using the “configure” button afterwards, as it will break your expression.  You’ll have to keep using the edit button and editing it by hand.

As always, I hope that helped someone out, and feel free to post a comment if I haven’t made anything clear or you have practical example you’d like to work through.

Posted in Computing | Tagged: , , , , | 1 Comment »

 
Follow

Get every new post delivered to your Inbox.