| « How-To: Import Computer Location Information Into OpsMgr (Part 3-3) | How-To: Import Computer Location Information Into OpsMgr (Part 1-3) » |
How-To: Import Computer Location Information Into OpsMgr (Part 2-3)
In the previous article I have explained how to extend an existing server class with a ‘Location’ attribute by building a custom Management Pack. In this article I will explain how to create a connector that reads information from a CSV file and updates the location information of a server in OpsMgr.
Follow up:
Introduction
In this blog post I will create a very rudimentary connector using Powershell reading information from a CSV file and updating the server object in OpsMgr. The goal of this post is to explain the possibilities and not to provide a full proof connector.
Before we can update information in OpsMgr we need to be able to match the object between OpsMgr and the CMDB source. Each class in OpsMgr has its own key field which makes an object unique. In the case of the ‘Windows.Server.Computer’ class this key field is the PrincipalName (or fully qualified domain name).
Creating the Source
In this example we use a CSV file named ‘CMDB.csv’ as a source for the connector. The file contains two fields:
- ‘KeyName’ (in this case the PrincipalName of the server)
- ‘Location’ (a string uniquely identifying the location)
To use this CSV file in your environment you need to change content so it matches the principal names of your servers.
KeyName, Location
"VM-TEST-SCOM01.testdom.savision.local", "New York/Room 2/Rack 2b"
"VM-TEST-AD01.testdom.savision.local", "Amsterdam/Room 1/Rack 1a"
Creating the Connector Script
As explained we will use Powershell to create this connector. The script source can be found at the end of the blog article.
First step in the script is to load the OpsMgr SDK files and set some variables. If you are going to use this script in your environment replace the ‘$rms’ variable to the name of your Root Management Server and the ‘$inputCSV’ variable to the location of your input file.
# load OpsMgr SDK assemblies
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.EnterpriseManagement.OperationsManager") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.EnterpriseManagement.OperationsManager.Common") | Out-Null
# set script variables
$baseClassName = "Microsoft.Windows.Computer"
$baseClassKeyName = "PrincipalName"
$extendedClassName = "Microsoft.Windows.Server.Computer.Extended"
$connectorName = "MyExtendedClass.Connector"
# set your input file location
$inputCSV = "c:\Scipts\CMDB.csv"
# set your RMS
$rms = "vm-test-scom01"
To be able to update information in OpsMgr using the SDK we need to create a connector object. We use a function to get the connector object if it already exists or create one if this script is run for the fist time.
# get monitoring connector
function GetMonitoringConnector([string] $connectorName)
{
$connectorAdmin = $mg.GetConnectorFrameworkAdministration()
foreach($connector in $connectorAdmin.GetMonitoringConnectors())
{
if ($connector.Name -eq $connectorName){return $connector;}
}
# connector does not exist / create new
$connectorInfo = New-Object Microsoft.EnterpriseManagement.ConnectorFramework.ConnectorInfo
$connectorInfo.Name = $connectorName
$connectorInfo.DisplayName = $connectorName
$connectorInfo.DiscoveryDataIsManaged = 'true'
$connector = $connectorAdmin.Setup($connectorInfo)
return $connector
}
Now lets get connected to OpsMgr, get the class and property objects we need and call the GetConnector function.
# connect to the OM management group
$mg = New-Object Microsoft.EnterpriseManagement.ManagementGroup $rms
#get class and property objects
$baseClass = $mg.GetMonitoringClasses($baseClassName)[0]
$extendedClass = $mg.GetMonitoringClasses($extendedClassName)[0]
$keyProperty = $baseClass.GetMonitoringProperty($baseClassKeyName)
$locationProperty = $extendedClass.GetMonitoringProperty("Location")
# get monitoring connector
$connector = GetMonitoringConnector($connectorName)
We are set to go…let the data flow! Next step is looping through the CSV file, check if the object exists in OpsMgr and then update the location attribute. To update an existing object we also need to set the key property.
if (Test-Path -Path $inputCSV)
{
$inputData = import-csv $inputCSV
$discoveryData = New-Object Microsoft.EnterpriseManagement.ConnectorFramework.IncrementalMonitoringDiscoveryData
foreach ($line in $inputData)
{
$criteriaString = $baseClassKeyName + " = '" + $line.KeyName + "'"
$criteria = New-Object Microsoft.EnterpriseManagement.Monitoring.MonitoringObjectCriteria($criteriaString, $baseClass)
# if object exists, update location property
if ($mg.GetMonitoringObjects($criteria).Count -eq 1)
{
Write-Host "Updating" $line.KeyName "..."
$cmo = New-Object Microsoft.EnterpriseManagement.Monitoring.CustomMonitoringObject($extendedClass)
$cmo.SetMonitoringPropertyValue($keyProperty, $line.KeyName)
$cmo.SetMonitoringPropertyValue($locationProperty, $line.Location)
$discoveryData.Add($cmo)
}
}
# submit the data
$discoveryData.Commit($connector)
}
else
{
Write-Host "Unable to find input file " + $inputCSV
}
Write-Host "Ready"
Running The Script
To run the script successfully you must:
- have PowerShell 2.0 installed
- have the PowerShell execution policy set to Unrestricted
- have the OpsMgr console installed
- be an OpsMgr administrator
If you have met al requirements you can run the script using using the command line. If the script runs successful you will see the following output.
Check The Results
To check the results of the update, go to the OpsMgr console and open the MyExtendedClass view in the Monitoring pane. If everything worked out fine you should see the updated server objects with location information.
We are passed the hard part …it will be all fun from now. In the next post I will explain different ways to dynamically visualize the servers with Live Maps based on the location attribute.
Downloads: Connector Script
More Information on Live Maps: www.savision.com
Related Articles:

