.\Matthew Long

{An unsorted collection of thoughts}

Posts Tagged ‘SCO 2012’

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!

Advertisements

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 »

Integrating Operations Manager 2012 beta with Opalis / Orchestrator

Posted by Matthew on October 10, 2011

I’m lucky enough in my lab environment to have access to both the Orchestrator beta and both SCOM 2007 and SCOM 2012 beta.  I was recently tasked with creating a demo for a customer focused around SCOM 2012 and Orchestrator.  Whilst an updated integration pack for SCOM 2012 has yet to be released for Orchestrator (or indeed, Opalis 6.3) you can use the existing IP just fine, providing you complete a few work arounds.

Requirements

First thing – you’re going to need access to the SCOM 2007 R2 media to be able to complete this.  As directed by the SCOM Integration pack, install the SCOM 2007 R2 console on your action/runbook servers and your Client/Designer machines.  If you attempt to use the SCOM 2012 console in it’s place you will (in my experience) receive connection errors when attempting to use the IP.

Create Alert object workaround

Secondly – In order to use the Create Alert object the Integration pack will normally deploy a management pack into SCOM automatically the first time it is used.  Unfortunately the SDK for SCOM has changed and the method previously employed no longer works (you will receive an error stating as such when the object attempts to run).  In order to resolve this, you will need to :

  1. Have Opalis/Orchestrator raise an alert in a SCOM 2007 environment
  2. Export the management pack from the SCOM 2007 environment that has been automatically imported.  Note that as the MP is sealed, you will need to use the Export-ManagementPack powershell command as the GUI will have the export option grayed out.  The management pack is called Opalis Integration Library.Get-ManagementPack | ? {$_.name -match ‘Opalis’} | Export-ManagementPack -path c:\Folder\
  3. Import the management pack into your SCOM 2012 environment

Following this, you will now be able to use all of the IP objects in both SCOM 2007 and SCOM 2012.

For those without access to SCOM 2007, i’ve attached a copy of the management pack that you can import into your environment.  Note : The management pack is unsealed as it’s been exported from within a SCOM environment.  If you are uncomfortable importing an unsealed MP into your environment, do not do so, and instead utilize the method above to obtain your own (still unsealed) version of the MP.

Link to Opalis.Integration.Library.zip

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

Book Review : System Center Opalis Integration Server 6.3

Posted by Matthew on October 10, 2011

Introduction

Penned by an all-star cast of Microsoft Evangelists and community MVPs, System Center Opalis Integration Server 6.3 Unleashed is a dedicated resource for all things Opalis.  The book is published by Sams, and is available in physical (paperback) and Kindle editions.

Review

For those looking for a thorough and in-depth resource on Opalis Integration Server, this is definitely it.  The book starts out discussing the history and concepts of Opalis integration server, introducing the product to new users and relating users of previous versions to the current product with ease.

The book then goes on to discuss the Architectural design, installation, implementation and best practises when setting up Opalis in your environment, complete with design discussions and important questions that you should consider before touching the installer binaries.

Key foundation objects and common/advanced tasks are covered, always with examples, including Data Manipulation, Data Persistence, Scheduling, calling external systems error control and more.  The book is not afraid to point to community Integration packs to ensure that you can get the most out of your environment, and I’d be surprised if you’ve heard of them all.

The 3rd party integration packs included with the product are then discussed, with object listings and installation requirements.  This is followed by dedicated chapters for integrating Opalis with each System Center product, covering the installation of the IP and then their object uses.  Sample workflows are included with step-by-step construction examples.  It would have been nice if a bit more time had been spent with the 3rd party IPs, but the breadth of products available in this category would have easily turned this 500 page book into a huge hulking tome).

An entire chapter is then dedicated to Data Center scenarios and workflows, with many challenges to/for private cloud tackled and demonstrated.  While the challenges in this chapter are solved primarily to System Center products, you can easily see how they could be resolved with comparable technologies (Swap out System Center Service Manager for your own CMDB and Service desk product, for example).

Finally, the book discusses the Quick Integration Kit, and unlike many other resources I’ve seen out there actually covers the QIK/Opalis SDK.  This chapter is a good compliment to the QIK SDK documentation and if you are interested in IP development is definitely a must read.

The appendices are full of useful links to various online resources, many of which readers will already (or should) be familiar with.

Looking ahead – System Center Orchestrator 2012

The book is very careful with the topic of Orchestrator and does not attempt to muddy the waters – it is firmly an Opalis 6.3 book.  However nearly all the topics discussed and skills learned are directly applicable to Orchestrator and i’d still recommend the book to anyone using scorch as aside from the system requirements and Operators console, everything else is directly transferable (albiet with a slightly different dictionary – Policies are now Runbooks, Objects are now activities, etc).

Summary

In closing, I felt this was a good resource with lots of practical, helpful example workflows.  The subject matter is discussed in-depth and limitations with the product are addressed, with best practise being discussed throughout.  There are unfortunately some editorial errors in the book (in one case a displaced paragraph!) but the technical content remains error free.  This is a book I am glad to own and one I’d recommend to anyone interested in or working with Opalis 6.3 or the upcoming Orchestrator 2012.

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

Courseware : 50507A Designing IT Process Automation with Opalis Integration Server

Posted by Matthew on October 10, 2011

I recently had the fortune to take part in the Microsoft official course 50507A – Designing IT Process Automation with Opalis Integration Server, and thought I would briefly share my views on the courseware.

For those of you looking for a solid introduction or rounding out of your Opalis knowledge/skills, this is a very good, hands on course.  The ratio of time spent in hands on labs to lecture/discussion is almost 2:1, so for those of you who like getting your hands on the product and learning for yourself, this is a great course.

Many of the powerful foundation objects are covered, with practical examples of the application of each.  The courseware also covers integrating with the entire system center suite, though labs neglect SCCM and SCDPM unless you/the instructor choose to set a challenge lab.  Also discussed (though not to a huge depth, given the courseware requirements and general accessibility) is the production of one’s own Integration Packs using the Quick Integration Kit, including a lab on the QIK CLI.

Finally, for those of you considering Orchestrator this course is completely applicable – all of the knowledge transfers directly across with only a few modifications (namely terminology, system requirements, and the Operations Console, the latter of which is only discussed but not featured in the courseware/labs).  A good instructor will point out these where appropriate so that you are ready to go when Orchestrator goes RTM (currently Orchestrator 2012 is in public beta).

In closing, this is one of the higher rated MOC in recent times, and it’s clear to see why.  I wouldn’t recommend taking every MOC, but I’d definitely recommend this one.

Course 50507A: Designing IT Process Automation with Opalis Integration Server

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