Windows Computer Property Discovery Data Source

Microsoft.SystemCenter.WindowsComputerPropertyDiscovery (DataSourceModuleType)

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityInternal
RunAsSystem.PrivilegedMonitoringAccount
OutputTypeSystem.Discovery.Data

Member Modules:

ID Module Type TypeId RunAs 
DataSource DataSource Microsoft.Windows.TimedPowerShell.DiscoveryProvider Default

Overrideable Parameters:

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

Source Code:

<DataSourceModuleType ID="Microsoft.SystemCenter.WindowsComputerPropertyDiscovery" Accessibility="Internal" RunAs="System!System.PrivilegedMonitoringAccount" Batching="false">
<Configuration>
<IncludeSchemaTypes>
<SchemaType>System!System.Discovery.MapperSchema</SchemaType>
</IncludeSchemaTypes>
<xsd:element name="IntervalSeconds" type="xsd:integer"/>
<xsd:element name="TimeoutSeconds" type="xsd:integer"/>
</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="DataSource" TypeID="Windows!Microsoft.Windows.TimedPowerShell.DiscoveryProvider">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<SyncTime/>
<ScriptName>DiscoverWindowsComputerProperties.ps1</ScriptName>
<ScriptBody><Script>
#-------------------------------------------------------------------------------
# DiscoverWindowsComputerProperties.ps1
#
# Script discovers the extended properties from AD/WMI given the
# DNS name of the computer.
#-------------------------------------------------------------------------------

param($SourceType, $SourceId, $ManagedEntityId, $ComputerIdentity)

$strDNSComputerName = $ComputerIdentity
$strNetBIOSDomain = $null
$strNetBIOSComputerName = $null
$strNetBIOSHostName = $null
$strDomainDNsName = $null
$strForestDnsName = $null
$strSite = $null
$strComputerOU = $null
$strIPAddresses = $null
$strLogicalProcessors = $null
$strPhysicalProcessors = $null
$strHostServerName = $null
$strVirtualMachineName = $null

$strDomainDN = $null;
$WIN_OS_2012_Ver = "6.2"

#Checks if the OS Version is more than 6.2 i.e. Server 2012
function CheckByOSCurrentVersion($strComputerDNS) #As Boolean
{
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $strComputerDNS)
$regKey = $reg.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion")
$strCurrentOSVer = $regKey.GetValue("CurrentVersion")
if($strCurrentOSVer -ge $WIN_OS_2012_Ver)
{
return $true;
}
return $false;
}

$Is_OS_More_Than_2012 = CheckByOSCurrentVersion $strDNSComputerName


#--------------------------------------------------------------
# Tests for NULL or Empty
#--------------------------------------------------------------
function IsNullOrEmpty($str)
{
return (($null -eq $str) -or (0 -eq $str.length))
}


#-----------------------------------------------------------
# Returns the DN domain name from DNS
#-----------------------------------------------------------
function DNDomainFromDNS($strDomainDNsName)
{
# Determine DN domain name from RootDSE object.
$query = "LDAP://$strDomainDNsName/RootDSE"
$objRootDSE = [System.DirectoryServices.DirectoryEntry]([ADSI]$query)
return $objRootDSE.Get("defaultNamingContext");
}


#-----------------------------------------------------------
# Returns the forest for the domain
#-----------------------------------------------------------
function ForestFromDomainDNS($strDNSDomain)
{
$strForestDNS = $null;
try
{
$query = "LDAP://$strDNSDomain/RootDSE"
$objRootDSE = [System.DirectoryServices.DirectoryEntry]([ADSI]$query);
$strForestDN = $objRootDSE.Get("rootdomainNamingContext");

# We got the DN (DC=corp,DC=microsoft,DC=com), translate to DNS (corp.microsoft.com)
$arrParseDN = $strForestDN.split(",");
for ($i = 0; $i -lt $arrParseDN.length; $i++)
{
$arrParseDC = $arrParseDN[$i].split("=");
if ($null -eq $strForestDNS)
{
$strForestDNS = $arrParseDC[1];
}
else
{
$strForestDNS = $strForestDNS + "." + $arrParseDC[1];
}
}
}
catch
{
; # Nothing to be done
}
return $strForestDNS
}
Function Load-CimModules
{
$error.Clear()

$CimModule = Get-Module CimCmdlets

if ($null -eq $CimModule)
{
Import-Module CimCmdlets
$error.Clear()
}
}
#-----------------------------------------------------------
# Returns the NetBIOS domain name from the DNS domain name
#-----------------------------------------------------------
function NetBIOSDomainFromDN($strDNSComputerName,$strDNDomain)
{
if($Is_OS_More_Than_2012)
{


try
{
# Constants for the NameTranslate object.

$ADS_NAME_INITTYPE_GC = 3
$ADS_NAME_TYPE_NT4 = 3
$ADS_NAME_TYPE_1779 = 1
$NameTranslate = New-Object -ComObject "NameTranslate"

# Use the NameTranslate object to find the NetBIOS domain name from the
# DNS domain name

$NameTranslate.GetType().InvokeMember("Init", "InvokeMethod", $NULL, $NameTranslate, ($ADS_NAME_INITTYPE_GC, "")) | Out-Null
$NameTranslate.GetType().InvokeMember("Set", "InvokeMethod", $NULL, $NameTranslate, ($ADS_NAME_TYPE_1779, $strDNDomain)) | Out-Null
$strNetBIOSDomain = $NameTranslate.GetType().InvokeMember("Get","InvokeMethod", $NULL, $NameTranslate, $ADS_NAME_TYPE_NT4)

# Remove trailing backslash.

$name = $strNetBIOSDomain.Substring(0,$strNetBIOSDomain.Length-1)
}
catch {
$DnsObject = Get-WmiObject Win32_ComputerSystem -ComputerName $strDNSComputerName
$name = $DnsObject.Domain
}
Finally {
if($NameTranslate)
{
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($NameTranslate) | Out-Null
}
}
}
else
{
$DnsObject = Get-WmiObject Win32_ComputerSystem -ComputerName $strDNSComputerName
$name = $DnsObject.Domain
}
return $name
}


#-------------------------------------------------------------
# Gets the IP addresses for the given computer name
#-------------------------------------------------------------
function GetIPAddresses($strDNSComputerName)
{
$strIPs =""
if($Is_OS_More_Than_2012)
{
Load-CimModules

try{
$cimSessionOption = New-CimSessionOption -Protocol DCOM
$cimsession = New-CimSession -ComputerName $strDNSComputerName -SessionOption $cimSessionOption
$arrItems = Get-CimInstance -CimSession $cimsession Win32_NetworkAdapterConfiguration -ErrorAction Stop

}
catch
{
$arrItems = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $strDNSComputerName -ErrorAction Stop
}
Finally{
Get-CimSession | Remove-CimSession
$cimsession =$null
$cimSessionOption = $null
}
}
else
{
$arrItems = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $strDNSComputerName
}
foreach($arrItem in $arrItems)
{
$IPValue = $arrItem.IPAddress;
if ($null -ne $IPValue)
{
$arrIPs = $IPValue

for ($i =0; $i -lt $arrIPs.length; $i++)
{
$strIP = $arrIPs[$i];
if ($null -ne $strIP)
{
if (($null -eq $strIPs) -or ($strIPs -eq ""))
{
$strIPs = $strIP;
}
else
{
$matchIP = $strIPs.IndexOf($strIP);
if($matchIP -eq -1)
{
$strIPs = $strIPs + ", " + $strIP;
}
}
}
}
}
}
if(($strIPs -ne "") -and ($strIPs -ne $null))
{
return $strIPs
}
$cimSession = New-CimSession -ComputerName $strDNSComputerName
$ipItems = Get-NetIPAddress -CimSession $cimSession
foreach($ipItem in $ipItems)
{
$ip = $ipItem.IPAddress
if(($ip -ne "::1") -and ($ip -ne "127.0.0.1"))
{
if (($null -eq $strIPs) -or ($strIPs -eq ""))
{
$strIPs = $ip
}else{
$strIPs = $strIPs + ', ' +$ip
}
}
}
return $strIPs
}

