Windows Physical Disk Discovery

Microsoft.Windows.Server.10.0.PhysicalDiskDiscovery.ModuleType (DataSourceModuleType)

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityInternal
RunAsSystem.PrivilegedMonitoringAccount
OutputTypeSystem.Discovery.Data

Member Modules:

ID Module Type TypeId RunAs 
Scheduler DataSource System.Discovery.Scheduler Default
ScriptProbe ProbeAction Microsoft.Windows.Server.10.0.PowerShellDiscoveryProbe Default

Overrideable Parameters:

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

Source Code:

<DataSourceModuleType ID="Microsoft.Windows.Server.10.0.PhysicalDiskDiscovery.ModuleType" RunAs="System!System.PrivilegedMonitoringAccount" Accessibility="Internal">
<Configuration>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ComputerName" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ComputerID" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="IntervalSeconds" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="TimeoutSeconds" type="xsd:int"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int"/>
<OverrideableParameter ID="TimeoutSeconds" ParameterType="int" Selector="$Config/TimeoutSeconds$"/>
</OverrideableParameters>
<ModuleImplementation>
<Composite>
<MemberModules>
<DataSource ID="Scheduler" TypeID="System!System.Discovery.Scheduler">
<Scheduler>
<SimpleReccuringSchedule>
<Interval Unit="Seconds">$Config/IntervalSeconds$</Interval>
</SimpleReccuringSchedule>
<ExcludeDates/>
</Scheduler>
</DataSource>
<ProbeAction ID="ScriptProbe" TypeID="Microsoft.Windows.Server.10.0.PowerShellDiscoveryProbe">
<ScriptName>Microsoft.Windows.Server.DiscoverWindows.10.0.PhysicalDisks.ps1</ScriptName>
<PSparam>param ($SourceID, $ManagedEntityId, $TargetComputer, $TargetComputerID)</PSparam>
<ScriptBody><Script>Function Add-LogicalDiskToPartition([string]$PartitionId,[string]$LogicalDiskPerfId,[HashTable]$PartToLogicalDisk)
{
if ([string]::IsNullOrEmpty($PartitionId) -or [string]::IsNullOrEmpty($LogicalDiskPerfId) )
{
return
}

$PartToLogicalDisk[$PartitionId] = $LogicalDiskPerfId
}

Function Add-DiskToPartition([string]$PartitionId,[string]$DiskId,[HashTable]$DiskToPartition)
{

if ([string]::IsNullOrEmpty($PartitionId) -or [string]::IsNullOrEmpty($DiskId) -or $null -eq $DiskToPartition)
{
return
}

$Partitions = $DiskToPartition[$DiskId]

if ($null -eq $Partitions)
{
$Partitions = @()
}

$Partitions += $PartitionId

$DiskToPartition[$DiskId] = $Partitions
}

Function Get-PerfInstancePostFix($oSet,[HashTable]$PartToLogicalDisk,[bool]$IsSet = $true)
{
$PerfPostFix = [string]::Empty
$iCount = $oSet.Count

if (0 -eq $iCount -or $null -eq $oSet)
{
return $PerfPostFix
}

if ($null -eq $iCount)
{
$iCount = 1
}

$PerfInstance = @(1..$iCount)
$Index = 0

foreach ($owObj in $oSet)
{
if ($true -eq $IsSet)
{
$PartitionId = $owObj.DeviceID
}
else
{
$PartitionId = $owObj
}

if ([string]::IsNullOrEmpty($PartitionId))
{
continue
}
$PerfPostFix = $PartToLogicalDisk[$PartitionId]
if($null -ne $PerfPostFix)
{
$PerfInstance[$Index] = $PerfPostFix
$Index++
}

}

if (0 -ne $Index)
{
for ($i = $Index;$i -lt $iCount; $i++)
{
$PerfInstance[$i] = [string]::Empty
}

$PerfPostFix = [string]::Join(" ",$PerfInstance).Trim(" ")
}

return $PerfPostFix
}

