Introduction

This is the 2nd instalment of the Automating OpsMgr series. Previously on this series:

Few weeks ago, I have also published a post: Collecting ConfigMgr Logs To Microsoft Operation Management Suite – The NiCE Way, which demonstrated how to use an OpInsights integrated OpsMgr management group and NiCE Log File MP to collect ConfigMgr client and server logs into Microsoft Operation Management Suite.

The solution I provided in that post included few sealed management packs and a demo management pack which includes few actual event collection rules for ConfigMgr log files. However, it requires some manual XML editing outside of whatever MP authoring tool that you might be using, which could be a bit complicated for IT Pros and non management pack developers. The manual XML editing is necessary because the log collection rules use a Write Action module called “Microsoft.SystemCenter.CollectCloudGenericEvent” to send the event data to the OpInsights workspace. This write action module is located in the “Microsoft.IntelligencePacks.Types” sealed management pack. This management pack is automatically pushed to your OpsMgr management group once you’ve configured the OpInsights connection.

When using management pack authoring tools such as VSAE, if you need to reference a sealed management pack (or management pack bundle), you must have the sealed MP or MP bundle files (.mp or .mpb) handy and add these files as references in your MP project. But since the sealed MP “Microsoft.IntelligencePacks.Types” is automatically pushed to your management group as part of the OpInsights integration, and Microsoft does not provide a downloadable .mp file for this MP (yes,I have asked the OpInsights product group). There was no alternatives but manually editing the XML outside of the authoring tool in order to create these rules.

Our goal is to create potentially a large number of event collection rules for all the ConfigMgr event logs that ConfigMgr administrators are interested in. In my opinion, this is a perfect automation candidate because you will need to create multiple near-identical rules, and it is very time consuming if you use MP authoring tools and text editors to create these rules (as I explained above).

Pre-requisites

I am going to demonstrate how to create these event collection rules using a SMA runbook which uses The OpsMgrExtended PowerShell module. In order to implement this solution, you will need the following:

  • An OpsMgr 2012 SP1 or R2 management group that has been connected to Azure Operational Insights (OMS)
  • A SMA infrastructure in your environment
  • Microsoft ConfigMgr 2012 management pack version 5.0.7804.1000 imported and configured in your OpsMgr management group
  • The ConfigMgr components of which you need to collect the logs from must be monitored by the OpsMgr (including ConfigMgr servers and clients). These computers must be agent monitored. Agentless monitoring is not going to work in this scenario.
  • NiCE Log File MP imported in your OpsMgr management group
  • OpsMgrExtended module imported into SMA and an “Operations Manager SDK” SMA connection object is created for your OpsMgr management group – Please refer to Part 1 of this series for details
  • The “ConfigMgr Logs Collection Library Management Pack” must also be imported into your OpsMgr management group – Download link provided in my previous post.

Runbook: New-ConfigMgrLogCollectionRule

