Windows Server 2008 Discovery (Discovery)

Microsoft.Windows.Server.2008.Discovery.DataSource (DataSourceModuleType)

This data source discovers Windows 2008 Server.

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityInternal
RunAsSystem.PrivilegedMonitoringAccount
OutputTypeSystem.Discovery.Data

Member Modules:

ID Module Type TypeId RunAs 
Scheduler DataSource System.CommandExecuterDiscoveryDataSource Default

Overrideable Parameters:

IDParameterTypeSelectorDisplay NameDescription
IntervalSecondsint$Config/IntervalSeconds$Interval Seconds
TimeoutSecondsint$Config/TimeoutSeconds$Timeout Seconds

Source Code:

<DataSourceModuleType ID="Microsoft.Windows.Server.2008.Discovery.DataSource" RunAs="System!System.PrivilegedMonitoringAccount" Accessibility="Internal">
<Configuration>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="IntervalSeconds" type="xsd:unsignedInt"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="TimeoutSeconds" type="xsd:unsignedInt"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="SourceId" type="xsd:string"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int"/>
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<DataSource ID="Scheduler" TypeID="System!System.CommandExecuterDiscoveryDataSource">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<ApplicationName>%SystemRoot%\system32\cmd.exe</ApplicationName>
<WorkingDirectory/>
<CommandLine>/c $file/Main.cmd$</CommandLine>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
<RequireOutput>true</RequireOutput>
<Files>
<File>
<Name>Main.cmd</Name>
<Contents><Script>

@echo off
set psscript=Microsoft.Windows.Server.2008.Discovery.Probe.ps1
set vbscript=Microsoft.Windows.Server.2008.Discovery.Probe.vbs
set cscript=%windir%\system32\cscript.exe
set ps=%windir%\system32\WindowsPowerShell\v1.0\powershell.exe
set params=

if Exist "%cscript%" goto vb
if Exist "%ps%" goto pshell
goto end
:vb
if not exist "%~dp0%vbscript%" goto end

if exist "%~dp0vbparams.txt" (
set /p params=&lt;"%~dp0vbparams.txt"
)

"%cscript%" /nologo "%~dp0%vbscript%" %params%
goto end
:pshell
if not exist "%~dp0%psscript%" goto end

if exist "%~dp0psparams.txt" (
set /p params=&lt;"%~dp0psparams.txt"
)
"%ps%" -nologo -EP bypass -command "&amp; '%~dp0%psscript%'" %params%
goto end

:end



</Script></Contents>
<Unicode>false</Unicode>
</File>
<File>
<Name>Microsoft.Windows.Server.2008.Discovery.Probe.ps1</Name>
<Contents><Script>

param($SourceId, $ManagedEntityId, $TargetComputer, $TargetComputerID, $boolIsVirtualNode)

