Delete orphaned Fujitsu iRMC Device instances Write Action Type

Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.DeleteOrphanedDevices.WA (WriteActionModuleType)

Element properties:

TypeWriteActionModuleType
IsolationAny
AccessibilityInternal
RunAsDefault
InputTypeSystem.BaseData

Member Modules:

ID Module Type TypeId RunAs 
Script.CleanupOrphanedDevices WriteAction Microsoft.Windows.PowerShellWriteAction Default

Source Code:

<WriteActionModuleType ID="Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.DeleteOrphanedDevices.WA" Accessibility="Internal" Batching="false">
<Configuration/>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<WriteAction ID="Script.CleanupOrphanedDevices" TypeID="Windows!Microsoft.Windows.PowerShellWriteAction">
<ScriptName>DeleteOrphanedDevices.ps1</ScriptName>
<ScriptBody><Script>
##################################################################################
# #
# NOTICE #
# #
# COPYRIGHT 2015 - 2018 FUJITSU LIMITED #
# ALL RIGHTS RESERVED #
# #
# This computer program is CONFIDENTIAL and contains TRADE SECRETS of #
# FUJITSU LIMITED. The receipt or possession of this program does #
# not convey any rights to reproduce or disclose its contents, or to #
# manufacture, use, or sell anything that it may describe, in whole or #
# in part, without the specific written consent of FUJITSU LIMITED. #
# Any reproduction of this program without the express written consent #
# of FUJITSU LIMITED is a violation of the copyright laws and may #
# subject you to civil liability and criminal prosecution. #
# #
##################################################################################

$ScriptApi = New-Object -comObject "MOM.ScriptAPI"
if ($ScriptApi -eq $Null) { Exit -1 }

# set CONSTANT variables (can not be changed):
set-variable -name PoShScriptName -value "iRMCCleanup.ps1" -option constant

$global:scriptMG = "."
$global:scriptWorkflow = "Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.CleanupOrphanedDevices.Rule"
$global:scriptInstanceName = "$Target/Property[Type='System!System.Entity']/DisplayName$"
$global:scriptInstanceId = "$Target/Id$"

$script:ErrorActionPreference = "SilentlyContinue"
trap
{
LogWorkflowEvent $WARNING_LEVEL 19031 ("Fujitsu iRMC Device Cleanup - Exception: $($_.Exception.Message)")
throw $_.Exception.Message
}

$OMPSInstallKey = "HKLM:\Software\Microsoft\System Center Operations Manager\12\Setup\Powershell\V2"
$regKey = Get-Item $OMPSInstallKey
$OMPSInstallPath = $regKey.GetValue("InstallDirectory")
$omModule = $OMPSInstallPath + "OperationsManager"
Import-Module -Name $omModule
# Start-Sleep -s 20

$computerName = $env:ComputerName + "." + $env:FQDN
$mg = New-Object -TypeName "Microsoft.EnterpriseManagement.ManagementGroup" -ArgumentList @($computerName)
$global:scriptMG = $mg.Name

Function Main {
Set-CurrentManagementPackVersion -MpName "Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC"

$relationshipCriteria = New-Object -TypeName "Microsoft.EnterpriseManagement.Configuration.ManagementPackRelationshipCriteria" -ArgumentList @("Name='Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.WindowsComputer.Contains.iRMC'")
$relationshipClass = $mg.GetMonitoringRelationshipClasses($relationshipCriteria)[0]

$ConnectorGuid = New-Object Guid("477B1F89-BCF1-4BBB-A868-A7AB718248B5");
try {
$Connector = $mg.ConnectorFramework.GetConnector($ConnectorGuid)
} catch {
LogScriptEvent -EventLevel $INFO_LEVEL -EventNumber 12345 -Message "$($PoShScriptName) - Connector not yet created (no templates created), nothing to do..."
Exit
}

$discoveryData = New-Object -TypeName "Microsoft.EnterpriseManagement.ConnectorFramework.IncrementalDiscoveryData"

$DeviceClassCriteria = New-Object Microsoft.EnterpriseManagement.Configuration.ManagementPackClassCriteria("Name='Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice'")
$DeviceClass = $mg.EntityTypes.GetClasses($DeviceClassCriteria)[0]
$DevicesRemoved = 0

if ($DeviceClass) {

$TemplateProperty = $DeviceClass["TemplateID"]
$IpProperty = $DeviceClass["IP"]

$GetObjectReaderMethod = [Microsoft.EnterpriseManagement.IEntityObjectsManagement].GetMethod("GetObjectReader", [Type[]]@([Microsoft.EnterpriseManagement.Configuration.ManagementPackClass],[Microsoft.EnterpriseManagement.Common.ObjectQueryOptions]))
$GetObjectReaderGenericMethod = $GetObjectReaderMethod.MakeGenericMethod([Microsoft.EnterpriseManagement.Monitoring.MonitoringObject])
$Devices = $GetObjectReaderGenericMethod.Invoke($mg.EntityObjects, @($DeviceClass, [Microsoft.EnterpriseManagement.Common.ObjectQueryOptions]::Default))

foreach ($Device in $Devices) {

if($Device -eq $null) { continue }

$TemplateId = $Device[$TemplateProperty].Value
$IP = $Device[$IpProperty].Value

PrepareLogging -Section $SectioniRMCDiscovery -HostTag $TagHostsDiscovery -ServerName $IP -MpName "Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC"
DebugOut "$IP - iRMC Check for Orphaned Devices: start"

$DeviceGroupCriteria = new-object Microsoft.EnterpriseManagement.Configuration.ManagementPackClassCriteria("Name='Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC." + $TemplateId + ".DeviceGroup'")
$DeviceGroupClasses = $mg.EntityTypes.GetClasses($DeviceGroupCriteria)

# DebugOut "$IP - TemplateId=$($TemplateId) GroupClassCount=$($DeviceGroupClasses.Count)"

if(($DeviceGroupClasses -eq $Null) -or ($DeviceGroupClasses.Count -ne 1)) {

DebugOut "$IP - TemplateId=$($TemplateId) is deleted, removing $($IP) from SCOM"

# Update Windows Computer Properties from optional Relationship (Note: located in extra MP)
if ($relationshipClass) {
$relationships = $mg.GetMonitoringRelationshipObjects($relationshipClass)
foreach($r in $relationships) {

if($r -eq $null) { continue }

if($r.TargetObject.Id -eq $Device.Id) {
DebugOut "$IP - Found my '$($r.SourceObject.DisplayName)' to '$($r.TargetObject.DisplayName)' Relationship Instance."

$properties = $r.SourceObject.GetProperties()
$propertiesChanged = 0
foreach($p in $properties) {
if($p.Name -eq "iRMCAvailable") {
DebugOut "$IP - Set Property '$($p.Name)' to '$($False)' of Windows Computer with iRMC '$($r.SourceObject.DisplayName)'."
$r.SourceObject[$p].Value = $False
$propertiesChanged++
}
if($p.Name -eq "iRMCDeviceState") {
DebugOut "$IP - Set Property '$($p.Name)' to 'N/A' of Windows Computer with iRMC '$($r.SourceObject.DisplayName)'."
$r.SourceObject[$p].Value = "N/A"
$propertiesChanged++
}
if($propertiesChanged -eq 2) {
break
}
}
$r.SourceObject.Commit()
}
}
}

# Delete the iRMC Device
$discoveryData.Remove($Device)
$DevicesRemoved++
LogWorkflowEvent 0 19030 "Fujitsu iRMC Device Cleanup Rule - deleted iRMC Device: '$($Device.DisplayName)' with IP '$($IP)' from template=$($TemplateId)"
} else {
DebugOut "$IP - TemplateId=$($TemplateId) has not been deleted, no need to delete iRMC Device '$($Device.DisplayName)' with IP '$($IP)'"
}
DebugOut "$IP - iRMC Check for Orphaned Devices: end"
}

if ($DevicesRemoved -ne 0) {
LogWorkflowEvent 0 19030 "Fujitsu iRMC Device Cleanup Rule - deleted $($DevicesRemoved) iRMC Device(s)"
$discoveryData.Commit($Connector)
}

$WinComputerClassName = "Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.WindowsComputerWithiRMC"
$WinComputerClassCriteria = New-Object Microsoft.EnterpriseManagement.Configuration.ManagementPackClassCriteria("Name='$WinComputerClassName'")
$WinComputerClass = $mg.EntityTypes.GetClasses($WinComputerClassCriteria)[0]

if ($WinComputerClass) {
$Computers = $mg.GetMonitoringObjects($WinComputerClass)

if ($Computers) {
PrepareLogging -Section $SectioniRMCDiscovery -HostTag $TagHostsDiscovery -ServerName 'All' -MpName "Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC"
DebugOut "Found $($Computers.Count) '$($WinComputerClass.DisplayName)'"

Start-Sleep -s 30
# We need to re-read the relationships in case the iRMC has just been deleted above
if ($relationshipClass) {
$relationships = $mg.GetMonitoringRelationshipObjects($relationshipClass)
}

foreach($WinComputer in $Computers) {
if($WinComputer -eq $null) { continue }

DebugOut "'$($WinComputer.DisplayName)'..."
$properties = $WinComputer.GetProperties()
foreach($p in $properties) {
if($p -eq $null) { continue }

if($p.Name -eq "iRMCAvailable") {
if ($WinComputer[$p].Value -eq $True) {
# Search for our relationship
$bFound = $false
foreach ($r in $relationships) {
if($r -eq $null) { continue }

DebugOut "'$($r.SourceObject.DisplayName)' to iRMC '$($r.TargetObject.DisplayName)' Relationship with Id $($r.Id)"
if ($r.SourceObject.Id -eq $WinComputer.Id) {
DebugOut "Found my '$($r.SourceObject.DisplayName)' to '$($r.TargetObject.DisplayName)' Relationship Instance with Id $($r.Id)."
$bFound = $True;
break;
}
}

if (!$bFound) {
DebugOut "'$($WinComputer.DisplayName)' - NO Relationship to iRMC found"
DebugOut "'$($WinComputer.DisplayName)' - Set Property '$($p.Name)' to '$($False)'"
$WinComputer[$p].Value = $False
# Also Reset iRMC Device State Property
foreach($prop in $properties) {
if($prop.Name -eq "iRMCDeviceState") {
if ($WinComputer[$prop].Value -ne 'N/A') {
$previousState = $WinComputer[$prop].Value
$WinComputer[$prop].Value = 'N/A'
DebugOut "'$($WinComputer.DisplayName)' - Set property '$($prop.Name)' from $($previousState) to 'N/A'"
} else {
DebugOut "'$($WinComputer.DisplayName)' - Property '$($prop.Name)' is up to date"
}
break
}
}
$WinComputer.Commit()
break
}
}
}
}
# $WinComputer.Commit()
}

} else {
DebugOut "No '$($WinComputerClass.DisplayName)' available"
}

} else {
# DebugOut "$($WinComputerClassName) class not present in SCOM (MP not imported), ignoring..."
}
}
}


