Introducing Windows PowerShell Desired State Configuration!

We have just announced the CTP of Desired State Configuration for Linux.  If you missed it, be sure to check out:

1) The announcement and demo at TechEd North America 2014

2) The announcement at the PowerShell Team Blog

3) A step-by-step guide for compiling and installing DSC for Linux and applying your first configuration MOF at the Building Clouds blog

4) The CTP release can be found over at Github

This is exciting stuff!

Advertisement

Using PowerShell to Check for Syntax Errors in System.ExpressionFilter Modules (OpsMgr Authoring)

With its wide range of usefulness in implementing conditional logic, expression evaluation, and error filtering, the System.ExpressionFilter module is likely to be a frequently used module in most OpsMgr Management Pack authoring scenarios.   However, the default configuration for the System.ExpressionFilter module may lead to a potential syntax error that is quite easy to miss, in my opinion.  This potential syntax error relates to the default configuration of the ValueExpression elements of the ExpressionFilter, in that the ValueExpression defaults to an XPathQuery value type.   If this default is not changed when evaluating a non-XPathQuery value, the workflow (as well as all workflows cooked down with the faulted workflow) will fail.

To illustrate an oversight resulting in this error, the following ExpressionFilter configuration would result in a workflow failure:

<SimpleExpression>
   <ValueExpression>
        <XPathQuery>ErrorCode</XPathQuery>
   </ValueExpression>
   <Operator>Equal</Operator>
   <ValueExpression>
       <XPathQuery>1</XPathQuery>
    </ValueExpression>
</SimpleExpression>

The correct implementation of this Expression Filter module would be:

<SimpleExpression>
   <ValueExpression>
        <XPathQuery>ErrorCode</XPathQuery>
   </ValueExpression>
   <Operator>Equal</Operator>
   <ValueExpression>
       <Value>1</Value>
    </ValueExpression>
</SimpleExpression>

Unfortunately, this type of error is not caught by the MPBPA, most likely due to the difficulty in differentiating between a valid XPathQuery value and string value.  To perform some basic error checking to identify these errors when authoring, I have written a simple PowerShell script that analyzes the XML of an unsealed Management Pack and reports errors and potential errors with ValueExpression configuration in ExpressionFilter modules.  

The logic of the script assumes the following:

  • Any ValueExpression configured as an XPathQuery expression and having a value that starts with a dollar sign ($) can be assumed to be a configuration error
  • Any ValueExpression configured as an XPathQuery expression and having a value that does not start with a forward slash or the strings:  Property or ErrorCode might be misconfigured

The script accepts the path to the Management Pack XML file as the single input parameter and then searches the XML for RegExExpression, SimpleExpression, and DayTimeExpression XML nodes.  These nodes are evaluated for mismatches on XPathQuery expressions and mismatches are reported to the console.

The output of the script looks like:

PS D:\Development\SCOM> ./checkexpressionfilters.ps1 -MPFIle:”d:\development\scom\xsnmp\1.1.Dev\xSNMP.AIX.xml”
Evaluating d:\development\scom\xsnmp\1.1.Dev\xSNMP.AIX.xml 

Error – Found mismatched XPathQuery value with XML:
<XPathQuery>$Target/Property[Type=”xSNMP.AIX.Processor”]/Name$</XPathQuery> 

Error – Found mismatched XPathQuery value with XML:
<XPathQuery>$Target/Property[Type=”xSNMP.AIX.Processor”]/Name$</XPathQuery> 

Errors found: 2
Warnings found: 0

The script can be downloaded here.

Read more of this post

OpsMgr: R2 PowerShell Modules Example – DNS Resolution Monitor

While I’m finalizing some work on the Oracle SCX management pack,  I wanted to interrupt that series of posts to make a post walking through the use of one of the OpsMgr R2 PowerShell modules –something that I have been meaning to write up for some time.

The addition of native PowerShell modules was one of the major improvements in OpsMgr R2, and these modules collectively introduce an incredible degree of flexibility and improved efficiency in highly customized script-based monitoring.  There are a total of six PowerShell modules available in R2, and in this post, I will walkthrough an example using the Microsoft.Windows.PowerShellPropertyBagProbe module.   The monitor created in this example is a simple DNS resolution check that can be deployed to Windows agent-managed systems for perspective monitoring of DNS client resolution.

The example management pack can be downloaded here.

Management Pack, Class, and Discovery

Firstly, to build this monitor, a new management pack named DNSClientMonitoring is created. 

Read more of this post

Automating WSS 3.0 Backups with a Script