Function Init-ScomHelper
{
$DiscHelper = @'
namespace SCOM.Helper
{
using System;
using System.Runtime.InteropServices;
public class ConvertData
{

public static string GetDataItemFromOutput(
Object oData)
{
NativeMethods.ISerialize discoverySerializer = null;
discoverySerializer = oData as NativeMethods.ISerialize;
string xmlString = null;
if (null != discoverySerializer)
{
int hr = discoverySerializer.SaveToString(out xmlString);
Marshal.ThrowExceptionForHR(hr);
}

return xmlString;
}

public static class NativeMethods
{
[Guid("A4E79E8A-9494-47A4-A280-8C7D35C88A2F"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ISerialize
{
int SaveToString([MarshalAs(UnmanagedType.BStr)] out string output);
int LoadFromString([MarshalAs(UnmanagedType.BStr)] string input);
}
}
}
}

'@

$ErrorActionPreference = "SilentlyContinue"
$Error.Clear()
Add-Type $DiscHelper

$result = 0 -eq $Error.Count

return $result
}#Copyright (c) Microsoft Corporation. All rights reserved.

# Parameters that should be passed to this script
# 0 MPElement ID
# 1 Target Id for ME this rule is running against
# 2 Computer (FQDN) that the OS will be hosted on
# 3 Computer ID (Key) that the OS will be hosted on
# 4 IsVirtualNode

$VersionPrefix = "6.0,6.1"
$Start_SnapShotDiscovery = 0
$Exit_SnapShotDiscovery = 1
$Exit_IncrementalDiscovery = 2
$SKUDatacenterServerCoreEdition = 12
$SKUStandardServerCoreEdition = 13
$SKUEnterpriseServerCoreEdition = 14

$momAPI = new-object -comObject MOM.ScriptAPI

Function Load-CimModules
{
$ErrorActionPreference = 'SilentlyContinue'
$error.Clear()

$CimModule = Get-Module CimCmdlets

if ($null -eq $CimModule)
{
Import-Module CimCmdlets
}
}

Function Main()
{
$ErrorActionPreference = "SilentlyContinue"
$error.Clear()

$result = Init-ScomHelper

if ($false -eq $result)
{
return
}

$oDiscoveryData = Get-DiscoveryData

if ($null -eq $oDiscoveryData)
{
return
}


$SerializeDiscoveryData = [Scom.Helper.ConvertData]::GetDataItemFromOutput($oDiscoveryData)
Write-Host "$SerializeDiscoveryData"
}

Function DoDiscovery
{
param ([string]$sTargetComputer, [string]$sTargetComputerID, $oDisc)

$ErrorActionPreference = "SilentlyContinue"
$result = $false

$CoreFull = "Full"
$ComputerClassId = "$MPElement[Name='Microsoft.Windows.Server.2008.Full.Computer']$"
$OsClassId = "$MPElement[Name='Microsoft.Windows.Server.2008.Full.OperatingSystem']$"
$OsVersion = GetRegistryKeyValue "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\" "CurrentVersion"
$Os = Get-WmiObject -Class "Win32_OperatingSystem"
if ( 0 -ne $error.Count)
{
Load-CimModules
try
{
$cimSessionOption = New-CimSessionOption -Protocol DCOM
$cimsession = New-CimSession -SessionOption $cimSessionOption
$Os = Get-CimInstance -CimSession $cimsession -ClassName "Win32_OperatingSystem"
}
Finally
{
Get-CimSession | Remove-CimSession
$cimsession =$null
$cimSessionOption = $null
}
}

$SKU = $Os.OperatingSystemSKU

if ("6.0" -eq $OsVersion)
{
if ( $SKUDatacenterServerCoreEdition -eq $SKU -or $SKUStandardServerCoreEdition -eq $SKU -or $SKUEnterpriseServerCoreEdition -eq $SKU)
{
$CoreFull = "Core"
$ComputerClassId = "$MPElement[Name='Microsoft.Windows.Server.2008.Core.Computer']$"
$OsClassId = "$MPElement[Name='Microsoft.Windows.Server.2008.Core.OperatingSystem']$"

}

}
elseif("6.1" -eq $OsVersion)
{
if ( $SKUDatacenterServerCoreEdition -eq $SKU -or $SKUStandardServerCoreEdition -eq $SKU -or $SKUEnterpriseServerCoreEdition -eq $SKU)
{
$CoreFull = "Core"
$ComputerClassId = "$MPElement[Name='Microsoft.Windows.Server.2008.R2.Core.Computer']$"
$OsClassId = "$MPElement[Name='Microsoft.Windows.Server.2008.R2.Core.OperatingSystem']$"

}
else
{
$ComputerClassId = "$MPElement[Name='Microsoft.Windows.Server.2008.R2.Full.Computer']$"
$OsClassId = "$MPElement[Name='Microsoft.Windows.Server.2008.R2.Full.OperatingSystem']$"

}

$PowerPlan = Get-PowerPlan

}

$error.Clear()


$oInstanceComputer = $oDisc.CreateClassInstance($ComputerClassId)
$oInstanceOperatingSystem = $oDisc.CreateClassInstance($OsClassId)
if (0 -ne $Error.Count)
{
return $result
}

$Error.Clear()


$oInstanceComputer.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $sTargetComputerID)
$oInstanceComputer.AddProperty("$MPElement[Name='Microsoft.Windows.Server.2008.Computer']/InstallType$", $CoreFull)
$oInstanceOperatingSystem.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $sTargetComputerID)
$oInstanceOperatingSystem.AddProperty("$MPElement[Name='Microsoft.Windows.Server.2008.OperatingSystem']/InstallType$", $CoreFull)

if ("6.1" -eq $OsVersion)
{
$oInstanceOperatingSystem.AddProperty("$MPElement[Name='Microsoft.Windows.Server.2008.R2.OperatingSystem']/PowerPlan$", $PowerPlan)
}

if (0 -ne $Error.Count)
{
return $result
}


$oDisc.AddInstance($oInstanceComputer)
$oDisc.AddInstance($oInstanceOperatingSystem)

$result = 0 -eq $Error.Count

return $result



}

Function Convert-ToBoolean([string] $sBool)
{
[bool] $result = $false
[bool] $iresult = $false

if ($false -eq [string]::IsNullOrEmpty($sBool) )
{
$result = $sBool.Equals("true",[System.StringComparison]::InvariantCultureIgnoreCase)
$iresult = $sBool.Equals("1",[System.StringComparison]::InvariantCultureIgnoreCase)
$result = $result -or $iresult
}

return $result
}

Function Get-OsFilter([string]$OSVersion,[string]$delimiter=",")
{
$ErrorActionPreference = "SilentlyContinue"
$Error.Clear()

$Filter = "ProductType != 1"

if([string]::IsNullOrEmpty($OsVersion))
{
return $Filter
}
$prefix = " and (Version like '"
$separator = "%' or Version like '"
$EndClause = "%')"

$OsVersions = $OSVersion.Split($delimiter,[StringSplitOptions]::RemoveEmptyEntries)
if ($OsVersions.Count -eq 0 -or $null -eq $OsVersions )
{
return $Filter
}

$SubFilter = [string]::Join($separator,$OsVersions)
$Filter = $Filter + $prefix + $SubFilter + $EndClause

return $Filter
}

Function Get-SnapshotDiscovery($OsVersion,$IsVirtualNode)
{
$ErrorActionPreference = "SilentlyContinue"

$bIsVirtualNode = Convert-ToBoolean -sBool $IsVirtualNode

if ($bIsVirtualNode)
{
return $Exit_SnapShotDiscovery
}

$Filter = Get-OsFilter -OSVersion $OsVersion
$Error.Clear()

Load-CimModules
try
{
$cimSessionOption = New-CimSessionOption -Protocol DCOM
$cimsession = New-CimSession -SessionOption $cimSessionOption
$result = Get-CimInstance -CimSession $cimsession -ClassName "Win32_OperatingSystem" -Filter $Filter
}
Finally
{
Get-CimSession | Remove-CimSession
$cimsession =$null
$cimSessionOption = $null
}

if(0 -ne $Error.Count)
{
$Error.Clear()
$result = Get-WmiObject -Class "Win32_OperatingSystem" -Filter $Filter

if (0 -ne $Error.Count)
{
return $Exit_IncrementalDiscovery
}

}

if ($null -eq $result)
{
$result = $Exit_SnapShotDiscovery
}
else
{
$result = $Start_SnapShotDiscovery
}

return $result
}