# This script part contains helper functions to perform various logging activities
# and is embedded into the final script via Visual Studio Authoring Extensions

[int]$ERROR_TRACEFILE_XML_PARSE_ERROR = 8299 # is not a prime

# Log an event into the registry, Source will be 'Health Service Script'
# See https://msdn.microsoft.com/en-us/library/bb437630.aspx
[int]$WARNING_LEVEL = 2
[int]$ERROR_LEVEL = 1
[int]$INFO_LEVEL = 0

$LOGFILE_VERSION = "8.5.1.0"

# Generic version
Function RaiseEvent {
Param (
[parameter(Mandatory=$true)]
[string]$EventSource = "Fujitsu Out-Of-Band",
[parameter(Mandatory=$true)]
[int]$EventLevel,
[parameter(Mandatory=$true)]
[int]$EventNumber,
[parameter(Mandatory=$true)]
[string]$Message
)

$channel = "Operations Manager"

if ([System.Diagnostics.EventLog]::SourceExists($EventSource) -eq $False) {
try {
[System.Diagnostics.EventLog]::CreateEventSource($EventSource, $channel)
} catch {

}
}

$eventLog = new-object System.Diagnostics.EventLog -ArgumentList @($channel)
$eventLog.Source = $EventSource

$eventData = @()
$eventData += $EventSource
$eventData += $Message
$eventData += $PoShScriptName

# Note: map different enum values
if($EventLevel -eq $INFO_LEVEL) {
$EventLevel = [System.Diagnostics.EventLogEntryType]::Information
} elseif($EventLevel -eq $WARNING_LEVEL) {
$EventLevel = [System.Diagnostics.EventLogEntryType]::Warning
} elseif($EventLevel -eq $ERROR_LEVEL) {
$EventLevel = [System.Diagnostics.EventLogEntryType]::Error
}

$eventInstance = new-object System.Diagnostics.EventInstance -ArgumentList @($EventNumber, 0, $EventLevel)
$eventLog.WriteEvent($eventInstance, $eventData)
}