#-----------------------------------------------------------
# Get the site name from the Computer DNS
#-----------------------------------------------------------
function GetSiteFromComputerDNS($strComputerDNS)
{
$strSiteName = $null;

try
{
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $strComputerDNS)
$regKey = $reg.OpenSubKey("System\\CurrentControlSet\\Services\\Netlogon\\Parameters")
$strSiteName = $regKey.GetValue("SiteName")

#If SiteName override is $null or empty, try DynamicSiteName
if(IsNullOrEmpty $strSiteName)
{
$strSiteName = $regKey.GetValue("DynamicSiteName")
}
}
catch
{
; # Nothing to be done
}

return $strSiteName;

}

#-----------------------------------------------------------
# Adds the property to the instance if the value is non-$null
#-----------------------------------------------------------
function AddClassProperty($oInstance, $strProperty, $strValue)
{
if ($null -ne $strValue) {
$oInstance.AddProperty($strProperty, $strValue);
}
}

# Need to retrieve these properties


$oAPI = new-object -comobject "MOM.ScriptAPI"
$SCRIPT_NAME = "DiscoverWindowsComputerProperties.ps1";
$ENU_MESSAGE_BASE = "Windows Property Discovery. ";
$oDiscovery = $oAPI.CreateDiscoveryData($SourceType, $SourceId, $ManagedEntityId);
# Get the virtual machine information
try
{
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $strDNSComputerName)
$regKey = $reg.OpenSubKey("SOFTWARE\\Microsoft\\Virtual Machine\\Guest\\Parameters")
$strHostServerName = $regKey.GetValue("HostName")

