Fujitsu ServerView Monitoring Collect Health State to OMS Write Action

Fujitsu.ServerView.Monitoring.OMS.IngestHealthStatusWriteAction (WriteActionModuleType)

Fujitsu ServerView Monitoring - Collect Health State to OMS Write Action

Element properties:

TypeWriteActionModuleType
IsolationAny
AccessibilityInternal
RunAsDefault
InputTypeSystem.BaseData

Member Modules:

ID Module Type TypeId RunAs 
WA WriteAction Microsoft.Windows.PowerShellWriteAction Default

Overrideable Parameters:

IDParameterTypeSelectorDisplay NameDescription
LogTypestring$Config/LogType$Log TypeCustom Log Type Name. Will be displayed as Custom Log 'LogType_CL' in OMS.
SkipWindowsServerbool$Config/SkipWindowsServer$Skip Windows ServerIf set to true, Fujitsu PRIMERGY Windows Server Health will not be included in the data sent to the OMS workspace
SkipLinuxServerbool$Config/SkipLinuxServer$Skip Linux ServerIf set to true, Fujitsu PRIMERGY Linux Server Health will not be included in the data sent to the OMS workspace
SkipESXiServerbool$Config/SkipESXiServer$Skip ESXi ServerIf set to true, Fujitsu PRIMERGY ESXi Server Health will not be included in the data sent to the OMS workspace
SkipOobServerbool$Config/SkipOobServer$Skip Out-Of-Band ServerIf set to true, Fujitsu PRIMERGY Out-Of-Band Server Health will not be included in the data sent to the OMS workspace
TimeoutSecondsint$Config/TimeoutSeconds$Timeout SecondsTimeout in Seconds for the Collect Health State to OMS Write Action Script

Source Code:

<WriteActionModuleType ID="Fujitsu.ServerView.Monitoring.OMS.IngestHealthStatusWriteAction" Accessibility="Internal" Batching="false">
<Configuration>
<IncludeSchemaTypes>
<SchemaType>Windows!Microsoft.Windows.PowerShellSchema</SchemaType>
</IncludeSchemaTypes>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="ScriptName" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="Certificate" type="xsd:string"/>
<!-- Will be displayed as Custom Log 'LogType_CL' in OMS -->
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="LogType" type="xsd:string"/>
<!-- Allow filtering of included Fujitsu Classes -->
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="SkipWindowsServer" type="xsd:boolean" default="false"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="SkipLinuxServer" type="xsd:boolean" default="false"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="SkipESXiServer" type="xsd:boolean" default="false"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="SkipOobServer" type="xsd:boolean" default="false"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="TimeoutSeconds" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="StrictErrorHandling" type="xsd:boolean"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="LogType" Selector="$Config/LogType$" ParameterType="string"/>
<OverrideableParameter ID="SkipWindowsServer" Selector="$Config/SkipWindowsServer$" ParameterType="bool"/>
<OverrideableParameter ID="SkipLinuxServer" Selector="$Config/SkipLinuxServer$" ParameterType="bool"/>
<OverrideableParameter ID="SkipESXiServer" Selector="$Config/SkipESXiServer$" ParameterType="bool"/>
<OverrideableParameter ID="SkipOobServer" Selector="$Config/SkipOobServer$" ParameterType="bool"/>
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<WriteAction ID="WA" TypeID="Windows!Microsoft.Windows.PowerShellWriteAction">
<ScriptName>$Config/ScriptName$</ScriptName>
<ScriptBody><Script>
##################################################################################
# #
# NOTICE #
# #
# COPYRIGHT 2015 - 2017 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. #
# #
##################################################################################

&lt;#

This Script sends health state together with basic Server data to an OMS workspace as JSON Data
where it can be analyzed as custom log type. For technical details see:
https://azure.microsoft.com/en-us/documentation/articles/log-analytics-data-collector-api/