workflow New-ConfigMgrLogCollectionRule
{
  Param(
    [Parameter(Mandatory=$true)][String]$RuleName,
    [Parameter(Mandatory=$true)][String]$RuleDisplayName,
    [Parameter(Mandatory=$true)][String]$ManagementPackName,
    [Parameter(Mandatory=$true)][ValidateSet("Microsoft.SystemCenter2012.ConfigurationManager.DistributionPoint","Microsoft.SystemCenter2012.ConfigurationManager.ManagementPoint","Microsoft.SystemCenter2012.ConfigurationManager.SiteServer","Microsoft.SystemCenter2012.ConfigurationManager.Client")][String]$ClassName,
    [Parameter(Mandatory=$true)][String]$LogDirectory,
    [Parameter(Mandatory=$true)][String]$LogFileName,
    [Parameter(Mandatory=$true)][String]$EventID,
    [Parameter(Mandatory=$true)][ValidateSet('Success', 'Error', 'Warning', 'Information', 'Audit Failure', 'Audit Success')][String]$EventLevel,
    [Parameter(Mandatory=$false)][Int]$IntervalSeconds=120
  )

  #Get OpsMgrSDK connection object
  $OpsMgrSDKConn = Get-AutomationConnection -Name "OpsMgrSDK_TYANG"

  #Get the destination MP
  Write-Verbose "Getting managemnet pack '$ManagementPackName'..."
  $MP = Get-OMManagementPack -SDKConnection $OpsMgrSDKConn -Name $ManagementPackName

  If ($MP)
  {
  #MP found, now check if it is sealed
    If ($MP.sealed)
    {
      Write-Error 'Unable to save to the management pack specified. It is sealed. Please specify an unsealed MP.'
      return $false
    }
  } else {
    Write-Error 'The management pack specified cannot be found. please make sure the correct name is specified.'
    return $false
  }

  #Make Sure the MP is referencing to 'Microsoft.Windows.Library' MP
  $WinLibRef = inlinescript {
    #Get the destination MP
    Write-Verbose "Getting managemnet pack '$USING:ManagementPackName'..."
      $MP = Get-OMManagementPack -SDKConnection $USING:OpsMgrSDKConn -Name $USING:ManagementPackName

      If ($MP)
      {
        #MP found, now check if it is sealed
        If ($MP.sealed)
        {
          Write-Error 'Unable to save to the management pack specified. It is sealed. Please specify an unsealed MP.'
          return $false
        }
      } else {
        Write-Error 'The management pack specified cannot be found. please make sure the correct name is specified.'
        return $false
      }

    #Make sure the destination MP is referencing the Microsoft.Windows.Library MP
    $MPReferences = $MP.References
    Foreach ($item in $MPReferences)
    {
      Write-Verbose "$($item.value.name)"
        If ($($item.value.Name) -eq "Microsoft.Windows.Library")
      {
        $WinLibRef = $item.key
        Write-Verbose "The MP ref key for 'Microsoft.Windows.Library' is $WinLibRef"
      }
    }
    If ($WinLibRef -eq $NULL)
    {
      Write-Verbose "The MP ref for 'Microsoft.Windows.Library' is not found."
      #Create the reference
      $NewMPRef = New-OMManagementPackReference -SDKConnection $USING:OpsMgrSDKConn -ReferenceMPName "Microsoft.Windows.Library" -Alias "Windows" -UnsealedMPName $USING:ManagementPackName
      If ($NewMPRef -eq $true)
      {
        $WinLibRef = "Windows"
      } else {
        Write-Error "Unable to create a reference for 'Microsoft.Windows.Library' MP in the destination management pack '$ManagementPackName'. Unable to continue."
        Return $false
      }
    }
      $WinLibRef
  }
  #Get Event Level
  $iEventLevel = Inlinescript
  {
    Switch ($USING:EventLevel)
    {
      'Success' {$iEventLevel = 0}
      'Error' {$iEventLevel = 1}
      'Warning' {$iEventLevel = 2}
      'Information' {$iEventLevel = 4}
      'Audit Failure' {$iEventLevel = 16}
      'Audit Success' {$iEventLevel = 8}
    }
    $iEventLevel
  }

  #Data Source Module Configuration:
  [OpsMgrExtended.ModuleConfiguration[]]$arrDataSourceModules = @()
  #Determine which Data Source module to use (client vs server)
  If ($ClassName -ieq 'Microsoft.SystemCenter2012.ConfigurationManager.Client')
  {
    $DAModuleTypeName = "ConfigMgr.Log.Collection.Library.ConfigMgr.Client.Log.DS"
  } else {
    $DAModuleTypeName = "ConfigMgr.Log.Collection.Library.ConfigMgr.Server.Log.DS"
  }

  Write-Verbose "WMI Query: `"$WMIQuery`""
  $DAConfiguration = @"
<IntervalSeconds>$IntervalSeconds</IntervalSeconds>
<ComputerName>`$Target/Host/Property[Type="$WinLibRef!Microsoft.Windows.Computer"]/NetworkName$</ComputerName>
<EventID>$EventID</EventID>
<EventCategory>0</EventCategory>
<EventLevel>$iEventLevel</EventLevel>
<LogDirectory>$LogDirectory</LogDirectory>
<FileName>$LogFileName</FileName>
"@
  $DAMemberModuleName = "DS"
  $DataSourceConfiguration = New-OMModuleConfiguration -ModuleTypeName $DAModuleTypeName -Configuration $DAConfiguration -MemberModuleName $DAMemberModuleName
  $arrDataSourceModules += $DataSourceConfiguration

  #Write Action modules
  [OpsMgrExtended.ModuleConfiguration[]]$arrWriteActionModules = @()
  $WAWriteToDBConfiguration = New-OMModuleConfiguration -ModuleTypeName "Microsoft.SystemCenter.CollectEvent" -MemberModuleName "WriteToDB"
  $WAWriteToDWConfiguration = New-OMModuleConfiguration -ModuleTypeName "Microsoft.SystemCenter.DataWarehouse.PublishEventData" -MemberModuleName "WriteToDW"
  $WAWriteToOMSConfiguration = New-OMModuleConfiguration -ModuleTypeName "Microsoft.SystemCenter.CollectCloudGenericEvent" -MemberModuleName "WriteToOMS"
  $arrWriteActionModules += $WAWriteToDBConfiguration
  $arrWriteActionModules += $WAWriteToDWConfiguration
  $arrWriteActionModules += $WAWriteToOMSConfiguration

  #Create WMI Event Collection Rule, MP Version will be increased by 0.0.0.1
  $RuleCreated = InlineScript
  {
    #Validate rule Name
    If ($USING:RuleName -notmatch "([a-zA-Z0-9]+\.)+[a-zA-Z0-9]+")
    {
      #Invalid rule name entered
      $ErrMsg = "Invalid rule name specified. Please make sure it only contains alphanumeric charaters and only use '.' to separate words. i.e. 'Your.Company.Application.Log.EventID.1234.Collection.Rule'."
      Write-Error $ErrMsg
    } else {
      #Name is valid, creating the rule
      New-OMRule -SDKConnection $USING:OpsMgrSDKConn -MPName $USING:ManagementPackName -RuleName $USING:RuleName -RuleDisplayName $USING:RuleDisplayName -Category "EventCollection" -ClassName $USING:ClassName -DataSourceModules $USING:arrDataSourceModules -WriteActionModules $USING:arrWriteActionModules -Remotable $false
    }
  }

  If ($RuleCreated)
  {
    Write-Output "Rule `"$RuleName`" created."
  } else {
    Write-Error "Unable to create Rule `"$RuleName`"."
  }
}