$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $strDNSComputerName)
$regKey = $reg.OpenSubKey("SOFTWARE\\Microsoft\\Virtual Machine\\Guest\\Parameters")
$strVirtualMachineName = $regKey.GetValue("VirtualMachineName")
}
catch
{
; # Nothing to be done
}
# Attempt to do things the 'right' way
try
{

$E_CLUSTER_RESOURCE_NOT_FOUND = -2146823281;

# Get the computer from the system
$astrSplit = ""
$objComputer = $null
$colSettings = $null
$astrSplit = $strDNSComputerName.split(".")
$strNetBIOSComputerName = $astrSplit[0]

try
{
$query = "Select Domain, Name, NumberOfLogicalProcessors, NumberOfProcessors from Win32_ComputerSystem WHERE Name = ""$strNetBIOSComputerName"""
if($Is_OS_More_Than_2012)
{
Load-CimModules

try{
$cimSessionOption = New-CimSessionOption -Protocol DCOM
$cimsession = New-CimSession -ComputerName $strDNSComputerName -SessionOption $cimSessionOption
$objComputer = Get-CimInstance -CimSession $cimsession -Namespace "root\cimv2" -Query $query -ErrorVariable ProcessError -ErrorAction Stop

}
catch
{
$objComputer = Get-WmiObject -ComputerName $strDNSComputerName -Namespace "root\cimv2" -Query $query -ErrorVariable ProcessError -ErrorAction Stop
}
Finally{
Get-CimSession | Remove-CimSession
$cimsession =$null
$cimSessionOption = $null
}
}
else
{
$objComputer = Get-WmiObject -ComputerName $strDNSComputerName -Namespace "root\cimv2" -Query $query -ErrorVariable ProcessError -ErrorAction Stop
}

$strDomainDNsName = $objComputer.Domain;
$strNetBIOSHostName = $objComputer.Name;
$strLogicalProcessors = $objComputer.NumberOfLogicalProcessors;
$strPhysicalProcessors = $objComputer.NumberOfProcessors;
if ($null -eq $strLogicalProcessors)
{
$strLogicalProcessors = $objComputer.NumberOfProcessors;
$strPhysicalProcessors = $null;
}
}
catch
{
$e = $_.Exception.Message
$message = $_.Exception.Message
$oAPI.LogScriptEvent("DiscoverWindowsComputerProperties", 100, 1, $message)
if ($e -ne $E_CLUSTER_RESOURCE_NOT_FOUND)
{
throw $e;
}
$query = "Select Domain, Name, NumberOfLogicalProcessors, NumberOfProcessors from Win32_ComputerSystem"
if($Is_OS_More_Than_2012)
{
Load-CimModules

try{
$cimSessionOption = New-CimSessionOption -Protocol DCOM
$cimsession = New-CimSession -ComputerName $strDNSComputerName -SessionOption $cimSessionOption
$colSettings = Get-CimInstance -CimSession $cimsession -Namespace "root\cimv2" -Query $query -ErrorVariable ProcessError -ErrorAction Stop

}
catch
{
$colSettings = Get-WmiObject -ComputerName $strDNSComputerName -Namespace "root\cimv2" -Query $query -ErrorVariable ProcessError -ErrorAction Stop
}
Finally{
Get-CimSession | Remove-CimSession
$cimsession =$null
$cimSessionOption = $null
}
}
else
{
$colSettings = Get-WmiObject -ComputerName $strDNSComputerName -Namespace "root\cimv2" -Query $query -ErrorVariable ProcessError -ErrorAction Stop
}
$objComputer = $colSettings.item();
$strDomainDNsName = $objComputer.Domain;
$strNetBIOSHostName = $objComputer.Name;
$strLogicalProcessors = $objComputer.NumberOfLogicalProcessors;
$strPhysicalProcessors = $objComputer.NumberOfProcessors;
if ($null -eq $strLogicalProcessors)
{
$strLogicalProcessors = $objComputer.NumberOfProcessors;
$strPhysicalProcessors = $null;
}
}

try
{
# Get the domain data. If computer is in a workgroup, it will catch exception.
$strDomainDN = DNDomainFromDNS $strDomainDNsName
}
catch
{
Write-Host "Domain Data Exception caught for " + $strDomainDNsName
}

if ($strDomainDN -ne $null)
{
$strNetBIOSDomain = NetBIOSDomainFromDN $strDNSComputerName $strDomainDN
}

$strIPAddresses = GetIPAddresses $strDNSComputerName

$ADSISearcher = New-Object System.DirectoryServices.DirectorySearcher
$ADSISearcher.Filter = '(&amp;(dnshostname=' + $strDNSComputerName + ')(name=' + $strNetBIOSComputerName + ')(objectClass=computer))';
$ADSISearcher.SearchScope = 'Subtree'
$Computer = $ADSISearcher.FindOne()
$strComputerOU = $($Computer.Properties.Item('distinguishedName'))
$ADS_SETTYPE_DN = 4
$ADS_FORMAT_X500_PARENT = 8
$Pathname = New-Object -ComObject "Pathname"
[void]$Pathname.GetType().InvokeMember("Set","InvokeMethod",$NULL,$Pathname,@($strComputerOU,$ADS_SETTYPE_DN))
$strComputerOU=$Pathname.GetType().InvokeMember("Retrieve","InvokeMethod",$NULL,$Pathname,@($ADS_FORMAT_X500_PARENT))
}

# Unable to contact the machine, (mis)use the DNS name
catch
{
$e = $_.Exception.Message
$message = "Exception retrieving properties '" + $e + "', using failsafe method" # Do nothing
Write-Host $message
}

if((IsNullOrEmpty $strNetBIOSComputerName) -or (IsNullOrEmpty $strNetBIOSDomain))
{
# Try to parse the DNS name of the system
$arrNameSplit = $strDNSComputerName.split(".");
if (IsNullOrEmpty $strNetBIOSComputerName -and ($arrNameSplit.length -gt 0))
{
$strNetBIOSComputerName = $arrNameSplit[0];
}
if ((IsNullOrEmpty $strNetBIOSDomain) -and ($arrNameSplit.length -gt 1))
{
$strNetBIOSDomain = $arrNameSplit[1];
}

# If there is no DNS name (no '.') then this is a workgroup, so use the domain name from WMI as NetBIOS Domain
if ((IsNullOrEmpty $strNetBIOSDomain) -and (-not (IsNullOrEmpty $strDomainDnsName)))
{
$strNetBIOSDomain = $strDomainDNsName;
}
}