#&gt;
param(
[string]$ScriptName,
[string]$WorkspaceId,
[string]$Certificate,
[string]$LogType,
[int] $TimeoutSeconds = 120,

[string]$SkipWindowsServer = "False",
[string]$SkipLinuxServer = "False",
[string]$SkipESXiServer = "False",
[string]$SkipOobServer = "False"
)

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

# --------------------------------------------------------------------------
# Defaults
#
[string]$MP_NAME = "Fujitsu.ServerView.Monitoring.Cloud"
[string]$SCRIPT_NAME = "IngestHealthStatus.ps1"
[int] $SCRIPT_EVENT_NUMBER = 8969 # is a prime
[int] $ERROR_BAD_CERT_DATA = 8971 # is a prime
[int] $ERROR_BAD_JSON_DATA = 8941 # is a prime
[int] $ERROR_SENDING_DATA = 8951 # is a prime

[string] $API_VERSION = "2016-04-01"

[bool] $SendSingleRecords = $False

# overwrite with passed in parameters
if ($ScriptName -ne '') { $SCRIPT_NAME = $ScriptName}

# set CONSTANT variables (can not be changed):
set-variable -name PoShScriptName -value "$SCRIPT_NAME" -option constant

$computerName = $env:ComputerName
if ($env:FQDN -ne $Null) {
$computerName = $computerName +"." + $env:FQDN
}

$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

# Management Group Connection
$mg = New-Object -TypeName "Microsoft.EnterpriseManagement.ManagementGroup" -ArgumentList @($computerName)

Function Send-OMSAPIData
{
Param
(
[Parameter(Mandatory = $True)]$customerId,
[Parameter(Mandatory = $True)]$logType,
[Parameter(Mandatory = $True)]$body,
[Parameter(Mandatory = $True)]$Certificate
)

try {
$body=[Text.Encoding]::UTF8.GetBytes($body)

$method = "POST"
$contentType = "application/json"
$contentLength = $body.Length
$rfc1123date = [DateTime]::UtcNow.ToString((Get-Culture).DateTimeFormat.RFC1123Pattern)

# Note: Sending JSON from SCOM with cert based authorization uses different API Endpoint
$uri = "https://$($customerId).ods.opinsights.azure.com/OperationalData.svc/PostJsonDataItems?api-version=$($API_VERSION)"

# Note: We do not use/have a dedicated time-stamp field
$headers = @{
"Log-Type" = $logType;
"x-ms-date" = $rfc1123date;
}

$response = Invoke-WebRequest -Uri $uri -Method $method -ContentType $contentType -Headers $headers -certificate $certificate -Body $body -UseBasicParsing -verbose

if ( ($response.StatusCode -eq [System.Net.HttpStatusCode]::Accepted) -or ($response.StatusCode -eq [System.Net.HttpStatusCode]::OK) ) {
DebugOut "SUCCESS sending Health State of Fujitsu ServerView Servers to Microsoft OMS..."
} else {
LogScriptEventWithEventSource -EventSource $SCRIPT_NAME -EventLevel $WARNING_LEVEL -EventNumber $ERROR_SENDING_DATA -Message ("Error sending Fujitsu ServerView Server Health Data to Microsoft OMS: Response='$($response)'")
DebugWarn "WARNING: Could not send Fujitsu ServerView Servers Health Data to Microsoft OMS: Response='$($response)'"
}
} catch {
DebugErr $ERROR_SENDING_DATA "ERROR sending Fujitsu ServerView Servers Health Data to Microsoft OMS:`nException=$_"
}
}

