Labels

Showing posts with label Operations Manager 2007. Show all posts
Showing posts with label Operations Manager 2007. Show all posts

Sunday, November 2, 2008

OpsMgr 2007 performance script - VMware datastores

This post provides a method of collecting VirtualCenter datastore information for ESX hosts in one or more clusters as performance data in Operations Manager 2007. You can then trend datastore usage for longer term analysis, and alert on the data for proactive problem management. This is my first attempt at using script to gather performance data in OpsMgr 2007, and my lack of OpsMgr knowledge combined with the limited documentation/examples made this difficult and possibly harder than it needs to be.

Background

In OpsMgr 2007, I thought it would be useful to report on LUN disk space on the ESX side of things in a similar fashion to agent-based Windows disk performance counters, and while this sounds quite easy, I couldn’t find a simple method because:

  1. ESX doesn’t seem to support an SNMP trap to report on VMFS volume capacity/free space. You could write a shell script and add a cron job on the Linux ESX service console, but this would be targeted at each ESX server, and the results would then be duplicated (and wouldn't work with ESX 3i)
  2. VirtualCenter doesn’t appear to support a custom alert based on storage usage, only storage transfer rates.
  3. The ESX servers are only in OpsMgr as network devices, not true agents, so we can’t use WBEM or any other method to query directly. If the upcoming OpsMgr 2007 cross platform extensions work on ESX, this may be easier, although as with option 1 this would still return duplicate datastore information for each ESX server in a cluster and wouldn't work with ESX 3i)

This left a few options to gather the data in OpsMgr:

  1. Query the VMFS storage through the VI snap-in and a PowerShell Script.
  2. Query the VC database directly for this information from a VBS or PowerShell script.
  3. Create a DTS job on the VC SQL server to extract the data to a suitable format.

Options two and three above would not be supported by VMware and may change as the database structure changes between VC versions.

Solution

Querying the VMFS storage from PowerShell and collect the information with VBScript, which includes:

  1. The PowerShell script using the VI snap-in to extract the datastore information
  2. The VBScript to gather the information as performance data in Operations Manager 2007
  3. A trigger to execute the powershell script and put the data in a file to be gathered.
  4. Rules in OpsMgr to gather the data using the type 'Script (Performance)'.

Steps taken:

  1. Install the VMware VI PowerShell snap-in to your Virtual Centre box (you may need to install PowerShell first). VMware-Vim4PS-1.0.0-113525.exe is the binary I used.
  2. Create an AD group and user for rights to VC. Add the user to the group.
  3. Set rights in VirtualCenter to allow the group read-only rights at the root. This should be more granular if possible.
  4. Add a recurring trigger on your VC box to run the PowerShell script to extract the information. Eg, this could be a scheduled task that runs a batch file or directly executes:
    1. powershell . ".\PerfGatherVMwareDSSpace.ps1"
  5. Create two rules in Operations Manager, Script (Performance) to gather the daily log file and store in the database as performance data. One rule is for the free space, another is for the free space as a percentage of the capacity. See the performance mapper notes below.
    1. The rules were created under ‘Windows Server 2003 Computer’, not enabled by default and overridden for the VC server (where the powershell script runs). You may want to target the rule differently, depending on your environment.
  6. Create a performance view, showing performance data collected by the two rules above.
  7. Create a monitor, using the LogicalDisk ‘% Disk Free’ object and counter to monitor on a threshold of 10%. Similarly, the monitor could be created under ‘Windows Server 2003 Computer’, not enabled by default and overridden for the VC server. The alert contains the following information:
    1. Object: $Data/Context/ObjectName$, Counter: $Data/Context/CounterName$, Instance: $Data/Context/InstanceName$, Value: $Data/Context/Value$

Note that when using the script performance data provider, the ‘Performance Mapper’ tab is used to map the data returned by the script to the database. To make this generic, both the instance name and the value are used from each element:

  • Object: LogicalDisk
  • Counter: Free Megabytes
  • Instance: $Data/Property/@Name$
  • Value: $Data/Property[@Name]$

Note that the VBScript creates three typed ‘property bags’ and returns all. This results in a single XML that contains three dataitem elements, one for each instance. Creating a single property bag and adding the three instances results in only the first being processed.

This should now gather free space in MB and as a percentage of the size for all VMFS datastores your VC server knows about, visible through the performance view, and alerted on when free space is less than 10% of the capacity for each volume.

SQL Queries

Some SQL queries against the OperationsManagerDW database I used along the way to query from the datawarehouse that the data was being gathered. Note that where I've specified 'datastore%' as a filter, you'll need to change this to the prefix of your datastores, eg ds01, ds02 would be ds%.

/*Return the raw performance data collected for the datastore* instances: */

select DateAdd(Hour, 10, DateTime) as DateTime, InstanceName, SampleValue from perf.vperfRaw
inner join vPerformanceRuleInstance on perf.vperfRaw.PerformanceRuleInstanceRowID = vPerformanceRuleInstance.PerformanceRuleInstanceRowID
where InstanceName like 'datastore%'
order by datetime desc

/* Find new rules: */
select top 10 * from dbo.vPerformanceRuleInstance
where instancename like 'datastore%'
order by performanceruleinstancerowid desc

/* Find new raw performance data: */

select top 100 DateTime, SampleValue, ObjectName, CounterName, FullName, Path, Name, DisplayName, ManagedEntityDefaultName from perf.vperfraw
inner join vPerformanceRule on perf.vperfraw.PerformanceRuleInstanceRowID = vPerformanceRule.RulerowID
inner join vManagedEntity on perf.vperfraw.ManagedEntityRowID = vManagedEntity.ManagedEntityRowID
order by datetime desc

/* Find new rule instances that have been created: */

select top 10 * from dbo.vPerformanceRuleInstance
order by performanceruleinstancerowid desc
--


#PowerShell Script - PerfGatherVMwareDSSpace.ps1
# Note that this includes a context to connect to VC, with hardcoded username and password.  You could avoid this by running the scheduled task under the security context you created with inherent rights to VC, and then remove the explicit -credential argument to Connect-VIServer.

$ErrorActionPreference = "SilentlyContinue"
add-pssnapin VMware.VimAutomation.Core

$ADMINLOG = "c:\admin\logs"
$outputFile = ""
$today = [DateTime]::Now.ToString("yyyyMMdd")

$scriptName = $MyInvocation.MyCommand.Name
$scriptName = $scriptname.substring(0, $scriptname.LastIndexOf("."))

if ($env:adminlog -ne $null) {        # Was there an adminlog environment variable?
    $outputFile = $env:adminlog
} else {
   $outputFile = $ADMINLOG        # No, use the constant default  
}

$outputFile += "\" + $scriptname + "_" + $today + ".csv"    # Construct the full path to the output file 

$server = "vc01"          # VC instance
$username = "domain\user"        # Hardcoding is bad, but at least this is a RO account.
$password = "password"

$pwd = convertto-securestring $password -asplaintext -force

$cred = New-Object Management.Automation.PSCredential ($username, $pwd)   # Create the credentials to use with the VC connection

$vmserver = & { trap {continue}; Connect-VIServer -server $server -Credential $cred } # Connect to VC, trapping the error

if ($vmserver -is [System.Object]) {       # Do we have a connection?
    Get-Datastore -server $vmserver | export-csv -noTypeInformation -path $outputFile # Yes, get the datastore details and store as CSV
    if (test-path -path $outputFile) {
        write-output "Datastore details exported to $outputFile"
    } else {
        write-output "Error: Datastore details were not exported to $outputFile"
    }
    $vmserver = $null
} else {
    write-output "Could not connect to $server"
}


#------



' VBScript


' Parse a CSV file containing the VMware volume information, and return the specified field from the data file or the calculated percent free

Const TOKEN_DATE = "%date%"
Dim SOURCE_FILE : SOURCE_FILE = "c:\admin\logs\PerfGatherVMwareDSSpace_" & TOKEN_DATE & ".csv"  ' Today's log file exported from the PowerShell VI-snapin script

Const DELIMITER = ","           ' CSV data file
Const ForReading = 1
Const DISKTYPE_VMFS = "VMFS"          ' We're interested only in lines with VMFS volumes

Const QUERY_SIZE = "Size"
Const QUERY_FREE = "Free"
QUERY_PERCENT = "Percent"

Dim QUERY_DEFAULT : QUERY_DEFAULT = QUERY_FREE 

Const FIELD_SIZE = 1           ' The field in the CSV that contains the capacity of the VMFS volume
Const FIELD_FREE = 0           ' The field in the CSV that contains the free disk space on the VMFS volume
Const FIELD_PERCENT = 2

Const PerfDataType  = 2

Set oFSO = CreateObject("Scripting.FileSystemObject")

Main()

wscript.quit(0)

Sub Main()

 If WScript.Arguments.UnNamed.Count >= 1 Then
  strQueryType = WScript.Arguments.UnNamed(0)
  wscript.echo "Command-line argument passed, querying for " & strQueryType
 Else
  strQueryType = QUERY_DEFAULT
  wscript.echo "No command-line argument passed, querying for the default of " & strQueryType
 End if

 Select Case strQueryType
  Case QUERY_SIZE  strField = FIELD_SIZE 
  Case QUERY_FREE  strField = FIELD_FREE
  Case QUERY_PERCENT strField = QUERY_PERCENT
  Case Else  strField = FIELD_FREE
 End Select

 dtmDate = Now 
 strToday = DatePart("yyyy", dtmDate)         ' YYYY
 strToday = strToday & String(2 - Len(DatePart("m", dtmDate)),"0") & DatePart("m", dtmDate) ' MM
 strToday = strToday & String(2 - Len(DatePart("d", dtmDate)),"0") & DatePart("d", dtmDate) ' DD

 strDataFile = Replace(SOURCE_FILE, TOKEN_DATE, strToday)     ' Build the path to the data file
 wscript.echo "Looking for " & strDataFile

 Dim oAPI, oBag
 Set oAPI = CreateObject("MOM.ScriptAPI")

 If oFSO.FileExists(strDataFile) Then        ' Does the data file exist for today?
  WScript.Echo "Log file found, continuing"
  Call ReadFile(strDataFile, strBuffer)       ' Yes, read the contents of the file into the buffer

  For Each strLine in Split(strBuffer, vbCRLF)      ' For each line
   arrEntry = Split(strLine, DELIMITER)      ' Split the line into an array on comma
   If UBound(arrEntry) = 5 Then       ' Did this line have a valid number of fields?
    If strComp(arrEntry(3), DISKTYPE_VMFS) = 0 Then    ' Yes, is it a VMFS volume? (excludes the header)
    wscript.echo "Processing " & strLine
     If IsNumeric(arrEntry(FIELD_FREE)) AND IsNumeric(arrEntry(FIELD_SIZE)) Then     ' Yes, is the field we're after a numeric?
      Set oBag = oAPI.CreateTypedPropertyBag(PerfDataType)  Create a typed name/value pair property bag

      If (strField = FIELD_SIZE) OR (strField = FIELD_FREE ) Then
       Call oBag.AddValue(arrEntry(5),CLng(arrEntry(strField))) ' Yes, convert to a long and add to the bag
      ElseIf strField = QUERY_PERCENT Then
       dblFreePercent = CDbl(arrEntry(FIELD_FREE) / arrEntry(FIELD_SIZE)*100)
       Call oBag.AddValue(arrEntry(5), Round(dblFreePercent, 2))
      End If
      oAPI.AddItem(oBag)     ' Add the item to the bag (doing it here results in three datatime elements)

     End If  
    End If
   End If
  Next

 Else
  WScript.Echo "Error: Daily data file not found - " & strDataFile 

 End If

 Call oAPI.ReturnItems 

End Sub    


'********************************************************
' Purpose: Read a file and store the contents in the buffer
' Assumptions: oFSO exists
'              strLogFile contains the path/filename of the file to operate on
' Effects: strBuffer is by reference
' Inputs: strFileName, Path and filename of the source file
'   strBuffer, the buffer used to store the contents of the file
' Returns: None
'
'********************************************************
Sub ReadFile (ByVal strFileName, ByRef strBuffer)   
 On Error Resume Next
 Dim objTextStream

 If Not oFSO.FileExists(strFileName) Then
  WScript.Echo "Error: " & strFileName & " file not found."
  Exit Sub
 End If
    Set objTextStream = oFSO.OpenTextFile(strFileName, ForReading)
 strBuffer = objTextStream.ReadAll
End Sub

'------

References:

How to Create a Probe-Based Performance Collection Rule in Operations Manager 2007
http://technet.microsoft.com/en-us/library/bb381406.aspx

MOMScriptAPI.CreatePropertyBag Method
http://msdn.microsoft.com/en-us/library/bb437556.aspx

XPath Examples:
http://msdn.microsoft.com/en-us/library/ms256086(VS.85).aspx

http://blogs.msdn.com/mariussutara/archive/2008/01/24/momscriptapi-createtypedpropertybag-method.aspx

http://blogs.technet.com/kevinholman/archive/2008/07/02/collecting-and-monitoring-information-from-wmi-as-performance-data.aspx

http://www.afinn.net/2008/07/collecting-performance-data-in-operations-manager-2007-and-publishing-to-sharepoint-part-1/

http://blogs.msdn.com/mariussutara/archive/2007/11/13/alert-description-and-parameter-replacement.aspx

Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin.


Read more!

Wednesday, August 6, 2008

OpsMgr 2007 Reports - Sorting, Filtering, Charting

This post provides information on sorting, filtering and adding reporting controls to custom Operations Manager 2007 reports. This is the fourth in a series of posts on creating customised Operations Manager reports; see the posts 'OpsMgr 2007 Customized Reporting - SQL Queries', 'OpsMgr 2007 SSRS Reports using SQL 2005 XML', and 'Passing Parameters between OpsMgr and SSRS'.

Data filtering and sorting

When creating tables and graphs in a report, the data returned in the SQL result set displayed in the table can be both filtered and sorted. Depending on the type of report, it may be more practical or flexible to sort and filter the data within the table.

The filters can be based on expressions, retrieving input from single or multi-valued controls to filter the data. When filtering based on a multi-valued text-box, the ‘in’ operator automatically filters based on each parameter, but unfortunately there is no ‘not in’ operator.

Sorting

Using the example of reporting current disk free space, a default sort of the report table could be:

‘=Fields!Path.Value’ and ‘=Fields!Instancename.Value’ in ascending order.


The choice of whether to sort and filter within the report or the stored procedures is left to the author, typically based on which process is easier to follow – updating a SQL stored procedure or updating an SSRS report and the associated source Management Pack XML. Another consideration is the ability to interactively filter and sort data in a report, as opposed to the static data returned from the SQL query.

Filtering columns

Columns in a result table can be filtered based on an expression. In the example of reporting the current free disk space, this value is returned in bytes and another field could be added to the table to show the value calculated as a number of gigabytes. However, if you’re using this as a generic report, you may not be returning a number, and you would want to hide the gigabytes field.

Filters can be set on a detail body field, a column in a table, or the whole table itself. The following expression could be set on a row in a table, to determine whether the row is hidden or not – based on the rule GUID being reported matching the default free space GUID from the default dataset query. This would be set in the Visibility Hidden property of a table row:

=UCase(Parameters!RuleInstance.Value) <> UCase(First(Fields!RuleGuid.Value, "DefaultLogicalDiskFreeMegabytes"))

Adding the Microsoft Chart Control DLLs

To add the ability to create charts using the Reporting Services Chart controls on a development workstation, the following must be done:

  1. Copy MicrosoftRSChart.dll and MicrosoftRSChartDesigner.dll from SSRS bin directory to Visual Studio private assemblies directory on your development machine.
  2. Update the Report Designer config file on your workstation




This was taken from the report authoring guide, see ‘Enabling the EnterpriseManagementChartControl’ in the references section. Copying the chart control files The location may vary, but for a typical installation, the files are in: \\ssrs_server\c$\Program Files\Microsoft SQL Server\MSSQL.2\Reporting Services\ReportServer\bin On your local workstation, the files need to be copied to the Visual Studio private assemblies directory, typically: C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies Note that the source also contains the Dundas web chart control, also referenced in the report guide, but not used in this post.

Directory of \\ssrs_server\c$\Program Files\Microsoft SQL Server\MSSQL.2\Reporting Services\ReportServer\bin

10/02/2007 05:15 AM 755,056 DundasWebChart.dll
16/02/2008 10:18 AM 1,549,360 MicrosoftRSChart.dll
16/02/2008 10:19 AM 9,884,720 MicrosoftRSChartDesigner.dll

Updating the report designer config In RSReportDesigner.config file in the Visual Studio private assemblies directory (C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies) and add the following elements, and then restart Visual Studio


<Configuration>
    <Extensions>
            ...
            ...
        <ReportItemDesigner>
            <ReportItem Name="EnterpriseManagementChartControl"
                    Type="Dundas.ReportingServices.DundasChartDesigner,
                              MicrosoftRSChartDesigner" />
        </ReportItemDesigner>
        <ReportItems>
            <ReportItem Name="EnterpriseManagementChartControl"
                    Type="Dundas.ReportingServices.DundasChart,
                              MicrosoftRSChart" />
        </ReportItems>
        <ReportItemConverter>
            <Converter Source="Chart" Target="EnterpriseManagementChartControl"
                    Type="Dundas.ReportingServices.RSChartConverter,
                              MicrosoftDundasRSChartDesigner" />
        </ReportItemConverter>
    </Extensions>
</Configuration>

References:

Operations Manager Report Authoring Guide
http://blogs.technet.com/momteam/archive/2008/02/26/operations-manager-report-authoring-guide.aspx

Microsoft Operations Manager 2007 Management Pack Authoring Guide
http://download.microsoft.com/download/7/4/d/74deff5e-449f-4a6b-91dd-ffbc117869a2/OM2007_AuthGuide.doc

Introduction to the Operations Manager 2007 Design Guide
http://download.microsoft.com/download/7/4/d/74deff5e-449f-4a6b-91dd-ffbc117869a2/OpsMgr2007_DesignGuid.doc

Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin.


Read more!

Friday, July 18, 2008

Passing Parameters between OpsMgr and SSRS

This post provides information on passing parameters between Operations Manager 2007 and SQL Server Reporting Services (SSRS) when creating customised reports. It discusses Operations Manager Smart Controls, using dataset queries and populating parameters from a string.

This is the third in a series of posts on creating customised Operations Manager reports; see the posts 'OpsMgr 2007 Customized Reporting - SQL Queries' and 'OpsMgr 2007 SSRS Reports using SQL 2005 XML'.

Report parameters define input parameters to the report, which are then typically passed to dataset parameters, used to determine the data displayed in the report. The dataset parameters can be used in-line with text-based SQL queries, or passed to a SQL Stored Procedure.

Report Smart Controls

Operations Manager provides several controls tailored to OpsMgr specific reporting. For example:

  • Microsoft.SystemCenter.DataWarehouse.Report.ParameterControl.MonitoringObjectXmlPicker
  • Microsoft.SystemCenter.DataWarehouse.Report.ParameterControl.PerformanceRulePicker
  • Microsoft.SystemCenter.DataWarehouse.Report.ParameterControl.TextBox

The controls are documented in the reporting guide and can be seen in use by unsealing the standard Microsoft Management Packs. Generally the controls relate to data stored in Operations Manager, such as the Monitoring Object or Performance Rule pickers, providing methods of selecting and passing existing OpsMgr data types as parameters.

The example below shows the definition of the control for a multi-value textbox, using the multiline property element to enable multiline support for the control. The idea of this control is to provide a text-string filter that would be passed as a parameter to SSRS to filter or determine the final output of a report.


<Control type="Microsoft.SystemCenter.DataWarehouse.Report.ParameterControl.TextBox" rowSpan="3" columnSpan="1">
  <ReportParameters>
    <ReportParameter name="InstanceFilter">
      <Prompt>Custom!Microsoft.SystemCenter.DataWarehouse.Report.ParameterPrompt.InstanceFilter</Prompt>
    </ReportParameter>
  </ReportParameters>
  <Properties>
    <Property name="Multiline">
      <Value>True</Value>
    </Property>
  </Properties>
</Control>


Populating parameters from a string

Single and multi-valued strings can be used to provide default parameters to the report. Unfortunately, the multi-line support of this control does not map to a multi-value string input expected by SSRS, and only the first instance works. The correct method would be to use another control to select instances based on the object/rule and then pass this to the SQL query for filtering.

Populating parameters from a dataset query

Populating parameters from a dataset query is a flexible method of providing parameter defaults that can be designed to minimise changes in the future. For example, the default group target for a report can remain constant, with only the members of that group changing as reporting needs change. Rather than hard-coding a partulcar GUID, a lookup based on a well-known name can also save re-work.

For example, the following direct text SQL query returns the Rule GUID for the 'Logical Disk Free Megabytes' rule, which could be used to populate a default report parameter, providing a default when the report is opened:

SELECT vRule.RuleGuid from vRule
inner join vPerformanceRule ON vPerformanceRule.RuleRowID = vRule.RuleRowID
WHERE vRule.RuleDefaultName = 'Logical Disk Free Megabytes'

Another example is constructing XML to find the ManadedEntityRowID of a particular group, again useful for populating report parameter defaults:

SELECT '<Data><Objects><Object Use=''Containment''>' + Cast(ManagedEntityRowID as varchar) + '</Object></Objects></Data>' as XMLManagedEntity
FROM vManagedEntity WHERE ManagedEntityDefaultName = 'Custom Group Name'


Note the use of the double single-quotes, required to allow this text to be stored in an XML management pack definition while still resulting in well-formed XML.

References

OpsMgr 2007 Customized Reporting - SQL Queries
http://waynes-world-it.blogspot.com/2008/07/opsmgr-2007-customized-reporting-sql.html

OpsMgr 2007 SSRS Reports using SQL 2005 XML
http://waynes-world-it.blogspot.com/2008/05/opsmgr-2007-ssrs-reports-using-sql-2005.html



Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin.


Read more!

Wednesday, July 9, 2008

OpsMgr 2007 Customized Reporting - SQL Queries

This post provides information on SQL queries relating to Microsoft Operations Manager 2007. I do not have much knowledge of OpsMgr 2007 or SQL, but the following includes information on becoming familiar with the database, using OpsMgr groups and querying XML with SQL - all integral parts of authoring Operations Manager 2007 reports.

Familiarity with the OpsMgr Data warehouse database

The default reports provide many specific and generic report types, but apart from modifying the layout of an existing result set, the only way to report on extra information is to run additional queries against the data warehouse.

There are several different ways to become familiar with the Operations Manager 2007 Data Warehouse database, including:

  1. The Management Pack authoring guide, the report authoring guide and the design guide. See the References section.
  2. There are dozens of example queries in the sealed management packs provided with Operations Manager 2007. See below for information on unsealing a management pack
  3. There are many web pages providing example SQL queries and custom management packs.

Unsealing a Management Pack

Management packs usually exist in:
c:\Program Files\System Center Operations Manager 2007\

To unseal a management pack:

  1. Copy the management pack from the server to your workstation
  2. Change directory to the folder containing the script, Start PowerShell, and then run
  3. . .\UnsealMP.ps1 -f %path%\%file%.mp

The powershell script can be found at the end of this post.

This provides the XML for the management pack, typically containing any SQL queries used in the operation of that management pack.

Parsing Managed Entity IDs

One of the most useful smart parameter controls available in Operations Manager 2007 is the ParameterPrompt.ObjectList control, providing the ability to select one or more groups and/or objects to use as the managed entity filter for the report.

Creating Groups

Depending on the data being queried, it seems that the direct objects returned in the search are not always relevant. For example, when choosing instances of performance-based rules, selecting specific objects - such as a specific ‘Windows Computer’ instance - does not return any results. This is because the performance rules are created against a different ManangedEntityRowID - the logical disk free counter for each instance of a logical disk against that windows computer instance.

It is more practical and less management overhead to create a structured series of dynamic groups, used throughout all functions of Operations Manager. For example, groups containing types of servers, such as clusters, IIS servers, SMS servers etc usually makes sense when reporting.

This OpsMgr smart control creates XML and passes it as a string parameter to SSRS (SQL Server Reporting Services), which is in turn passed to the stored procedure used for the main dataset.

The following SQL query creates an example XML string containing the object ID of a group which essentialy contain a group of servers. This would return multiple managed entities relating to each server in the group, including the servers themselves, cluster servers, logical drives, network connections, group policy and license objects.



DECLARE @ExecError int
DECLARE @StartDate datetime
DECLARE @EndDate datetime
Set @EndDate = GetDate()
Set @StartDate = DateAdd(day, -1, @EndDate)

DECLARE @ManagedEntity table (ManagedEntityID int)
DECLARE @TESTGROUP nvarchar(256)

Select @TESTGROUP = '<data><objects><object use="Containment">
' + Cast(ManagedEntityRowID as varchar) + '</object></objects></data>'
from vmanagedentity where managedentitydefaultname = 'Test Group'

INSERT INTO @ManagedEntity
EXECUTE @ExecError = [Microsoft_SystemCenter_DataWarehouse_Report_Library_ReportObjectListParse]
@StartDate = @StartDate,
@EndDate = @EndDate,
@ObjectList = @TESTGROUP

select * from vmanagedentity
inner join @ManagedEntity MET on vmanagedentity.ManagedEntityRowID = MET.ManagedEntityID


Querying XML using TSQL

Passing multi-valued parameters from the Operations Manager Smart Controls through the SSRS report to SQL can be difficult, and the method employed most by the default Microsoft reports seems to be XML.

SQL 2005 includes the XML data type and associated methods, including XQuery, a subset of the XPath query standard. In addition, SQL supports OPENXML – a rowset provider to construct a relational rowset view of an XML document.

The second method below is used in the ‘Managed Entity Current Instance’ report to pass a multi-valued string parameter as XML to the SQL query. After the XML has been transformed to a rowset, it is then used in the where clause to filter the instance names of the performance counters being returned.

Included below are two examples of processing an XML string, and querying an element value from the XML elements inside a SQL insert/select clause.


declare @execerror int
declare @xmldoc xml
declare @ixmldoc int
set @xmldoc = '<data><objects><object use="Containment">
123</object><object use="Containment">
234</object></objects></data>'
'

DECLARE @tblTest table (test int)

/* Parse the XML document and insert the converted int object element value into temporary table */
element value into temporary table */
EXEC @ExecError = sp_xml_preparedocument @ixmldoc OUTPUT, @xmldoc
INSERT INTO @tblTest
SELECT * FROM
OPENXML (@ixmldoc, '/Data/Objects/Object')
WITH (InstanceFilter int '.')

select * from @tbltest

/* Translate the value of object nodes to an int from XML document into the test field of the table */ nodes to an int from XML document into the test field of the table */
INSERT INTO @tblTest (test)
select tblTest.test.value('.', 'int')
from @xmldoc.nodes('/Data/Objects/Object') AS tblTest(test)

select * from @tbltest



Example SQL

An example I was providing executes a generic version of the following SQL, selecting the most recent performance rule instance for each the specified rule and managed entity, in this case, servers with a name matching ‘%testserver%’ and the 'Logical Disk Free Megabytes’ performance rule.

This query generates a temporary named result set, partitioning that result set using the row-number() ranking windowing function, over managed entities by time and then selecting the first record of each partition.


WITH CurrentDiskFree AS
(SELECT PRI.Instancename, DateAdd(Hour, 10, PPR.DateTime) as DateTime, ME.Path, ME.ManagedEntityRowID, PPR.SampleValue,
ROW_NUMBER() OVER (partition by ME.ManagedEntityRowID order by PPR.DateTime DESC)as RowNumber
from vperformanceruleinstance PRI
inner join vPerformanceRule PR on PRI.RuleRowID = PR.RuleRowID
inner join perf.vPerfRaw PPR on PRI.PerformanceRuleInstanceRowID = PPR.PerformanceRuleInstanceRowID
inner join vManagedEntity ME on ME.ManagedEntityRowID = PPR.ManagedEntityRowID
inner join vRule RU ON RU.RuleRowID = PR.RuleRowID
WHERE RU.RuleDefaultName = 'Logical Disk Free Megabytes'
AND ME.Path like '%testserver%')
SELECT *
FROM CurrentDiskFree
where RowNumber = 1






# -- UnsealMP.ps1 -- #

param(
  $FileInput = "",
  $outputDirectory = $pwd)

# Usage:
#  . .\UnsealMP.ps1 -f c:\temp\test.mp
#  . .\UnsealMP.ps1 -f c:\temp\test.mp -o c:\ManagementPacks
#

$OMManagement = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.EnterpriseManagement.OperationsManager")

if ($FileInput -ne "") {
    $mp = new-object Microsoft.EnterpriseManagement.Configuration.ManagementPack($FileInput)
    $mpWriter = new-object Microsoft.EnterpriseManagement.Configuration.IO.ManagementPackXmlWriter($outputDirectory)
    $mpWriter.WriteManagementPack($mp)
} else {
  write-host "No management pack specified"
}


References:

Operations Manager Report Authoring Guide
http://blogs.technet.com/momteam/archive/2008/02/26/operations-manager-report-authoring-guide.aspx

Microsoft Operations Manager 2007 Management Pack Authoring Guide
http://download.microsoft.com/download/7/4/d/74deff5e-449f-4a6b-91dd-ffbc117869a2/OM2007_AuthGuide.doc

Introduction to the Operations Manager 2007 Design Guide
http://download.microsoft.com/download/7/4/d/74deff5e-449f-4a6b-91dd-ffbc117869a2/OpsMgr2007_DesignGuid.doc

Operator Element (RDL)
http://technet.microsoft.com/en-us/library/ms154634.aspx

FilterExpression Element (RDL)
http://technet.microsoft.com/en-us/library/ms154035.aspx

Reports in Management Packs.
http://blogs.msdn.com/eugenebykov/archive/2007/05/18/reports-in-management-packs.aspx

ManagementPackDataWarehouseScript.UpgradeUnsupported Property
http://msdn.microsoft.com/en-us/library/microsoft.enterprisemanagement.configuration.managementpackdatawarehousescript.upgradeunsupported.aspx

Enabling the EnterpriseManagementChartControl
http://go.microsoft.com/fwlink/?LinkId=111034

Example XML:
http://blogs.technet.com/momteam/archive/2008/02/26/operations-manager-report-authoring-guide.aspx
http://blogs.msdn.com/eugenebykov/archive/2007/05/18/reports-in-management-packs.aspx

Defining Report Datasets for a SQL Server Relational Database
http://msdn.microsoft.com/en-us/library/ms159260.aspx

Select the Data Source (Report Wizard)
http://technet.microsoft.com/en-us/library/ms189364.aspx?ref=Sawos.Org

SSRS examples
http://www.simple-talk.com/sql/learn-sql-server/beginning-sql-server-reporting-services-part-4/

Expression Examples in Reporting Services
http://msdn.microsoft.com/en-us/library/ms157328.aspx

Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin.


Read more!

Friday, May 23, 2008

OpsMgr 2007 SSRS Reports using SQL 2005 XML

This post relates mostly to the concept of passing XML between SQL Server Reporting Services (SSRS), Operations Manager Smart Controls, and SQL Stored Procedures when you are customising Operations Manager 2007 reporting.

Passing multi-valued parameters from the Operations Manager Smart Controls through the SSRS report to SQL can be difficult, and the method employed most by the default Microsoft reports seems to be XML.

SQL 2005 includes the XML data type and associated methods, including XQuery, a subset of the XPath query standard. In addition, SQL supports OPENXML – a rowset provider to construct a relational rowset view of an XML document.

Included below are two examples of processing an XML string and querying an element value from the XML elements with a SQL insert/select clause.

declare @execerror int
declare @xmldoc xml
declare @ixmldoc int
set @xmldoc = '<Data><Objects><Object Use="Containment">376</Object><Object Use="Containment">300</Object></Objects></Data>'
DECLARE @tblTest table (test int)


/* Parse the XML document and insert the converted int <object> element value into a temporary table */

EXEC @ExecError = sp_xml_preparedocument @ixmldoc OUTPUT, @xmldoc
INSERT INTO @tblTest
SELECT * FROM
OPENXML (@ixmldoc, '/Data/Objects/Object')
WITH (InstanceFilter int '.')

select * from @tbltest


/* Translate the value of <object> nodes to an int from an XML document into the test field of the table */

INSERT INTO @tblTest (test)
select tblTest.test.value('.', 'int')
from @xmldoc.nodes('/Data/Objects/Object') AS tblTest(test)

select * from @tbltest


Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin.


Read more!

Tuesday, May 6, 2008

OpsMgr 2007 Current Performance Instances

In the default Operations Manager 2007 reports there doesn’t seem to be a report that will show you the most recent gathered performance instance of something. For example, for a group of servers, I wanted a report that showed the current free disk space on all logical drives of those servers.

I couldn’t find anything in OpsMgr 2007, so to start with I’ve written a SQL query that will provide the information from the Operations Manager Data Warehouse database.

Note that I don’t know much about SQL or Operations Manager, so this may not be the best method.

The following query generates a temporary named result set, partitioning that result set using the row-number() ranking windowing function, over managed entities by time. This provies a method of selecting the most recent performance rule instance for each the specified rule and managed entity.

WITH CurrentDiskFree AS
(SELECT PRI.Instancename, DateAdd(Hour, 10, PPR.DateTime) as DateTime,

ME.Path, ME.ManagedEntityRowID, PPR.SampleValue,
ROW_NUMBER() OVER

(partition by ME.ManagedEntityRowID order by PPR.DateTime DESC)as RowNumber
FROM vPerformanceRuleInstance PRI
inner join vPerformanceRule PR on PRI.RuleRowID = PR.RuleRowID
inner join perf.vPerfRaw PPR on PRI.PerformanceRuleInstanceRowID = PPR.PerformanceRuleInstanceRowID
inner join vManagedEntity ME on ME.ManagedEntityRowID = PPR.ManagedEntityRowID
inner join vRule RU ON RU.RuleRowID = PR.RuleRowID
WHERE RU.RuleDefaultName = 'Logical Disk Free Megabytes'
AND ME.Path like '%server%')

SELECT *
FROM CurrentDiskFree
where RowNumber = 1


Notes:


  1. You could also restrict the query based on the members of a group, a more standard method in Operations Manager terms.
  2. One managed entity path can and will usually have more than one performance rule instance and ManagedEntityRowID. For example, C: and D: drive in a server would have one row each.
  3. The date is recorded in the database is UTC – GMT+0, I’ve calculated GMT+10 for my local timezone in the SQL query.
  4. To make this generic in a reporting sense, something with ManagementGroupID should be added to query and use the appropriate management group.

An example resultset:

C:2008-05-06 22:10:50.000server1.domain.com277251501
D:2008-05-06 22:15:50.000server1.domain.com278367491
C:2008-05-06 22:30:49.000server2.domain.com282128161
D:2008-05-06 22:10:49.000server3.domain.com183367701


Read more!

All Posts

printQueue AD objects for 2003 ClusterVirtualCenter Physical to VirtualVirtual 2003 MSCS Cluster in ESX VI3
Finding duplicate DNS recordsCommand-line automation – Echo and macrosCommand-line automation – set
Command-line automation - errorlevels and ifCommand-line automation - find and findstrBuilding blocks of command-line automation - FOR
Useful PowerShell command-line operationsMSCS 2003 Cluster Virtual Server ComponentsServer-side process for simple file access
OpsMgr 2007 performance script - VMware datastores...Enumerating URLs in Internet ExplorerNTLM Trusts between 2003 and NT4
2003 Servers with Hibernation enabledReading Shortcuts with PowerShell and VBSModifying DLL Resources
Automatically mapping printersSimple string encryption with PowerShellUseful NTFS and security command-line operations
Useful Windows Printer command-line operationsUseful Windows MSCS Cluster command-line operation...Useful VMware ESX and VC command-line operations
Useful general command-line operationsUseful DNS, DHCP and WINS command-line operationsUseful Active Directory command-line operations
Useful command-linesCreating secedit templates with PowerShellFixing Permissions with NTFS intra-volume moves
Converting filetime with vbs and PowerShellDifference between bat and cmdReplica Domain for Authentication
Troubleshooting Windows PrintingRenaming a user account in ADOpsMgr 2007 Reports - Sorting, Filtering, Charting...
WMIC XSL CSV output formattingEnumerating File Server ResourcesWMIC Custom Alias and Format
AD site discoveryPassing Parameters between OpsMgr and SSRSAnalyzing Windows Kernel Dumps
Process list with command-line argumentsOpsMgr 2007 Customized Reporting - SQL QueriesPreventing accidental NTFS data moves
FSRM and NTFS Quotas in 2003 R2PowerShell Deleting NTFS Alternate Data StreamsNTFS links - reparse, symbolic, hard, junction
IE Warnings when files are executedPowerShell Low-level keyboard hookCross-forest authentication and GP processing
Deleting Invalid SMS 2003 Distribution PointsCross-forest authentication and site synchronizati...Determining AD attribute replication
AD Security vs Distribution GroupsTroubleshooting cross-forest trust secure channels...RIS cross-domain access
Large SMS Web Reports return Error 500Troubleshooting SMS 2003 MP and SLPRemotely determine physical memory
VMware SDK with PowershellSpinning Excel Pie ChartPoke-Info PowerShell script
Reading web content with PowerShellAutomated Cluster File Security and PurgingManaging printers at the command-line
File System Filters and minifiltersOpsMgr 2007 SSRS Reports using SQL 2005 XMLAccess Based Enumeration in 2003 and MSCS
Find VM snapshots in ESX/VCComparing MSCS/VMware/DFS File & PrintModifying Exchange mailbox permissions
Nested 'for /f' catch-allPowerShell FindFirstFileW bypassing MAX_PATHRunning PowerSell Scripts from ASP.Net
Binary <-> Hex String files with PowershellOpsMgr 2007 Current Performance InstancesImpersonating a user without passwords
Running a process in the secure winlogon desktopShadow an XP Terminal Services sessionFind where a user is logged on from
Active Directory _msdcs DNS zonesUnlocking XP/2003 without passwords2003 Cluster-enabled scheduled tasks
Purging aged files from the filesystemFinding customised ADM templates in ADDomain local security groups for cross-forest secu...
Account Management eventlog auditingVMware cluster/Virtual Center StatisticsRunning scheduled tasks as a non-administrator
Audit Windows 2003 print server usageActive Directory DiagnosticsViewing NTFS information with nfi and diskedit
Performance Tuning for 2003 File ServersChecking ESX/VC VMs for snapshotsShowing non-persistent devices in device manager
Implementing an MSCS 2003 server clusterFinding users on a subnetWMI filter for subnet filtered Group Policy
Testing DNS records for scavengingRefreshing Computer Account AD Group MembershipTesting Network Ports from Windows
Using Recovery Console with RISPAE Boot.ini Switch for DEP or 4GB+ memoryUsing 32-bit COM objects on x64 platforms
Active Directory Organizational Unit (OU) DesignTroubleshooting computer accounts in an Active Dir...260+ character MAX_PATH limitations in filenames
Create or modify a security template for NTFS perm...Find where a user is connecting from through WMISDDL syntax in secedit security templates

About Me

I’ve worked in IT for over 20 years, and I know just about enough to realise that I don’t know very much.