Function LogScriptEventWithEventSource {
Param (
[parameter(Mandatory=$true)]
[string]$EventSource = "Fujitsu Out-Of-Band",
[parameter(Mandatory=$true)]
[ValidateRange(0,2)]
[int]$EventLevel,
[parameter(Mandatory=$true)]
[int]$EventNumber,
[parameter(Mandatory=$true)]
[string]$Message
)
DebugOut "Writing Event $($EventNumber) Level=($EventLevel) Source='$($EventSource)' Message='$($Message)'"
if ($ScriptApi -ne $Null) {
$ScriptApi.LogScriptEvent($EventSource, $EventNumber, $EventLevel, $Message)
}
}

# Backwards compatible wrapper
Function LogScriptEvent {
Param (
[parameter(Mandatory=$true)]
[ValidateRange(0,2)]
[int]$EventLevel,
[parameter(Mandatory=$true)]
[int]$EventNumber,
[parameter(Mandatory=$true)]
[string]$Message
)
# Note: Log will be written always with Event Source 'Health Service Script'
if ($ScriptApi -ne $Null) {
# Note: do not use actual script name to consolidate Alert Suppression from parallel scripts
$ScriptApi.LogScriptEvent("Fujitsu Out-Of-Band", $EventNumber, $EventLevel, $Message)
# $ScriptApi.LogScriptEvent($PoShScriptName, $EventNumber, $EventLevel, $Message)
}
}

# Similar, but log with different Event Source ('Health Service Modules Ex') and workflow instance information
Function LogWorkflowEvent {
Param (
[parameter(Mandatory=$true)]
[ValidateRange(0,2)]
[int]$EventLevel,
[parameter(Mandatory=$true)]
[int]$EventNumber,
[parameter(Mandatory=$true)]
[string]$Message
)

$channel = "Operations Manager"
$source = "Health Service Modules Ex"
$eventLog = new-object System.Diagnostics.EventLog -ArgumentList @($channel)
$eventLog.Source = $source

$eventData = @()
$eventData += $global:scriptMG
$eventData += $global:scriptWorkflow
$eventData += $global:scriptInstanceName
$eventData += $global:scriptInstanceId
$eventData += $message
$eventData += $source

if($EventLevel -eq $INFO_LEVEL) {
$EventType = [System.Diagnostics.EventLogEntryType]::Information
} elseif($EventLevel -eq $WARNING_LEVEL) {
$EventType = [System.Diagnostics.EventLogEntryType]::Warning
} elseif($EventLevel -eq $ERROR_LEVEL) {
$EventType = [System.Diagnostics.EventLogEntryType]::Error
}

$eventInstance = new-object System.Diagnostics.EventInstance -ArgumentList @($EventNumber, 0, $EventType)
$eventLog.WriteEvent($eventInstance, $eventData)
}


# set CONSTANT variables (can not be changed):
set-variable -name SVISCOMLogXmlName -value "SVISCOM-OutOfBand.xml" -option constant
set-variable -name SVISCOMLogXm_Name -value "SVISCOM-OutOfBand.xm_" -option constant
set-variable -name SectionRoot -value "root" -option constant
set-variable -name SectionCommentSection -value "CommentSection" -option constant

# Traces for Discoveries
set-variable -name SectionServerDiscovery -value "ServerDiscovery" -option constant
set-variable -name SectionSmashDiscovery -value "SmashDiscovery" -option constant
set-variable -name SectionRaidDiscovery -value "RaidDiscovery" -option constant
set-variable -name SectionPerformanceDiscovery -value "PerformanceDiscovery" -option constant
set-variable -name SectioniRMCDiscovery -value "iRMCDiscovery" -option constant

# Traces for Monitors
set-variable -name SectionHardwareComponentMonitor -value "HardwareComponentsMonitor" -option constant
set-variable -name SectionComponentStatusMonitor -value "ComponentStatusMonitor" -option constant
set-variable -name SectionRaidMonitor -value "RaidMonitor" -option constant
set-variable -name SectionPerformanceMonitor -value "PerformanceMonitor" -option constant
set-variable -name SectioniRMCMonitor -value "iRMCMonitor" -option constant

