Output list of scripts contained in a management pack

I was perusing my library of powershell scripts today and stumbled across this neat little gem. I do not recall writing it, so probably cannot take the credit. But I wanted to post it here in case anyone else can make use of it.

If the original author is here, please raise your hand!

$xml = New-Object “System.Xml.XmlDocument”
$xml.Load(“path to management pack xml”)
$scripts = $xml.SelectNodes(“descendant::ScriptName”)
$scripts | group “#text” | select name | sort name

Query SQL Server using Powershell

Just provide the required parameters to query your SQL Server.

$dbConnection: FQDN[,Port]

$dbName: database name

Param([string]$dbConnection, [string]$dbName)

function QuerySqlDatabase
{
    # Setup the SQL connection
    $connection = new-object system.data.sqlclient.sqlconnection("Data Source=$dbConnection;Initial Catalog=$dbName;Integrated Security=SSPI;");

    # Define TSQL
    [string]$query =
                "
                your SQL statement here
                "
   
    # Create the dataset and catch errors
    Try {
        $execute = new-object system.data.sqlclient.sqldataadapter ($query, $connection)
        $dataset = new-object system.data.dataset
        $execute.Fill($dataset) | Out-Null #speeds processing
     }
    Catch {
        [System.Exception]
        write-host "Exception while attempting to connect to SQL Server"
        $connectionDetails = $error[0]
        Write-Host "Exception details: $connectionDetails"
        Write-Host "Exiting"
        Exit
    }
    # Create an empty collection
    [System.Collections.ArrayList]$Rows = @()
   
    # Add each row in dataset to the collection
    foreach ($row in $dataset.Tables[0]) {
        $Rows.Add($row) | Out-Null #speeds processing
    }
   
    # Pass collection to main script.
    return $Rows
   
}

QuerySqlDatabase $dbConnection $dbName

Starting a Fragment Library using Visual Studio Authoring Extensions

Started using Visual Studio Authoring Extensions recently for all MP authoring, and leaving the Authoring Console behind since it is no longer supported.

I still can’t get used to the templates that are included with VSAE, so I like to create empty management pack fragments. I do this in order to create a library of fragments that I can easily add to management packs in the future.

In this example, I will demonstrate how to start a fragment library by adding a powershell write action that will be used in a scheduled powershell rule.

Create a new Operations Manager 2012 add-on project and add a couple folders to the solution: modules and rules. Then create a new item in the modules folder.

image

Add a new empty management pack fragment.

image

Give it a logical name, like Powershell Write Action, and enter code similar to the following.

 

<ManagementPackFragment SchemaVersion=”2.0″ xmlns:xsd=”http://www.w3.org/2001/XMLSchema”>
<TypeDefinitions>
<ModuleTypes>
<WriteActionModuleType ID=”YourMp.YourPowershellWriteAction” Accessibility=”Internal” Batching=”true”>
<Configuration>
<xsd:element minOccurs=”1″ name=”TimeoutSeconds” type=”xsd:integer” />
<xsd:element minOccurs=”1″ name=”YourScriptParamter1″ type=”xsd:string” />
<xsd:element minOccurs=”1″ name=”YourScriptParamter2″ type=”xsd:string” />
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID=”TimeoutSeconds” Selector=”$Config/TimeoutSeconds$” ParameterType=”int” />
<OverrideableParameter ID=”YourScriptParamter1″ Selector=”$Config/YourScriptParamter1$” ParameterType=”string” />
<OverrideableParameter ID=”YourScriptParamter2″ Selector=”$Config/YourScriptParamter2$” ParameterType=”string” />
</OverrideableParameters>
<ModuleImplementation>
<Composite>
<MemberModules>
<WriteAction ID=”WA” TypeID=”Windows!Microsoft.Windows.PowerShellWriteAction”>
<ScriptName>ScriptName.ps1</ScriptName>
<ScriptBody>
<![CDATA[
Param(
[string]$YourScriptParamter1,
[string]$YourScriptParamter2
)
Do stuff
]]>
</ScriptBody>
<Parameters>
<Parameter>
<Name>YourScriptParamter1</Name>
<Value>$Config/YourScriptParamter1$</Value>
</Parameter>
<Parameter>
<Name>YourScriptParamter2</Name>
<Value>$Config/YourScriptParamter2$</Value>
</Parameter>
</Parameters>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
</WriteAction>
</MemberModules>
<Composition>
<Node ID=”WA” />
</Composition>
</Composite>
</ModuleImplementation>
<InputType>System!System.BaseData</InputType>
</WriteActionModuleType>
</ModuleTypes>
</TypeDefinitions>
</ManagementPackFragment>

Of course, add you script in the script body section. This is an example that will pass in two parameters to the script.

Now add another new empty management pack fragment to the rules folder, and enter code similar to the following.

<ManagementPackFragment SchemaVersion=”2.0″ xmlns:xsd=”http://www.w3.org/2001/XMLSchema”>
<Monitoring>
<Rules>
<Rule ID=”YourMp.YourPowershellRule” Enabled=”true” Target=”YourMp.YourClass” ConfirmDelivery=”true” Remotable=”true” Priority=”Normal” DiscardLevel=”100″>
<Category>Operations</Category>
<DataSources>
<DataSource ID=”Schedule” TypeID=”System!System.SimpleScheduler”>
<IntervalSeconds>600</IntervalSeconds>
<SyncTime />
</DataSource>
</DataSources>
<WriteActions>
<WriteAction ID=”WA” TypeID=”YourMp.YourPowershellWriteAction”>
<TimeoutSeconds>300</TimeoutSeconds>
<YourScriptParamter1>first parameter to pass into script</YourScriptParamter1>
<YourScriptParamter2>second parameter to pass into script</YourScriptParamter2>
</WriteAction>
</WriteActions>
</Rule>
</Rules>
</Monitoring>
</ManagementPackFragment>

This rule uses a scheduler as a data source and your new powershell write action module. Remember to fill in the script paramter elements after the script body – this is how the parameter are actually passed into the script.

If you continue saving new fragments to this library project, you can easily add these to your management pack projects in the future by adding an existing item and navigating to your library project.

This is your starter fragment library.

image

Detected malicious verification code when verifying element

Quick post here. Hopefully you find this before spending an hour on it like I did. It ended up being a typo in a write action type id.

Basically, it simply came down to changing this:

<WriteAction ID=”WA” TypeID=”MyMp.MyWriteActin”>

To this:

<WriteAction ID=”WA” TypeID=”MyMp.MyWriteAction”>

Lesson learned – be careful when authoring XML directly and use intellisense when it’s available.

 

Below is the full error I receive by the Visual Studio Authoring Extensions.

Error    72    Detected malicious verification code when verifying element of type Microsoft.EnterpriseManagement.Configuration.ManagementPackRule with inner exception: System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at Microsoft.EnterpriseManagement.Configuration.ManagementPackRule.VerifyDataTypes(Dictionary`2 moduletypes)
at Microsoft.EnterpriseManagement.Configuration.ManagementPackRule.Verify(VerificationContext context)
at Microsoft.EnterpriseManagement.Configuration.Verification.VerificationEngine.VerifyCollectionItems(Object context)   (Path = DR.DiscoveryAutomation)    Management Pack Display Name.mpx    11    10    Discovery Automation