if (IsNullOrEmpty $strDomainDnsName)
{
for($i = 1; $i -lt $arrNameSplit.length; $i++)
{
if (-not (IsNullOrEmpty $strDomainDnsName))
{
$strDomainDNsName = $strDomainDNsName + ".";
$strDomainDNsName = $strDomainDNsName + $arrNameSplit[$i];
}
else
{
$strDomainDNsName = $arrNameSplit[$i];
}
}
}


# Get the forest if we have the Domain DNS name
if((IsNullOrEmpty $strForestDnsName) -and (-not (IsNullOrEmpty $strDomainDNsName)))
{
$strForestDnsName = ForestFromDomainDNS $strDomainDNsName
}

# Get the site name
if (IsNullOrEmpty $strSite)
{
$strSite = GetSiteFromComputerDNS $strDNSComputerName
}

Write-Host "NetBIOS Computer Name: " $strNetBIOSComputerName
Write-Host "NetBIOS Domain Name: " $strNetBIOSDomain
Write-Host "Forest DNS Name: " $strForestDnsName
Write-Host "Domain DNS Name: " $strDomainDNsName
Write-Host "AD Site: " $strSite
Write-Host "OU: " $strComputerOU
Write-Host "IP Addresses: " $strIPAddresses
Write-Host "Logical Processors: " $strLogicalProcessors
Write-Host "Physical Processors: " $strPhysicalProcessors
Write-Host "Host Server Name: " $strHostServerName
Write-Host "Virtual Machine Name: " $strVirtualMachineName

$oInstance = $oDiscovery.CreateClassInstance("$MPElement[Name='Windows!Microsoft.Windows.Computer']$");
AddClassProperty $oInstance "$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$" $ComputerIdentity
AddClassProperty $oInstance "$MPElement[Name='Windows!Microsoft.Windows.Computer']/NetbiosComputerName$" $strNetBIOSComputerName
AddClassProperty $oInstance "$MPElement[Name='Windows!Microsoft.Windows.Computer']/NetbiosDomainName$" $strNetBIOSDomain
AddClassProperty $oInstance "$MPElement[Name='Windows!Microsoft.Windows.Computer']/ForestDnsName$" $strForestDnsName
AddClassProperty $oInstance "$MPElement[Name='Windows!Microsoft.Windows.Computer']/DomainDnsName$" $strDomainDNsName
AddClassProperty $oInstance "$MPElement[Name='Windows!Microsoft.Windows.Computer']/ActiveDirectorySite$" $strSite
AddClassProperty $oInstance "$MPElement[Name='Windows!Microsoft.Windows.Computer']/OrganizationalUnit$" $strComputerOU
AddClassProperty $oInstance "$MPElement[Name='Windows!Microsoft.Windows.Computer']/IPAddress$" $strIPAddresses
AddClassProperty $oInstance "$MPElement[Name='Windows!Microsoft.Windows.Computer']/LogicalProcessors$" $strLogicalProcessors
AddClassProperty $oInstance "$MPElement[Name='Windows!Microsoft.Windows.Computer']/PhysicalProcessors$" $strPhysicalProcessors
AddClassProperty $oInstance "$MPElement[Name='Windows!Microsoft.Windows.Computer']/HostServerName$" $strHostServerName
AddClassProperty $oInstance "$MPElement[Name='Windows!Microsoft.Windows.Computer']/VirtualMachineName$" $strVirtualMachineName

$oDiscovery.AddInstance($oInstance);
$oDiscovery

</Script></ScriptBody>
<Parameters>
<Parameter>
<Name>SourceType</Name>
<Value>0</Value>
</Parameter>
<Parameter>
<Name>SourceId</Name>
<Value>$MPElement$</Value>
</Parameter>
<Parameter>
<Name>ManagedEntityId</Name>
<Value>$Target/Id$</Value>
</Parameter>
<Parameter>
<Name>ComputerIdentity</Name>
<Value>$Target/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Value>
</Parameter>
</Parameters>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
</DataSource>
</MemberModules>
<Composition>
<Node ID="DataSource"/>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.Discovery.Data</OutputType>
</DataSourceModuleType>