Undiscovery of improper Windows cluster objects [2016 and 1709+]

Microsoft.Windows.Server.10.0.Undiscovery.Improper.Cluster.Objects.Task (Task)

The task provides undiscovery of improper cluster entities (logical disks, CPUs, network adapters, disk partitions) for Agentless Managed virtual cluster computers (Cluster Instances and Cluster Groups) and Agent Managed cluster node computers.

Element properties:

TargetMicrosoft.SystemCenter.AllManagementServersPool
AccessibilityPublic
CategoryMaintenance
EnabledTrue
RemotableFalse
Timeout3600

Member Modules:

ID Module Type TypeId RunAs 
Undiscover WriteAction Microsoft.Windows.PowerShellWriteAction Microsoft.Windows.Server.10.0.RunAsUnDiscoveryProfile

Source Code:

<Task ID="Microsoft.Windows.Server.10.0.Undiscovery.Improper.Cluster.Objects.Task" Accessibility="Public" Enabled="true" Target="SC!Microsoft.SystemCenter.AllManagementServersPool" Timeout="3600" Remotable="true">
<Category>Maintenance</Category>
<WriteAction ID="Undiscover" TypeID="Windows!Microsoft.Windows.PowerShellWriteAction" RunAs="Microsoft.Windows.Server.10.0.RunAsUnDiscoveryProfile">
<ScriptName>UndiscoveryImProperClusterObjects.ps1</ScriptName>
<ScriptBody><Script>
Function Get-OmClass ($mg,[string]$ClassName)
{
if ($null -eq $mg -or $true -eq [string]::IsNullOrEmpty($ClassName))
{
return $null
}

$ErrorActionPreference = "SilentlyContinue"
$error.Clear()

$scriteria = "Name='$ClassName'"
$Criteria = New-Object Microsoft.EnterpriseManagement.Configuration.MonitoringClassCriteria($scriteria)

if (0 -ne $error.Count)
{
return $null
}

$EntityTypes = $mg.EntityTypes

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

$mtypes = $mg.EntityTypes.GetClasses($Criteria)

if (0 -ne $error.Count)
{
return $null
}

$result = $mtypes[0]

return $result
}
Function Get-OmClassById ($mg,[string]$ClassId)
{
if ($null -eq $mg -or $true -eq [string]::IsNullOrEmpty($ClassId))
{
return $null
}

$ErrorActionPreference = "SilentlyContinue"
$error.Clear()

$scriteria = "Id='$ClassId'"
$Criteria = New-Object Microsoft.EnterpriseManagement.Configuration.MonitoringClassCriteria($scriteria)

if (0 -ne $error.Count)
{
return $null
}

$EntityTypes = $mg.EntityTypes

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

$mtypes = $mg.EntityTypes.GetClasses($Criteria)

if (0 -ne $error.Count)
{
return $null
}

$result = $mtypes[0]

return $result
}

Function Get-OmDiscoveries($mg,[string]$TargetClassName)
{

$ErrorActionPreference = "SilentlyContinue"
$error.Clear()
$TargetClass = Get-OmClass -mg $mg -ClassName $TargetClassName
if($null -eq $TargetClass.Id)
{
return $null
}

$ClassId = $TargetClass.Id.ToString()
if ($true -eq [string]::IsNullOrEmpty($ClassId))
{
return $null
}

$error.Clear()
$StrCriteria = "Target='$ClassId'"
$criteria = New-Object Microsoft.EnterpriseManagement.Configuration.MonitoringDiscoveryCriteria($StrCriteria)

if (0 -ne $error.Count)
{
return $null
}

$error.Clear()
$result = $mg.GetMonitoringDiscoveries($criteria)

if (0 -ne $error.Count)
{
return $null
}

return $result
}

Function Get-DiscoveryObjectType($mg,$ObjectType,[HashTable]$types)
{
$TypeId = $ObjectType.TypeId.Id
if ($null -eq $TypeId -or $null -eq $mg)
{
return
}

$sTypeId = $TypeId.ToString()
$Class = Get-OmClassById -mg $mg -ClassId $sTypeId

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

if (-Not $types.ContainsKey($Class))
{
$types[$Class] = [string]::Empty
}

}

Function Get-OmDiscoveriesObjectTypes($mg,[string]$TargetClassName)
{
$result = @{}
$ErrorActionPreference = "SilentlyContinue"
$error.Clear()
$discoveries = Get-OmDiscoveries -mg $mg -TargetClassName $TargetClassName
if($null -eq $discoveries )
{
return $result
}

$error.Clear()
foreach($discovery in $discoveries)
{
foreach($ObjectType in $discovery.DiscoveryClassCollection)
{
Get-DiscoveryObjectType -mg $mg -ObjectType $ObjectType -types $result
}
}

return $result
}

Function Get-OmClusterComputerInstance($mg)
{
$ErrorActionPreference = "SilentlyContinue"
$error.Clear()

$ClassName = "Microsoft.Windows.Server.Computer"
$class = Get-OmClass -mg $mg -ClassName $ClassName

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

$error.Clear()
$query = "IsVirtualNode = 'true'"

$criteria = New-Object Microsoft.EnterpriseManagement.Monitoring.MonitoringObjectCriteria($query,$class)
if (0 -ne $error.Count)
{
return $null
}

$result = $mg.GetMonitoringObjects($criteria)

return $result
}

