Windows PowerShell

Applies To: Operations Manager 2007 R2

Microsoft Operations Manager 2007 R2 now includes the ability to run Windows PowerShell scripts from within management packs by using new module types provided in the Windows Core Library management pack. This section covers the capabilities, usage, and troubleshooting of those Windows PowerShell modules.

Important

The Microsoft Operations Manager 2007 agent requires that Windows PowerShell is installed in order to run any Windows PowerShell scripts. Windows PowerShell is not installed by default with the agent and must be installed separately.

What is Windows PowerShell?

Windows PowerShell is a command-line shell and scripting language that can be used to automate many tasks. Windows PowerShell includes small utility programs, called cmdlets, that can either be run directly from the command shell prompt or called from within a batch file or script. Cmdlets can be used by themselves, or they can be combined with other cmdlets to perform complex administrative tasks. Unlike traditional command-line environments that work by returning text results to the end user or routing (“piping”) text to different command-line utilities, Windows PowerShell manipulates .NET Framework objects directly. This provides a more robust and efficient mechanism for interacting with the system.

Note

This topic serves as an overview to the Operations Manager Command Shell. To learn more about Windows PowerShell, see the Windows PowerShell 1.0 Documentation Pack.

Windows PowerShell Hosting in Operations Manager

In previous versions of Operations Manager, it is possible to run Windows PowerShell scripts from management packs by calling the Windows PowerShell executable directly, which often resulted in unacceptable resource utilization. Operations Manager 2007 R2 now provides modules for running Windows PowerShell scripts from within management pack workflows. These scripts are run via hosted Windows PowerShell runspaces. Existing Monitoring Host processes require far less resources than running scripts out of process by using the Windows PowerShell executable.

The Windows PowerShell hosting functionality is available in many workflow types, including discoveries, rules, monitors, agent tasks, diagnostics and recoveries. To enable use this new functionality, a number of new public module types, defined in the Windows Core Library management pack, are provided with Operations Manager 2007 R2 for use by advanced management pack authors. These modules include:

  • Microsoft.Windows.TimedPowerShell.DiscoveryProvider

  • Microsoft.Windows.PowerShellDiscoveryProbe

  • Microsoft.Windows.PowerShellPropertyBagProbe

  • Microsoft.Windows.PowerShellTriggerOnlyProbe

  • Microsoft.Windows.PowerShellProbe

  • Microsoft.Windows.PowerShellWriteAction

  • Microsoft.Windows.PowerShellPropertyBagWriteAction

Windows PowerShell Module Inputs

Windows PowerShell modules have a base set of common inputs. This section provides general descriptions of these inputs. For more specific details about syntax and examples, refer to the module documentation.

Windows PowerShell modules recognize the following common parameters:

ScriptName

This parameter is used as an identifier for event logging and tracing purposes. This value is a logic name only and not a file name. Windows PowerShell scripts used by the modules are never stored to the local file system as stand-alone files.

ScriptBody

This parameter contains the actual Windows PowerShell script to be run by the module.

SnapIns

This optional parameter can be used to pass a list of one or more snap-ins (which are used to register sets of cmdlets and providers with Windows PowerShell) that must be loaded within the runspace for the given script. This method of loading snap-ins is preferred over loading the snap-ins from within the Windows PowerShell script because it allows the modules to optimize loading and reuse these snap-ins.

Parameters

Parameters are used to pass information such as static values or variables from runtime into Windows PowerShell scripts, where they can be accessed as variables.

Parameters are defined within the management pack as Name/Value pairs. Each Name/Value pair in the collection is internally added to the $args string array variable in the same order in which they are listed in the collection.

For example, consider the following parameters in this XML code snippet:

<Parameters>
   <Parameter>
      <Name>stringArg</Name>
      <Value>my arg</Value>
  </Parameter>
  <Parameter>
      <Name>intArg</Name>
      <Value>5</Value>
   </Parameter>