Function Get-PartitionToLogicalDiskTable($sTargetComputer)
{
$PartToLogicalDisk = @{}
$oWMISet= WMIGetInstanceNoAbort $sTargetComputer "root\cimv2" $WMI_Partition_To_LogicalDisk

foreach ($owObj in $oWMISet)
{
$PartitionId = $owObj.Antecedent.DeviceId
$LogicalDiskPerfId = $owObj.Dependent.DeviceId

Add-LogicalDiskToPartition -PartitionId $PartitionId -LogicalDiskPerfId $LogicalDiskPerfId -PartToLogicalDisk $PartToLogicalDisk

}

return $PartToLogicalDisk
}

Function Get-DiskToPartitionTable($sTargetComputer)
{

$DiskToPartition = @{}
$oWMISet= WMIGetInstanceNoAbort $sTargetComputer "root\cimv2" $WMI_DISk_To_Partition

foreach ($owObj in $oWMISet)
{
$DiskId = $owObj.Antecedent.DeviceId
$PartitionId = $owObj.Dependent.DeviceId

Add-DiskToPartition -PartitionId $PartitionId -DiskId $DiskId -DiskToPartition $DiskToPartition

}

return $DiskToPartition
}

Function Get-DiskToPartitionPerfInstance($sTargetComputer)
{

$DiskToPerfInstance = @{}
$PartToLogicalDisk = Get-PartitionToLogicalDiskTable -sTargetComputer $sTargetComputer
$DiskToPartitionTable = Get-DiskToPartitionTable -sTargetComputer $sTargetComputer
foreach ($DiskId in $DiskToPartitionTable.Keys)
{
$sPerfInstance = [string]::Empty
$oSet = $DiskToPartitionTable[$DiskId]

$PerfInstancePostfix = Get-PerfInstancePostFix -oSet $oSet -PartToLogicalDisk $PartToLogicalDisk -IsSet $false

if (-Not [string]::IsNullOrEmpty($PerfInstancePostfix))
{
$sPerfInstance += $PerfInstancePostfix
}

$DiskToPerfInstance[$DiskId] = $sPerfInstance
}

return $DiskToPerfInstance
}

Function Get-LogicalDiskSerialNmber([string]$TargetComputer,[string]$LogicalDiskId)
{
if ([string]::IsNullOrEmpty($LogicalDiskId) )
{
return [string]::Empty
}

$Query = "Select VolumeSerialNumber From Win32_LogicalDisk Where DeviceID='$LogicalDiskId'"
$oInstances = WMIExecQueryNoAbort $sTargetComputer "root\cimv2" $Query

$SerialNumber = [string]::Empty
if (0 -ne $oInstances.Count )
{
$SerialNumber = $oInstances[0].VolumeSerialNumber
if($null -eq $SerialNumber)
{
$SerialNumber = [string]::Empty
}
}

return $SerialNumber
}

Function GetHddPerfmonInstance
{
param ( [string]$DriveId, [string]$Index,[HashTable]$DiskPerfInstance)

$sPerfInstance = "$Index "

$PerfInstancePostfix = $DiskPerfInstance[$DriveId]
if (-Not [string]::IsNullOrEmpty($PerfInstancePostfix))
{
$sPerfInstance += $PerfInstancePostfix
}

return $sPerfInstance
}

#Copyright (c) Microsoft Corporation. All rights reserved.
#Include DiskLibrary First
# Parameters that should be passed to this script
# 0 MPElement ID ($MPElement$)
# 1 Target Id for ME this rule is running against ($Target/Id$)
# 2 Computer (FQDN) that the CPU will be hosted on
# 3 Computer ID (Key) that the CPU will be hosted on

Function Main()
{
$oDiscoveryData = $momAPI.CreateDiscoveryData(0, $SourceID, $ManagedEntityId)

if ((DoDiscovery $TargetComputer $TargetComputerID $oDiscoveryData) -ne 0)
{
$oDiscoveryData = $momAPI.CreateDiscoveryData(0, $SourceID, $ManagedEntityId)
$oDiscoveryData.IsSnapshot = $false
}

$oDiscoveryData
}

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

$WMISet = WMIGetInstance $sTargetComputer "root\cimv2" "Win32_DiskDrive"
$ErrorActionPreference = "SilentlyContinue"
$error.Clear()
$DiskPerfInstance = Get-DiskToPartitionPerfInstance -sTargetComputer "."
if(0 -ne $error.Count -or $null -eq $DiskPerfInstance)
{
return 1
}

