-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathClass.Group.SQLQueryBasedGroupWindowsComputers.mpx
More file actions
269 lines (239 loc) · 11.8 KB
/
Class.Group.SQLQueryBasedGroupWindowsComputers.mpx
File metadata and controls
269 lines (239 loc) · 11.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
<ManagementPackFragment SchemaVersion="2.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!--
%%
Description:
A GROUP of Windows Computers that are pulled from a SQL Query
CompanyID - is a short abbreviation for your company with NO SPACES OR SPECIAL CHARACTERS ALLOWED
AppName - is a short name for your app with NO SPACES OR SPECIAL CHARACTERS ALLOWED
GroupNameNoSpaces - needs to be the UNIQUE name that describes your group with NO SPACES OR SPECIAL CHARACTERS ALLOWED.
SQLServer - the servername and instancename (if required) of the SQL server to connect to
SQLDBName - the database name to query
SQLQuery - the SQL query that will return a list of FQDN names ONLY
Version: 1.3
LastModified: 29-Mar-2022
%%
In this fragment you need to replace:
##CompanyID##
##AppName##
##GroupNameNoSpaces##
##SQLServer##
##SQLDBName##
##SQLQuery##
This fragment depends on references:
RequiredReference: Alias="System", ID="System.Library"
RequiredReference: Alias="SC", ID="Microsoft.SystemCenter.Library"
RequiredReference: Alias="Windows", ID="Microsoft.Windows.Library"
RequiredReference: Alias="MSIL", ID="Microsoft.SystemCenter.InstanceGroup.Library"
@@Author=Kevin Holman@@
-->
<TypeDefinitions>
<EntityTypes>
<ClassTypes>
<ClassType ID="##CompanyID##.##AppName##.##GroupNameNoSpaces##.SQLBased.Group" Accessibility="Public" Abstract="false" Base="MSIL!Microsoft.SystemCenter.InstanceGroup" Hosted="false" Singleton="true" />
</ClassTypes>
<RelationshipTypes>
<RelationshipType ID="##CompanyID##.##AppName##.##GroupNameNoSpaces##.SQLBased.Group.Contains.Windows.Computers" Accessibility="Internal" Abstract="false" Base="System!System.Containment">
<Source ID="##CompanyID##.##AppName##.##GroupNameNoSpaces##.SQLBased.Group.Rel.Source" Type="##CompanyID##.##AppName##.##GroupNameNoSpaces##.SQLBased.Group" />
<Target ID="##CompanyID##.##AppName##.##GroupNameNoSpaces##.SQLBased.Group.Rel.Target" Type="Windows!Microsoft.Windows.Computer" />
</RelationshipType>
</RelationshipTypes>
</EntityTypes>
</TypeDefinitions>
<Monitoring>
<Discoveries>
<Discovery ID="##CompanyID##.##AppName##.##GroupNameNoSpaces##.SQLBased.Group.Discovery" Enabled="true" Target="##CompanyID##.##AppName##.##GroupNameNoSpaces##.SQLBased.Group" ConfirmDelivery="false" Remotable="true" Priority="Normal">
<Category>Discovery</Category>
<DiscoveryTypes>
<DiscoveryClass TypeID="##CompanyID##.##AppName##.##GroupNameNoSpaces##.SQLBased.Group" />
</DiscoveryTypes>
<DataSource ID="DS" TypeID="Windows!Microsoft.Windows.TimedPowerShell.DiscoveryProvider">
<IntervalSeconds>86400</IntervalSeconds>
<SyncTime></SyncTime>
<ScriptName>##CompanyID##.##AppName##.##GroupNameNoSpaces##.SQLBased.Group.Discovery.ps1</ScriptName>
<ScriptBody><![CDATA[
#=================================================================================
# Group Population script based on SQL Query
# Your query should return a list of FQDN names only
#
# Kevin Holman
# v1.1
#=================================================================================
param($SourceID, $ManagedEntityID)
# Manual Testing section - put stuff here for manually testing script - typically parameters:
#=================================================================================
# $SourceId = '{00000000-0000-0000-0000-000000000000}'
# $ManagedEntityId = '{00000000-0000-0000-0000-000000000000}'
# $SQLServer = "FOO"
# $SQLDBName = "CMDB"
# $SQLQuery = "SELECT SERVERNAME from serverlist"
#=================================================================================
# Constants section - modify stuff here:
#=================================================================================
# Assign script name variable for use in event logging
$ScriptName = "##CompanyID##.##AppName##.##GroupNameNoSpaces##.SQLBased.Group.Discovery.ps1"
$EventID = "7501"
$SQLServer = "##SQLServer##"
$SQLDBName = "##SQLDBName##"
$SQLQuery = "##SQLQuery##"
#=================================================================================
# Starting Script section
#=================================================================================
# Gather the start time of the script
$StartTime = Get-Date
# Load MOMScript API
$momapi = New-Object -comObject MOM.ScriptAPI
# Load SCOM Discovery module
$DiscoveryData = $momapi.CreateDiscoveryData(0, $SourceId, $ManagedEntityId)
#Set variables to be used in logging events
$whoami = whoami
#Log script event that we are starting task
$momapi.LogScriptEvent($ScriptName,$EventID,0,"`n Script is starting. `n Running as ($whoami).")
#=================================================================================
# Connect to local SCOM Management Group Section
#=================================================================================
# Clear any previous errors
$Error.Clear()
# Import the OperationsManager module and connect to the management group
$SCOMPowerShellKey = "HKLM:\SOFTWARE\Microsoft\System Center Operations Manager\12\Setup\Powershell\V2"
$SCOMModulePath = Join-Path (Get-ItemProperty $SCOMPowerShellKey).InstallDirectory "OperationsManager"
Import-module $SCOMModulePath
New-DefaultManagementGroupConnection "localhost"
IF ($Error)
{
$momapi.LogScriptEvent($ScriptName,$EventID,1,"`n FATAL ERROR: Failure loading OperationsManager module or unable to connect to the management server. `n Terminating script. `n Error is: ($Error).")
EXIT
}
#=================================================================================
# Begin MAIN script section
#=================================================================================
#Log event for captured parameters
$momapi.LogScriptEvent($ScriptName,$EventID,0,"`n SQLServer: ($SQLServer) `n SQLDatabase: ($SQLDBName). `n SQL Query: ($SQLQuery).")
# Health Service class section
# We need this list of SCOM agents, so we can only submit discovery data for a Healthservice in SCOM otherwise SCOM will reject the discovery data, and this will clean up deleted stale Windows Computer objects that will remain until the next discovery
# Clear any previous errors
$Error.Clear()
# Get all instances of a existing Health Service class
$HS = Get-SCOMClass -Name "Microsoft.SystemCenter.Healthservice" | Get-SCOMClassInstance
$HSNames = $HS.DisplayName
$HSCount = $HSNames.count
IF($Error)
{
$momapi.LogScriptEvent($ScriptName,$EventID,1, "`n FATAL ERROR: Unable to gather Healthservice instances from SCOM. `n Error is: $Error")
EXIT
}
ELSE
{
$momapi.LogScriptEvent($ScriptName,$EventID,0, "`n Get all Health Service Objects has completed. `n Returned ($HSCount) Health Service Objects from SCOM.")
}
# END Health Service class section
# Connect to and then Query the database
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server=$SQLServer;Database=$SQLDBName;Integrated Security=True"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = $SqlQuery
$SqlCmd.Connection = $SqlConnection
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$ds = New-Object System.Data.DataSet
$SqlAdapter.Fill($ds) | Out-Null
$SqlConnection.Close()
# Check for errors connecting to SQL
IF ($Error)
{
$momapi.LogScriptEvent($ScriptName,$EventID,1,"`n FATAL ERROR: There was an attempting to connect to and query SQL. `n Terminating script. `n Error is: ($Error).")
EXIT
}
# Set the output to a variable
[array]$SQLNames = $ds.Tables[0]
$SQLNamesCount = $SQLNames.Count
IF ($SQLNamesCount -ge 1)
{
$momapi.LogScriptEvent($ScriptName,$EventID,0,"`n Successfully collected ($SQLNamesCount) records from the SQL query.")
}
ELSE
{
$momapi.LogScriptEvent($ScriptName,$EventID,1,"`n FATAL ERROR: There was an error getting records from SQL or no records were returned. `n Number of objects returned: ($SQLNamesCount). `n Terminating script.")
EXIT
}
# Set namelist array to empty
[array]$NameList = @()
# Loop through each Name from SQL and build an array of FQDN hostnames
FOREACH ($SQLName in $SQLNames)
{
#Get the Hostname property from SQL
[string]$DNSComputerName = $SQLName[0]
$NameList += $DNSComputerName
}
$NameListCount = $NameList.Count
#Discovery Section
#Set the group instance we will discover members of
$GroupInstance = $DiscoveryData.CreateClassInstance("$MPElement[Name='##CompanyID##.##AppName##.##GroupNameNoSpaces##.SQLBased.Group']$")
# Loop through each SCOM computer and add a group membership containment relationship to the discovery data
$i=0;
FOREACH ($Name in $NameList)
{
#Check to make sure the name we got from AD exists as a Healthservice in this Management Group
IF ($Name -in $HSNames)
{
$i = $i+1
$ServerInstance = $DiscoveryData.CreateClassInstance("$MPElement[Name='Windows!Microsoft.Windows.Computer']$")
$ServerInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $Name)
$RelationshipInstance = $DiscoveryData.CreateRelationshipInstance("$MPElement[Name='##CompanyID##.##AppName##.##GroupNameNoSpaces##.SQLBased.Group.Contains.Windows.Computers']$")
$RelationshipInstance.Source = $GroupInstance
$RelationshipInstance.Target = $ServerInstance
$DiscoveryData.AddInstance($RelationshipInstance)
}
}
IF ($i -ge 1)
{
$momapi.LogScriptEvent($ScriptName,$EventID,0,"`n Successfully found ($i) Computers in SCOM from the original ($NameListCount) DNS names from the query.")
}
ELSE
{
$momapi.LogScriptEvent($ScriptName,$EventID,1,"`n FATAL ERROR: No computers in SCOM were found matching the ($NameListCount) DNS names from the query. `n Terminating script.")
EXIT
}
# Return Discovery Items Normally
$DiscoveryData
# Return Discovery Bag to the command line for testing (does not work from ISE)
# $momapi.Return($DiscoveryData)
#=================================================================================
# End MAIN script section
# End of script section
#=================================================================================
#Log an event for script ending and total execution time.
$EndTime = Get-Date
$ScriptTime = ($EndTime - $StartTime).TotalSeconds
$momapi.LogScriptEvent($ScriptName,$EventID,0,"`n Script Ending. `n Script Runtime: ($ScriptTime) seconds.")
#=================================================================================
#End Script
]]></ScriptBody>
<Parameters>
<Parameter>
<Name>sourceId</Name>
<Value>$MPElement$</Value>
</Parameter>
<Parameter>
<Name>managedEntityId</Name>
<Value>$Target/Id$</Value>
</Parameter>
</Parameters>
<TimeoutSeconds>300</TimeoutSeconds>
</DataSource>
</Discovery>
</Discoveries>
</Monitoring>
<LanguagePacks>
<LanguagePack ID="ENU" IsDefault="true">
<DisplayStrings>
<DisplayString ElementID="##CompanyID##.##AppName##.##GroupNameNoSpaces##.SQLBased.Group">
<Name>##CompanyID## ##AppName## ##GroupNameNoSpaces## SQLQueryBased Group</Name>
</DisplayString>
<DisplayString ElementID="##CompanyID##.##AppName##.##GroupNameNoSpaces##.SQLBased.Group.Discovery">
<Name>##CompanyID## ##AppName## ##GroupNameNoSpaces## SQLQueryBased Group Discovery</Name>
<Description>This discovery rule populates a group of Windows Computer Objects that are returned from a SQL query</Description>
</DisplayString>
</DisplayStrings>
</LanguagePack>
</LanguagePacks>
</ManagementPackFragment>