Although SQL backups of the content databases for a Windows SharePoint Services farm can be used for data recovery, it’s usually a good idea to also perform backups through the stsadm.exe utility to facilitate site and object-level restores.   I recently took on a task to script a more robust solution for the automation of WSS farm backups, which I will describe here.

The stsadm.exe utility can be used to backup in two modes, site collection and catastrophic.  The site collection method backups up an individual site and content for an individual site, specified by URL, and the catastrophic backup method backs up the entire farm or a specified object in a full or differential mode.    I opted to go with the catastrophic backup method in this script to support differential backups and eliminate the requirement to enumerate individual sites for backup operations. 

WSS Backup Script Overview

The script is a bit too long to post in its entirity, but it can be downloaded here.   The script accepts three parameters:

  • The target backup directory path
  • The backup type (full or differential)
  • The number of backups to maintain

The backup operation is relatively simple:  the script uses the WScript.Shell.exec method to execute the stsadm.exe command (after querying the registry to determine the install path of WSS).

Command = sPath & “\STSADM.exe -o backup -Directory ” & BackupDir & ” -BackupMethod ” & BackupType

Set oExec = WshShell.Exec(command) 
While Not oExec.StdOut.AtEndOfStream 
    OutPut = oExec.StdOut.ReadAll
Wend 
Do While oExec.Status = 0
    WScript.Sleep 5000
Loop

To improve monitoring of the operation, the script performs a shell execution to the eventcreate.exe utility to log status to the Windows Application Log.   (Although the WScript.Shell supports basic EventLog logging, I wanted to control the event source and ID, so the eventcreate.exe utility seemed to be a better option).

If blSuccessful then
   Command =  “Eventcreate /L Application /T INFORMATION /ID 943 /SO “”SharePoint Backups”” /D “” ” & sMesg & “”
Else
   Command =  “Eventcreate /L Application /T WARNING /ID 944 /SO “”SharePoint Backups”” /D “” ” & sMesg & “”
End if
Set oExec = WshShell.Exec(command)

The most complex operation of this WSS backup automation script is the maintenance of old backups.  The stsadm backup operation maintains an XML file named spbrtoc.xml in the backup directory with meta-data related to past backups.   While an example of deleting backups older than a certain time interval can be found here, I wanted to maintain past backups based on a count (x number of fulls, x number of differentials).    To implement this, the script loads meta-data from the Table of Contents XML file into an array, determines the number of backups to be purged (correlated to the current backup operation type – full or differential), flags the oldest backups for deletion, and then deletes the related backup directories and XML nodes.  

Automating With System Center Operations Manager 2007

Read more of this post

Recursively Listing Security Group Members with PowerShell, Version 2

In this post, I described the use of PowerShell for the purpose of generating a report of all members of a particular group, including nested groups.  The script utilized ADSI calls to the WinNT:// provider to recursively retrieve both local and domain group members.   However, it was brought to my attention that the WinNT:// provider cannot access group objects located in non-default OU’s, but only the default Users container.   In order to access group objects located in OU’s, the ADSI queries have to be targeted to the LDAP:// provider.   This posed a bit of a challenge in correcting due to the fact that LDAP:// can’t access local group members so both the WinNT:// and LDAP:// providers had to be selectively utilized.

An updated version of this script can be downloaded here.  This version utilizes the same command line syntax:  powershell.exe c:\scripts\listusers.ps1 “Domain_or_Server_Name\Group_Name” 5.   The first parameter can be a domain name or server name followed by a backslash and the group name.  If the group name contains spaces, this parameter must be wrapped in quotes.  The second parameter is the recursion depth, how many levels of nested groups the script will traverse and report on.  The script outputs group membership details to the command window as well as a text file (located in the same directory as the script) named with the group name. 

The inner workings of this script became more complicated in this version, largely because I wanted the script to automatically select which provider to use in the ADSI calls.  The functional overview of the script is as follows:

Read more of this post

SCOM: WSH Vs. PowerShell Modules in Composite Workflows – Resource Utilization in SNMP Data Manipulation

One of the realities of working with SNMP monitoring is that more often than not, the monitoring data are presented in a raw form that requires some kind of manipulation in order to render meaningful output.  For example, required data manipulation may be a simple arithmetic operation on two values to calculate a percentage, or in the case of Counter data, mathematical operations based on the delta between values recorded in multiple polling cycles.  In Operations Manager, these manipulations require exiting the realm of managed code and utilizing script-based modules to perform the operations or facilitate temporary storage of values from previous polling cycles.  Two sets of modules are available for the Operations Manager –supported scripting engines: WSH and PowerShell.  To date, I had been opting to use VB scripts when authoring Management Packs for two reasons: 1) WSH is universally deployed in Windows environments whereas PowerShell is not necessarily so – by using VB scripts, there is no requirement to install Power Shell on proxy agents 2) I had assumed that the resource utilization impact of PowerShell was equal or greater than that of WSH.   I had assumed that PowerShell would carry a heavier impact based on the simple notion that if one were to watch process resource utilization when simply launching powershell.exe and cscript.exe, powershell.exe consumes more memory and CPU time (assuming WSH 5.7 is installed).  

