Undiscovery of legacy cluster objects for Nano Server

Microsoft.Windows.Server.ClusterSharedVolumeMonitoring.VirtualServer.NanoServer.LegacyObjects.UnDiscovery.Task (Task)

The task provides undiscovery of instances belonging to legacy cluster classes hosted on the cluster virtual server representing the cluster on Nano Server.

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.ClusterDisksMonitoring.RunAsUnDiscoveryProfile

Source Code:

<Task ID="Microsoft.Windows.Server.ClusterSharedVolumeMonitoring.VirtualServer.NanoServer.LegacyObjects.UnDiscovery.Task" Accessibility="Public" Enabled="true" Target="SCLibrary!Microsoft.SystemCenter.AllManagementServersPool" Timeout="3600" Remotable="true">
<Category>Maintenance</Category>
<WriteAction ID="Undiscover" TypeID="Windows!Microsoft.Windows.PowerShellWriteAction" RunAs="Microsoft.Windows.Server.ClusterDisksMonitoring.RunAsUnDiscoveryProfile">
<ScriptName>UndiscoveryClusterNano.ps1</ScriptName>
<ScriptBody><Script>$objMomScriptAPI = New-Object -ComObject Mom.ScriptAPI -ErrorAction SilentlyContinue

#Event constants
$EVENT_TYPE_SUCCESS = 0
$EVENT_TYPE_ERROR = 1
$EVENT_TYPE_WARNING = 2
$EVENT_TYPE_INFORMATION = 4

$EVENT_ID_SUCCESS = 1001 #Use IDs in the range 1 - 1000
$EVENT_ID_SCRIPTERROR = 999 #Then you can use eventcreate.exe to test the MP
$SCRIPT_NAME = "UndiscoveryNanoObjectScript"

Function LogScriptEvent($EVENTID = $EVENT_ID_SUCCESS , $EVENTYPE=$EVENT_TYPE_INFORMATION , $Message)
{
if ($null -eq $objMomScriptAPI)
{
return
}

$objMomScriptAPI.LogScriptEvent($SCRIPT_NAME, $EVENTID, $EVENTYPE, $Message)

}

Function Get-OmManagementGroup([bool]$IsPowerShell = $true)
{
$ErrorActionPreference = "SilentlyContinue"

if($true -eq $IsPowerShell)
{
$mg = Get-SCOMManagementGroup -ComputerName localhost
}
else
{
$message = "Connecting to SCOM Management Group.."
Write-Host $message
$mg = New-Object Microsoft.EnterpriseManagement.ManagementGroup("localhost")
}

return $mg
}