Function Get-RelatedObjects($ObjectColl,[HashTable]$MonObjects)
{

if ($null -eq $ObjectColl -or $null -eq $MonObjects )
{
return
}

foreach($object in $ObjectColl)
{
$MonObjects[$object] = [string]::Empty
}

return
}


Function Get-RelatedMonitoringObjects($monObject,[HashTable]$types,[HashTable]$relObjects)
{
$ErrorActionPreference = "SilentlyContinue"
$error.Clear()

if ($null -eq $monObject -or 0 -eq $types.Count -or $null -eq $relObjects)
{
return
}

foreach($class in $types.Keys)
{
$Objects = $monObject.GetRelatedMonitoringObjects($Class,[Microsoft.EnterpriseManagement.Common.TraversalDepth]::OneLevel)
Get-RelatedObjects -ObjectColl $Objects -MonObjects $relObjects
}

}

Function Get-ClusterImproperObjects($mg)
{
$ErrorActionPreference = "SilentlyContinue"
$error.Clear()

$result = @{}

$Target = "Microsoft.Windows.Server.10.0.OperatingSystem"
$Clusters = Get-OmClusterComputerInstance -mg $mg

if($null -eq $Clusters)
{
return $result
}

$ObjectTypes = Get-OmDiscoveriesObjectTypes -mg $mg -TargetClassName $Target
if($null -eq $ObjectTypes)
{
return $result
}

foreach($Cluster in $Clusters)
{
Get-RelatedMonitoringObjects -monObject $Cluster -types $ObjectTypes -relObjects $result
}

$Count = $result.Count

if (0 -ne $Count)
{
Write-Host "Improper windows 2016 cluster objects search ended."
Write-Host "Improper windows 2016 cluster objects: $Count"

}

return $result
}

Function Start-Undiscovery($mg)
{
$ErrorActionPreference = "SilentlyContinue"
$error.Clear()

Write-Host "Checking security permissions.."
$IsAdministrator = $false
$IsAdministrator = $mg.IsUserAdministrator()

if ($false -eq $IsAdministrator)
{
$message = "User doesn't have enough permission to perform undisovery."
Write-Host $message
return
}

$undiscovery = New-Object Microsoft.EnterpriseManagement.ConnectorFramework.IncrementalDiscoveryData

if ($null -eq $undiscovery -or $errror.Count -ne 0)
{
$message = "Cannot create undiscovery data item. " + $error[0]
Write-Host $message
return ;
}

Write-Host "Finding Improper cluster objects.."
$Objects = Get-ClusterImproperObjects -mg $mg


if (0 -eq $Objects.Count)
{
Write-Host "Improper windows 2016 cluster objects were not found."
return
}

Write-Host "Marking Improper windows 2016 cluster objects for removal.."
$error.Clear()
foreach ($Object in $Objects.Keys)
{
$undiscovery.Remove($Object)
}

if (0 -eq $error.Count)
{
Write-Host "Marking Improper windows 2016 cluster objects for removal finished successfully."
}
else
{
$Count = $Error.Count
Write-Host "Marking Improper windows 2016 cluster objects for removal finished with errors."
Write-Host " $Count Improper windows 2016 cluster objests are affected."
}

$error.Clear()
Write-Host "Trying to remove marked Improper windows 2016 cluster objects."

$undiscovery.Commit($mg)

if ($error.Count -ne 0)
{
$message = "Cannot commit undiscovery data. " + $error[0]
Write-Host $message
return
}
else
{
Write-Host "Successfully remove marked Improper windows 2016 cluster objects."
}

}

Function Load-SCOMAssemblies()
{
$ErrorActionPreference = "Stop"
$result = $true
$OpsMgrMainLib = "Microsoft.EnterpriseManagement.OperationsManager,Version=7.0.5000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
$ScomDiscoverySdk = "Microsoft.EnterpriseManagement.Core,Version=7.0.5000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

try
{
[void][Reflection.Assembly]::Load($OpsMgrMainLib)
[void][Reflection.Assembly]::Load($ScomDiscoverySdk)
}
catch
{
$result = $false
}

return $result
}

Function Start-FullUndiscovery
{
$ErrorActionPreference = "SilentlyContinue"
$error.Clear()
Write-Host "Connecting to Management Group.."

$mg = New-Object Microsoft.EnterpriseManagement.ManagementGroup("localhost")
if ($Null -eq $mg -or 0 -ne $error.Count)
{
$message = "Cannot connect to Management Group. " + $error[0]
Write-Host $message
return
}

Start-Undiscovery -mg $mg
}

Function Main
{
$message = "Starting Undiscovery of Improper windows 2016 cluster objects..."
Write-Host $message
Write-Host "Loading SCOM SDK Libraries.."

$result = Load-SCOMAssemblies
if ($true -eq $result)
{
Start-FullUndiscovery
}
else
{
$message = "Cannot Load SCOM SDK Libraries."

}
}

Main</Script></ScriptBody>
<TimeoutSeconds>3600</TimeoutSeconds>
</WriteAction>
</Task>