Function Get-DiscoveryData
{
$ErrorActionPreference = "SilentlyContinue"
$Error.Clear()
$oDiscoveryData = $momAPI.CreateDiscoveryData(0, $SourceId, $ManagedEntityId)
if (0 -ne $Error.Count)
{
return $null
}

$discoveryType = Get-SnapshotDiscovery -OsVersion $VersionPrefix -IsVirtualNode $boolIsVirtualNode

If ($Start_SnapShotDiscovery -eq $discoveryType)
{
$result = DoDiscovery $TargetComputer $TargetComputerID $oDiscoveryData
if ($false -eq $result)
{
$Error.Clear()
$oDiscoveryData = $momAPI.CreateDiscoveryData(0, $SourceID, $ManagedEntityId)
$oDiscoveryData.IsSnapshot = $false
}
}
else
{
if ($Exit_IncrementalDiscovery -eq $discoveryType)
{
$oDiscoveryData.IsSnapshot = $false
}
}

return $oDiscoveryData

}

Function Get-PowerPlan
{
$ErrorActionPreference = "SilentlyContinue"
$error.Clear()
$Filter = "IsActive=true"
$PowerPlan = ""

# Some group policies can restrict accessing to Win32_PowerPlan,
# need to handle it gracefully (for more information please see
# PS# 162496 in Server Management)
$WMIPowerSet = Get-WmiObject -Class "Win32_PowerPlan" -Namespace "root\cimv2\power" -Filter $Filter

if(0 -ne $Error.Count)
{
$Error.Clear()

Load-CimModules
try
{
$cimSessionOption = New-CimSessionOption -Protocol DCOM
$cimsession = New-CimSession -SessionOption $cimSessionOption
$WMIPowerSet = Get-CimInstance -CimSession $cimsession -ClassName "Win32_PowerPlan" -Namespace "root\cimv2\power" -Filter $Filter
}
Finally
{
Get-CimSession | Remove-CimSession
$cimsession =$null
$cimSessionOption = $null
}
}

if ($null -eq $WMIPowerSet)
{
$error.Clear()
return $PowerPlan
}

foreach ($oPlan in $WMIPowerSet)
{
$PowerPlan = $oPlan.ElementName
break
}

if ($error.Count -ne 0)
{
$error.Clear()
$PowerPlan = ""
}

return $PowerPlan
}

Function GetRegistryKeyValue
{
param ([string]$keyPath,
[string]$key)

$ErrorActionPreference = "SilentlyContinue"
$error.Clear()
$result = ""
$strKeyValue = Get-ItemProperty -Path $keyPath -Name $key

if ($error.Count -eq 0)
{
$result = $strKeyValue.$key
}

$error.Clear()

return $result
}


if ($null -eq $momAPI)
{
exit
}


Load-CimModules

Main

</Script></Contents>
<Unicode>true</Unicode>
</File>
<File>
<Name>Microsoft.Windows.Server.2008.Discovery.Probe.vbs</Name>
<Contents><Script>
'Copyright (c) Microsoft Corporation. All rights reserved.

'*************************************************************************
' $ScriptName: "Microsoft.Windows.Server.Common"$
'
' Purpose: To have one place for common stuff across various BaseOS VBScripts
'
' $File: Microsoft.Windows.Server.Common.vbs$
'*************************************************************************

Option Explicit

SetLocale("en-us")

' LogScripEvent Constants
Const lsEventError = 1
Const lsEventWarning = 2
Const lsEventInformation = 3

' WMI Constants
Const wbemCimtypeUseDefault = 0 'Use Default Type CIM type - Custom
Const wbemCimtypeSint16 = 2 'Signed 16-bit integer
Const wbemCimtypeSint32 = 3 'Signed 32-bit integer
Const wbemCimtypeReal32 = 4 '32-bit real number
Const wbemCimtypeReal64 = 5 '64-bit real number
Const wbemCimtypeString = 8 'String
Const wbemCimtypeBoolean = 11 'Boolean value
Const wbemCimtypeObject = 13 'CIM object
Const wbemCimtypeSint8 = 16 'Signed 8-bit integer
Const wbemCimtypeUint8 = 17 'Unsigned 8-bit integer
Const wbemCimtypeUint16 = 18 'Unsigned 16-bit integer
Const wbemCimtypeUint32 = 19 'Unsigned 32-bit integer
Const wbemCimtypeSint64 = 20 'Signed 64-bit integer
Const wbemCimtypeUint64 = 21 'Unsigned 64-bit integer
Const wbemCimtypeDatetime = 101 'Date/time value
Const wbemCimtypeReference = 102 'Reference to a CIM object
Const wbemCimtypeChar16 = 103 '16-bit character

Const ErrAction_None = 0
Const ErrAction_Trace = 1
Const ErrAction_ThrowError = 16
Const ErrAction_Abort = 32
Const ErrAction_ThrowErrorAndAbort = 48

Const DISKSIZE_BYTES_IN_MB = 1048576

Dim g_ErrorEventNumber, g_TraceEventNumber, g_DebugFlag
g_ErrorEventNumber = 4001
g_TraceEventNumber = 4002
g_DebugFlag = False

'---------------------------------------------------------------------------
' Returns WMI Instance requested. Tries to execute WMI query a N times.
'---------------------------------------------------------------------------
Function WMIGetInstanceExTryN(oWMI, ByVal sInstance, ByVal N)
Dim oInstance, nInstanceCount
Dim e, i
Set e = New Error