Function Main {

try {
Set-CurrentManagementPackVersion -MpName $MP_NAME
PrepareLogging -Section $SectionHealthMonitor -HostTag $TagHostsMonitoring -ServerName $computerName -CreateSampleLogFile -MpName $MP_NAME

# Get the WebProxyAddress property from the advisor settings class.
$advisorSettingsClass = Get-SCOMClass -Name 'Microsoft.SystemCenter.Advisor.Settings'
$advisorSettingsInstance = Get-SCOMClassInstance -Class $advisorSettingsClass
$WorkspaceId = $advisorSettingsInstance.'[Microsoft.SystemCenter.Advisor.Settings].CustomerIdentifier'.Value
$proxyAddress = $advisorSettingsInstance.'[Microsoft.SystemCenter.Advisor.Settings].WebProxyAddress'.Value

DebugOut "Collect Health State of Fujitsu ServerView Servers to OMS - START"
DebugOut "ScriptName=$($ScriptName) LogType='$($LogType)'"
DebugOut "Skip Servers: Windows='$($SkipWindowsServer)' Linux='$($SkipLinuxServer)' ESXi='$($SkipESXiServer)' Out-Of-Band='$($SkipOobServer)'"
DebugOut "OMS WorkspaceId='$($WorkspaceId)' OMS Proxy='$($proxyAddress)'"

if ([string]::IsNullOrEmpty($WorkspaceId)) {
LogScriptEventWithEventSource -EventSource $SCRIPT_NAME -EventLevel $ERROR_LEVEL -EventNumber $SCRIPT_EVENT_NUMBER -Message ("ERROR: invalid/empty workspace ID")
DebugErr $SCRIPT_EVENT_NUMBER "ERROR: invalid/empty workspace ID"
Exit -1
}

if ([string]::IsNullOrEmpty($LogType)) {
LogScriptEventWithEventSource -EventSource $SCRIPT_NAME -EventLevel $ERROR_LEVEL -EventNumber $SCRIPT_EVENT_NUMBER -Message ("ERROR: invalid/empty Log Type")
DebugErr $SCRIPT_EVENT_NUMBER "ERROR: invalid/empty Log Type"
Exit -1
}

if ([string]::IsNullOrEmpty($Certificate)) {
LogScriptEventWithEventSource -EventSource $SCRIPT_NAME -EventLevel $ERROR_LEVEL -EventNumber $SCRIPT_EVENT_NUMBER -Message ("ERROR: invalid/empty certificate data")
DebugErr $SCRIPT_EVENT_NUMBER "ERROR: invalid/empty certificate data"
Exit -1
}

try {
[byte[]] $bytes = [Convert]::FromBase64String($Certificate);
[string] $astring = [System.Text.Encoding]::Unicode.GetString($bytes);
[byte[]] $rawData = [Convert]::FromBase64String($astring);
[System.Security.Cryptography.X509Certificates.X509Certificate2] $Cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$Cert.Import($rawData)
DebugOut "Certificate Subject='$($Cert.Subject)' Valid To: '$($Cert.NotAfter)'"
} catch {
LogScriptEventWithEventSource -EventSource $SCRIPT_NAME -EventLevel $ERROR_LEVEL -EventNumber $ERROR_BAD_CERT_DATA -Message ("ERROR: converting Cert data: Exception=$_")
DebugErr $ERROR_BAD_CERT_DATA "ERROR: converting Cert data: Exception=$_"
Exit -1
}


$fts_servers = @(Get-SCOMClassInstance -Class (Get-SCOMClass -Name 'Fujitsu.ServerView.Server')) # | sort-object HealthState -descending
# # Also collect Blade and PRIMEQUEST overall Health Data
# $fts_servers = @(Get-SCOMClassInstance -Class (Get-SCOMClass -Name 'Fujitsu.ServerView.System')) # | sort-object HealthState -descending
DebugOut "Found a total of $($fts_servers.Count) Fujitsu ServerView Server(s)"

$serverList = @()
foreach ($server in $fts_servers) {
$ClassName = $server.GetMostDerivedClasses()[0].Name
if ($ClassName -match "Fujitsu.Servers.PRIMERGY.Windows.") { if ($SkipWindowsServer -eq $True) { DebugOut "Skipping '$($Server)' Windows Server..."; continue; } }
if ($ClassName -match "Fujitsu.Servers.PRIMERGY.OutOfBand.") { if ($SkipOobServer -eq $True) { DebugOut "Skipping '$($Server)' Out-Of-Band Server..."; continue; } }
if ($ClassName -match "Fujitsu.Servers.PRIMERGY.Linux.") { if ($SkipLinuxServer -eq $True) { DebugOut "Skipping '$($Server)' Linux Server..."; continue; } }
if ($ClassName -match "Fujitsu.Servers.PRIMERGY.ESXi.") { if ($SkipESXiServer -eq $True) { DebugOut "Skipping '$($Server)' ESXi Server..."; continue; } }

$serverList += $server
}

$serverData = ""
foreach ($server in $serverList) {
# More a overall/generic type than specific SCOM class type
switch -wildcard ( $server.GetMostDerivedClasses()[0].Name) {
"Fujitsu.Servers.PRIMERGY.Windows.*" { $ClassType = "PRIMERGY Windows Server"}
"Fujitsu.Servers.PRIMERGY.OutOfBand.*" { $ClassType = "PRIMERGY Out-Of-Band Server"}
"Fujitsu.Servers.PRIMERGY.Linux.*" { $ClassType = "PRIMERGY Linux Server"}
"Fujitsu.Servers.PRIMERGY.ESXi.*" { $ClassType = "PRIMERGY ESXi Server"}

# "Fujitsu.PRIMERGY.BladeSystem.*" { $ClassType = "PRIMERGY Blade System"}
# "Fujitsu.PRIMEQUEST.*" { $ClassType = "PRIMERGY PRIMEQUEST System"}

default { $ClassType = "Other PRIMERGY ServerView server"}
}

# Make sure we have these properties in the right order
$ServerInfo = New-Object PSObject -Property @{}

$ServerInfo | Add-Member -Force -MemberType NoteProperty -Name "ServerName" -Value $server.DisplayName
$ServerInfo | Add-Member -Force -MemberType NoteProperty -Name "NetworkName" -Value $server.'[Fujitsu.ServerView.Server].NetworkName'.Value
$ServerInfo | Add-Member -Force -MemberType NoteProperty -Name "ServerModel" -Value $server.'[Fujitsu.ServerView.System].Model'.Value
$ServerInfo | Add-Member -Force -MemberType NoteProperty -Name "ServerHealth" -Value $server.HealthState.ToString()
$ServerInfo | Add-Member -Force -MemberType NoteProperty -Name "MaintenanceMode" -Value $server.inMaintenanceMode

$ServerInfo | Add-Member -Force -MemberType NoteProperty -Name "ClassType" -Value $ClassType
$ServerInfo | Add-Member -Force -MemberType NoteProperty -Name "ClassName" -Value $server.GetMostDerivedClasses()[0].DisplayName

$payload = (ConvertTo-JSON $ServerInfo -Compress)
DebugOut "$payload"

if ( $SendSingleRecords -eq $True ) {
Send-OMSAPIData -customerId $WorkspaceId -logType $LogType -body $payload -Certificate $cert
} else {
# single server? Send as single JSON record
if ($serverList.Count -eq 1) {
$serverData = $payload
} else {
# Send as JSON array
if ($server -eq $serverList[0]) {
$serverData += "[ " + $payload +", `n"
} elseif ($server -eq $serverList[-1]) {
$serverData += $payload +" ]"
} else {
$serverData += $payload +", `n"
}
}
}
}

if ( $SendSingleRecords -eq $False ) {
if (! [string]::IsNullOrEmpty($serverData)) {
try {
# Make sure we have correctly formatted JSON data
( ConvertFrom-JSON $serverData ) | Out-Null
} catch {
DebugErr $ERROR_BAD_JSON_DATA "ERROR Re-Converting JSON data:`nData=$($serverData)`nException=$_"
Exit -1
}

Send-OMSAPIData -customerId $WorkspaceId -logType $LogType -body $serverData -Certificate $cert

}
}

} catch {
# Generic Exception ...
LogScriptEventWithEventSource -EventSource $SCRIPT_NAME -EventLevel $ERROR_LEVEL -EventNumber $SCRIPT_EVENT_NUMBER -Message ("Collect Health State of Fujitsu ServerView Servers to OMS: Exception=$_")
Exit -1
}

DebugOut "Collect Health State of Fujitsu ServerView Servers to OMS - END"
}





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