set-variable -name SectionCommentHosts -value "CommentHosts" -option constant
set-variable -name TagDebugMode -value "DebugMode" -option constant
set-variable -name TagOverWrite -value "OverWrite" -option constant
set-variable -name TagHostsDiscovery -value "HostsForDiscovery" -option constant
set-variable -name TagHostsMonitoring -value "HostsForMonitoring" -option constant

# --------------------------------------------------------------------------
# Global variables = variables, which are changed in different functions ...
# ... and the changed value shall be available in the calling function
# --------------------------------------------------------------------------
$global:DebugMode = $False
$global:DebugFile = $False
$global:OverWrite = $True
$global:DebugHosts = ""
$global:DebugForHost = "$False"
$global:ErrFilePrefix = "ERRORTrace"
$global:WarnFilePrefix = "WARNINGTrace"
$global:LogTargetName = ""
$global:LogFilePrefix = ""
$global:LogFilePath = "$Env:TEMP\SVISCOM\SVISCOM-OutOfBand"
$global:LogFileName = "$LogFilePath\$($LogFilePrefix).log"

$global:MPVERSION = "N/A" # default
$global:MP_NAME = "N/A" # default

# --------------------------------------------------------------------------
Function Set-CurrentManagementPackVersion
{
Param (
[string] $RegistryPath = "HKLM:\SOFTWARE\Fujitsu\ServerView Suite\SCOM Integration\SVISCOM-OutOfBand",
[string] $MpName = "Fujitsu.Servers.PRIMERGY.OutOfBand"
)

if ($RegistryPath -ne $Null -and $MpName -ne $Null) {
# Load SCOM Extensions if not already done
$OMPSInstallKey = "HKLM:\Software\Microsoft\System Center Operations Manager\12\Setup\Powershell\V2"
$regKey = get-item $OMPSInstallKey
$OMPSInstallPath = $regKey.GetValue("InstallDirectory")
$omModule = $OMPSInstallPath + "OperationsManager"
Import-Module -Name $omModule

$MP = Get-SCOMManagementPack -Name $MpName
if ($MP -ne $Null) {
$MpVersion = "$($MP.Version.Major).$($MP.Version.Minor).$($MP.Version.Build).$($MP.Version.Revision)"
DebugOut "'$($MP.DisplayName)' Management Pack Version is $MpVersion"
try {
if (!(Test-Path -Path $RegistryPath)) {
New-Item -Path $RegistryPath | Out-Null
}
Set-ItemProperty -Path $RegistryPath -Name ( "$($MpName).CurrentVersion") -Value $MpVersion -Type String -ErrorAction Stop
} catch {
DebugErr $SCRIPT_EVENT_NUMBER "Error writing Management Pack CurrentVersion. Exception: $_"
}
}
}
}

Function Get-CurrentManagementPackVersion
{
Param (
[string] $RegistryPath = "HKLM:\SOFTWARE\Fujitsu\ServerView Suite\SCOM Integration\SVISCOM-OutOfBand",
[string] $MpName = "Fujitsu.Servers.PRIMERGY.OutOfBand"
)
if ($RegistryPath -ne $Null -and $MpName -ne $Null) {
try {
$regKey = get-item $RegistryPath
$global:MPVERSION = $regKey.GetValue( "$($MpName).CurrentVersion" )
} catch {}
}
}

Function PrepareLogging
{
Param (
[string] $Section,
[string] $HostTag,
[string] $ServerName,
[switch] $CreateSampleLogFile,
[string] $MpName = "Fujitsu.Servers.PRIMERGY.OutOfBand"
)

$global:LogFilePrefix = GiveBaseName $PoShScriptName
$global:MP_NAME = $MpName

# Prepare for IPv6 ...
if ($ServerName.Contains(':') ) {
$IPv6FileName = $ServerName.Replace(":", "_")
$global:LogFileName = "$global:LogFilePath\$($global:LogFilePrefix)Trace_$IPv6FileName.log"
$global:LogTargetName = $IPv6FileName
} else {
$global:LogFileName = "$global:LogFilePath\$($global:LogFilePrefix)Trace_$ServerName.log"
$global:LogTargetName = $ServerName
}

Get-CurrentManagementPackVersion -MpName $MpName

if ($CreateSampleLogFile) {
CreateLogXmlFile
}
if ($global:DebugMode -eq $False) {
GetLogXmlFile $Section $HostTag $ServerName
}

CreateLogFile

# DebugOut "LogFileName = $global:LogFileName"

}