The resource utilization of these script providers becomes a major concern particularly when implementing script-based modules in SNMP monitoring scenarios.   To illustrate this point, if a proxy agent were configured to proxy SNMP requests for 10 Cisco switches, with each of these switches having an average of 20 interfaces discovered, and each interface monitored with two monitors that utilize a script probe action to manipulate the raw SNMP data (e.g. collisions and octets), 400 scripts would be executed in a single polling cycle for just the interface monitors for this small scale monitoring scenario.  This poses a threat to the scalability of SNMP monitoring and could severely limit the number of devices/objects a single proxy agent can handle effectively.  

In the course of trying to find a way to address this scalability issue, I was fortunate enough to communicate with someone possessing a great deal of insight into Operations Manager who helpfully suggested that the PowerShell modules should be more efficient than WSH-based modules in composite workflows.  I rewrote all of the scripts in the Cisco MP to convert them from VB Script to PowerShell and began some testing.  I was familiar with the tighter integration of PowerShell in R2 modules (PS scripts no longer have to be launched as external commands), but to be honest, I was expecting to see a large number of powershell.exe processes spawned as the monitors fired.   However, this is not the case.  Rather, it looks to me that the modules are executing the PowerShell script through the .NET framework within the context of the monitoringhost.exe process.   This does appear to be more efficient overall, as the overhead associated with spawning new processes is effectively eliminated, and my impressions thus far are that CPU utilization overall is reduced.

However, switching from WSH scripts to PowerShell scripts in R2 workflows is a little bit of jumping from the frying pan and into the fire in that, instead of spawning a large number of processes each consuming relatively small amounts of processor and memory resources, the PowerShell script modules drive a single process (monitroinghost.exe) to consume a large quantity of resources, particularly CPU cycles.   Overall, memory utilization looks a lot better with the PowerShell modules, and although CPU utilization does seem to be better, it is still a concern for scalability. 

Thus far, I have been doing this performance testing in a development environment, with OpsMgr running on some virtual machines on both on workstation and older server class hardware, neither of which provide a good indication of real-world scalability (particularly given the fact that I have these VM’s running SQL, all OpsMgr duties, and SNMP simulations to boot).  On one of these woefully over-utilized VM’s, something around 130-150 interfaces on 10 monitored Cisco devices seemed to be the breaking point, but a more realistic OpsMgr deployment scenario (segregated database, RMS, and MS duties) on physical hardware should be able to handle far more than that.   I will report an update once I get a chance to do some broader scalability testing with the PowerShell version of the MP on more appropriate hardware. 

In summary, both the WSH and PowerShell probe and write action modules introduce a relatively heavy CPU load when utilized for data manipulation – relative to the very simple operations required to manipulate SNMP data, and a managed code module would be far more desirable, if available.  However, at present, these two providers are the only supported mechanisms for handling data that require processing before returning to a rule or monitor.   My testing thus far appears to support the assertion that R2 implements the PowerShell modules more efficiently than the WSH-based modules, which is welcome news, given the relative ease and impressive flexibility of scripting with PowerShell.  I’ve seen a bit of talk that PowerShell V2 is supposed to bring significant performance improvements over V1, and I hope to do some testing with the CTP version of V2 on an OpsMgr proxy agent in the very near future to see if it helps address any of the scalability challenges in SNMP monitoring with OpsMgr.  As for the best approach for the present, it looks like PowerShell is the way to go, and the overall impact on the MS/proxy agents can be mitigated by spreading monitored objects across multiple proxy agents, focusing discovery to only those objects which are required to be monitored (i.e. interfaces), and avoiding overly-aggressive scheduling of monitors.

SCOM: Advanced SNMP Monitoring Part II: Designing the SNMP Monitors

For the Cisco Management Pack, a handful of different approaches were required when designing the monitors and rules and their supporting workflows.  These approaches can generally be placed into three categories:

  • Simple SNMP GET operations
  • Operations that require data manipulation
  • Operations that require access to previously collected values  

For example, monitoring of an interface’s operational status only requires current SNMP GET requests (to retrieve the ifOperStatus and ifAdminStatus values) from the SNMP ifTable.  Condition detection for the monitor type definition can handle the SNMP values as they are presented with no further manipulation.   However, to monitor a value such as the percent free bytes on a Cisco memory pool, data manipulation is required.  In this example, a percentage value is not exposed via SNMP, but free and available values are.  So, to calculate a percentage, the free and available bytes values must be summed and then the free value divided by that sum.  And lastly, in some cases, a value from a previous poll must be referenced to detect the desired condition, such as monitoring for an increase in the collisions reported for a Cisco interface.  In this example, the locIfCollisions values can be retrieved from the locIfTable, but this is a continually augmenting counter, which is difficult to monitor.   By recording the value from the immediately previous poll, and comparing it with the current poll, a delta value can be established for that polling cycle to determine the number of collisions recorded in a single polling cycle. 

Read more of this post

VBS: Decoding Base64 Strings (in 10 lines of code)

This code snippet can be used to decode Base64 encoded strings into plain text, which I have found useful recently when working on VBscript scripts that require decoding the Base64-encoded SNMP community strings stored in OpsMgr.  I thought it would be worth sharing.

Function Decode(strB64)
 strXML = “<B64DECODE xmlns:dt=” & Chr(34) & _
        “urn:schemas-microsoft-com:datatypes” & Chr(34) & ” ” & _
        “dt:dt=” & Chr(34) & “bin.base64” & Chr(34) & “>” & _
        strB64 & “</B64DECODE>”
 Set oXMLDoc = CreateObject(“MSXML2.DOMDocument.3.0”)
 oXMLDoc.LoadXML(strXML)
 decode = oXMLDoc.selectsinglenode(“B64DECODE”).nodeTypedValue
 set oXMLDoc = nothing
End Function

Recursively Listing Security Group Members with PowerShell

It seems like a favorite request of auditors is one for lists of all members of a set of local or domain groups that are associated with a resource that is being audited, and these requests typically stipulate that all members of nested groups must be listed as well (i.e. full recursion).  I used to use a VBS script to perform this functionality, but I’ve recently rewritten it in PowerShell.  The script accepts a group name (either local or domain) as well as a recursion depth as command line arguments and outputs a list of all group members to a text file.

The method used to retrieve the group members is:

 $Group= [ADSI]”WinNT://$GroupName,group”
 $Members = @($Group.psbase.Invoke(“Members”))
 

With that, it’s just a matter of configuring a function that accepts a group name as an input parameter, outputs the members, and loops through the member groups until the defined recursion depth is reached.

The script can be downloaded here.  And the output looks like:

The script could be easily modified to accept a text file with a list of group or server names as in input, or modified to output the results in HTML instead of plain text.

SCOM: Automating Management Pack Documentation

It’s easy to argue the case for keeping accurate documentation of SCOM management pack monitors and customizations, both for the abstract purpose of maintaining good documentation, as well as the more practical purpose of being able to answer the “can you list what is being monitored?” question. However, it can be tedious to keep on top of this documentation. But, given the flexibility of the SCOM command shell, it’s relatively easy to configure a powershell script to automate the documentation of management pack entities. By using a script to loop through unsealed management packs and itemize management pack entities such as groups, rules, monitors and views, along with their description, all it takes to automate documentation of custom management packs is completing the description fields for objects as they are created.

To loop through unsealed management packs, we can defined the list of management packs as an object:

$mps = Get-ManagementPack | where-object{$_.Sealed -eq $false} |Sort-Object DisplayName

Then create the loop logic:

foreach($mp in $mps)
{
  $mpDisplayName=$mp.DisplayName
…functions to list MP objects
}

With a set of functions to list the management pack objects that write the object lists to a formatted file (I use an HTML file so I can utilize CSS for formatting), we can create an automatically-generated document covering all unsealed MP’s.

I’ve posted the script I use here.   This script exports groups, rules, monitors, and views for all unsealed management packs in a formatted html file.  As always, it is provided as-is.

https://i0.wp.com/jxjzig.bay.livefilestore.com/y1pjtnzM9RDmStqJ-ZMgzC1HYtJbO2G9rUylcr1AiV5DQ5Jrq_vO2QlZZom8juYCZgFcLGCiQJe1qd2v4aOE2wb4w/report.JPG

My preference is to combine a single scheduled task that runs this documentation script as well as an automated export of all unsealed management packs. The output of both of these processes is then backed up nightly, creating a hands-off set of documentation and management pack history that can be utilized as necessary.

More on exporting unsealed MP’s for backup can be found at: http://searchwindowsserver.techtarget.com/generic/0,295582,sid68_gci1317380,00.html