Wednesday, September 3, 2014

Tip: Approve all In Progress Activities in Service Manager

Stop manually approving each test review activity. Service Manager implementations usually include immense amounts of testing. If you are testing Service Requests or Change Requests, you probably have tons of review activities to approve. It can be time consuming to approve each activity, because, unlike manual activities, we can't just select them all and complete them. We have the option of deleting or canceling the work items, but this isn't really testing.

SMLETS and powershell makes our lives much easier when it comes to administration. However, review activity relationships are slightly different than most other relationships. It can sometimes be difficult to figure out what to do when it comes to powershell and reviewers.

The below powershell script retrieves all review activities, retrieves the reviewers for those activities, and then sets the decision to approved. This will allow the review activity to review the decisions, and then complete itself - exactly as it would happen inside the console.

If you don't care how it works, then just grab the script and run it on your management server where you have SMLETS installed.
If you want to learn a little and become a better Service Manager Administrator, I have broken down the script.
If you don't have SMLETS, you can get it from Codeplex.

The script with explanation comments:
#This is pretty self-explanatory, but we are importing SMLETS.
Import-Module SMLETS
#Before we can retrieve any objects, we need to get the object class. The Object class we are looking for is "ReviewActivity". Why the "$" (dollar sign) at the end? As part of this particular cmdlet,  the search is using regexp. The "$" marks the end of the line. We use this because there are cases where the cmdlet would retrieve more than one object class due to regexp matching.
$RAC = get-SCSMClass System.WorkItem.Activity.ReviewActivity$
#We need to filter out object results to only "In Progress" review activities. "Activity Status" is an enumeration.
$ActStatusEnumInProgress = Get-SCSMEnumeration ActivityStatusEnum.Active$
#We need the GUID of the enumeration so our "filter" switch will retrieve the correct results.
$InProgressEnumId = $ActStatusEnumInProgress.id
#Here, we are querying the review activity objects. The "class" switch specifies what class we want, in this case, "review activity".
#The "Filter" switch is a server side filter that is far more efficient than "Where-object". We can filter on any column for that object.
$RAS = get-SCSMObject -class $RAC -filter "Status -eq '$InProgressEnumId'"
#So far, we should have all of the Review activities that are in progress. You can type $RAS to see a list of the review activities.
#We probably have more than one activity in an array, but we need to perform actions on each individual object. 
foreach ($RA in $RAS){
  #We are going to retrieve any relationships for each activity, where the activity is the source of the relationship.
  $RElObj = Get-SCSMRelationshipObject -BySource $RA
  #We do not want all relationships, only the reviewer relationship.
  foreach ($Obj in $RELObj) {
    if ($Obj.TargetObject.ClassName -eq "System.Reviewer") {
      #Now we are getting the reviewer object itself, but rather than specifying class and filter, we have the GUID. We can use the "id" switch.
      #Once we get the object, we are piping the object into the "Set-SCSMObject" command, which will update the object. The only thing we have to do is set the status to approved for each of the reviewers and internal SCSM workflow will take care of the rest.
      #The command below will not actually make any changes. The "whatif" switch is a powershell switch that essentially tells you what the command is going to do, but does not commit the command. This is a great way to test non-destrutively.
      #Many commands perform actions without output, so it is sometimes difficult to see what is going on. The "verbose" switch will output additional details at command execution.
      #If you are ready to execute the command and approve your activities, simply remove "-whatif".
      get-SCSMObject -id ($Obj.Targetobject.ID) | Set-SCSMObject -Property Decision -Value "Approved" -whatif -verbose
    }
  }
}

The Script with no comments:
Import-Module SMLETS
$RAC = get-SCSMClass System.WorkItem.Activity.ReviewActivity$
$ActStatusEnumInProgress = Get-SCSMEnumeration ActivityStatusEnum.Active$
$InProgressEnumId = $ActStatusEnumInProgress.id
$RAS = get-SCSMObject -class $RAC -filter "Status -eq '$InProgressEnumId'"
foreach ($RA in $RAS){
  $RElObj = Get-SCSMRelationshipObject -BySource $RA
  foreach ($Obj in $RELObj) {
    if ($Obj.TargetObject.ClassName -eq "System.Reviewer") {
      get-SCSMObject -id ($Obj.Targetobject.ID) | Set-SCSMObject -Property Decision -Value "Approved" -whatif -verbose
    }
  }
}

When you begin writing powershell scripts, it is a good idea to keep them in a repository, as you will most likely need them more than once, especially when it comes to System Center. If you want to talk more about powershell or System Center, come see me at Techfest Saturday, September 13th at the Sparkhound booth!
Techfest Registration: Techfest Registration
Techfest Site: Houston Techfest

Friday, August 1, 2014

Orchestrator - Misrepresented and Misunderstood

Purpose:
1.       Talk about the misrepresentation of Orchestrator.
2.       Point out some things about Orchestrator that people don't quite understand.
3.       Convince people to give Orchestrator a try.

Summary:
System Center Orchestrator is a product in the System Center Suite. If you have heard of Orchestrator, you have probably heard it along with other buzzwords like "automation" and "cloud." This text is not about writing a cool runbook, automation, pitching cloud services, or discussing how System Center can solve all of the world's IT problems (it can though). I want to discuss a misconstrued view of Orchestrator that I continue to see over and over, which I think prevents IT Organizations from using it or trying it out.

I think that Orchestrator is both misrepresented and misunderstood.

What was my original perception of Orchestrator?

As an Operations Manager and Service Manager guy, I knew that I could build automation for nearly anything without ever relying on any products outside thoese two systems. I have been using Operations Manager to automate IT tasks, and perform cleanup as a result of alerts for years.