For i = 0 To i &lt; N
On Error Resume Next
Set oInstance = oWMI.InstancesOf(sInstance)
e.Save
On Error Goto 0
If IsEmpty(oInstance) Or e.Number &lt;&gt; 0 Then
If i = N - 1 Then
ThrowScriptError "The class name '" &amp; sInstance &amp; "' returned no instances. Please check to see if this is a valid WMI class name.", e
End If
Else
On Error Resume Next
nInstanceCount = oInstance.Count
e.Save
On Error Goto 0
If e.Number &lt;&gt; 0 Then
If i = N - 1 Then
ThrowScriptError "The class name '" &amp; sInstance &amp; "' did not return any valid instances. Please check to see if this is a valid WMI class name.", e
End If
Else
Exit For
End If
End If
WScript.Sleep(1000)
Next

Set WMIGetInstanceExTryN = oInstance
End Function

'---------------------------------------------------------------------------
' Returns WMI Instance requested.
'---------------------------------------------------------------------------
Function WMIGetInstanceEx(oWMI, ByVal sInstance)
Dim oInstance, nInstanceCount
Dim e
Set e = New Error

On Error Resume Next
Set oInstance = oWMI.InstancesOf(sInstance)
e.Save
On Error Goto 0
If IsEmpty(oInstance) Or e.Number &lt;&gt; 0 Then
ThrowScriptError "The class name '" &amp; sInstance &amp; "' returned no instances. Please check to see if this is a valid WMI class name.", e
End If

'Determine if we queried a valid WMI class - Count will return 0 or empty
On Error Resume Next
nInstanceCount = oInstance.Count
e.Save
On Error Goto 0
If e.Number &lt;&gt; 0 Then
ThrowScriptError "The class name '" &amp; sInstance &amp; "' did not return any valid instances. Please check to see if this is a valid WMI class name.", e
End If

Set WMIGetInstanceEx = oInstance
End Function

'---------------------------------------------------------------------------
' Connect to WMI.
'---------------------------------------------------------------------------
Function WMIConnect(ByVal sNamespace)
Dim oWMI
Dim e
Set e = New Error
On Error Resume Next
Set oWMI = GetObject(sNamespace)
e.Save
On Error Goto 0
If IsEmpty(oWMI) Then
ThrowScriptError "Unable to open WMI Namespace '" &amp; sNamespace &amp; "'. Check to see if the WMI service is enabled and running, and ensure this WMI namespace exists.", e
End If
Set WMIConnect = oWMI
End Function

'---------------------------------------------------------------------------
' Returns WMI Instance requested.
'---------------------------------------------------------------------------
Function WMIGetInstance(ByVal sNamespace, ByVal sInstance)
Dim oWMI, oInstance
Set oWMI = WMIConnect(sNamespace)
Set oInstance = WMIGetInstanceEx(oWMI, sInstance)
Set WMIGetInstance = oInstance
End Function

'---------------------------------------------------------------------------
' Returns WMI Instance requested.
'---------------------------------------------------------------------------
Function WMIGetInstanceNoAbort(ByVal sNamespace, ByVal sInstance)
Dim oWMI, oInstance, nInstanceCount

On Error Resume Next
Set oWMI = GetObject(sNamespace)
If Not IsEmpty(oWMI) Then
Set oInstance = oWMI.InstancesOf(sInstance)
If Not IsEmpty(oInstance) And Err.Number = 0 Then
'Determine if we queried a valid WMI class - Count will return 0 or empty
nInstanceCount = oInstance.Count
If Err.Number = 0 Then
Set WMIGetInstanceNoAbort = oInstance
On Error Goto 0
Exit Function
End If
End If
End If

On Error Goto 0
Set WMIGetInstanceNoAbort = Nothing
End Function

'---------------------------------------------------------------------------
' Executes the WMI query and returns the result set.
'---------------------------------------------------------------------------
Function WMIExecQuery(ByVal sNamespace, ByVal sQuery)
Dim oWMI, oQuery, nInstanceCount
Dim e
Set e = New Error
On Error Resume Next
Set oWMI = GetObject(sNamespace)
e.Save
On Error Goto 0
If IsEmpty(oWMI) Then
ThrowScriptError "Unable to open WMI Namespace '" &amp; sNamespace &amp; "'. Check to see if the WMI service is enabled and running, and ensure this WMI namespace exists.", e
End If

On Error Resume Next
Set oQuery = oWMI.ExecQuery(sQuery)
e.Save
On Error Goto 0
If IsEmpty(oQuery) Or e.Number &lt;&gt; 0 Then
ThrowScriptError "The Query '" &amp; sQuery &amp; "' returned an invalid result set. Please check to see if this is a valid WMI Query.", e
End If

'Determine if we queried a valid WMI class - Count will return 0 or empty
On Error Resume Next
nInstanceCount = oQuery.Count
e.Save
On Error Goto 0
If e.Number &lt;&gt; 0 Then
ThrowScriptError "The Query '" &amp; sQuery &amp; "' did not return any valid instances. Please check to see if this is a valid WMI Query.", e
End If

Set WMIExecQuery = oQuery
End Function

'---------------------------------------------------------------------------
' Executes the WMI query and returns the result set, no abort version.
'---------------------------------------------------------------------------
Function WMIExecQueryNoAbort(ByVal sNamespace, ByVal sQuery)
Dim oWMI, oQuery
Set oWMI = GetObject(sNamespace)
Set oQuery = oWMI.ExecQuery(sQuery)
Set WMIExecQueryNoAbort = oQuery
End Function

'---------------------------------------------------------------------------
' Retrieves WMI property.
'---------------------------------------------------------------------------
Function GetWMIProperty(oWmi, sPropName, nCIMType, ErrAction)
Dim sValue, oWmiProp, oError
Set oError = New Error

