Fujitsu.Servers.PRIMERGY.PS.CIMSubscribe (DeployableResource)

Element properties:

TypeDeployableResource
File NameCIMSubscribe.psm1
AccessibilityPublic

Source Code:

<DeployableResource ID="Fujitsu.Servers.PRIMERGY.PS.CIMSubscribe" Accessibility="Public" FileName="CIMSubscribe.psm1" HasNullStream="false"/>

File Content: CIMSubscribe.psm1



#-------------------------------------------------------------------
# Fujitsu
# Copyright 2015-2019 FUJITSU LIMITED
#
# CIMSubscribe.ps1
#
# Summary:
# Adds CIM indications functions to CIMClient object.
#-------------------------------------------------------------------

$script:NICAddresses = @()
$script:CIMListenerAddress = ""

function Get-CIMListenerAddress
{
<#
.SYNOPSIS
Returns nice address for CIMListener.
.DESCRIPTION
Function returns proper address for CIMListener.
.PARAMETER IPAddress
IPAddress of a target CIMOM.
.PARAMETER CIMPort
CIM port of a target CIMOM.
.PARAMETER RegKey
Registry path to get registry setting.
.EXAMPLE
Get-CIMListenerAddress -IPAddress "127.0.0.1" -CIMPort 5989 -RegKey "RegPath"
#>
Param (
[IPAddress] $IPAddress,
[int] $CIMPort,
[string] $RegKey
)

if ($script:CIMListenerAddress -ne "") {
return $script:CIMListenerAddress
}

$cimlistener = ""
$listenhost = ""

Get-NICAddresses

foreach ($addresses in $script:NICAddresses) {
$address = $addresses[0]
$mask = $addresses[1]
if (Compare-IPAddressesSubnet $address $IPAddress $mask) {
$listenhost = $address
break
}
}

if ($listenhost -eq "") {
foreach ($addresses in $script:NICAddresses) {
$address = $addresses[0]
if (Test-Port $address $IPAddress $CIMPort) {
$listenhost = $address
break
}
}
}
if ($listenhost -eq "") {
Throw "Cannot determine which network interface to use"
}

$listenport = (Get-ItemProperty $RegKey -Name "ListenPort" -Ea Stop).ListenPort
$listenproto = (Get-ItemProperty $RegKey -Name "ListenProtocol" -Ea Stop).ListenProtocol
$cimlistener = "$($listenproto)://$($listenhost):$($listenport)"
$script:CIMListenerAddress = $cimlistener

return $cimlistener
}

function Get-NICAddresses
{
<#
.SYNOPSIS
Function discovers all NIC addresses.
.DESCRIPTION
Function discovers all NIC addresses and remember them in NICAddresses table.
.EXAMPLE
Get-NICAddresses
#>
if ($script:NICAddresses.Count -gt 0) {
return
}
$list = [Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces()
foreach ($interface in $list) {
if ($interface.OperationalStatus -eq [Net.NetworkInformation.OperationalStatus]::Up) {
if (($interface.NetworkInterfaceType -eq [Net.NetworkInformation.NetworkInterfaceType]::Ethernet) -or
($interface.NetworkInterfaceType -eq [Net.NetworkInformation.NetworkInterfaceType]::Ethernet3Megabit) -or
($interface.NetworkInterfaceType -eq [Net.NetworkInformation.NetworkInterfaceType]::FastEthernetFx) -or
($interface.NetworkInterfaceType -eq [Net.NetworkInformation.NetworkInterfaceType]::FastEthernetT) -or
($interface.NetworkInterfaceType -eq [Net.NetworkInformation.NetworkInterfaceType]::GigabitEthernet)) {
$addresses = $interface.GetIPProperties().UnicastAddresses
foreach ($address in $addresses) {
if ($address.Address.AddressFamily -eq [Net.Sockets.AddressFamily]::InterNetwork) {
$script:NICAddresses += ,@($address.Address.IPAddressToString, $address.IPv4Mask.IPAddressToString)
}
}
}
}
}
}

function Test-Port
{
<#
.SYNOPSIS
Tests if connection from source to target can be established.
.DESCRIPTION
Tests if connection from source to target on particular port can be established.
.PARAMETER Source
Source IPAddress.
.PARAMETER Target
Target IPAddress.
.PARAMETER Port
Port number.
.PARAMETER TimeOut
Timeout.
.EXAMPLE
Test-Port -Source "127.0.0.1" -Target "127.0.0.2" -Port 1234 -TimeOut 1000
#>
Param (
[string] $Source,
[string] $Target,
[int] $Port,
[int] $TimeOut = 1000
)

if ($Port -eq 0) { return $False }

$result = $True
try {
$ep = New-Object System.Net.IPEndPoint ([IPAddress]$Source), 0
$tcp = New-Object System.Net.Sockets.TcpClient $ep
$conn = $tcp.BeginConnect(([IPAddress] $Target), $Port, $Null, $Null)
$wait = $conn.AsyncWaitHandle.WaitOne($TimeOut, $False)
if (! $wait) {
$result = $False
} else {
$tcp.EndConnect($conn) | Out-Null
}
$tcp.Close()
} catch {
$result = $False
}

return $result
}

function Get-SubnetBroadcast {
<#
.SYNOPSIS
Gets subnet broadcast.
.DESCRIPTION
Returns subnet broadcast for given ip and mask.
.PARAMETER ip
IPAddress.
.PARAMETER mask
Mask for subnet.
.EXAMPLE
Get-SubnetBroadcast -ip "127.0.0.1" -mask "255.255.255.0"
#>
Param (
[IPAddress] $ip,
[IPAddress] $mask
)

if ($ip -eq $Null -or $mask -eq $Null) { return [IPAddress] 0 }

$ipbytes = $ip.GetAddressBytes()
$maskbytes = $mask.GetAddressBytes()
if ($ipbytes.Length -ne $maskbytes.Length) {
return [IPAddress] 0
}

$SubnetBroadcast = @()
for ($i=0;$i -le 3;$i++) {
$SubnetBroadcast += $ipbytes[$i] -band $maskbytes[$i]
}

return [IPAddress] ($SubnetBroadcast -Join ".")
}

function Compare-IPAddressesSubnet
{
<#
.SYNOPSIS
Checks if two IP addresses are in the same subnet.
.DESCRIPTION
Compare if two IP addresses are in the same subnet.
.PARAMETER ip1
IPAddress one.
.PARAMETER ip2
IPAddress two.
.PARAMETER mask
Mask for subnet.
.EXAMPLE
Compare-IPAddressesSubnet -ip1 "127.0.0.1" -ip2 "127.0.0.2" -mask "255.255.255.0"
#>
Param(
[IPAddress] $ip1,
[IPAddress] $ip2,
[IPAddress] $mask
)

$broadcast1 = Get-SubnetBroadcast $ip1 $mask
$broadcast2 = Get-SubnetBroadcast $ip2 $mask

return $broadcast1.Equals($broadcast2)
}

#-------------------------------------------------------------------

function Invoke-CIMSubscribe
{
<#
.SYNOPSIS
Subscribes target to CIM indications.
.DESCRIPTION
Subscribes CIMClient object to CIM Indications.
.PARAMETER Cim
CIMClient object.
.PARAMETER HostName
Hostname to use for registry info.
.PARAMETER Force
Force registration even if registry says something else.
.EXAMPLE
Invoke-CIMSubscribe -Cim $Cim -HostName 'localhost' -Force
#>
Param (
[object] $Cim,
[string] $HostName,
[switch] $Force
)

if ($Force -or ! $Cim.Subscribed) {
# Ensure that there is no subscription, if so unsubscribe
if (! $Force -and (Test-TargetSubscribed -Cim $Cim)) {
Invoke-CIMUnsubscribe -Cim $Cim
}

try {
$listener = Get-CIMListenerAddress -IPAddress $Cim.Address -CIMPort $Cim.Port -RegKey $Cim.RegKeyListener
} catch {
$Cim.Logger.Debug("CIM Indications: $($_.Exception.Message)")
return $False
}

$Cim.Logger.Debug("CIM Indications: CIM Indications Listener address: $($listener)")

$class = "SVS_PGYIndicationRegistrationService"
$method = "RegisterCIMXMLIndication"
$params = @{}
$params.Add("Query", "SELECT * FROM SVS_PGYLogEntryArrived")
$params.Add("EventReceiver", $listener)
$params.Add("QueryType", 0)
$params.Add("Tag", $Cim.IndicationTag)

try {
$Cim.Refresh()
$CimData = $Cim.Client.Invoke("CallMethod", @($class, $method, $params))

if ($CimData.MethodResult -eq 0) {
$Cim.Logger.Debug("CIM Indications: Host successfully subscribed to CIM indications.")

if (! (Test-Path -Path $Cim.RegKeySubscribed)) {
New-Item -Path $Cim.RegKeySubscribed -Force
}
Set-ItemProperty -Path $Cim.RegKeySubscribed -Name $Cim.IndicationTag -Type String -Value "$($HostName);$($Cim.Address);$($Cim.Port);$([string]$Cim.CheckCert);$($listener)" -Force

if (! $Force) {
# Additionally we save heartbeat
$AppDataPath = "$($Env:LOCALAPPDATA)\Fujitsu\SVISCOM\SVISCOM-ESXi"
if (! (Test-Path -Path "$($AppDataPath)\Heartbeats")) {
New-Item -ItemType directory -Path "$($AppDataPath)\Heartbeats" | Out-Null
}
(Get-Date).Ticks.ToString() | Out-File -FilePath "$($AppDataPath)\Heartbeats\$($Cim.IndicationTag)"
}
} else {
$Cim.Logger.Debug("CIM Indications: RegisterCIMXMLIndication error=$($CimData.MethodResult) ipaddress=$($Cim.Address)")
}
} catch [Exception] {
$Cim.Logger.Debug("CIM Indications: $($_.Exception.Message)")
return $False
}
} else {
$Cim.Logger.Debug("CIM Indications: Host already subscribed to CIM indications.")
return $False
}

return $True
}

function Invoke-CIMUnsubscribe
{
<#
.SYNOPSIS
Unsubscribes target from CIM indications.
.DESCRIPTION
Unsubscribes CIMClient object from CIM Indications.
.PARAMETER Cim
CIMClient object.
.EXAMPLE
Invoke-CIMUnsubscribe -Cim $Cim
#>
Param (
[object] $Cim
)

$class = "SVS_PGYIndicationRegistrationService"
$method = "UnRegisterIndicationsByTag"
$params = @{}
$params.Add("Tag", $Cim.IndicationTag)

try {
$Cim.Refresh()
$CimData = $Cim.Client.Invoke("CallMethod", @($class, $method, $params))

if ($CimData.MethodResult -eq 0) {
$Cim.Logger.Debug("CIM Indications: Host successfully unsubscribed.")
return $True
} else {
$Cim.Logger.Debug("CIM Indications: UnRegisterIndicationsByTag error=$($CimData.MethodResult) ipaddress=$($Cim.Address)")
}
} catch [Exception] {
$Cim.Logger.Debug("CIM Indications: $($_.Exception.Message)")
}

return $False
}

function Test-TargetSubscribed
{
<#
.SYNOPSIS
Tests if target is subscribed.
.DESCRIPTION
Tests if CIMClient object is subscribed to CIM Indications.
.PARAMETER Cim
CIMClient object.
.EXAMPLE
Test-TargetSubscribed -Cim $Cim
#>
Param (
[object] $Cim
)

$class = "SVS_PGYIndicationRegistrationService"
$method = "ListRegistrations"

try {
$Cim.Refresh()
$CimData = $Cim.Client.Invoke("CallMethod", @($class, $method, $null))

if ($CimData.MethodResult -eq 0) {
$Cim.Logger.Debug("CIM Indications: ListRegistrations executed successfully.")
$tags = $CimData.Tags
foreach ($t in $tags) {
if ($t -ieq $Cim.IndicationTag) {
$Cim.Logger.Debug("CIM Indications: host subscribed")
$Cim.Subscribed = $True
return $True
}
}
} else {
$Cim.Logger.Debug("CIM Indications: ListRegistrations error=$($CimData.MethodResult) ipaddress=$($Cim.Address)")
return $True # We do not know what error means, host can be unsubscribed
}
} catch [Exception] {
$Cim.Logger.Debug("CIM Indications: $($_.Exception.Message)")
}

return $False
}

#-------------------------------------------------------------------
# Exportable functions:
#-------------------------------------------------------------------

function Add-CIMIndications {
<#
.SYNOPSIS
Extends CIMClient object with Indications functionality.
.DESCRIPTION
Function adds CIM Indications functionality to passed CIMClient object.
.PARAMETER CIMClientObject
CIMClient object to extend.
.PARAMETER RegKeyListener
Registry path to CIM Listener settings.
.PARAMETER RegKeySubscribed
Registry path to CIM subscriptions.
.EXAMPLE
$cim = Add-CIMIndications -CIMClientObject $Cim -RegKeyListener "RegPathForListener" -RegKeySubscribed "RegPathForSubscribe"
#>
Param (
[object] $CIMClientObject,
[string] $RegKeyListener,
[string] $RegKeySubscribed
)

$cimSubscribe = {
<#
.SYNOPSIS
Subscribes to CIM Indications.
.DESCRIPTION
Subscribes current CIMClient object to CIM Indications.
.PARAMETER HostName
Hostname to use for registry info.
.PARAMETER Force
Force registration even if registry says something else.
.EXAMPLE
$cim.Subscribe('localhost', $True)
#>
Param (
[string] $HostName,
[bool] $Force = $False
)

return Invoke-CIMSubscribe -Cim $this -HostName $HostName -Force:$Force
}

$cimUnsubscribe = {
<#
.SYNOPSIS
Unsubscribes from CIM Indications.
.DESCRIPTION
Unsubscribes current CIMClient object from CIM Indications.
.EXAMPLE
$cim.Unsubscribe()
#>
return Invoke-CIMUnsubscribe -Cim $this
}

$cimIsSubscribed = {
<#
.SYNOPSIS
Checks if subscribed to CIM Indications.
.DESCRIPTION
Checks if CIMClient object is subscribed to CIM Indications.
.EXAMPLE
$cim.IsSubscribed()
#>
return Test-TargetSubscribed -Cim $this
}

$cimListener = {
<#
.SYNOPSIS
Returns CIM Indications listener address.
.DESCRIPTION
Returns CIM Indications listener address.
.EXAMPLE
$cim.GetListener()
#>
return Get-CIMListenerAddress -IPAddress $this.Address -CIMPort $this.Port -RegKey $this.RegKeyListener
}

$CIMClientObject | Add-Member -MemberType NoteProperty -Name "RegKeyListener" -Value $RegKeyListener
$CIMClientObject | Add-Member -MemberType NoteProperty -Name "RegKeySubscribed" -Value $RegKeySubscribed
$CIMClientObject | Add-Member -MemberType NoteProperty -Name "Subscribed" -Value $False
$CIMClientObject | Add-Member -MemberType NoteProperty -Name "IndicationTag" -Value ""
$CIMClientObject | Add-Member -MemberType ScriptMethod -Name "GetListener" -Value $cimListener
$CIMClientObject | Add-Member -MemberType ScriptMethod -Name "Subscribe" -Value $cimSubscribe
$CIMClientObject | Add-Member -MemberType ScriptMethod -Name "Unsubscribe" -Value $cimUnsubscribe
$CIMClientObject | Add-Member -MemberType ScriptMethod -Name "IsSubscribed" -Value $cimIsSubscribed

return $CIMClientObject
}

#-------------------------------------------------------------------

Export-ModuleMember -Function 'Add-CIMIndications'