QND OMS - Azure Backup Server Discovery

QND.OMS.Backup.Server.Cheat.DPMServerDiscovery (Discovery)

Element properties:

TargetMicrosoft.SystemCenter.DataProtectionManager.2011.Library.DPMSeed
EnabledTrue
Frequency21600
RemotableFalse

Object Discovery Details:

Discovered Classes and their attribuets:
Discovered relationships and their attribuets:

Member Modules:

ID Module Type TypeId RunAs 
DS DataSource Microsoft.Windows.TimedScript.DiscoveryProvider Default

Source Code:

<Discovery ID="QND.OMS.Backup.Server.Cheat.DPMServerDiscovery" Enabled="true" Target="DPM!Microsoft.SystemCenter.DataProtectionManager.2011.Library.DPMSeed" ConfirmDelivery="false" Remotable="true" Priority="Normal">
<Category>Discovery</Category>
<DiscoveryTypes>
<DiscoveryClass TypeID="DPM!Microsoft.SystemCenter.DataProtectionManager.2011.Library.DPMServer"/>
<DiscoveryRelationship TypeID="DPM!Microsoft.SystemCenter.DataProtectionManager.2011.Library.DPMSeedHostsDPMServer"/>
</DiscoveryTypes>
<DataSource ID="DS" TypeID="Windows!Microsoft.Windows.TimedScript.DiscoveryProvider">
<IntervalSeconds>21600</IntervalSeconds>
<SyncTime/>
<ScriptName>DPMDiscovery.vbs</ScriptName>
<Arguments>0 $MPElement$ $Target/Id$ $Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$ $Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetbiosComputerName$ $Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetbiosDomainName$ "$Target/ManagementGroup/Name$"</Arguments>
<ScriptBody><Script>
'ok this is a really silly way to discover the server let's change it in the next release
SetLocale("en-us")
Set oAPI = CreateObject("MOM.ScriptAPI")
Set oArgs = WScript.Arguments

call oAPI.LogScriptEvent("DPMServerDiscovery", 125, 4, "OMS AzBksSrvr Cheat server discovery start event")

if oArgs.Count &lt; 7 Then
call oAPI.LogScriptEvent("DPMServerDiscovery", 12, 1, "Expected 7 arguments. There were only " &amp; oArgs.Count &amp; " arguments. Exiting script.")
Wscript.Quit -1
End If

SourceType = oArgs(0)
SourceId = oArgs(1)
ManagedEntityId = oArgs(2)
TargetComputer = oArgs(3)
NetbiosComputerName = oArgs(4)
NetbiosDomainName = oArgs(5)
ManagementGroupName = oArgs(6)

Dim dpmProductCode, installstate, dpmversion

Const msiInstallStateUnknown = -1
Const msiInstallStateAbsent = 2

isDPMPresent = True

Set oDiscData = oAPI.CreateDiscoveryData(SourceType, SourceId, ManagedEntityId)

'this discovery method is silly, anyway stick to the original MP
dpmProductCode = "{54CF55F6-45E0-494E-94E4-6D9AA80663B0}" 'Azure Backup Server v1 = DPM2012R2

installstate = MsiQueryProductState(dpmProductCode)

if installstate = msiInstallStateUnknown or installState = msiInstallStateAbsent then
dpmProductCode = "{967E1926-C053-41E8-AF10-0E0061A9E00F}"
installstate = MsiQueryProductState(dpmProductCode)
End if


If installstate = msiInstallStateUnknown or installState = msiInstallStateAbsent then
call oAPI.LogScriptEvent("DPMServerDiscovery", 125, 1, "OMS AzBksSrvr Cheat Server is not present on this computer")
isDPMPresent = False
else
'MsgBox("DPM is Present")

dpmversion = MsiGetProductInfo(dpmProductCode)

Set oInst = oDiscData.CreateClassInstance("$MPElement[Name="DPM!Microsoft.SystemCenter.DataProtectionManager.2011.Library.DPMServer"]$")