When executing this runbook, the user must specify the following parameters:

  • RuleName: the internal name of the OpsMgr rule
  • RuleDisplayName: the display name of the OpsMgr rule
  • ManagementPackName: The internal name of the management pack (must be an existing MP in your OpsMgr management group)
  • ClassName: The target class of the rule. It must be one of the following values:
    • “Microsoft.SystemCenter2012.ConfigurationManager.DistributionPoint”
    • “Microsoft.SystemCenter2012.ConfigurationManager.ManagementPoint”
    • “Microsoft.SystemCenter2012.ConfigurationManager.SiteServer”
    • “Microsoft.SystemCenter2012.ConfigurationManager.Client”
  • LogDirectory: The directory where the log is located (i.e. “C:\Windows\CCM\Logs”)
  • LogFileName: The name of the log file (i.e. “UpdatesStore.Log”)
  • EventID: The Event ID that you wish to use when converting log file entries to Windows events
  • EventLevel: Windows event level. Must be one of the following values:
    • ‘Success’
    • ‘Error’
    • ‘Warning’
    • ‘Information’
    • ‘Audit Failure’
    • ‘Audit Success’
  • IntervalSeconds: How often does the rule run

On line 16 of the runbook, I’ve coded the runbook to retrieve a SMA connection object called “OpsMgrSDK_TYANG”:

image

This is because my SMA connection object for my OpsMgr management group is named “OpsMgrSDK_TYANG”. You will need to change this line according to how you’ve created your SMA connection:

SNAGHTML10a57cfa

You can also further simplify the runbook in the following possible areas:

  • Hardcoding the destination management pack in the runbook
  • Hardcoding the interval seconds (i.e. to 120 seconds)
  • Create a switch statement for the target class, so instead entering “Microsoft.SystemCenter2012.ConfigurationManager.Client”, users can simply enter “Client” for example.
  • Create a switch statement for the LogDirectory parameter. for example, when the target class of “Client” is specified, set LogDirectory variable to “C:\Windows\CCM\Logs”.
  • Automatically populate Rule name and display name based on the target class and the log file name.
  • Build a user’s request portal using System Center Service Manager or SharePoint List (This would be a separate topic for another day, but Please refer to my previous MVP Community Camp presentation recording for some samples I’ve created in the past using SharePoint Lists).

Lastly, needless to say, you can also execute this PowerShell workflow in a standalone PowerShell environment (or convert this PowerShell workflow into a regular PowerShell script). When running it outside of SMA, you will need to use another Parameter Set for the “New-OMManagementPackReference” and “New-OMRule” activities. So instead of using –SDKConnection Parameter, you will have to use –SDK (and optionally –Username and –Password) to connect to your OpsMgr management group. To Change it, please modify the following lines:

Change Line 16 to

$SDK = "<Your OpsMgr management server>"

Change Line 47 to:

image

$NewMPRef = New-OMManagementPackReference -SDK $SDK -ReferenceMPName "Microsoft.Windows.Library" -Alias "Windows" -UnsealedMPName $ManagementPackName

Change Line 117 to:

image

New-OMRule -SDK $USING:SDK -MPName $USING:ManagementPackName -RuleName $USING:RuleName -RuleDisplayName $USING:RuleDisplayName -Category "EventCollection" -ClassName $USING:ClassName -DataSourceModules $USING:arrDataSourceModules -WriteActionModules $USING:arrWriteActionModules -Remotable $false

Result:

After I filled out all the parameters:

image

image

image

And executed the runbook:

image

The rule was successfully created:

image

And shortly after it, you should start seeing the log entries in your OMS workspace:

image

Conclusion

I have demonstrated how to use the OpsMgrExtended module in a SMA runbook to enable users creating large number of similar OpsMgr management pack workflows.

Given this is only part 2 of the series, and the first example I have released, maybe I should have started with something easier. The reason I’ve chosen this example as Part 2 is because I am going to present in the next Melbourne System Center, Security, & Infrastructure user group meeting next Tuesday 7th July among with 3 other MVPs (David O’Brien, James Bannan and Orin Thomas). I am going to demonstrate this very same scenario - using OpInsights to collect SCCM log files. So I thought I’ll make this the 2nd instalment of the series, so people who attended the user group meeting have something to refer to. In this sample runbook, I’ve used a relatively more complicated activity called New-OMRule to create these event collection rules. This activity is designed as a generic method to create any types of OpsMgr rules. I will dedicate another blog post just for this one in the future.

Lastly, if you are based in Melbourne and would like to see this in action, please come to the user group meeting in the evening of 7th July. It is going to be held at Microsoft Melbourne office in South Bank. the registration details is available on the website: http://mscsig.azurewebsites.net/.

Leave a comment