' Check that object is valid.
If Not IsValidObject(oWmi) Then
If (ErrAction And ErrAction_ThrowError) = ErrAction_ThrowError Then _
ThrowScriptErrorNoAbort "Accessing property on invalid WMI object.", oError
If (ErrAction And ErrAction_Abort) = ErrAction_Abort Then _
Quit()

GetWMIProperty = ""
Exit Function
End If

' Get properties...
On Error Resume Next
Set oWmiProp = oWmi.Properties_.Item(sPropName)
oError.Save
If oError.Number &lt;&gt; 0 Then
If (ErrAction And ErrAction_ThrowError) = ErrAction_ThrowError Then _
ThrowScriptErrorNoAbort "An error occurred while accessing WMI property: '" &amp; sPropName &amp; "'.", oError
If (ErrAction And ErrAction_Abort) = ErrAction_Abort Then _
Quit()
End If
On Error Goto 0

If IsValidObject(oWmiProp) Then
sValue = oWmiProp.Value

If IsNull(sValue) Then ' If value is null, return blank to avoid any issues
GetWMIProperty = ""
Else
Select Case (oWmiProp.CIMType)
Case wbemCimtypeString, wbemCimtypeSint16, wbemCimtypeSint32, wbemCimtypeReal32, wbemCimtypeReal64, wbemCimtypeSint8, wbemCimtypeUint8, wbemCimtypeUint16, wbemCimtypeUint32, wbemCimtypeSint64, wbemCimtypeUint64:
If Not oWmiProp.IsArray Then
GetWMIProperty = Trim(CStr(sValue))
Else
GetWMIProperty = Join(sValue, ", ")
End If
Case wbemCimtypeBoolean:
If sValue = 1 Or UCase(sValue) = "TRUE" Then
GetWMIProperty = "True"
Else
GetWMIProperty = "False"
End If
Case wbemCimtypeDatetime:
Dim sTmpStrDate

' First attempt to convert the whole wmi date string
sTmpStrDate = Mid(sValue, 5, 2) &amp; "/" &amp; _
Mid(sValue, 7, 2) &amp; "/" &amp; _
Left(sValue, 4) &amp; " " &amp; _
Mid (sValue, 9, 2) &amp; ":" &amp; _
Mid(sValue, 11, 2) &amp; ":" &amp; _
Mid(sValue, 13, 2)
If IsDate(sTmpStrDate) Then
GetWMIProperty = CDate(sTmpStrDate)
Else
' Second, attempt just to convert the YYYYMMDD
sTmpStrDate = Mid(sValue, 5, 2) &amp; "/" &amp; _
Mid(sValue, 7, 2) &amp; "/" &amp; _
Left(sValue, 4)
If IsDate(sTmpStrDate) Then
GetWMIProperty = CDate(sTmpStrDate)
Else
' Nothing works - return passed in string
GetWMIProperty = sValue
End If
End If
Case Else:
GetWMIProperty = ""
End Select
End If
Else
If (ErrAction And ErrAction_ThrowError) = ErrAction_ThrowError Then _
ThrowScriptErrorNoAbort "An error occurred while accessing WMI property: '" &amp; sPropName &amp; "'.", oError
If (ErrAction And ErrAction_Abort) = ErrAction_Abort Then _
Quit()

GetWMIProperty = ""
End If

If (ErrAction And ErrAction_Trace) = ErrAction_Trace Then _
WScript.Echo " + " &amp; sPropName &amp; " :: '" &amp; GetWMIProperty &amp; "'"
Err.Clear
End Function

'---------------------------------------------------------------------------
' Class for error handling.
'---------------------------------------------------------------------------
Class Error
Private m_lNumber
Private m_sSource
Private m_sDescription
Private m_sHelpContext
Private m_sHelpFile
Public Sub Save()
m_lNumber = Err.number
m_sSource = Err.Source
m_sDescription = Err.Description
m_sHelpContext = Err.HelpContext
m_sHelpFile = Err.helpfile
End Sub
Public Sub Raise()
Err.Raise m_lNumber, m_sSource, m_sDescription, m_sHelpFile, m_sHelpContext
End Sub
Public Sub Clear()
m_lNumber = 0
m_sSource = ""
m_sDescription = ""
m_sHelpContext = ""
m_sHelpFile = ""
End Sub
Public Default Property Get Number()
Number = m_lNumber
End Property
Public Property Get Source()
Source = m_sSource
End Property
Public Property Get Description()
Description = m_sDescription
End Property
Public Property Get HelpContext()
HelpContext = m_sHelpContext
End Property
Public Property Get HelpFile()
HelpFile = m_sHelpFile
End Property
End Class

'---------------------------------------------------------------------------
' Creates an event and sends it back to the mom server.
'---------------------------------------------------------------------------
Function ThrowScriptErrorNoAbort(ByVal sMessage, ByVal oErr)
' Retrieve the name of this (running) script
Dim FSO, ScriptFileName
Set FSO = CreateObject("Scripting.FileSystemObject")
ScriptFileName = FSO.GetFile(WScript.ScriptFullName).Name
Set FSO = Nothing

If Not IsNull(oErr) Then _
sMessage = sMessage &amp; ". " &amp; oErr.Description

On Error Resume Next
Dim oAPITemp
Set oAPITemp = CreateObject("MOM.ScriptAPI")
oAPITemp.LogScriptEvent ScriptFileName, g_ErrorEventNumber, lsEventError, sMessage
On Error Goto 0

WScript.Echo sMessage
End Function

'---------------------------------------------------------------------------
' Creates an event and sends it back to the mom server.
'---------------------------------------------------------------------------
Function ThrowScriptError(Byval sMessage, ByVal oErr)
On Error Resume Next
ThrowScriptErrorNoAbort sMessage, oErr
Quit()
End Function

