'=============
' Method: Main
' Description: The Sub called by MOM Runtime (with ScriptContext object)
'=============
Sub Main()
'log information
Set g_oUtil = new Util
Call g_oUtil.SetDebugLevel(g_oUtil.DBG_TRACE)
Call g_oUtil.LogMessage(g_oUtil.DBG_TRACE, "DNS Service Discovery starting: at machine local time: " + CStr(Time))
Call g_oUtil.LogMessage(g_oUtil.DBG_TRACE, "Local Machine Name: " + ScriptContext.TargetComputer)
DoDnsDiscovery
Call g_oUtil.LogMessage(g_oUtil.DBG_TRACE, "Done with Service Discovery Script at local time: " + CStr(time))
End Sub
'=============
' Method: DoDNSDiscovery
' Description: Perform DNS service discovery.
'=============
Sub DoDnsDiscovery()
Dim objDiscData
Dim oDiscoveryHelper
Dim owObj
Dim WMISet
Dim strServerName
Dim strZoneName
Dim strZoneType
Dim strAllowUpdates
Dim strLookupZoneType
Dim i
Dim oRel
Dim strOSName
'log trace
Call g_oUtil.LogMessage(g_oUtil.DBG_TRACE, "Starting DNS Server Computer Discovery.")
' Perform test for DNS WMI Provider
if False = FindDNSWMIProvider() then
Exit Sub
end if
Set WMISet = WMIGetInstance("winmgmts:\\" + ScriptContext.TargetComputer + "\root\MicrosoftDNS", "MicrosoftDNS_Server")
'Call g_oUtil.LogMessage(g_oUtil.DBG_TRACE, "Count:" + CStr(owObj.Count))
For Each owObj In WMISet
strServerName = owObj.Name
' strOSName = g_oUtil.GetOSName(ScriptContext.TargetComputer)
' Call oDiscoveryHelper.CreateDnsServerInstance(strOSName)
Call oDiscoveryHelper.CreateDnsServerInstance()
Exit For
Next
If g_oUtil.IsServiceRunning("DNS", ScriptContext.TargetComputer) Then
Call g_oUtil.LogMessage(g_oUtil.DBG_TRACE, "Reading DNSZone attributes")
Set WMISet = WMIGetInstance("winmgmts:\\" + ScriptContext.TargetComputer + "\root\MicrosoftDNS", "MicrosoftDNS_Zone")
Call g_oUtil.LogMessage(g_oUtil.DBG_TRACE, "Count:" + CStr(WMISet.Count))
Dim aZoneTypes2003
aZoneTypes2003 = Array("Cache", "Primary", "Secondary", "Stub", "Forwarder")
Dim aZoneTypes2000
aZoneTypes2000 = Array("DS integrated", "Primary", "Secondary")
For Each owObj In WMISet
Call g_oUtil.LogMessage(g_oUtil.DBG_TRACE, "Name:" +owObj.Name)
strZoneName = owObj.Name
strZoneType = aZoneTypes2003(owObj.ZoneType)
If owObj.Reverse Then strLookupZoneType = "Reverse" Else strLookupZoneType = "Forward"
If owObj.AllowUpdate = 0 Then strAllowUpdates = "No" Else strAllowUpdates = "Yes"
Call oDiscoveryHelper.CreateDnsZoneInstance(strZoneName, strLookupZoneType)
Call oDiscoveryHelper.CreateDNSServerToDNSZoneRelationshipInstance(strZoneName, strZoneType, strAllowUpdates)
Next
End If
ScriptContext.Submit objDiscData
End Sub
'=============
' Method: FindDNSWMIProvider
' Description: Perform DNS WMI Provider test.
'=============
Function FindDNSWMIProvider
Dim oWMI
Dim oNewEvent
Dim strInstallMessage
On Error Resume Next
Set oWMI = WMIGetObjectDNS("winmgmts:\\" + ScriptContext.TargetComputer + "\root\MicrosoftDNS")
' Set oWMI = WMIGetObject("winmgmts:\\" + ScriptContext.TargetComputer + "\root\MicrosoftDNS")
If IsEmpty(oWMI) Then
Call g_oUtil.LogMessage(g_oUtil.DBG_TRACE, "Windows 2000 DNS WMI Provider not installed. " + CStr(time))
' create 20001 event
Set oNewEvent = ScriptContext.CreateEvent
strInstallMessage = "Windows 2000 DNS WMI Provider not installed. " & _
"The Windows 2000 DNS WMI Provider must be installed on " & ScriptContext.TargetComputer & " to be fully managed by MOM. " & _
"Obtain the DNS WMI Provider for Windows 2000 from the Windows 2000 Server Resource Kit, or from the following location: " & _
"ftp://ftp.microsoft.com/reskit/win2000/dnsprov.zip"
' Set event properties
oNewEvent.Message = strInstallMessage
oNewEvent.EventNumber = ID_DNSWMIPROVIDER
oNewEvent.EventType = EVENT_TYPE_ERROR
oNewEvent.EventSource = "DNS Service Discovery"
' Submit the event
ScriptContext.Submit oNewEvent
Set oNewEvent = Nothing
FindDNSWMIProvider = False
Exit Function
End If
On Error Goto 0
FindDNSWMIProvider = True
End Function
Function WMIGetObject(sNamespace)
'
' WMIGetObject :: Returns the WMI object requested.
'
'
Dim oWMI
On Error Resume Next
Set oWMI = GetObject(sNamespace)
If IsEmpty(oWMI) Then
Call g_oUtil.LogMessage(g_oUtil.DBG_TRACE, "WMIGetObject: Unable to open WMI Namespace '" & sNamespace & "'. " + CStr(time))
ThrowScriptError "Unable to open WMI Namespace '" & sNamespace & "'. Check to see if the WMI service is enabled and running, and ensure this WMI namespace exists.", Err
End If
On Error Goto 0
Set WMIGetObject = oWMI
Set oWMI = Nothing
End Function
Function WMIGetInstance(sNamespace, sInstance)
'
' WMIGetInstance :: Returns WMI Instance requested.
'
'
Dim oWMI, oInstance, nInstanceCount
On Error Resume Next
Set oWMI = GetObject(sNamespace)
If IsEmpty(oWMI) Then
Call g_oUtil.LogMessage(g_oUtil.DBG_TRACE, "WMIGetInstance: Unable to open WMI Namespace '" & sNamespace & "'. " + CStr(time))
ThrowScriptError "Unable to open WMI Namespace '" & sNamespace & "'. Check to see if the WMI service is enabled and running, and ensure this WMI namespace exists.", Err
End If
Set oInstance = oWMI.InstancesOf(sInstance)
If IsEmpty(oInstance) Or Err.Number <> 0 Or IsNull(oInstance) Then
ThrowScriptError "The class name '" & sInstance & "' returned no instances. Please check to see if this is a valid WMI class name.", Err
End If
'Determine if we queried a valid WMI class - Count will return 0 or empty
nInstanceCount = oInstance.Count
If Err.Number <> 0 Then
ThrowScriptError "The class name '" & sInstance & "' did not return any valid instances. Please check to see if this is a valid WMI class name. This error might have been caused by insufficent MOM response account privilege, please check to see if the MOM response account have a high enough privilege to access the WMI namespace.", Err
End If
On Error Goto 0
Set WMIGetInstance = oInstance
Set oInstance = Nothing
Set oWMI = Nothing
End Function
Function WMIExecQuery(sNamespace, sQuery)
'
' WMIExecQuery :: Executes the WMI query and returns the result set.
'
'
Dim oWMI, oQuery, nInstanceCount
On Error Resume Next
Set oWMI = GetObject(sNamespace)
If IsEmpty(oWMI) Then
Call g_oUtil.LogMessage(g_oUtil.DBG_TRACE, "WMIExecQuery: Unable to open WMI Namespace '" & sNamespace & "'. " + CStr(time))
ThrowScriptError "Unable to open WMI Namespace '" & sNamespace & "'. Check to see if the WMI service is enabled and running, and ensure this WMI namespace exists.", Err
End If
Set oQuery = oWMI.ExecQuery(sQuery)
If IsEmpty(oQuery) Or Err.Number <> 0 Then
ThrowScriptError "The Query '" & sQuery & "' returned an invalid result set. Please check to see if this is a valid WMI Query.", Err
End If
'Determine if we queried a valid WMI class - Count will return 0 or empty
nInstanceCount = oQuery.Count
If Err.Number <> 0 Then
ThrowScriptError "The Query '" & sQuery & "' did not return any valid instances. Please check to see if this is a valid WMI Query.", Err
End If
On Error Goto 0
Set WMIExecQuery = oQuery
Set oQuery = Nothing
Set oWMI = Nothing
End Function
Function WMIGetObjectDNS(sNamespace)
'
' WMIGetObjectDNS :: Returns the DNS WMI object requested. Customized to return detailed message when DNS provider does not exist or not accessible
'
'
Dim oWMI
On Error Resume Next
Set oWMI = GetObject(sNamespace)
If IsEmpty(oWMI) Then
Call g_oUtil.LogMessage(g_oUtil.DBG_TRACE, "Windows 2000 DNS WMI Provider not installed. " + CStr(time))
' create 20001 event
Set oNewEvent = ScriptContext.CreateEvent
strInstallMessage = "Windows 2000 DNS WMI Provider not installed. " & _
"The Windows 2000 DNS WMI Provider must be installed on " & ScriptContext.TargetComputer & " to be fully managed by MOM. " & _
"Obtain the DNS WMI Provider for Windows 2000 from the Windows 2000 Server Resource Kit, or from the following location: " & _
"ftp://ftp.microsoft.com/reskit/win2000/dnsprov.zip"
' Set event properties
oNewEvent.Message = strInstallMessage
oNewEvent.EventNumber = ID_DNSWMIPROVIDER
oNewEvent.EventType = EVENT_TYPE_ERROR
oNewEvent.EventSource = "DNS Service Discovery"
oNewEvent.SetEventParameter strInstallMessage
' Submit the event
ScriptContext.Submit oNewEvent
Set oNewEvent = Nothing
FindDNSWMIProvider = False
Exit Function
End If
On Error Goto 0
Set WMIGetObjectDNS = oWMI
Set oWMI = Nothing
End Function
Function ThrowScriptError(sMessage, oErr)
'
' ThrowScriptError :: Creates an event and sends it back to the mom server
'
'
On Error Resume Next
Dim oScriptErrorEvent
Set oScriptErrorEvent = ScriptContext.CreateEvent()
With oScriptErrorEvent
.EventNumber = 40000
.EventType = EVENT_TYPE_ERROR
.Message = sMessage
.SetEventParameter "DNS Service Discovery"
.SetEventParameter sMessage
.SetEventParameter oErr.Description
.SetEventParameter oErr.Number
End With
ScriptContext.Submit oScriptErrorEvent
ScriptContext.Echo "ThrowScriptError('" & sMessage & "')"
ScriptContext.Quit()
End Function
'==========================================================================
' Class: DiscoveryHelper
' Description: Used to create Discovery collections and instances
'==========================================================================
Class DiscoveryHelper
Private m_objDiscData
'=============
' Method: SetData
' Description: Stores a reference to the discovery data object in the class.
' Parameters:
' objDiscData - The reference to the discovery object.
'=============
Public Sub SetData(ByRef objDiscData)
Set m_objDiscData = objDiscData
End Sub
Public Sub CreateDNSServerToDNSZoneRelationshipInstance(ByVal strZoneName, _
ByVal strZoneType, _
ByVal strAllowUpdates)
Dim oRelationshipCollection
Set oRelationshipCollection = m_objDiscData.CreateRelationshipCollection()
With oRelationshipCollection
.TypeID = DNS_ZONE_TO_DNS_SERVER_RELATIONSHIP_ID
.SourceScopeFilter.AddKeyProperty COMPUTER_NAME_ATTRIBUTE_ID, ScriptContext.TargetComputerIdentity
.SourceScopeFilter.AddKeyProperty DNS_SERVER_NAME_ATTRIBUTE_ID, ScriptContext.TargetNetbiosComputer
.TargetScopeFilter.AddKeyProperty DNS_ZONE_ZONE_NAME_ATTRIBUTE_ID, strZoneName
.AddScopeProperty DNS_ZONE_TO_DNS_SERVER_ALLOW_UPDATES_ATTRIBUTE_ID
.AddScopeProperty DNS_ZONE_TO_DNS_SERVER_ZONE_TYPE_ATTRIBUTE_ID
End With
Dim oRelationshipInstance
Set oRelationshipInstance = oRelationshipCollection.CreateInstance()
With oRelationshipInstance
.AddProperty DNS_ZONE_TO_DNS_SERVER_ALLOW_UPDATES_ATTRIBUTE_ID, strAllowUpdates
.AddProperty DNS_ZONE_TO_DNS_SERVER_ZONE_TYPE_ATTRIBUTE_ID, strZoneType
End With
m_objDiscData.AddCollection oRelationshipCollection
End Sub
'=============
' Method: CreateDnsServerInstance
' Description: Creates an instance of the DnsServer class in the database.
' Parameters:
'=============
' Public Sub CreateDnsServerInstance (ByVal strOSName)
Public Sub CreateDnsServerInstance ()
Dim oServerCollection
Set oServerCollection = m_objDiscData.CreateCollection()
With oServerCollection
.ClassID = DNS_SERVER_CLASS_ID
.AddScopeFilter COMPUTER_NAME_ATTRIBUTE_ID, ScriptContext.TargetComputerIdentity
' .AddScopeProperty DNS_SERVER_OS_VERSION_ATTRIBUTE_ID
End With
Dim oServerInstance
Set oServerInstance = oServerCollection.CreateInstance()
With oServerInstance
.AddKeyProperty DNS_SERVER_NAME_ATTRIBUTE_ID, ScriptContext.TargetNetbiosComputer
' .AddProperty DNS_SERVER_OS_VERSION_ATTRIBUTE_ID, strOSName
End With
oServerCollection.AddInstance oServerInstance
m_objDiscData.AddCollection oServerCollection
end sub
'=============
' Method: CreateDnsZoneInstance
' Description: Creates an instance of the DnsServer class in the database.
' Parameters:
' strComputerName - the FQDN for the DNS server
'=============
Public Sub CreateDnsZoneInstance (ByVal strZoneName, ByVal strLookupZoneType)
Dim oZoneCollection
Set oZoneCollection = m_objDiscData.CreateCollection()
With oZoneCollection
.ClassID = DNS_ZONE_CLASS_ID
.AddScopeFilter DNS_ZONE_ZONE_NAME_ATTRIBUTE_ID, strZoneName
.AddScopeProperty DNS_ZONE_LOOKUP_ZONE_TYPE_ATTRIBUTE_ID
End With
Dim oZoneInstance
Set oZoneInstance = oZoneCollection.CreateInstance()
With oZoneInstance
.AddProperty DNS_ZONE_LOOKUP_ZONE_TYPE_ATTRIBUTE_ID, strLookupZoneType
End With
oZoneCollection.AddInstance oZoneInstance
m_objDiscData.AddCollection oZoneCollection
End Sub
End Class
'==========================================================================
' Class: Util
' Description: Utility methods for logging, creating MOM alert
'==========================================================================
Class Util
' Used to say to LogMessage when/how to print the message.
Public DBG_NONE
Public DBG_ERROR
Public DBG_WARNING
Public DBG_TRACE
Public HKEY_LOCAL_MACHINE
'=============
' Method: Class_Initialize
' Description: This is the constructor
' Parameters:
'=============
Private Sub Class_Initialize()
' Initialize Debug level constants
DBG_TRACE = 1
DBG_WARNING = 2
DBG_ERROR = 3
DBG_NONE = 4
HKEY_LOCAL_MACHINE = &H80000002
'by default only errors are logged
m_nDebugLevel = DBG_ERROR
End Sub
'=============
' Method: Class_Terminate
' Description: This is the destructor
' Parameters:
'=============
Private Sub Class_Terminate()
End Sub
'=============
' Method: SetDebugLevel
' Description: To change the debugging output level of information
' generated by this utility.
' Parameters:
' nLevel - Level, either DBG_NONE, DBG_TRACE,
' DBG_WARNING or DBG_ERROR
'=============
Public Sub SetDebugLevel(ByVal nLevel)
m_nDebugLevel = nLevel
End Sub
' '=============
' ' Method: GetOSName
' ' Description: Get the name of the OS running on a computer
' ' Parameters:
' ' strComputerName - The name of the computer
' '=============
' Public Function GetOSName(ByVal strComputerName)
' Dim oOSSet
' Set oOSSet = WMIGetInstance("winmgmts:\\" & strComputerName & "\root\cimv2", "Win32_OperatingSystem")
'
' Dim oOS
' For Each oOS in oOSSet
' GetOSName = oOS.Caption
' Exit Function
' Next
' End Function
'=============
' Method: LogMessage
' Description: Log a debug message to ScriptContext
' Parameters:
' nLevel - Debug level for the message that we're logging.
' strMessage - The message to write to the trace.
'=============
Public Sub LogMessage( _
ByVal nLevel, _
ByVal strMessage _
)
If (nLevel <= m_nDebugLevel) Then
if (nLevel = DBG_ERROR) Then
ScriptContext.Echo "[Error]: " + strMessage
ElseIf (nLevel = DBG_WARNING) Then
ScriptContext.Echo "[Warning]: " + strMessage
ElseIf (nLevel = DBG_TRACE) Then
ScriptContext.Echo "[Trace]:" + strMessage
End If
End If
End Sub
'=============
' Method: ReadRegistryValue
' Description: Used to read strings from the registry
' Parameters:
' Root - Root of the registry (HKEY_LOCAL_MACHINE, HKEY_USERS etc. Refer to constants defined earlier)
' strKeyPath - Key path for the Registry key to read
' (like "SOFTWARE\Microsoft\WindowsNT\CurrentVersion")
' strValueName - Name of the registry entry to read (like "SoftwareType")
'
' Returns:
' The value of the registry key specified. "Nothing" if it fails. Callee needs to handle null value return.
'=============
Public Function ReadRegistryValue(strKeyPath, strValueName, strHostName)
Dim strValueData, oReg, HostName
Set oReg = ConnectToRegistry(strHostName)
'read from registry
if oReg.GetStringValue(HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValueData) = 0 Then
Call LogMessage(DBG_TRACE, "Value of Registry Key: " + strKeyPath + "\" + strValueName + " = " + strValueData)
ReadRegistryValue = strValueData
Else
Call LogMessage(DBG_ERROR, "Reading Registry Key: " + strKeyPath + "\" + strValueName + " Failed!" )
ReadRegistryValue = empty
End If
Set oReg = Nothing
End Function
Private Function ConnectToRegistry(ByVal strHostName)
Dim oReg
if (strHostName = empty) Then
'get the registry object for local machine
Set oReg =WMIGetObject("winmgmts:root\default:StdRegProv")
Else
Call LogMessage(DBG_TRACE, "Connecting to WMI Registry : " + "winmgmts:\\"+ strHostName+ "\root\default:StdRegProv")
Set oReg =WMIGetObject("winmgmts:\\"+ strHostName+ "\root\default:StdRegProv")
End If
Set ConnectToRegistry = oReg
End Function
'=============
' Method: IsServiceInstalled
' Description: Check if a given NT service is installed.
' Parameters:
' strServiceName - The name of the NT service.
'=============
Public Function IsServiceInstalled(ByVal strServiceName, ByVal strHost)
Dim ServiceSet
Set ServiceSet = WMIExecQuery("winmgmts:\\" + strHost, "select * from Win32_Service where Name='" + strServiceName +"'")
if ServiceSet.Count > 0 Then
IsServiceInstalled = 1
Else
IsServiceInstalled = 0
end if
End Function
'=============
' Method: IsServiceRunning
' Description: Check if a given NT service is running.
' Parameters:
' strServiceName - The name of the NT service.
'=============
Public Function IsServiceRunning(ByVal strServiceName, ByVal strHost)
IsServiceRunning = false
Dim oService
On Error Resume Next
Set oService = WMIGetObject("winmgmts:\\" & strHost & "\root\cimv2:Win32_Service.Name='" & strServiceName & "'")
If Err.Number <> 0 Then Exit Function
On Error Goto 0
If oService.State = "Running" Then
IsServiceRunning = true
End If
End Function
End Class</Script></Body>
<Language>VBScript</Language>
<Name>DNS Service Discovery Script</Name>
<Parameters/>
<ManagementPackId>[Microsoft.Windows.Server.DNS,,1.0.0.1]</ManagementPackId>
</WriteAction>
</MemberModules>
<Composition>
<Node ID="RunScriptAction"/>
</Composition>
</Composite>
</ModuleImplementation>
<InputType>SystemLibrary!System.BaseData</InputType>
</WriteActionModuleType>