$errorCount = 0
foreach ($owObj in $WMISet)
{
$DeviceId = $owObj.DeviceId
$Index = $owObj.Index

if ([string]::IsNullOrEmpty($DeviceId) -or [string]::IsNullOrEmpty($Index))
{
continue
}

$PerfInstance = GetHddPerfmonInstance -DriveId $DeviceId -Index $Index -DiskPerfInstance $DiskPerfInstance
$Model = $owObj.Model
$Manufacturer = Get-HddManufacturer -Model $Model -sManufacturer $owObj.Manufacturer
$Model = Get-StringProperty -Property $Model
$Manufacturer = Get-StringProperty -Property $Manufacturer

$oInstance = $oDisc.CreateClassInstance("$MPElement[Name='Microsoft.Windows.Server.10.0.PhysicalDisk']$")
$oInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $sTargetComputerID)
$oInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.LogicalDevice']/DeviceID$", $DeviceId)
$oInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.LogicalDevice']/Name$", $owObj.Name)
$oInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.LogicalDevice']/Description$", $owObj.Description)
$oInstance.AddProperty("$MPElement[Name='WindowsServer!Microsoft.Windows.Server.PhysicalDisk']/Caption$", $owObj.Caption)
$oInstance.AddProperty("$MPElement[Name='WindowsServer!Microsoft.Windows.Server.PhysicalDisk']/Index$", $Index)
$oInstance.AddProperty("$MPElement[Name='WindowsServer!Microsoft.Windows.Server.PhysicalDisk']/InterfaceType$", $owObj.InterfaceType)
$oInstance.AddProperty("$MPElement[Name='WindowsServer!Microsoft.Windows.Server.PhysicalDisk']/Manufacturer$", $Manufacturer)
$oInstance.AddProperty("$MPElement[Name='WindowsServer!Microsoft.Windows.Server.PhysicalDisk']/Model$",$Model )
$oInstance.AddProperty("$MPElement[Name='WindowsServer!Microsoft.Windows.Server.PhysicalDisk']/SCSIBus$", $owObj.SCSIBus)
$oInstance.AddProperty("$MPElement[Name='WindowsServer!Microsoft.Windows.Server.PhysicalDisk']/SCSILogicalUnit$", $owObj.SCSILogicalUnit)
$oInstance.AddProperty("$MPElement[Name='WindowsServer!Microsoft.Windows.Server.PhysicalDisk']/SCSIPort$", $owObj.SCSIPort)
$oInstance.AddProperty("$MPElement[Name='WindowsServer!Microsoft.Windows.Server.PhysicalDisk']/SCSITargetID$", $owObj.SCSITargetID)
$oInstance.AddProperty("$MPElement[Name='WindowsServer!Microsoft.Windows.Server.PhysicalDisk']/Size$", $owObj.Size)
$oInstance.AddProperty("$MPElement[Name='WindowsServer!Microsoft.Windows.Server.PhysicalDisk']/TotalCylinders$", $owObj.TotalCylinders)
$oInstance.AddProperty("$MPElement[Name='WindowsServer!Microsoft.Windows.Server.PhysicalDisk']/TotalHeads$", $owObj.TotalHeads)
$oInstance.AddProperty("$MPElement[Name='WindowsServer!Microsoft.Windows.Server.PhysicalDisk']/TotalSectors$", $owObj.TotalSectors)
$oInstance.AddProperty("$MPElement[Name='WindowsServer!Microsoft.Windows.Server.PhysicalDisk']/TotalTracks$", $owObj.TotalTracks)
$oInstance.AddProperty("$MPElement[Name='WindowsServer!Microsoft.Windows.Server.PhysicalDisk']/TracksPerCylinder$", $owObj.TracksPerCylinder)
$oInstance.AddProperty("$MPElement[Name='WindowsServer!Microsoft.Windows.Server.PhysicalDisk']/PerfmonInstance$", $PerfInstance)
$oInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", "Disk " + $owObj.Index)

if (0 -eq $error.Count)
{
$oDisc.AddInstance($oInstance)
}