Function Remove-OldNanoData([bool]$IsPowerShell = $true)
{
$ErrorActionPreference = "SilentlyContinue"
$error.Clear()

$mg = Get-OmManagementGroup -IsPowerShell $IsPowerShell
if ($null -eq $mg -or $error.Count -ne 0)
{
$message = "Cannot connect to SCOM Management Group. " + $error[0]
LogScriptEvent -EVENTID $EVENT_ID_SCRIPTERROR -EVENTYPE $EVENT_TYPE_ERROR -Message $message
Write-Host $message
return
}

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

if ($null -eq $undiscovery -or $errror.Count -ne 0)
{
$message = "Cannot create undiscovery object. " + $error[0]
LogScriptEvent -EVENTID $EVENT_ID_SCRIPTERROR -EVENTYPE $EVENT_TYPE_ERROR -Message $message
Write-Host $message
return ;
}

$IsAdministrator = $false
$IsAdministrator = $mg.IsUserAdministrator()

if ($false -eq $IsAdministrator)
{
$message = "User doesn't have enough permission to perform undisovery old objects"
LogScriptEvent -EVENTID $EVENT_ID_SCRIPTERROR -EVENTYPE $EVENT_TYPE_ERROR -Message $message
Write-Host $message
return
}

$error.Clear()

$CSVSeedClassName = "Microsoft.Windows.Server.ClusterSharedVolumeMonitoring.Cluster"
$CSVClassName = "Microsoft.Windows.Server.ClusterSharedVolumeMonitoring.ClusterSharedVolume"
$ClusterDiskClassName = "Microsoft.Windows.Server.ClusterDisksMonitoring.ClusterDisk"

$NanoCSVSeedClassName = "Microsoft.Windows.Server.ClusterSharedVolumeMonitoring.Cluster.NewOS"
$NanoCSVClassName = "Microsoft.Windows.Server.ClusterSharedVolumeMonitoring.ClusterSharedVolume.NewOS"
$NanoClusterDiskClassName = "Microsoft.Windows.Server.ClusterDisksMonitoring.ClusterDisk.NewOS"

$message = "Finding duplicated Nano Server cluster objects.."
Write-Host $message
if ($true -eq $IsPowerShell)
{
$NanoSeeds = Get-ScomObjectsHashTable -ScomObjects (Get-ScomObject -ClassName $NanoCSVSeedClassName)
$NaNoCSV = Get-ScomObjectsHashTable -ScomObjects (Get-ScomObject -ClassName $NanoCSVClassName) -IsCSV $true
$NanoClusterDisks = Get-ScomObjectsHashTable -ScomObjects (Get-ScomObject -ClassName $NanoClusterDiskClassName)

$CSVobjects = Get-ScomObjectsHashTable -ScomObjects (Get-ScomObject -ClassName $CSVClassName) -IsCSV $true
$CsvSeeds = Get-ScomObjectsHashTable -ScomObjects (Get-ScomObject -ClassName $CSVSeedClassName )
$ClusterDisks = Get-ScomObjectsHashTable -ScomObjects (Get-ScomObject -ClassName $ClusterDiskClassName)

}
else
{
$NanoSeeds = Get-ScomObjectsHashTable -ScomObjects (Get-OmClassInstance -ClassName $NanoCSVSeedClassName -mg $mg)
$NaNoCSV = Get-ScomObjectsHashTable -ScomObjects (Get-OmClassInstance -ClassName $NanoCSVClassName -mg $mg) -IsCSV $true
$NanoClusterDisks = Get-ScomObjectsHashTable -ScomObjects (Get-OmClassInstance -ClassName $NanoClusterDiskClassName -mg $mg)

$CSVobjects = Get-ScomObjectsHashTable -ScomObjects (Get-OmClassInstance -ClassName $CSVClassName -mg $mg) -IsCSV $true
$CsvSeeds = Get-ScomObjectsHashTable -ScomObjects (Get-OmClassInstance -ClassName $CSVSeedClassName -mg $mg)
$ClusterDisks = Get-ScomObjectsHashTable -ScomObjects (Get-OmClassInstance -ClassName $ClusterDiskClassName -mg $mg)

}

$IsDuplicateFound = -Not ((0 -eq $NanoSeeds.Count -or $null -eq $NanoSeeds) -and (0 -eq $NaNoCSV.Count -or $null -eq $NaNoCSV ) -and (0 -eq $NanoClusterDisks.Count -or $null -eq $NanoClusterDisks))
$IsDuplicateFound = $IsDuplicateFound -and (-Not ((0 -eq $CSVobjects.Count -or $null -eq $CSVobjects) -and (0 -eq $CsvSeeds.Count -or $null -eq $CsvSeeds) -and (0 -eq $ClusterDisks.Count -or $null -eq $ClusterDisks) ) )

if ($true -eq $IsDuplicateFound)
{
$message = "Marking duplicated Nano Server cluster objects for removal.."
Write-Host $message

Start-UndiscoveryOldObjects -OldObjects $CsvSeeds -NanoObjects $NanoSeeds -undiscovery $undiscovery
Start-UndiscoveryOldObjects -OldObjects $ClusterDisks -NanoObjects $NanoClusterDisks -undiscovery $undiscovery
Start-UndiscoveryOldObjects -OldObjects $CSVobjects -NanoObjects $NaNoCSV -undiscovery $undiscovery

$error.Clear()
$message = "Removing duplicated Nano Server cluster objects.."
Write-Host $message

$undiscovery.Commit($mg)

if ($error.Count -ne 0)
{
$message = "Cannot commit undiscovery data. " + $error[0]
LogScriptEvent -EVENTID $EVENT_ID_SCRIPTERROR -EVENTYPE $EVENT_TYPE_ERROR -Message $message
Write-Host $message
return
}
else
{
$message = "Undiscovery finished successfully."
Write-Host $message

}
}
else
{
$message = "Duplicated Nano Server cluster objects were not found."
Write-Host $message
}


}