'---------------------------------------------------------------------------
' Creates automation objects and returns it.
'---------------------------------------------------------------------------
Function MomCreateObject(ByVal sProgramId)
Dim oError
Set oError = New Error

On Error Resume Next
Set MomCreateObject = CreateObject(sProgramId)
oError.Save
On Error Goto 0

If oError.Number &lt;&gt; 0 Then
ThrowScriptError "Unable to create automation object '" &amp; sProgramId &amp; "'", oError
End If
End Function

'---------------------------------------------------------------------------
' Quits the script.
'---------------------------------------------------------------------------
Function Quit()
WScript.Quit()
End Function

'---------------------------------------------------------------------------
' Checks whether oObject is valid.
'---------------------------------------------------------------------------
Function IsValidObject(ByVal oObject)
IsValidObject = False
If IsObject(oObject) Then
If Not oObject Is Nothing Then
IsValidObject = True
End If
End If
End Function

'---------------------------------------------------------------------------
' Outputs arguments for debugging purposes
'---------------------------------------------------------------------------
Function TraceLogArguments
Dim oArgs
Set oArgs = WScript.Arguments
Dim i, sArgs
For i = 0 To oArgs.Count - 1
sArgs = sArgs &amp; " {" &amp; oArgs(i) &amp; "}"
Next
TraceLogMessage "Arguments:" &amp; sArgs
End Function

'---------------------------------------------------------------------------
' Verifies that number of arguments is correct
'---------------------------------------------------------------------------
Function VerifyNumberOfArguments(ByVal NumberOfArguments)
Dim oArgs
Set oArgs = WScript.Arguments
If oArgs.Count &lt;&gt; NumberOfArguments Then
Dim i, sArgs
For i = 0 To oArgs.Count - 1
sArgs = sArgs &amp; " {" &amp; oArgs(i) &amp; "}"
Next
ThrowScriptError "Invalid number of arguments (" &amp; oArgs.Count &amp; " instead of " &amp; NumberOfArguments &amp; "). Arguments:" &amp; sArgs, Null
End If
End Function

'---------------------------------------------------------------------------
' Outputs to file and echo for debugging purposes
'---------------------------------------------------------------------------
Function TraceLogMessage(ByVal sMessage)
WScript.Echo sMessage

If g_DebugFlag = True Then
' Retrieve the name of this (running) script
Dim FSO, ScriptFileName
Set FSO = CreateObject("Scripting.FileSystemObject")
ScriptFileName = FSO.GetFile(WScript.ScriptFullName).Name
Set FSO = Nothing

On Error Resume Next
Dim oAPITemp
Set oAPITemp = MOMCreateObject("MOM.ScriptAPI")
oAPITemp.LogScriptEvent ScriptFileName, g_TraceEventNumber, lsEventInformation, sMessage
On Error Goto 0
End If
End Function

'---------------------------------------------------------------------------
' Verifies the expression. If equals to False then generates an error and quits the script
' Usage:
' Verify Not WMISet Is Nothing, "WMISet is invalid!"
' Verify WMISet.Count = 1, "Invalid quantity of services with name 'Server' (qty = " &amp; WMISet.Count &amp; ")."
'---------------------------------------------------------------------------
Function Verify(ByVal bBool, ByVal sMessage)
If bBool = False Then
ThrowScriptError sMessage, Null
End If
End Function


Function GetRegistryKeyValue(ByVal keyPath, ByVal key)
Dim oReg, strKeyValue

On Error Resume Next
Err.Clear
Set oReg = MOMCreateObject("WScript.Shell")

strKeyValue = oReg.RegRead(keyPath &amp; key)
If Err.Number &lt;&gt; 0 Then
strKeyValue = ""
End If
Err.Clear
' resume error
On Error Goto 0

GetRegistryKeyValue = strKeyValue
End Function

'---------------------------------------------------------------------------
' Function: ExpressedInMB
' Usage:
' Parameter (SizeInBytes)
' Returns the Size Expressed in MBytes
'---------------------------------------------------------------------------
Function ExpressedInMB(byref SizeInBytes)
Dim NumberSizeExpInMB
NumberSizeExpInMB = Round(SizeInBytes / DISKSIZE_BYTES_IN_MB, 0)
ExpressedInMB = NumberSizeExpInMB
End Function

'****************************************************************************************************************
' FUNCTION: GetClusterNameFromRegistry
' DESCRIPTION: Returns the cluster name of the given cluster virtual name

'****************************************************************************************************************
Function GetClusterNameFromRegistry

Const ClusterNamePath = "HKLM\Cluster\"
Const ClusterNameValue = "ClusterName"

GetClusterNameFromRegistry = GetRegistryKeyValue(ClusterNamePath,ClusterNameValue)

End Function

Function CheckCluster(sTargetComputer)
Dim oWMI, sInstance
Dim oInstances, nCount
Dim e

Set e = New Error

On Error Resume Next
Set oWMI = WMIConnect("winmgmts:\\" + sTargetComputer + "\root\cimv2")

e.Save
On Error Goto 0

If e.Number &lt;&gt; 0 Then
CheckCluster = False
Else
CheckCluster = True
End If

sInstance = "Select ID, Name from Win32_ServerFeature where Name = 'Failover Clustering'"

On Error Resume Next
Err.Clear
Set oInstances = oWMI.ExecQuery(sInstance)
nCount = oInstances.Count

e.Save
On Error Goto 0

If nCount = 0 Or e.Number &lt;&gt; 0 Then
CheckCluster = False
Else
If Len(GetClusterNameFromRegistry()) &gt; 0 Then
CheckCluster = True
Else
CheckCluster = False
End If
End If
End Function