Function GiveBaseName
{
Param (
[string] $in
)

$a = $in.split('.')
Write-Output "$($a[0])"
}

Function CreateLogXmlFile
{
$fileOK = $False
$pathOK = $False
$Xm_FileName = "$global:LogFilePath\$SVISCOMLogXm_Name"

# create the target directory, if it does not exist
if ( ! (Test-Path -Path $global:LogFilePath)) {
New-Item -ItemType directory -Path $global:LogFilePath | Out-Null
}
if (Test-Path -Path $global:LogFilePath) {
$pathOK = $True
}

if (Test-Path -Path $Xm_FileName) {
$txt = Get-Content $Xm_FileName
foreach ($line in $txt) {
if ($line.contains($LOGFILE_VERSION)) {
$fileOK = $True
break
}
}
}

if (($pathOK -eq $True) -and ($fileOK -eq $False)) {
# we write a new SVISCOM-OutOfBand.xm_ file every time the MP is changed to make sure all
# INI-Values are documented for use by the customer if anything changes.
if (Test-Path -Path $Xm_FileName) {
Remove-Item -Path $Xm_FileName -Force | Out-Null
}
#Create xm_ file
New-Item -Path $Xm_FileName -ItemType File | Out-Null

Add-Content -Path $Xm_FileName -Value @"
&lt;$SectionRoot&gt;
&lt;!--
$($SVISCOMLogXmlName) Debug XML file Version $($LOGFILE_VERSION)

With this file logging for PowerShell scripts within the
- Fujitsu Out-Of-Band Management Pack and
- Optional Extension Management Packs for the Fujitsu Out-Of-Band Management Pack
can be enabled.

Rename the file type from '.xm_' to '.xml' to enable reading this file.

Note: You have to enable debug for a script and also select the server in
the '&lt;$TagHostsDiscovery&gt;' or '&lt;$TagHostsMonitoring&gt;' section to generate traces (see below).

The following sections specify for which PowerShell scripts the traces will be generated;
Each of the sections represents a single PowerShell script.

'&lt;$TagDebugMode&gt;' enables logging (yes) or disables logging (no)
'&lt;$TagOverWrite&gt;' defines continuous logging (no) or single script run logging (yes)
--&gt;
&lt;!-- DISCOVERIES --&gt;
&lt;!-- The following section enables trace files for the Out-Of-Band iRMC Device discovery script --&gt;
&lt;$SectioniRMCDiscovery&gt;
&lt;$TagDebugMode&gt;yes&lt;/$TagDebugMode&gt;
&lt;$TagOverWrite&gt;no&lt;/$TagOverWrite&gt;
&lt;/$SectioniRMCDiscovery&gt;

&lt;!-- The following section enables trace files for the Out-Of-Band Server discovery script --&gt;
&lt;$SectionServerDiscovery&gt;
&lt;$TagDebugMode&gt;yes&lt;/$TagDebugMode&gt;
&lt;$TagOverWrite&gt;no&lt;/$TagOverWrite&gt;
&lt;/$SectionServerDiscovery&gt;

&lt;!-- The following section enables trace files for the RAID discovery script --&gt;
&lt;$SectionRaidDiscovery&gt;
&lt;$TagDebugMode&gt;yes&lt;/$TagDebugMode&gt;
&lt;$TagOverWrite&gt;no&lt;/$TagOverWrite&gt;
&lt;/$SectionRaidDiscovery&gt;

&lt;!-- MONITORS --&gt;
&lt;!-- The following section enables trace files for basic iRMC monitoring script --&gt;
&lt;$SectioniRMCMonitor&gt;
&lt;$TagDebugMode&gt;yes&lt;/$TagDebugMode&gt;
&lt;$TagOverWrite&gt;no&lt;/$TagOverWrite&gt;
&lt;/$SectioniRMCMonitor&gt;

&lt;!-- The following section enables trace files for the main server Hardware Components (CPU/Memory/Fan/PowerSupply) monitoring script --&gt;
&lt;$SectionHardwareComponentMonitor&gt;
&lt;$TagDebugMode&gt;yes&lt;/$TagDebugMode&gt;
&lt;$TagOverWrite&gt;no&lt;/$TagOverWrite&gt;
&lt;/$SectionHardwareComponentMonitor&gt;

&lt;!-- The following section enables trace files for the 'Component Status' monitoring script --&gt;
&lt;$SectionComponentStatusMonitor&gt;
&lt;$TagDebugMode&gt;yes&lt;/$TagDebugMode&gt;
&lt;$TagOverWrite&gt;no&lt;/$TagOverWrite&gt;
&lt;/$SectionComponentStatusMonitor&gt;

&lt;!-- The following section enables trace files for the RAID monitoring script --&gt;
&lt;$SectionRaidMonitor&gt;
&lt;$TagDebugMode&gt;yes&lt;/$TagDebugMode&gt;
&lt;$TagOverWrite&gt;no&lt;/$TagOverWrite&gt;
&lt;/$SectionRaidMonitor&gt;

&lt;!-- The following section enables trace files for the Performance monitoring script --&gt;
&lt;$SectionPerformanceMonitor&gt;
&lt;$TagDebugMode&gt;yes&lt;/$TagDebugMode&gt;
&lt;$TagOverWrite&gt;no&lt;/$TagOverWrite&gt;
&lt;/$SectionPerformanceMonitor&gt;

&lt;!--
The following sections specify for which servers the traces will be generated:

In the '&lt;$TagHostsDiscovery&gt;' and '&lt;$TagHostsMonitoring&gt;' sections
single or multiple servers can be specified for verbose debug output
during the discovery and/or during monitoring.

Use '&lt;$TagHostsDiscovery&gt;' for selecting hosts for the discovery trace.
Use '&lt;$TagHostsMonitoring&gt;' for selecting hosts for the monitoring trace.

Use 'all' (without quote signs) for all Fujitsu iRMC / Out-Of-Band Servers monitored by SCOM.
Use a single IP address or a comma separated list to select multiple single servers
Example:
&lt;$TagHostsDiscovery&gt;all&lt;/$TagHostsDiscovery&gt;
&lt;$TagHostsMonitoring&gt;192.168.1.100,192.168.1.101,192.168.1.102&lt;/$TagHostsMonitoring&gt;

will generate discovery traces for all Fujitsu iRMC / Out-Of-Band Servers and
will generate monitoring traces only for servers with the IP address
192.168.1.100 192.168.1.101 and 192.168.1.102
--&gt;
&lt;$TagHostsDiscovery&gt;all&lt;/$TagHostsDiscovery&gt;
&lt;$TagHostsMonitoring&gt;all&lt;/$TagHostsMonitoring&gt;
&lt;/$SectionRoot&gt;
"@
}
}