$errorCount += $error.Count
$error.Clear()
}

return $errorCount
}

Function Get-HddManufacturer ([string]$Model,[string]$sManufacturer)
{
$Manufacturer = [string]::Empty
if([string]::IsNullOrEmpty($Model))
{
return $Manufacturer
}

$HModel = $Model.Trim(" ")

$Manufacturer = Get-HddManuFacturerByCode -Model $HModel

if([string]::IsNullOrEmpty($Manufacturer) )
{
$SpaceIndex = $HModel.IndexOf(" ")

if (-1 -ne $SpaceIndex)
{
$Manufacturer = $HModel.Substring(0,$SpaceIndex)
}
else
{
$Manufacturer = [string]::Empty
}
}

if([string]::IsNullOrEmpty($Manufacturer) )
{
$Manufacturer = $sManufacturer
}

return $Manufacturer
}

Function Get-HddManuFacturerByCode([string]$Model)
{
$Manufacturer = [string]::Empty
if([string]::IsNullOrEmpty($Model))
{
return $Manufacturer
}

if ($Model.Length -lt 2)
{
return $Manufacturer
}

$M2Prefix = $Model.Substring(0,2)

$Vendors2Prefix = @{
"HT" = "Hitachi";"HM" = "Hitachi";"IC" = "Hitachi";"DK" = "Hitachi";"DJ" = "Hitachi";"ST" = "Seagate";"WD" = "Western Digital";
"HE" = "Samsung";"MQ" = "Toshiba";"MG" = "Toshiba";"MK" = "Toshiba";"MD" = "Toshiba";"MC" = "Toshiba";"PX" = "Toshiba";"AL" = "Toshiba";"PT" = "Patriot";

}

$Vendors3Prefix = @{
"HUS" = "Hitachi";"HUA" = "Hitachi";"HUH" = "Hitachi";"HMH" = "Hitachi";"HTS" = "Hitachi";"HDP" = "Hitachi";"HDS" = "Hitachi";
"HDT" = "Hitachi";"HCS" = "Hitachi";"HCP" = "Hitachi";"HCC" = "Hitachi";"HEN" = "Hitachi";"HEJ" = "Hitachi";"OCZ" = "OCZ Technology"
}

$Vendors4Prefix = @{
"DYSA" = "Hitachi";"DARA" = "Hitachi";"DCXA" = "Hitachi";"DCYA" = "Hitachi";"DTLA" = "Hitachi";"DPTA" = "Hitachi";"DJNA" = "Hitachi";"DTTA" = "Hitachi";"DDYS" = "Hitachi";"DPSS" = "Hitachi";
"DRHS" = "Hitachi";"DMVS" = "Hitachi";"DGHS" = "Hitachi";"DRVS" = "Hitachi";"DDRS" = "Hitachi";"DGVS" = "Hitachi"; "DT01" = "Toshiba"

}

$ML = $Vendors2Prefix[$M2Prefix]
if ($null -eq $ML -or "HE" -eq $M2Prefix)
{
if ($Model.Length -gt 2)
{
$M3Prefix = $Model.Substring(0,3)
$ML = $Vendors3Prefix[$M3Prefix]
if ($null -eq $ML -and $Model.Length -gt 3)
{
$M4Prefix = $Model.Substring(0,4)
$ML = $Vendors4Prefix[$M4Prefix]

}
}
}

if( $null -ne $ML)
{
$Manufacturer = $ML
}

return $Manufacturer
}

Main




</Script></ScriptBody>
<Parameters>
<Parameter>
<Name>SourceID</Name>
<Value>$MPElement$</Value>
</Parameter>
<Parameter>
<Name>ManagedEntityId</Name>
<Value>$Target/Id$</Value>
</Parameter>
<Parameter>
<Name>TargetComputer</Name>
<Value>$Config/ComputerName$</Value>
</Parameter>
<Parameter>
<Name>TargetComputerID</Name>
<Value>$Config/ComputerID$</Value>
</Parameter>
</Parameters>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
</ProbeAction>
</MemberModules>
<Composition>
<Node ID="ScriptProbe">
<Node ID="Scheduler"/>
</Node>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.Discovery.Data</OutputType>
</DataSourceModuleType>