call oInst.AddProperty("$MPElement[Name="Windows!Microsoft.Windows.Computer"]/PrincipalName$", TargetComputer)
call oInst.AddProperty("$MPElement[Name="DPM!Microsoft.SystemCenter.DataProtectionManager.2011.Library.DPMSeed"]/DPMServerName$", TargetComputer)
call oInst.AddProperty("$MPElement[Name="System!System.Entity"]/DisplayName$",NetbiosComputerName)
call oInst.AddProperty("$MPElement[Name="DPM!Microsoft.SystemCenter.DataProtectionManager.2011.Library.DPMServer"]/DPMServerName$", TargetComputer)
call oInst.AddProperty("$MPElement[Name="DPM!Microsoft.SystemCenter.DataProtectionManager.2011.Library.DPMServer"]/Domain$", NetbiosDomainName)

call oDiscData.AddInstance(oInst)
End if

call oAPI.LogScriptEvent("DPMServerDiscovery", 125, 4, "OMS AzBksSrvr Cheat server discovery SCOM ManagementGroup:" &amp; ManagementGroupName)

AddSCOMServerToDPMSCOMGroup(ManagementGroupName)

if (isDPMPresent) then
CheckForScriptLimitRegistry()
end if

call oAPI.LogScriptEvent("DPMServerDiscovery", 125, 4, "OMS AzBksSrvr Cheat server discovery completed event")

call oAPI.Return(oDiscData)

Function MsiQueryProductState(ProductCode)
Dim InstallState

Dim Installer : Set Installer = Nothing
Set Installer = CreateObject("WindowsInstaller.Installer")
InstallState = Installer.ProductState(ProductCode)

MsiQueryProductState = InstallState

Exit Function
End Function

Function MsiGetProductInfo(ProductCode)
Dim InstallInfo
Dim Installer : Set Installer = Nothing
Set Installer = CreateObject("WindowsInstaller.Installer")
InstallInfo = Installer.ProductInfo(ProductCode,"VersionString")

MsiGetProductInfo = InstallInfo
End Function

Function AddSCOMServerToDPMSCOMGroup(managementGroupName)

'This is required as discovery should not stop because of err in this script
on error resume next

Const HKEY_LOCAL_MACHINE = &amp;H80000002
Const REG_SZ = 1
strComputer = "."
hDefKey = HKEY_LOCAL_MACHINE
strKeyPath = "SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\Agent Management Groups\" &amp; managementGroupName &amp; "\Parent Health Services\0"
dpmConfigKeyPath = "SOFTWARE\Microsoft\Microsoft Data Protection Manager\Configuration"
strValueName = "NetworkName"
DPMScomGroupName = "DPMScom"

'Reading Registry
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &amp; strComputer &amp; "\root\default:StdRegProv")
oReg.GetExpandedStringValue hDefKey, strKeyPath, strValueName, scomSvrName

'Adding To DPMScom Group Variables
'Seperating Machine name and domain name
DotPosition = InStr (scomSvrName, ".")
DomainName = Mid (scomSvrName, DotPosition+1)
DotPosition2 = InStr (DomainName, ".")
simpleDomainName = Mid (DomainName, 1, DotPosition2 - 1)
MachineName = Mid (scomSvrName, 1, DotPosition-1) &amp; "$"
Set net = WScript.CreateObject("WScript.Network")
local = net.ComputerName

'Read Machine Name
Set WshShell = WScript.CreateObject("WScript.Shell")
DPMMachineName = WshShell.ExpandEnvironmentStrings("%COMPUTERNAME%")
DPMScomGroupNameDCMachineName = "DPMScom$" &amp; DPMMachineName

'Adding SCOMServer to DPMSCOM Group for non-dc machine
set group = GetObject("WinNT://"&amp; local &amp;"/" &amp; DPMScomGroupName)
group.Add "WinNT://"&amp; DomainName &amp;"/"&amp; MachineName &amp;""

'Adding SCOMServer to DPMSCOM Group for dc machine
set group = GetObject("WinNT://"&amp; local &amp;"/DPMScomGroupNameDCMachineName")
group.Add "WinNT://"&amp; DomainName &amp;"/"&amp; MachineName &amp;""

'Adding registry for the scomserver so indicate when discovery happened subKeyName = "domain\serverName$" value = "Just Discovered"
valueTemp = "Just Discovered"
subKeyValue = simpleDomainName &amp; "\" &amp; MachineName
oReg.SetStringValue HKEY_LOCAL_MACHINE, dpmConfigKeyPath, subKeyValue, valueTemp

End Function

Function CheckForScriptLimitRegistry()

'This is required as discovery should not stop because of err in this script
on error resume next