Function Start-UndiscoveryOldObjects([HashTable]$OldObjects,[HashTable]$NanoObjects,$undiscovery)
{
if ($null -eq $undiscovery)
{
return
}

if ($NanoObjects.Count -eq 0 -or $null -eq $NanoObjects)
{
$message = "Nano objects not found."
LogScriptEvent -Message $message


return
}

if ($OldObjects.Count -eq 0 -or $null -eq $OldObjects)
{
$message = "Legacy Nano object not found."
LogScriptEvent -Message $message

return
}

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

foreach ($NanoKey in $NanoObjects.Keys)
{
if ($true -eq $OldObjects.ContainsKey($NanoKey) -and $NanoKey.Length -gt 1)
{

$oldObject = $OldObjects[$NanoKey]
foreach($obj in $oldObject)
{
$key = $obj.Path + "-" + $obj.Name
$undiscovery.Remove($obj)
}
}
}


}

Function Get-ScomObject([string]$ClassName)
{
$ErrorActionPreference = "SilentlyContinue"
$error.Clear()

$result = $null

if ([string]::IsNullOrEmpty($ClassName))
{
return $result
}

$Class = Get-SCOMClass -Name $ClassName

if($null -ne $Class)
{
$result = Get-SCOMClassInstance -Class $Class
}


return $result
}

Function Get-ScomObjectsHashTable($ScomObjects,[bool]$IsCSV =$false)
{
$ErrorActionPreference = "SilentlyContinue"
$error.Clear()
$hashtbl = @{}

if ($null -eq $ScomObjects)
{
return $hashtbl
}


if($false -eq $IsCSV)
{
foreach ($obj in $ScomObjects)
{
$key = $obj.Path + "-" + $obj.Name
$hashtbl[$key] = $obj
}
}
else
{
foreach ($obj in $ScomObjects)
{
$key = $obj.Path
if ($false -eq $hashtbl.ContainsKey($key))
{
$objs = @()

}
else
{
$objs = $hashtbl[$key]

}

$objs += $obj
$hashtbl[$key] = $objs
}
}


return $hashtbl
}

Function Load-SCOModule
{
$ErrorActionPreference = "SilentlyContinue"
$result = $true
$omModule = get-module -name "OperationsManager"
$error.Clear()

if ($omModule -eq $null)
{
$SCOMPowerShellKey = "HKLM:\SOFTWARE\Microsoft\System Center Operations Manager\12\Setup\Powershell\V2"
$SCOMModulePath = (Get-ItemProperty $SCOMPowerShellKey).InstallDirectory
if ($true -eq [string]::IsNullOrEmpty($SCOMModulePath))
{
return $false
}

$SCOMModulePath = Join-Path $SCOMModulePath "OperationsManager"
$error.Clear()

Import-module $SCOMModulePath | Out-Null

$result = 0 -eq $error.Count
}

return $result

}


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-OmClassInstance($mg,[string]$ClassName)
{
$Class = Get-OmClass -mg $mg -ClassName $ClassName

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

$ErrorActionPreference = "SilentlyContinue"
$error.Clear()
$query = "Id like '%'"

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

$result = $mg.GetMonitoringObjects($criteria)

return $result
}

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
{
[Reflection.Assembly]::Load($OpsMgrMainLib)
[Reflection.Assembly]::Load($ScomDiscoverySdk)
}
catch
{
$result = $false
}

return $result
}

Function Main
{
$message = "Starting undiscovery of duplicated Nano Server Cluster Object.. "
LogScriptEvent -Message $message
Write-Host $message
$result = Load-SCOModule
if ($true -eq $result)
{
$message = "Using PowerShell Undiscovery Method"
LogScriptEvent -Message $message
$error.Clear()
$message = "Connecting to SCOM Management Group.."
Write-Host $message
New-SCManagementGroupConnection -ComputerName "localhost"
if (0 -eq $error.Count)
{
Remove-OldNanoData
}
else
{
$message = "Cannot connect to Management Group. " + $error[0]
LogScriptEvent -EVENTID $EVENT_ID_SCRIPTERROR -EVENTYPE $EVENT_TYPE_ERROR -Message $message
Write-Host $message
}

}
else
{
$message ="Loading SCOM SDK Libraries.."
Write-Host $message
$result = Load-SCOMAssemblies
if ($true -eq $result)
{
Remove-OldNanoData -IsPowerShell $false
}
else
{
$message = "Cannot load SCOM SDK Libraries. Undiscoveries failed."
Write-Host $message
}
}
}

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