Service Manager provides the tools to take a ticket system and turn it into an automation machine using the authoring console, Powershell, and the native flexibility of the system.

So when Microsoft began touting Orchestrator, my first reaction was, why in the world do I need that?” The simple answer is, I don't…

As a matter of fact, I have never had to use Orchestrator for anything…ever. I still haven't found a task, workflow, process, or anything else I couldn't complete by using the other System Center products that were already implemented, even when they were communicating outside the realm of Microsoft. (Thanks PowerShell!)

So, in a sense, Orchestrator almost seems like a novelty - an unnecessary System Center Product…but it's not.

Why use a complex system when a simple system is available?

Let's take a look at Operations Manager and Service Manager. We know they both can do just about anything that we want in terms of process and automation. When you get down deep, both products can get somewhat complicated. They both run complex operations on the back-end, which allows it to use a simple front-end. I mean, have you looked at the databases or stored procedures? My point is, there is a lot going on that we don't see. Even without much of anything configured, the systems are churning away.

The beauty in Orchestrator is its back-end simplicity. What is Orchestrator doing? Nothing. A little maintenance here or there, checking schedules, checking the clock, etc. What are the others doing? Constantly performing complex operations even at base load. And what are they doing when you begin automating your processes, performing remediation, or waiting for a criteria match? Even more. So much in fact, you can easily drop 40 GB of ram or more with several separated disks on the SQL server to maintain an acceptable level of performance while the systems are performing their operations.

So why are so many people taking such complex operations and stuffing them full of more complex operations creating a memory and disk eater, when we have this nice, little calculator waiting for its command? A nice little calculator that will do anything you tell it to do, and communicate with any machine you want to communicate with. Yet a lot of people still don't use it.

I think the answer is simply misrepresentation.

Everyone talks about all the cool, complex things Orchestrator can do, all the systems it can talk to, and all the integration packs that are available. It actually sounds kind of scary. I mean, who has time to do all that?

But, at its base, Orchestrator is not much more than a scheduling engine - a simple calculator.

"Simple" is what Orchestrator was meant to be all along. Take a complex operation and break it down into simple steps.

Do this…

o    Find something you would like to do – such as automation, remediation, communication between 2 systems. Whatever it is, start out with a goal.
o    Document the exact technical process that should happen on paper. If you can't write your process on paper, you can't write it with a computer.
o    Read through Kevin Holman's Orchestrator quick start guide.
o    Take 15 minutes and install Orchestrator 2012 R2.
o    Take another 10 minutes to download and install the integration packs.
o    Create a Runbook

Remember this…
1.       You will stumble through your first runbook, but keep at it, it will get easier.
2.       The more complex operations you remove from other systems and enter into Orchestrator, the easier it will be to maintain, document, and transfer knowledge.
3.       Don't make it complicated. Don't write a giant PowerShell script and enter it into Orchestrator; this defeats the purpose of simplicity.  Break out your steps into multiple activities.

Tuesday, April 22, 2014

Query ALL Service Manager ENUMS and their Hierarchy

I find myself listing out all of the enumerations for lists in Service Manager quite a bit. Rather than spending time doing this over and over, I wrote a query that retrieves all of the enumeration items from Service Manager. I tried to keep it simple so anyone could adjust to his or her needs. It does not require the DW, as I am pulling directly from the ServiceManager database.

   
  SELECT [EnumType].[EnumTypeId] AS Id,
      [EnumType].[ManagementPackId] AS ManagementPackId,
      ep.EnumTypeName,
      [EnumType].[EnumTypeName] AS Name,
      [EnumType].[EnumTypeAccessibility] AS Accessibility,
      [EnumType].[ParentEnumTypeId] AS ParentId,
      DisplayName
  into #eview
  FROM dbo.EnumType
  LEFT Join dbo.EnumType ep on EnumType.EnumTypeId = ep.EnumTypeId and ep.ParentEnumTypeId IS NULL
  LEFT OUTER JOIN DisplayStringView DS1 ON DS1.LTStringId = dbo.[EnumType].[EnumTypeId] AND DS1.LanguageCode = 'ENU'
 
  INNER JOIN dbo.ManagementPack
   ON dbo.ManagementPack.ManagementPackId = [EnumType].ManagementPackId AND dbo.ManagementPack.ContentReadable = 1;
   
  with tree as (
  SELECT ManagementPackid, Id, name,
  cast(DisplayName as varchar(max)) as Hierarchy,
  DisplayName,
  ParentId
  FROM #eview
  Where ParentId IS NULL and displayName IS NOT NULL
  UNION ALL
  SELECT c.ManagementPackId, c.Id, c.name,
  p.hierarchy + ', ' + cast(c.DisplayName as varchar(max)),
  c.DisplayName, c.ParentId
  FROM #eview c
  join tree p on p.Id = c.parentID
  WHERE c.displayName IS NOT NULL
  )
select ManagementPackid, parentid, Name, Hierarchy, DisplayName
from tree
order by 3
drop table #eview

Thursday, February 13, 2014

Get Parent Affected User for Notifications

This is more of a note for myself. For an activity, this will get the affected user of the parent work item.

$Context/Path[Relationship='CoreActivity!System.WorkItemContainsActivity' SeedRole='Target' TypeConstraint='WorkItem!System.WorkItem']/Path[Relationship='WorkItem!System.WorkItemAffectedUser' TypeConstraint='System!System.User']/Property[Type='System!System.User']/FirstName$

Obviously it is only the first name and the references will need to be changed to match the reference alias in the MP.