Function GetClusterDiskCollection(sTargetComputer)
Dim oWMI, sInstance, oInstances, nCount
Dim e

Set e = New Error
On Error Resume Next
Err.Clear
Set oWMI = WMIConnect("winmgmts:\\" + sTargetComputer + "\root\MSCluster")
e.Save
On Error Goto 0

If e.Number &lt;&gt; 0 Then
Set GetClusterDiskCollection = Nothing
Exit Function
End If

sInstance = "Select Path, SerialNumber,VolumeGuid From MSCluster_DiskPartition"

On Error Resume Next
Set oInstances = oWMI.ExecQuery(sInstance)

e.Save
On Error Goto 0

If e.Number &lt;&gt; 0 Then
Set GetClusterDiskCollection = Nothing
Exit Function
End If

On Error Resume Next

nCount = oInstances.Count
e.Save
On Error Goto 0

If e.Number &lt;&gt; 0 Then
Set GetClusterDiskCollection = Nothing
Else
Set GetClusterDiskCollection = oInstances
End If
End Function

Public Function RemoveFirstZeroChar(sHex)
Dim sTempString
Dim iLen,iPos,i

iLen = 0
iPos = 0
iLen = Len(sHex)

For i = 1 To iLen
If (Mid(sHex,i,1) &lt;&gt; "0") Then
iPos = i - 1
Exit For
End If
Next

If ( 0 = iPos) Then
sTempString = sHex
Else
sTempString = Right(sHex,iLen - iPos)
End if

RemoveFirstZeroChar = sTempString
End Function


'Copyright (c) Microsoft Corporation. All rights reserved.

' Parameters that should be passed to this script
' 0 MPElement ID
' 1 Target Id for ME this rule is running against
' 2 Computer (FQDN) that the OS will be hosted on
' 3 Computer ID (Key) that the OS will be hosted on
' 4 Windows Current Version (6.0 - Server 2008, 6.1 - Server 2008 R2)

' If OperatingSystemSKU equals to one of these values then we deal with Core OS
Const SKUDatacenterServerCoreEdition = "12"
Const SKUStandardServerCoreEdition = "13"
Const SKUEnterpriseServerCoreEdition = "14"
Const Start_SnapShotDiscovery = 0
Const Exit_SnapShotDiscovery = 1
Const Exit_IncrementalDiscovery = 2
Const OsVersion = "6.0,6.1"


Call Main()

Sub Main()

Dim oArgs
Set oArgs = WScript.Arguments
Dim SourceID, ManagedEntityId, TargetComputer, TargetComputerID, IsVirtualNode

If (oArgs.Count &lt; 4 ) Then
Exit Sub
End If

SourceID = oArgs(0)
ManagedEntityId = oArgs(1)
TargetComputer = oArgs(2)
TargetComputerID = oArgs(3)

If (oArgs.Count &lt; 5) Then
IsVirtualNode = ""
Else
IsVirtualNode = UCase(oArgs(4) )
End If


Dim oAPI, oDiscoveryData,result,oError

result = GetSnapshotDiscovery(OsVersion,IsVirtualNode)
Set oAPI = MOMCreateObject("MOM.ScriptAPI")
On Error Resume Next
Err.Clear
Set oError = New Error
Set oDiscoveryData = oAPI.CreateDiscoveryData(0, SourceID, ManagedEntityId)
If (Err.Number &lt;&gt; 0) Then
oError.Save
ThrowScriptError "Unable to create discovery data object ", oError
End If

If (Exit_IncrementalDiscovery = result) Then
oDiscoveryData.IsSnapshot = False
ElseIf (Start_SnapShotDiscovery = result) Then
DoDiscovery TargetComputer, TargetComputerID, oDiscoveryData
End If

Call oAPI.Return(oDiscoveryData)

On Error Goto 0
End Sub

Function DoDiscovery(ByVal sTargetComputer, ByVal sTargetComputerID, ByVal oDisc)
Dim WMISet, owObj, oInstanceComputer, oInstanceOperatingSystem, SKUValue, IsCore, CoreFull, WMIPowerSet, oPlan, PowerPlan
Dim sWindowsCurrentVersion

sWindowsCurrentVersion = GetRegistryKeyValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\", "CurrentVersion")
Set WMISet = WMIGetInstance("winmgmts:\\" + sTargetComputer + "\root\cimv2", "Win32_OperatingSystem")

For Each owObj In WMISet
SKUValue = GetWMIProperty(owObj, "OperatingSystemSKU", wbemCimtypeUseDefault, ErrAction_Abort Or ErrAction_ThrowError)

If (SKUValue = SKUDatacenterServerCoreEdition) Or (SKUValue = SKUStandardServerCoreEdition) Or (SKUValue = SKUEnterpriseServerCoreEdition) Then
IsCore = True
Else
IsCore = False
End If

If (sWindowsCurrentVersion = "6.0") Then
If (IsCore = True) Then
Set oInstanceComputer = oDisc.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Server.2008.Core.Computer']$")
Set oInstanceOperatingSystem = oDisc.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Server.2008.Core.OperatingSystem']$")
CoreFull = "Core"
Else
Set oInstanceComputer = oDisc.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Server.2008.Full.Computer']$")
Set oInstanceOperatingSystem = oDisc.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Server.2008.Full.OperatingSystem']$")
CoreFull = "Full"
End If
Else
If (sWindowsCurrentVersion = "6.1") Then
If (IsCore = True) Then
Set oInstanceComputer = oDisc.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Server.2008.R2.Core.Computer']$")
Set oInstanceOperatingSystem = oDisc.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Server.2008.R2.Core.OperatingSystem']$")
CoreFull = "Core"
Else
Set oInstanceComputer = oDisc.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Server.2008.R2.Full.Computer']$")
Set oInstanceOperatingSystem = oDisc.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Server.2008.R2.Full.OperatingSystem']$")
CoreFull = "Full"
End If