Dim objShell
Set objShell=CreateObject("WScript.Shell")

scriptString = "$regPath = 'HKLM:\Software\Microsoft\Microsoft Operations Manager\3.0\Modules\Global\Powershell' "&amp;_
Chr(10) &amp; "$setRegistry = $false "&amp;_
Chr(10) &amp; "if(Test-Path $regPath) "&amp;_
Chr(10) &amp; "{ "&amp;_
Chr(10) &amp; " write-host ""Key exists"" "&amp;_
Chr(10) &amp; " $value = Get-ItemProperty -Name ""ScriptLimit"" -Path $regPath -ErrorAction silentlycontinue "&amp;_
Chr(10) &amp; " if($value -eq $null) "&amp;_
Chr(10) &amp; " { "&amp;_
Chr(10) &amp; " New-ItemProperty $regPath -Name ""ScriptLimit"" -Value 15 -PropertyType DWORD "&amp;_
Chr(10) &amp; " $setRegistry = $true "&amp;_
Chr(10) &amp; " } "&amp;_
Chr(10) &amp; " elseif($value.ScriptLimit -gt 15) "&amp;_
Chr(10) &amp; " { "&amp;_
Chr(10) &amp; " write-host ""Value is null or value is greater than 15"" "&amp;_
Chr(10) &amp; " Set-ItemProperty -path $regPath -Name ""ScriptLimit"" -Value 15 "&amp;_
Chr(10) &amp; " $setRegistry = $true "&amp;_
Chr(10) &amp; " } "&amp;_
Chr(10) &amp; "} "&amp;_
Chr(10) &amp; "else "&amp;_
Chr(10) &amp; "{ "&amp;_
Chr(10) &amp; " write-host ""Key doesnt exist"" "&amp;_
Chr(10) &amp; " md $regPath "&amp;_
Chr(10) &amp; " New-ItemProperty $regPath -Name ""ScriptLimit"" -Value 15 -PropertyType DWORD "&amp;_
Chr(10) &amp; " $setRegistry = $true "&amp;_
Chr(10) &amp; "} "&amp;_
Chr(10) &amp; "if($setRegistry) "&amp;_
Chr(10) &amp; "{ "&amp;_
Chr(10) &amp; " $evt = new-object System.Diagnostics.EventLog('DPM Alerts'); "&amp;_
Chr(10) &amp; " $evt.Source = 'DPM-EM'; "&amp;_
Chr(10) &amp; " $eventSeverity = [System.Diagnostics.EventLogEntryType]::Information; "&amp;_
Chr(10) &amp; " $eventString = 'Restarting the health service'; "&amp;_
Chr(10) &amp; " $eventId = 126; "&amp;_
Chr(10) &amp; " $evt.WriteEntry($eventString, $eventSeverity, $eventId) "&amp;_
Chr(10) &amp; " $time= (Get-Date).AddMinutes(10) "&amp;_
Chr(10) &amp; " $timeStr = $time.ToString('HH:mm') "&amp;_
Chr(10) &amp; " $result = schtasks /create /tn DPMDiscoveryHelper /tr 'net start healthservice' /st $timeStr /rl highest /sc once /ru system /rp /f "&amp;_
Chr(10) &amp; " if($LASTEXITCODE -eq 0) "&amp;_
Chr(10) &amp; " { "&amp;_
Chr(10) &amp; " $eventString = 'Successfully created the scheduled task'; "&amp;_
Chr(10) &amp; " } "&amp;_
Chr(10) &amp; " else "&amp;_
Chr(10) &amp; " { "&amp;_
Chr(10) &amp; " $eventString = 'Failed creating scheduled task with message' + $result; "&amp;_
Chr(10) &amp; " } "&amp;_
Chr(10) &amp; " $evt.WriteEntry($eventString, $eventSeverity, $eventId) "&amp;_
Chr(10) &amp; " Stop-Service healthservice "&amp;_
Chr(10) &amp; " Start-Service healthservice "&amp;_
Chr(10) &amp; "}"

strCMD="powershell -nologo -command """ &amp; scriptString &amp; """"

'Uncomment next line for debugging
'MsgBox("strCMD: " &amp; strCMD)

'use 0 to hide window
objShell.Run strCMD,0,true

End Function
</Script></ScriptBody>
<TimeoutSeconds>900</TimeoutSeconds>
</DataSource>
</Discovery>