# 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.3.0.0

# Generic version
Function RaiseEvent {
Param (
[parameter(Mandatory=$true)]
[string]$EventSource = "Fujitsu ServerView",
[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 ServerView",
[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 ServerView", $EventNumber, $EventLevel, $Message)
# $ScriptApi.LogScriptEvent($PoShScriptName, $EventNumber, $EventLevel, $Message)
}
}

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

# Traces for Discoveries (currently none)

# Traces for Monitors
set-variable -name SectionHealthMonitor -value "HealthMonitor" -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 = ""
# Note: do not mix with Custom Log update directory for the time being
$global:LogFilePath = "$Env:TEMP\SVISCOM\SVISCOM-Cloud"
$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-Cloud",
[string] $MpName = "Fujitsu.ServerView.Monitoring.Cloud"
)

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-Cloud",
[string] $MpName = "Fujitsu.ServerView.Monitoring.Cloud"
)
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.ServerView.Monitoring.Cloud"
)

$global:LogFilePrefix = GiveBaseName $PoShScriptName
$global:LogFileName = "$global:LogFilePath\$($global:LogFilePrefix)Trace_$ServerName.log"
$global:MP_NAME = $MpName

Get-CurrentManagementPackVersion -MpName $MpName

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

CreateLogFile

#DebugOut "SYSTEMDRIVE = $env:SYSTEMDRIVE"
#DebugOut "TEMP = $env:TEMP"
#DebugOut "LogFilePath = $global:LogFilePath"
#DebugOut "LogFileName = $global:LogFileName"

