-
Notifications
You must be signed in to change notification settings - Fork 1
/
CreateMP-CustomServiceMonitor.ps1
293 lines (229 loc) · 13.5 KB
/
CreateMP-CustomServiceMonitor.ps1
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
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# --- [CreateMP-CustomServiceMonitor] PowerShell Script ---
#
# Author(s): Ryan Irujo
# Inception: 08.18.2013
# Last Modified: 08.23.2013
#
# Description: This Script provides an automated method of creating Service Monitors in SCOM that are discovered
# by using Filtered Registry Key Discoveries.
#
#
# Changes: 08.20.2013 - [R. Irujo]
# - Parameterized Script and added logic to verify that Parameters are provided.
# - Added function to replace all '$' with '_' for the Service Name in the $CustomClass and $Monitor variables to
# support custom SQL Instances.
# 08.21.2013 - [R. Irujo]
# - Removed Importing of the PowerShell OperationsManager Module and instead import the SDK DLL Files.
# - Replaced most of the Where-Object filters with .NET Function calls to speed up the Script.
# 08.22.2013 - [R. Irujo]
# - Added Check to Script to see if the Management Pack ID Provided already exists in SCOM.
# 08.23.2013 - [R. Irujo]
# - Added Try-Catch Wrapper around entire Script to display better troubleshooting data when Errors occur.
#
#
# Additional Notes: Mind the BACKTICKS throughout the Script! In particular, any XML changes that you may decide to add/remove/change
# will require use of them to escape special characters that are commonly used.
#
#
# Syntax: ./CreateMP-CustomServiceMonitor <Management_Pack_ID> <Management_Pack_Name> <Management_Pack_Display_Name> <Service_Name> <Service_Display_Name> <Check_Startup_Type_Value> <Registry_Key>
#
# Example: ./CreateMP-CustomServiceMonitor SCOMMS01.fabrikam.local custom.service.monitor.mp01 custom.service.monitor.mp01 "Windows Update Service Monitor" wuauserv "Windows Update" True CSMWindowsUpdate
param($ManagementServer,$ManagementPackID,$ManagementPackName,$ManagementPackDisplayName,$ServiceName,$ServiceDisplayName,$CheckStartupType,$RegistryKey)
# [---START---] Try-Catch Wrapper for Entire Script.
try {
Clear-Host
# Importing SCOM SDK DLL Files.
Import-Module "C:\Program Files\System Center 2012\Operations Manager\Console\SDK Binaries\Microsoft.EnterpriseManagement.Core.dll"
Import-Module "C:\Program Files\System Center 2012\Operations Manager\Console\SDK Binaries\Microsoft.EnterpriseManagement.OperationsManager.dll"
Import-Module "C:\Program Files\System Center 2012\Operations Manager\Console\SDK Binaries\Microsoft.EnterpriseManagement.Runtime.dll"
# Checking Parameter Values.
if (!$ManagementServer) {
Write-Host "A Management Server Name must be provided, i.e. - SCOMMS01.fabrikam.local."
exit 2;
}
if (!$ManagementPackID) {
Write-Host "A Management Pack ID must be provided, i.e. - custom.service.monitor.mp01. The Management Pack ID can be the same as the Management Pack Name."
exit 2;
}
if (!$ManagementPackName) {
Write-Host "A Management Pack Name must be provided, i.e. - custom.service.monitor.mp01. The Management Pack Name can be the same as the Management Pack ID."
exit 2;
}
if (!$ManagementPackDisplayName) {
Write-Host "A Management Pack Display Name must be provided, i.e. - Custom Service Monitor MP01."
exit 2;
}
if (!$ServiceName) {
Write-Host "The Name of the Service you want to Monitor must be provided, i.e. - wuauserv."
exit 2;
}
if (!$ServiceDisplayName) {
Write-Host "The Display Name of the Service you want to Monitor must be provided, i.e. - Windows Update."
exit 2;
}
if (!$CheckStartupType) {
Write-Host "A Check Startup Type Value for the Service Monitor must be provided, i.e. 'True' or 'False'."
exit 2;
}
if (!$RegistryKey) {
Write-Host "A Registry Key for the Discovery must be provided, i.e. - CustomServiceMonitorWindowsUpdate."
exit 2;
}
Write-Host "ManagementServer: " $ManagementServer
Write-Host "ManagementPackID: " $ManagementPackID
Write-Host "ManagementPackName: " $ManagementPackName
Write-Host "ManagementPackDisplayName: " $ManagementPackDisplayName
Write-Host "Connecting to the SCOM Management Group"
$MG = New-Object Microsoft.EnterpriseManagement.ManagementGroup($ManagementServer)
# Making sure that the Management Pack ID provided doesn't already exist in SCOM.
Write-Host "Determining if Management Pack ID [$($ManagementPackID)] already exists"
try {
$CheckManagementPackName = $MG.GetManagementPacks($ManagementPackID)[0]
If ($CheckManagementPackName.ToString().Length -gt "0") {
Write-Host "Management Pack ID [$($ManagementPackID)] was found in SCOM. Script will now exit."
exit 2;
}
}
catch {
[System.Management.Automation.MethodInvocationException] | Out-Null
}
Write-Host "Management Pack ID [$($ManagementPackID)] was not found in SCOM. Script will continue."
# Starting the Process of Creating a New Management Pack.
Write-Host "Creating new [Microsoft.EnterpriseManagement.Configuration.IO.ManagementPackFileStore] object"
$MPStore = New-Object Microsoft.EnterpriseManagement.Configuration.IO.ManagementPackFileStore
Write-Host "Creating new [Microsoft.EnterpriseManagement.Configuration.ManagementPack] object"
$MP = New-Object Microsoft.EnterpriseManagement.Configuration.ManagementPack($ManagementPackID, $ManagementPackName, (New-Object Version(1, 0, 0)), $MPStore)
Write-Host "Importing New Management Pack"
$MG.ImportManagementPack($MP)
Write-Host "Retrieving Newly Created Management Pack"
$MP = $MG.GetManagementPacks($ManagementPackID)[0]
Write-Host "Setting Management Pack Display Name."
$MP.DisplayName = $ManagementPackDisplayName
Write-Host "Setting Management Pack Description."
$MP.Description = "Auto Generated Management Pack via PowerShell"
# Getting System Library Reference
$SystemLibrary = "System.Library"
$MPToAdd = $MG.GetManagementPacks($SystemLibrary)[0]
$MPAlias = "System"
# Adding References to Management Pack
$MPReference = New-Object Microsoft.EnterpriseManagement.Configuration.ManagementPackReference($MPToAdd)
$MP.References.Add($MPAlias, $MPReference)
Write-Host "New References Added to Management Pack [$($MP.DisplayName)]."
# Creating Custom Class
$CustomClass = New-Object Microsoft.EnterpriseManagement.Configuration.ManagementPackClass($MP,("CustomServiceMonitor_"+$ServiceName.ToString().Replace("$","_")+"_"+[Guid]::NewGuid().ToString().Replace("-","")),"Public")
$CustomClassBase = $MG.EntityTypes.GetClasses("Name='Microsoft.Windows.ComputerRole'")[0]
$CustomClass.Base = $CustomClassBase
$CustomClass.Hosted = $true
$CustomClass.DisplayName = "Custom Service Monitor - $($ServiceDisplayName), Registry Key - $($RegistryKey)"
Write-Host "$($CustomClass.DisplayName) Added to Management Pack [$($MP.DisplayName)]."
# Create Discoveries - <Discoveries> - XML Portion
$Discovery = New-Object Microsoft.EnterpriseManagement.Configuration.ManagementPackDiscovery($MP,"RegKeyDiscovery")
$Discovery.Category = "Discovery"
$Discovery.DisplayName = "Discovery by Registry Key"
$Discovery.Description = "Applies Custom Service Monitoring to a host if it contains a specific Registry Key Entry"
# Create Discovery <Discovery> - XML Portion and Setting 'Target' Value
$DiscoveryTarget = $MG.EntityTypes.GetClasses("Name='Microsoft.Windows.OperatingSystem'")[0]
$Discovery.Target = $DiscoveryTarget
# Create Discovery Class <DiscoveryClass> - XML Portion and Setting 'TypeID' Value.
$DiscoveryClass = New-Object Microsoft.EnterpriseManagement.Configuration.ManagementPackDiscoveryClass
$DiscoveryClass.set_TypeID($CustomClass)
$Discovery.DiscoveryClassCollection.Add($DiscoveryClass)
# Create DataSource for Discovery
$DSModuleType = $MG.GetMonitoringModuleTypes("Microsoft.Windows.FilteredRegistryDiscoveryProvider")[0]
$DSModule = New-Object Microsoft.EnterpriseManagement.Configuration.ManagementPackDataSourceModule($Discovery, "DS")
$DSModule.TypeID = [Microsoft.EnterpriseManagement.Configuration.ManagementPackDataSourceModuleType]$DSModuleType
$DataSourceConfiguration = "<ComputerName>`$Target/Host/Property[Type=`"Windows!Microsoft.Windows.Computer`"]/NetworkName$</ComputerName>
<RegistryAttributeDefinitions>
<RegistryAttributeDefinition>
<AttributeName>$($RegistryKey)</AttributeName>
<Path>SOFTWARE\SCOM\$($RegistryKey)</Path>
<PathType>0</PathType>
<AttributeType>0</AttributeType>
</RegistryAttributeDefinition>
</RegistryAttributeDefinitions>
<Frequency>300</Frequency>
<ClassId>`$MPElement[Name=`"$($CustomClass)`"]$</ClassId>
<InstanceSettings>
<Settings>
<Setting>
<Name>`$MPElement[Name=`"Windows!Microsoft.Windows.Computer`"]/PrincipalName$</Name>
<Value>`$Target/Host/Property[Type=`"Windows!Microsoft.Windows.Computer`"]/PrincipalName$</Value>
</Setting>
<Setting>
<Name>`$MPElement[Name=`"System!System.Entity`"]/DisplayName$</Name>
<Value>`$Target/Host/Property[Type=`"Windows!Microsoft.Windows.Computer`"]/PrincipalName$</Value>
</Setting>
</Settings>
</InstanceSettings>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type=`"String`">Values/$($RegistryKey)</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type=`"String`">True</Value>
</ValueExpression>
</SimpleExpression>
</Expression>"
# Adding DataSource and DataSource Configuration to Discovery.
$DSModule.Configuration = $DataSourceConfiguration
$Discovery.DataSource = $DSModule
Write-Host "Discovery Configuration was successfully deployed to Management Pack - $($MP.DisplayName)"
# Creating New Service Monitor
$ServiceMonitorType = $MG.GetUnitMonitorTypes() | Where-Object {$_.Name -eq "Microsoft.Windows.CheckNTServiceStateMonitorType"}
$Monitor = New-Object Microsoft.EnterpriseManagement.Configuration.ManagementPackUnitMonitor($MP,($ServiceName.ToString().Replace("$","_")+"_"+[Guid]::NewGuid().ToString().Replace("-","")),"Public")
# Setting new New Monitor Up as a Service Monitor and targeting the Hosts of the Group in the MP.
$Monitor.set_DisplayName($ServiceDisplayName)
$Monitor.set_Category("Custom")
$Monitor.set_TypeID($ServiceMonitorType)
$Monitor.set_Target($CustomClass)
# Configure Monitor Alert Settings
$Monitor.AlertSettings = New-Object Microsoft.EnterpriseManagement.Configuration.ManagementPackMonitorAlertSettings
$Monitor.AlertSettings.set_AlertOnState("Error")
$Monitor.AlertSettings.set_AutoResolve($true)
$Monitor.AlertSettings.set_AlertPriority("Normal")
$Monitor.AlertSettings.set_AlertSeverity("Error")
$Monitor.AlertSettings.set_AlertParameter1("`$Target/Host/Property[Type=`"Windows!Microsoft.Windows.Computer`"]/NetworkName$")
$Monitor.AlertSettings.AlertMessage
# Configure Alert Settings - Alert Message
$AlertMessage = New-Object Microsoft.EnterpriseManagement.Configuration.ManagementPackStringResource($MP, "Service.Monitor.Alert.Message")
$AlertMessage.set_DisplayName("The $($ServiceDisplayName) Service has Stopped")
$AlertMessage.set_Description("The $($ServiceDisplayName) Service has Stopped on {0}")
$Monitor.AlertSettings.set_AlertMessage($AlertMessage)
# Configure Health States for the Monitor
$HealthyState = New-Object Microsoft.EnterpriseManagement.Configuration.ManagementPackUnitMonitorOperationalState($Monitor, "Success")
$ErrorState = New-Object Microsoft.EnterpriseManagement.Configuration.ManagementPackUnitMonitorOperationalState($Monitor, "Error")
$HealthyState.set_HealthState("Success")
$HealthyState.set_MonitorTypeStateID("Running")
$ErrorState.set_HealthState("Error")
$ErrorState.set_MonitorTypeStateID("NotRunning")
$Monitor.OperationalStateCollection.Add($HealthyState)
$Monitor.OperationalStateCollection.Add($ErrorState)
# Specifying Service Monitoring Configuration
$MonitorConfig = "<ComputerName>`$Target/Host/Property[Type=`"Windows!Microsoft.Windows.Computer`"]/NetworkName$</ComputerName>
<ServiceName>$($ServiceName)</ServiceName>
<CheckStartupType>$($CheckStartupType)</CheckStartupType>"
$Monitor.set_Configuration($MonitorConfig)
# Specify Parent Monitor by ID
$MonitorCriteria = New-Object Microsoft.EnterpriseManagement.Configuration.ManagementPackMonitorCriteria("Name='System.Health.AvailabilityState'")
$ParentMonitor = $MG.GetMonitors($MonitorCriteria)[0]
$Monitor.ParentMonitorID = [Microsoft.EnterpriseManagement.Configuration.ManagementPackElementReference``1[Microsoft.EnterpriseManagement.Configuration.ManagementPackAggregateMonitor]]::op_implicit($ParentMonitor)
Write-Host "$($Monitor.DisplayName) - Service Monitor was successfully deployed to Management Pack - $($MP.DisplayName)"
# Applying changes to the Management Pack in the SCOM Database.
try {
$MP.AcceptChanges()
}
catch [System.Exception]
{
echo $_.Exception
exit 2
}
# [---END---] Try-Catch Wrapper for Entire Script.
}
catch [System.Exception]
{
echo $_.Exception
exit 2
}
Write-Host "Deployment of Custom Service Monitor for [$($ServiceDisplayName)] and New Management Pack - [$($ManagementPackDisplayName)] is Complete!"