Function GetLogXmlFile
{
Param (
[string] $Section,
[string] $HostTag,
[string] $ServerName
)

$XmlFileName = "$global:LogFilePath\$SVISCOMLogXmlName"
$ListOfHosts = ""

if (Test-Path -Path $global:LogFilePath) {
if (Test-Path -Path $XmlFileName) {

[string]$xmlData = Get-Content $XmlFileName

if ([string]::IsNullOrWhiteSpace($xmlData)) {
return
}

$xmlDoc = New-Object System.Xml.XmlDocument
try {
if ($xmlDoc.LoadXml($xmlData)) {
LogScriptEventWithEventSource -EventSource "Fujitsu ServerView Integration" -EventLevel $WARNING_LEVEL -EventNumber $ERROR_TRACEFILE_XML_PARSE_ERROR -Message ("XML File '$($XmlFileName)' Parse error: " + [string]($xmlDoc.ParseError))
}
} catch {
# Parsing failed
LogScriptEventWithEventSource -EventSource "Fujitsu ServerView Integration" -EventLevel $WARNING_LEVEL -EventNumber $ERROR_TRACEFILE_XML_PARSE_ERROR -Message ("XML File '$($XmlFileName)' Parse error: $_")
return
}
# Verify basic XML structure
if ( ($xmlDoc.FirstChild.Name -eq $SectionRoot) -and ($xmlDoc.FirstChild.NextSibling -eq $Null)) {
foreach ($node in $xmlDoc.FirstChild.ChildNodes) {
if ($Node.NoteType -eq [System.Xml.XmlNodeType]::Comment) { continue }

if ($Node.Name -eq $section) {
if ($xmlDoc.$SectionRoot.$section.$TagDebugMode -ne $null) {
if ($($xmlDoc.$SectionRoot.$Section.$TagDebugMode).ToUpper() -eq "YES") {
$global:DebugMode = $True
$global:DebugFile = $True
}
}

if ($xmlDoc.$SectionRoot.$section.$TagOverWrite -ne $null) {
if ($($xmlDoc.$SectionRoot.$Section.$TagOverWrite).ToUpper() -eq "NO") {
$global:OverWrite = $False
}
}
break
}
}
}

if ($xmlDoc.$SectionRoot.$HostTag -ne $null) {
$global:DebugHosts = $($xmlDoc.$SectionRoot.$HostTag).ToLower()
}

# Check if DEBUG shall run for this server.
# There are two possibilities to check: "all" server DEBUG is on or this server is in the list.
if ($global:DebugHosts -eq "all") {
$global:DebugForHost = $True
} else {
# Check if this host is in the list of DebugHosts
$ListOfHosts = $($global:DebugHosts).split(',')
DebugOut "Searching for host: $ServerName"
DebugOut "in list of DebugHosts: $global:DebugHosts"

if ($ServerName.ToLower() -in $ListOfHosts) {
$global:DebugForHost = $True
}
}

} # else file does not exist
} # else directory does not exist
}