$global:LogTargetName = $ServerName
}

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 ServerView Integration Management Pack and
- Optional Extension Management Packs for the Fujitsu ServerView Integration 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;!-- currently none --&gt;

&lt;!-- MONITORS --&gt;
&lt;!-- The following section enables trace files for the Health monitoring script --&gt;
&lt;$SectionHealthMonitor&gt;
&lt;$TagDebugMode&gt;yes&lt;/$TagDebugMode&gt;
&lt;$TagOverWrite&gt;no&lt;/$TagOverWrite&gt;
&lt;/$SectionHealthMonitor&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 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 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) {
[xml]$xmlfile = Get-Content $XmlFileName

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

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

if ($xmlfile.$SectionRoot.$HostTag -ne $null) {
$global:DebugHosts = $($xmlfile.$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>
<SnapIns/>
<Parameters>
<Parameter>
<Name>ScriptName</Name>
<Value>$Config/ScriptName$</Value>
</Parameter>
<Parameter>
<Name>Certificate</Name>
<Value>$Config/Certificate$</Value>
</Parameter>
<Parameter>
<Name>LogType</Name>
<Value>$Config/LogType$</Value>
</Parameter>
<Parameter>
<Name>TimeoutSeconds</Name>
<Value>$Config/TimeoutSeconds$</Value>
</Parameter>
<!-- Support optional filtering of included Fujitsu classes -->
<Parameter>
<Name>SkipWindowsServer</Name>
<Value>$Config/SkipWindowsServer$</Value>
</Parameter>
<Parameter>
<Name>SkipLinuxServer</Name>
<Value>$Config/SkipLinuxServer$</Value>
</Parameter>
<Parameter>
<Name>SkipESXiServer</Name>
<Value>$Config/SkipESXiServer$</Value>
</Parameter>
<Parameter>
<Name>SkipOobServer</Name>
<Value>$Config/SkipOobServer$</Value>
</Parameter>
</Parameters>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
<StrictErrorHandling>$Config/StrictErrorHandling$</StrictErrorHandling>
</WriteAction>
</MemberModules>
<Composition>
<Node ID="WA"/>
</Composition>
</Composite>
</ModuleImplementation>
<InputType>System!System.BaseData</InputType>
</WriteActionModuleType>