' Some group policies can restrict accessing to Win32_PowerPlan,
' need to handle it gracefully (for more information please see
' PS# 162496 in Server Management)
On Error Resume Next
Set WMIPowerSet = WMIExecQueryNoAbort("winmgmts:\\" + sTargetComputer + "\root\cimv2\power", "select ElementName from Win32_PowerPlan where IsActive=true")
For Each oPlan In WMIPowerSet
PowerPlan = oPlan.ElementName
Next

If Err.Number &lt;&gt; 0 Then
PowerPlan = ""
End If
On Error Goto 0
End If
End If

With oInstanceComputer
.AddProperty "$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", sTargetComputerID
.AddProperty "$MPElement[Name='Microsoft.Windows.Server.2008.Computer']/InstallType$", CoreFull
End With

With oInstanceOperatingSystem
.AddProperty "$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", sTargetComputerID
.AddProperty "$MPElement[Name='Microsoft.Windows.Server.2008.OperatingSystem']/InstallType$", CoreFull

If (sWindowsCurrentVersion = "6.1") Then
.AddProperty "$MPElement[Name='Microsoft.Windows.Server.2008.R2.OperatingSystem']/PowerPlan$", PowerPlan
End If
End With

Call oDisc.AddInstance(oInstanceComputer)
Call oDisc.AddInstance(oInstanceOperatingSystem)
Next
End Function

Function HasValue(Value)

Dim bNothing

bNothing = false

IF ( IsObject(Value) ) THEN
IF (Nothing is Value) THEN
bNothing = true
END IF
END IF

HasValue = Not ( IsEmpty(Value) or bNothing or IsNull(Value) )
End Function

Function GetOsFilter(strOSVersion,delimiter)

On Error Resume Next
Err.Clear

Dim Filter,Prefix,Separator,EndClause
Dim OsVersions,SubFilter

Filter = " where ProductType != 1"
GetOSFilter = Filter

If (Not HasValue(strOSVersion) or 0 = Len(strOSVersion)) Then
Exit Function
End If
If (Not HasValue(delimiter)) Then
delimiter = ","
End If

If (delimiter = strOSVersion) Then
Exit Function
End If

Prefix = " and (Version like '"
Separator = "%' or Version like '"
EndClause = "%')"

OsVersions = Split(strOSVersion,delimiter)

SubFilter = Join(OsVersions,Separator)
Filter = Filter &amp; Prefix &amp; SubFilter &amp; EndClause

GetOSFilter = Filter
On Error Goto 0
End Function

Function GetServerOsVersionCheck(sComputerName, OsVersions,ByRef IsError)

On Error Resume Next

Err.Clear

Dim strQuery,oWmiSet, sWmiTarget, Count, Filter,OsData
IsError = False
GetServerOsVersionCheck = False

If ( IsObject(OsVersions)) Then
Exit Function
End If

sWmiTarget = "."

If ( Not IsObject(sComputerName)) Then
If (HasValue(sComputerName) and Len(sComputerName) &gt; 0 ) Then
sWmiTarget = "" &amp; sComputerName
End If
End If

sWmiTarget = "winmgmts:\\" &amp; sWmiTarget &amp; "\root\cimv2"
Filter = GetOsFilter(OsVersions,",")
StrQuery = "select Version from Win32_OperatingSystem" + Filter
Set oWmiSet = WMIExecQueryNoAbort(sWmiTarget, strQuery)

If Err.Number &lt;&gt; 0 Then
IsError = True
Exit Function
End If

Count = oWmiSet.Count
If Err.Number &lt;&gt; 0 Then
IsError = True
Exit Function
End If

GetServerOsVersionCheck = ( Count &gt; 0)

On Error Goto 0
End Function

Function GetSnapshotDiscovery(OsVersions,IsVirtualNode)

Dim bIsOsValid,bIsError,iResult

On Error Resume Next

If IsEmpty(IsVirtualNode) = True Or IsVirtualNode = "" Or IsVirtualNode = "FALSE" Then
bIsOsValid = GetServerOsVersionCheck(".",OsVersions,bIsError)

If (bIsOsValid) Then
iResult = Start_SnapShotDiscovery
Else
If (bIsError) Then
iResult = Exit_IncrementalDiscovery
Else
iResult = Exit_SnapShotDiscovery
End IF

End If

Else
iResult = Exit_SnapShotDiscovery
End If

GetSnapshotDiscovery = iResult
End Function


</Script></Contents>
<Unicode>false</Unicode>
</File>
<File>
<Name>vbparams.txt</Name>
<Contents><Script>"$Config/SourceId$" "$Target/Id$" "$Target/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$" "$Target/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$" "$Target/Property[Type="Windows!Microsoft.Windows.Server.Computer"]/IsVirtualNode$"</Script></Contents>
<Unicode>false</Unicode>
</File>
<File>
<Name>psparams.txt</Name>
<Contents><Script>'$Config/SourceId$' '$Target/Id$' '$Target/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$' '$Target/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$' '$Target/Property[Type="Windows!Microsoft.Windows.Server.Computer"]/IsVirtualNode$'</Script></Contents>
<Unicode>false</Unicode>
</File>
</Files>
</DataSource>
</MemberModules>
<Composition>
<Node ID="Scheduler"/>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.Discovery.Data</OutputType>
</DataSourceModuleType>