Forgot to mention, the error shows when trying to view the Property of the newly created groups. And 'view group memberships' shows empty.
Forgot to mention, the error shows when trying to view the Property of the newly created groups. And 'view group memberships' shows empty.
I managed to get the groups populated, but I also get the "no group population rule defined" when trying to open the properties of the group.
I am getting that same error "The group can not be modified because there is no group population rule defined for this group". Problem with that is I modified the script so it populates specific group for WSUS reboots based on AD OU. If I try to add these groups to SCOM Scheduler to put them in Maintenance Mode, it doesn't work due to the above error.
Is there a way around this?
If you need a fully dynamic solution, you can set the base class to Microsoft.SystemCenter.ComptuerGroup and flag Singleton=false. Then we can use variable notation to populate display names. This way, we do not need to update the XML each time a group is added/removed from the CMDB.
Hey Kevin,
I implimented this just fine except for one annoyance. The solution appears to be case sensative. The case of the computer name in the CMDB has to match the case of the Name in SCOM. Any thoughts on how to work around this?
Thanks,
Brian
Health Watcher (Agent) group from CMDB
For anyone interested here is Kevin's script modified to create a group of Health Watchers from a CMDB:
Dim objConnection
Dim oRS
Dim oRS2
Dim sConnectString
Dim ManagedEntityID
Dim oAPI
Dim oDiscoveryData
SourceId = WScript.Arguments(0)
ManagedEntityId = WScript.Arguments(1)
Set oAPI = CreateObject("MOM.ScriptAPI")
Set oDiscoveryData = oAPI.CreateDiscoveryData(0,SourceId,ManagedEntityId)
Set groupInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name="CMDBGroupPopulation.HealthWatchers']$")
oDiscoveryData.IsSnapshot = true
sConnectString = "Driver={SQL Server};Server=<server>; Database=<database>;"
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Open sConnectString
Set oRS = CreateObject("ADODB.Recordset")
oRS.Open "select distinct servername instancename from serverlist ", objConnection
While Not oRS.EOF
sConnectString2 = "Driver={SQL Server};Server=<Ops DB Server>; Database=OperationsManager;"
Set objConnection2 = CreateObject("ADODB.Connection")
objConnection2.Open sConnectString2
Set oRS2 = CreateObject("ADODB.Recordset")
oRS2.Open("SELECT DISTINCT [Id] FROM [OperationsManager].[dbo].[ManagedEntityGenericView] where path = '" + oRS.Fields("instancename") + "' and FullName like 'Microsoft.SystemCenter.HealthService:%'"), objConnection2
id = oRS2.Fields("Id")
id = Left(Right(Id,37),36)
Set serverInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='SC!Microsoft.SystemCenter.AgentWatcher']$")
Set relationshipInstance = oDiscoveryData.CreateRelationshipInstance("$MPElement[Name='CMDBGroupPopulation.ContainsHealthWatchers']$")
serverInstance.AddProperty "$MPElement[Name='System!System.Entity']/DisplayName$",oRS.Fields("InstanceName")
serverInstance.AddProperty "$MPElement[Name='SC!Microsoft.SystemCenter.HealthServiceWatcher']/HealthServiceId$",id
serverInstance.AddProperty "$MPElement[Name='SC!Microsoft.SystemCenter.HealthServiceWatcher']/HealthServiceName$",oRS.Fields("InstanceName")
serverInstance.AddProperty "$MPElement[Name='SC!Microsoft.SystemCenter.HealthServiceWatchersGroup']/WatcherGroupName$","Microsoft.SystemCenter.AgentWatchersGroup"
relationshipInstance.Source = groupInstance
relationshipInstance.Target = serverInstance
oDiscoveryData.AddInstance relationshipInstance
oRS.MoveNext
Wend
objConnection2.Close
objConnection.Close
Call oAPI.Return(oDiscoveryData)
Here is an expansion of the post by MedeBay and Kevin to populate groups with health watcher agent items. i have incorporated some error handling to allow for CMDB databases which may or may not include servers that don’t have SCOM agents or have correct FQDN's in your CMDB, previously the script would just error and fail. This modified script is also case independent and uses the Datawarehouse's own FQDN instead of the one in your CMDB, as long as the NETBIOS name is correct it will pick it up.
Thanks for this initial post it has helped me with a large scale deployment of SCOM which i look after. Previously we have had to manually keep our OpsMgr groups updated with our CMDB which has gotten more and more complicated as new customers have come on-board. Currently we have over 1000 agents deployed including windows and unix machines. I am currently modifying this script to also populate "Windows.Unix.Computer" items.
-----------
Option Explicit
Dim objConnection
Dim objConnection2
Dim oRS
Dim oRS2
Dim sConnectString
Dim sConnectString2
Dim SourceId
Dim ManagedEntityID
Dim oAPI
Dim oDiscoveryData
Dim groupInstance
Dim serverInstance
Dim relationshipInstance
Dim id
SourceId = WScript.Arguments(0)
ManagedEntityId = WScript.Arguments(1)
Set oAPI = CreateObject("MOM.ScriptAPI")
Set oDiscoveryData = oAPI.CreateDiscoveryData(0,SourceId,ManagedEntityId)
Set groupInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='Group.CAASLA5X16.HealthWatchers']$")
oDiscoveryData.IsSnapshot = true
sConnectString = "Provider=SQLOLEDB;User ID=***********;Password=**********;Initial Catalog=MDB;Data Source=**************;"
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Open sConnectString
Set oRS = CreateObject("ADODB.Recordset")
oRS.Open("SELECT DISTINCT [resource_name] FROM [database] WHERE [inactive_flag] != '1' AND [service_type] LIKE '%16%'"), objConnection
While Not oRS.EOF
sConnectString2 = "Provider=SQLOLEDB.1;Data Source=*************;Initial Catalog=OperationsManager;User Id=**********;Password=*********;"
Set objConnection2 = CreateObject("ADODB.Connection")
objConnection2.Open sConnectString2
Set oRS2 = CreateObject("ADODB.Recordset")
oRS2.Open("SELECT DISTINCT [Id], [Path] FROM [OperationsManager].[dbo].[ManagedEntityGenericView] WHERE FullName LIKE '" + "Microsoft.SystemCenter.HealthService:" + LTRIM(RTRIM(oRS.Fields("resource_name"))) + "%" + "'"), objConnection2
If Not oRS2.BOF Then
oRS2.MoveFirst
End If
If Not oRS2.EOF Then
If Not IsNull(oRS2.Fields("Id")) AND oRS2.Fields("Id") <> "" Then
id = oRS2.Fields("Id")
id = Left(Right(Id,37),36)
Set serverInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='SC!Microsoft.SystemCenter.AgentWatcher']$")
Set relationshipInstance = oDiscoveryData.CreateRelationshipInstance("$MPElement[Name='Group.CAASLA5X16.ContainsHealthWatchers']$")
serverInstance.AddProperty "$MPElement[Name='System!System.Entity']/DisplayName$",oRS2.Fields("Path")
serverInstance.AddProperty "$MPElement[Name='SC!Microsoft.SystemCenter.HealthServiceWatcher']/HealthServiceId$",id
serverInstance.AddProperty "$MPElement[Name='SC!Microsoft.SystemCenter.HealthServiceWatcher']/HealthServiceName$",oRS2.Fields("Path")
serverInstance.AddProperty "$MPElement[Name='SC!Microsoft.SystemCenter.HealthServiceWatchersGroup']/WatcherGroupName$","Microsoft.SystemCenter.AgentWatchersGroup"
relationshipInstance.Source = groupInstance
relationshipInstance.Target = serverInstance
oDiscoveryData.AddInstance relationshipInstance
End If
End If
oRS.MoveNext
Wend
objConnection2.Close
objConnection.Close
Set objConnection2 = nothing
Set objConnection = nothing
Call oAPI.Return(oDiscoveryData)
Greetings,
I know this is a bit out dated, but I was wondering if anyone had insight into whether this should still function in SCOM 2012?
I'm quite new to SCOM 2012 and am setting up a test here. Would like to set up a way for our individuals / teams to scope their views, notifications, etc. Seems odd that this isn't built into the product yet, but I stumbled across this post : )
I have everything seemingly working. The management pack imports. If I slightly modify the vbscript to remove the SCOM items and just list out the hostname/user, I get the expected results... but nothing shows up when I try to view group members.
Here's an example xml file: http://pastebin.com/TMj6nkaS
Does anything need to be updated for this to work in SCOM 2012? Your insight would be greatly appreciated!
I spoke to soon. It turns out having a single incorrect entry in the text file (non FQDN) invalidates the entire process. This works now : )
Kevin Holman, you said:
"Therefore - if you need error correction - your script will need to gather the data from your CMDB datasource, ensure that each object exists as an object in SCOM, then it will be submitted. Essentially, you need to put error correction in your script. This is the single biggest reason that people have challenges implementing this solution."
That is exactly where I am stuck. I modified this script to pull from LDAP ADSI and get a list of group memberships that are basically PrincipalNames of workstations/laptops in AD. What I am finding is that some of the names in AD are not for whatever reason in SCOM as a Windows Computer and the entire SCOM submission fails and I get an error in the event log. I verified this by altering my script and making only valid entries become submitted.
My question is, how in the world can I do 'error correction' or 'ensure that each object exists as an object in SCOM" ? I don't see any SCOM scripting methods that allow me to query SCOM for status or data. I would even consider exporting out the list of PrincipalNamed computers in SCOM and cross referencing that before I add them but I cant find anything for that either. It appears when you call .Return on the SCOM scripting object, you are done, no more interaction.
Any ideas?
Dim SourceId
Dim objConnection
Dim oRS
Dim objCommand
Dim sConnectString
Dim ManagedEntityID
Dim oAPI
Dim iCounter
Dim oDiscoveryData
Const ADS_SCOPE_SUBTREE = 2
SourceId = WScript.Arguments(0)
ManagedEntityId = WScript.Arguments(1)
Set objFileToWrite = CreateObject("Scripting.FileSystemObject").OpenTextFile("d:\log.txt",2,true)
'-- insert ad query
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection
objCommand.CommandText ="SELECT sAMAccountName FROM 'LDAP://dc=domain,dc=com' WHERE memberOf='cn=Appsense.GPO.Computer,OU=Appsense Groups,OU=Software,dc=domain,dc=com"
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Timeout") = 30
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
objCommand.Properties("Cache Results") = False
Set oRS = objCommand.Execute
' -- end ad query
Set oAPI = CreateObject("MOM.ScriptAPI")
Set oDiscoveryData = oAPI.CreateDiscoveryData(0,SourceId,ManagedEntityId)
Set groupInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='GroupPopulation.AppsenseComputers']$")
oDiscoveryData.IsSnapshot = true
objFileToWrite.WriteLine("Source ID: " + SourceID)
objFileToWrite.WriteLine("ManagedEntityID: " + ManagedEntityId)
objFileToWrite.WriteLine("Start of loop")
While Not oRS.EOF
strComputerName = replace(oRS("sAMAccountName").Value, "$", "")
objFileToWrite.WriteLine(strComputerName + ".lgeenergy.int")
Set serverInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='Windows!Microsoft.Windows.Computer'
serverInstance.AddProperty "$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$",strComputerName + ".domain.com"
Set relationshipInstance = oDiscoveryData.CreateRelationshipInstance("$MPElement[Name='GroupPopulation.AppsenseComputersContainsWindowsComputers']$")
relationshipInstance.Source = groupInstance
relationshipInstance.Target = serverInstance
oDiscoveryData.AddInstance relationshipInstance
oRS.MoveNext
Wend
Call oAPI.Return(oDiscoveryData)
objFileToWrite.WriteLine("End of Loop")
Set oAPI = nothing
Set oDiscoveryData = nothing
Set groupInstance = nothing
objConnection.Close
objFileToWrite.Close