</Parameters>

There are two ways to access these parameter Name/Value pairs in script. The first way is to access the $args string array directly. In the following sample code, the script is accessing the $args elements in order to assign their values to named variables.

$myfirstparam = $args[0]
$mysecondparam = $args[1]
…

The second and easier way to access parameter Name/Value pairs in the script, is to use the Param function. The Param function takes the named variables as arguments. The named variables must be listed in the same order as the list of Name/Value pairs in the collection. The Param function must be the first line in your script. In the following code sample, the script is assigning the $args elements to named variables by simply calling the Param function.

Params($myfirstparam, $mysecondparam)
…

Since Windows PowerShell scripts can access the variables to use the values, it is possible to test the script from a Windows PowerShell command prompt by simply setting the variables and running the script.

The follow table lists examples of possible parameter cases and the behavior for each at script runtime. Note that the variables in the Variable name column are available only if you use one of the above mentioned parameter access methods and explicitly declare their names.

Case <Name> <Value> Variable name Value Description

Literal string

X

LiteralString

$X

“LiteralString”

The parameter named “X” is assigned a literal string value is accessible in the script as “$X”.

<DataItem> XPath query

Y

$Data/EventNumber$

$Y

XPath result as a string value

At runtime, the XPATH query “$Data/EventNumber$” is replaced with the actual string value and is accessible in the script is “$Y”.

Entire <DataItem>

Z

$Data$

$Z

String equivalent of the entire <DataItem> XML

The entire <DataItem> is passed in the variable “$Z” as an XML string.

In the following example, two parameters – a string and an integer – are passed to the Windows PowerShell script:

<Task ID="SamplePowerShellTask" Accessibility="Public" Enabled="true" Target="SCLibrary!Microsoft.SystemCenter.HealthService" Timeout="300" Remotable="false">
        <Category>Maintenance</Category>
        <ProbeAction ID="PA" TypeID="Microsoft.Windows.PowerShellProbe">
          <ScriptName>PowerShell Parameter Test Script</ScriptName>
          <ScriptBody><![CDATA[
          Param($stringArg, $intArg)
          ]]></ScriptBody>
          <Parameters>
            <Parameter>
              <Name>stringArg</Name>
              <Value>
                <![CDATA[This is my string arg
                with formatting]]></Value>
            </Parameter>
            <Parameter>
              <Name>intArg</Name>
              <Value>5</Value>
            </Parameter>
          </Parameters>
          <TimeoutSeconds>60</TimeoutSeconds>
        </ProbeAction>
      </Task>

You can also pass parameters as a single XML data item, which the script can retrieve by using XPath queries. For example, given the following script definition for the module:

<ScriptBody><![CDATA[
          Param($xmlData= [xml]$data)
          $xmlData
          $xmlData.SelectSingleNode("DataItem/Parameter[1]")

          ]]></ScriptBody>
          <Parameters>
            <Parameter>
              <Name>data</Name>
              <Value>$Data$</Value>
            </Parameter>

…the parameter values could extracted using the following command:

PS C:\ > $xmlData.SelectSingleNode("DataItem/Parameter[1]")

…which would produce the following output:

type                             #text
----                             -----
System.String                    PowerShell is cool

PowerShell Script Output

Windows PowerShell modules can output discovery data, property bags, or serialized .NET objects, depending on the type of module. In both cases, the results will be returned by the script by using the Windows PowerShell Pipeline.Output object.

In the case of a .NET object, the returned object will be interpreted by the Windows PowerShell module into an Operations Manager data type. A single data item which contains a collection of each of the objects returned from the Windows PowerShell script is returned upon completion of the script.

Scalar types are returned as property elements. Complex types are returned as <Object> elements, and any public properties returned as subelements. For example, the following System.String object:

System.String myString = “Sample String”;

…will return the following XML to Operations Manager:

<Property type=’System.String’>Sample String</Property>

Complex types returned by a Windows PowerShell script are presented back to the Operations Manager module as an <Object> element, with any properties on the original complex type being presented as subelements of the <Object> element. For example, this .NET object:

namespace Sample 
{
class SampleComplexType
{
public string SampleString { get { return “Sample”; } }
public int SampleInt { get { return 1; } }
public SampleComplexType2 SampleSubType { get { return subtype; } }
public subtype = new SampleComplexType2();
}
class SampleComplexType2
{
public SampleComplexType2() {}

public string SampleString2 { get { return “Sample2”; } }
}
}

…is returned to Operations Manager with the following XML:

        <Object type="Sample.SampleComplexType">
          <Property name="SampleString" type="System.String">Sample</Property>
          <Property name="SampleInt" type="System.Int32">1</Property>
          <Object name="SampleSubType" type="System.String">
            <Property name="SampleString2" type="System.String">Sample2</Property>
          </Object>
        </Object>

Scripting Considerations for Operations Manager

This section covers special considerations for Windows PowerShell scripts hosted from within Operations Manager 2007 R2 modules.

Application Isolation and Performance

By default, each script instance will be hosted in a separate runspace in the default application domain. This behavior can be overridden by setting the Isolation registry key to a value of 1.

Application isolation can enhance system stability by preventing simultaneously executed Windows PowerShell scripts and cmdlets – most of which were designed to be called from a single-threaded application – from interfering with each other, but can also cause a severe performance degradation.

To increase performance while running in Isolation mode, AppDomains will be pooled to alleviate the overheard required to instantiate them. Runspaces will not be shared or reused, but they will be cached on each module type.

The Runspace Manager

In order to allow multiple Windows PowerShell scripts to run simultaneously, a mechanism known as a Runspace Manager is used. The Runspace Manager provides a runspace in an isolated application domain in which to run scripts. It implements a First In, First Out (FIFO) queue in which scripts are placed for execution, and handles limiting the number of scripts that are running at the same time.

By default, the maximum number of scripts that can be running in at a time is 20, and scripts in the runspace manager’s queue will expire and be removed after 10 minutes.

Hosting-related Registration Keys

Some default aspects of script execution and behavior in Operations Manager-hosted Windows PowerShell scripts can be customized by setting registry keys. These values can be found in the following node in the registry:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\Modules\Global\PowerShell

The following table shows the registry keys used to control script execution behavior for Windows PowerShell scripts run from an Operations Manager module:

Key Description Default Value

ScriptLimit

Controls how many hosted Windows PowerShell scripts are allowed to run globally.

0x00000014

QueueMinutes

Defines how many minutes before a script expires from the queue.

0x0000000a

IsolationLevel

Specifies whether a separate AppDomain will be used for each script. A value of 1 indicates that a separate AppDomain is used for each script.

0x00000000

Other Scripting Considerations

Because Windows PowerShell scripts executing from within Operations Manager modules are running in the context of a service, any method or function calls that prompt for user input will throw “not implemented” exceptions. These application programming interfaces (APIs) include:

  • PromptForChoice

  • PromptForCredential

  • ReadLine

  • ReadLineAsSecureString

Any method or function calls that are used to write output will be redirected by the Operations Manager host into trace logs that can be used for debugging purposes. For more focused debugging, this output can also be echoed to the ModuleDebug and DbgOut trace logs if the TraceEnabled override is set for the host workflow.

The table below lists the trace level used for each Write API for Windows PowerShell script tracing only (the trace level for Module Debug is always ModuleDebug).

Function Trace Level

WriteDebugLine

Information

WriteWarningLine

Warning

WriteErrorLine

Error

Write

Verbose

WriteLine

Verbose

WriteVerboseLine

Verbose

Note

The WriteProgress function is not traced.

See Also

Reference

Windows PowerShell
Windows PowerShell Snap-ins

Other Resources

Microsoft Operations Manager 2007 Management Pack Module Reference