Function CreateLogFile
{
# For some reason checking for "$True" with "if ($global:a -and $global:b)" is not evaluated correctly!!!
# It works OK in a test with a simple PS script ... no idea why ... Thus we use:
if ($global:DebugForHost -eq $True) {
if ($global:DebugFile -eq $True) {
# Create the target directory, if it does not exist
if (!(Test-Path -Path $global:LogFilePath)) {
New-Item -ItemType directory -Path $global:LogFilePath | Out-Null
}

# Check if file exists and delete if it does and OverWrite is set to TRUE
if (Test-Path -Path $global:LogFileName) {
DebugOut ""
DebugOut "Log file already exists at: $global:LogFileName"
if ($global:OverWrite -eq $True) {
Remove-Item -Path $global:LogFileName -Force | Out-Null
}
}
# If the file has just been removed (OverWrite = YES) or the file does not exist: create it
if (!(Test-Path -Path $global:LogFileName)) {
#Create log file
New-Item -Path $global:LogFileName -ItemType File | Out-Null
}

Add-Content -Path $global:LogFileName -Value @"
********** $(Get-Date -Format F) **********`r
********** $($global:LogFileName) **********`r
********** Management Pack '$($global:MP_NAME)' Version: $($global:MPVERSION)`r
"@
}
}
}

Function DebugOut
{
Param (
[string] $Text
)

if ($global:DebugForHost -eq $True) {
if ($global:DebugMode -eq $True) {
Write-Host $Text
}

if ($global:DebugFile -eq $True) {
if ($global:LogFileName.Length -gt 0) {
if (Test-Path -Path $global:LogFileName) {
$DateTime = Get-Date -format "yyyy-MM-dd HH:mm:ss"
Add-Content -Path $global:LogFileName -Value "$DateTime $Text"
}
}
}
}
}

Function DebugWarn
{
Param (
[string] $Text
)

DebugOut "Warning: $Text"

if ($global:DebugForHost -eq $True) {
if ($global:DebugFile -eq $True) {
$WarnLogFile = "$global:LogFilePath\$($WarnFilePrefix)_$($global:LogTargetName).log"
$DateTime = Get-Date -format "yyyy-MM-dd HH:mm:ss"
Add-Content -Path $WarnLogFile -Value "[$($DateTime)] [$($PoShScriptName)] $($Text)"
}
}
}

Function DebugErr
{
Param (
[int] $ErrNo,
[string] $Text
)

DebugOut "Error: $Text"

if ($global:DebugForHost -eq $True) {
if ($global:DebugFile -eq $True) {
$ErrLogFile = "$global:LogFilePath\$($ErrFilePrefix)_$($global:LogTargetName).log"
$DateTime = Get-Date -format "yyyy-MM-dd HH:mm:ss"
Add-Content -Path $ErrLogFile -Value "[$($ErrNo)] [$($DateTime)] [$($PoShScriptName)] $($Text)"
}
}
}




Main
</Script></ScriptBody>
<TimeoutSeconds>600</TimeoutSeconds>
</WriteAction>
</MemberModules>
<Composition>
<Node ID="Script.CleanupOrphanedDevices"/>
</Composition>
</Composite>
</ModuleImplementation>
<InputType>System!System.BaseData</InputType>
</WriteActionModuleType>