Out-Of-Band RAID Discovery

Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.RaidDiscovery (Discovery)

Discovers Out-Of-Band RAID components

Knowledge Base article:

Summary

This Discovery discovers all supported Fujitsu Out-Of-Band RAID classes and relationships via the integrated Remote Management Controller iRMC S4/S5.

Element properties:

TargetFujitsu.Servers.PRIMERGY.OutOfBand.Server
EnabledTrue
Frequency14400
RemotableFalse

Object Discovery Details:

Discovered Classes and their attribuets:
Discovered relationships and their attribuets:

Member Modules:

ID Module Type TypeId RunAs 
DS DataSource Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.RaidDiscoveryDataSource Default

Source Code:

<Discovery ID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.RaidDiscovery" Target="FujitsuOutOfBand!Fujitsu.Servers.PRIMERGY.OutOfBand.Server" Enabled="true" ConfirmDelivery="false" Remotable="true" Priority="Normal">
<Category>Discovery</Category>
<DiscoveryTypes>
<DiscoveryClass TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem">
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem" PropertyID="ID"/>
<Property TypeID="FTSLIB!Fujitsu.ServerView.HealthCollection" PropertyID="ServerName"/>
<Property TypeID="FTSLIB!Fujitsu.ServerView.HealthCollection" PropertyID="Devices"/>
<Property TypeID="FTSLIB!Fujitsu.ServerView.HealthCollection" PropertyID="DevicesInfo"/>
<Property TypeID="System!System.Entity" PropertyID="DisplayName"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter">
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter" PropertyID="AdapterNumber"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter" PropertyID="ControllerNumber"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter" PropertyID="Vendor"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter" PropertyID="Product"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter" PropertyID="SerialNumber"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter" PropertyID="SASAddress"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter" PropertyID="Protocol"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter" PropertyID="DriverName"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter" PropertyID="DriverVersion"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter" PropertyID="FWPackageVersion"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter" PropertyID="FWBuildDate"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter" PropertyID="BiosVersion"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter" PropertyID="BiosBuildDate"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter" PropertyID="BusType"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter" PropertyID="VendorID"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter" PropertyID="DeviceID"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter" PropertyID="SubVendorID"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter" PropertyID="SubDeviceID"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter" PropertyID="PortCount"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter" PropertyID="SMARTSupport"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ServerName"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ManagementUrl"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ODataType"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ODataId"/>
<Property TypeID="System!System.Entity" PropertyID="DisplayName"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Battery">
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Battery" PropertyID="ID"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Battery" PropertyID="Vendor"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Battery" PropertyID="Product"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Battery" PropertyID="ManufactureDate"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Battery" PropertyID="SerialNumber"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Battery" PropertyID="IntelligentBBU"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Battery" PropertyID="DesignVoltage"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Battery" PropertyID="DesignCapacity"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ServerName"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ManagementUrl"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ODataType"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ODataId"/>
<Property TypeID="System!System.Entity" PropertyID="DisplayName"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDriveGroup">
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup" PropertyID="ID"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup" PropertyID="ServerName"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup" PropertyID="ODataId"/>
<Property TypeID="System!System.Entity" PropertyID="DisplayName"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive">
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive" PropertyID="DriveNumber"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive" PropertyID="LogicalSize"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive" PropertyID="PhysicalSize"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive" PropertyID="VolumeType"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive" PropertyID="RAIDLevel"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive" PropertyID="StripeSize"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive" PropertyID="Encrypted"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive" PropertyID="ReadMode"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive" PropertyID="CacheMode"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive" PropertyID="AccessMode"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive" PropertyID="DiskCacheMode"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ServerName"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ManagementUrl"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ODataType"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ODataId"/>
<Property TypeID="System!System.Entity" PropertyID="DisplayName"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive.Internal">
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="DeviceNumber"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="EnclosureNumber"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="SlotNumber"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="Type"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="MediaType"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="Vendor"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="Product"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="SerialNumber"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="FirmwareVersion"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="PhysicalSize"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="HotSpareType"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="SASAddress"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="TransferSpeed"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="RPM"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="ForeignConfig"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ServerName"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ManagementUrl"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ODataType"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ODataId"/>
<Property TypeID="System!System.Entity" PropertyID="DisplayName"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive.Enclosure">
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="DeviceNumber"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="EnclosureNumber"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="SlotNumber"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="Type"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="MediaType"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="Vendor"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="Product"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="SerialNumber"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="FirmwareVersion"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="PhysicalSize"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="HotSpareType"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="SASAddress"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="TransferSpeed"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="RPM"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive" PropertyID="ForeignConfig"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ServerName"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ManagementUrl"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ODataType"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ODataId"/>
<Property TypeID="System!System.Entity" PropertyID="DisplayName"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDriveGroup.Enclosure">
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup" PropertyID="ID"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup" PropertyID="ServerName"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup" PropertyID="ODataId"/>
<Property TypeID="System!System.Entity" PropertyID="DisplayName"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDriveGroup.Internal">
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup" PropertyID="ID"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup" PropertyID="ServerName"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup" PropertyID="ODataId"/>
<Property TypeID="System!System.Entity" PropertyID="DisplayName"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure">
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure" PropertyID="EnclosureNumber"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure" PropertyID="Vendor"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure" PropertyID="Product"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure" PropertyID="HardwareVersion"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure" PropertyID="SASAddress"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ServerName"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ManagementUrl"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ODataType"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ODataId"/>
<Property TypeID="System!System.Entity" PropertyID="DisplayName"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.SensorGroup">
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup" PropertyID="ID"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup" PropertyID="ServerName"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup" PropertyID="ODataId"/>
<Property TypeID="System!System.Entity" PropertyID="DisplayName"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Sensor">
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Sensor" PropertyID="ID"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Sensor" PropertyID="Location"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ServerName"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ManagementUrl"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ODataType"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ODataId"/>
<Property TypeID="System!System.Entity" PropertyID="DisplayName"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Sensor.NotPresent">
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Sensor.NotPresent" PropertyID="Location"/>
<Property TypeID="FujitsuOutOfBand!Fujitsu.Servers.PRIMERGY.OutOfBand.ComponentNotPresent" PropertyID="ID"/>
<Property TypeID="FujitsuOutOfBand!Fujitsu.Servers.PRIMERGY.OutOfBand.ComponentNotPresent" PropertyID="Status"/>
<Property TypeID="System!System.Entity" PropertyID="DisplayName"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.FanGroup">
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup" PropertyID="ID"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup" PropertyID="ServerName"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup" PropertyID="ODataId"/>
<Property TypeID="System!System.Entity" PropertyID="DisplayName"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Fan">
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Fan" PropertyID="ID"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Fan" PropertyID="Location"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ServerName"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ManagementUrl"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ODataType"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ODataId"/>
<Property TypeID="System!System.Entity" PropertyID="DisplayName"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Fan.NotPresent">
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Fan.NotPresent" PropertyID="Location"/>
<Property TypeID="FujitsuOutOfBand!Fujitsu.Servers.PRIMERGY.OutOfBand.ComponentNotPresent" PropertyID="ID"/>
<Property TypeID="FujitsuOutOfBand!Fujitsu.Servers.PRIMERGY.OutOfBand.ComponentNotPresent" PropertyID="Status"/>
<Property TypeID="System!System.Entity" PropertyID="DisplayName"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.PowerSupplyGroup">
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup" PropertyID="ID"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup" PropertyID="ServerName"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup" PropertyID="ODataId"/>
<Property TypeID="System!System.Entity" PropertyID="DisplayName"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.PowerSupply">
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.PowerSupply" PropertyID="ID"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.PowerSupply" PropertyID="PartNumber"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.PowerSupply" PropertyID="SerialNumber"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.PowerSupply" PropertyID="HardwareVersion"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ServerName"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ManagementUrl"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ODataType"/>
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent" PropertyID="ODataId"/>
<Property TypeID="System!System.Entity" PropertyID="DisplayName"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.PowerSupply.NotPresent">
<Property TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.PowerSupply.NotPresent" PropertyID="Location"/>
<Property TypeID="FujitsuOutOfBand!Fujitsu.Servers.PRIMERGY.OutOfBand.ComponentNotPresent" PropertyID="ID"/>
<Property TypeID="FujitsuOutOfBand!Fujitsu.Servers.PRIMERGY.OutOfBand.ComponentNotPresent" PropertyID="Status"/>
<Property TypeID="System!System.Entity" PropertyID="DisplayName"/>
</DiscoveryClass>
<DiscoveryRelationship TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.Server.Hosts.RaidSubSystem"/>
<DiscoveryRelationship TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem.HostsAdapter"/>
<DiscoveryRelationship TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter.Hosts.Battery"/>
<DiscoveryRelationship TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter.Hosts.LogicalDriveGroup"/>
<DiscoveryRelationship TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter.Hosts.PhysicalDriveGroup.Internal"/>
<DiscoveryRelationship TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter.Hosts.PhysicalDriveGroup.Enclosure"/>
<DiscoveryRelationship TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDriveGroup.Hosts.LogicalDrive"/>
<DiscoveryRelationship TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDriveGroup.Internal.Hosts.PhysicalDrive.Internal"/>
<DiscoveryRelationship TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDriveGroup.Internal.Hosts.PhysicalDrive.SSD.Internal"/>
<DiscoveryRelationship TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDriveGroup.Enclosure.Hosts.PhysicalDrive.Enclosure"/>
<DiscoveryRelationship TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDriveGroup.Enclosure.Hosts.PhysicalDrive.SSD.Enclosure"/>
<DiscoveryRelationship TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter.Hosts.Enclosure"/>
<DiscoveryRelationship TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Hosts.PowerSupplyGroup"/>
<DiscoveryRelationship TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.PowerSupplyGroup.Hosts.PowerSupply"/>
<DiscoveryRelationship TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.PowerSupplyGroup.Hosts.PowerSupply.NotPresent"/>
<DiscoveryRelationship TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Hosts.FanGroup"/>
<DiscoveryRelationship TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.FanGroup.Hosts.Fan"/>
<DiscoveryRelationship TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.FanGroup.Hosts.Fan.NotPresent"/>
<DiscoveryRelationship TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Hosts.SensorGroup"/>
<DiscoveryRelationship TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.SensorGroup.Hosts.Sensor"/>
<DiscoveryRelationship TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.SensorGroup.Hosts.Sensor.NotPresent"/>
</DiscoveryTypes>
<DataSource ID="DS" TypeID="Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.RaidDiscoveryDataSource" Comment="RAID Data Source evaluates the iRMC System Report data">
<!-- Note: default every 4 hours (14400) -->
<IntervalSeconds>14400</IntervalSeconds>
<!-- Note: spread discovery of all running discovery instances over 15 minutes -->
<SpreadInitializationOverInterval>900</SpreadInitializationOverInterval>
<ScriptName>RaidDiscovery.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. #
# #
##################################################################################

param(
$TargetId,
[string]$IP, # Key of Fujitsu iRMC Device
[int] $Port,
[string]$UserName,
[string]$Password,
[string]$SkipCACheck = "False",
[string]$SkipCNCheck = "False",
[string]$RedfishSupported, # from iRMC Object
[string]$UseRedfishSession = "False",
[int] $TimeoutSeconds = 300,
[string]$NetworkName, # Key of Fujitsu.ServerView.Server

[string]$IncludeNotPresentEnclosureSensors = "False",
[string]$IncludeNotPresentEnclosureFans = "False",
[string]$IncludeNotPresentEnclosurePowerSupplies = "False"

)

[string]$SubSystemName = 'RAID'

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

$ScriptApi = New-Object -comObject "MOM.ScriptAPI"
if ($ScriptApi -eq $Null) { Exit -1 }
$discoveryData = $ScriptApi.CreateDiscoveryData(0, "$MPElement$", "$Target/Id$")

[int]$SCRIPT_EVENT_NUMBER = 8803 # a prime
[int]$ERROR_NO_RAID_INFORMATION = 8839 # a prime

# we need to make multiple authenticated HTTP requests...
[System.Net.NetworkCredential]$NetworkCredential = New-Object System.Net.NetworkCredential ($UserName, $Password)
[System.Net.ServicePointManager]::DefaultConnectionLimit = 1000

$Devices = ""
$DevicesInfo = ""

# Import SCOM Cmdlets
$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

$bmcObjectId = [Guid]$TargetId
[int]$NumAdapter = 0
[int]$NumLogicalDrives = 0
[int]$NumPhysicalDisks = 0
[int]$NumEnclosures = 0

# Totally unsupported
Function BailOut
{
$discoveryData.IsSnapshot = $True
$discoveryData
Exit
}

# something went wrong
Function EarlyExit
{
# Close Redfish session if we opened one
if ( ![String]::IsNullOrEmpty($script:RedfishSession) ) {
try {
DebugOut "$IP - Delete Redfish session '$($script:RedfishSession)'"
(doWebRequest -url "$hostURL$($script:RedfishSession)" -Method "DELETE" -XAuthData $script:AuthData) | Out-Null
} catch {}
}

$discoveryData.IsSnapshot = $False
$discoveryData
Exit
}

# Check if there is already an existing RAID object for this discovery.
# If so, mark discovery
Function BailOutAndTestForExisting
{
# Close Redfish session if we opened one
if ( ![String]::IsNullOrEmpty($script:RedfishSession) ) {
try {
DebugOut "$IP - Delete Redfish session '$($script:RedfishSession)'"
(doWebRequest -url "$hostURL$($script:RedfishSession)" -Method "DELETE" -XAuthData $script:AuthData) | Out-Null
} catch {}
}

$discoveryData.IsSnapshot = $True # default to not found ...
try {
$MyObj = Get-SCOMClass -Name 'Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem' | Get-SCOMClassInstance | Where {$_.'[Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice].IP'.Value -eq $IP}
if ($MyObj -ne $Null) {
DebugOut "$IP - Found existing Fujitsu Out-of-Band RAID object - marking discovery incomplete..."
$discoveryData.IsSnapshot = $False
} else {
DebugOut "$IP - Could not find existing Fujitsu Out-of-Band RAID object - giving up"
}
} catch {
DebugErr $SCRIPT_EVENT_NUMBER "$IP - Could not determine existing object. Exception: $_"
}

$discoveryData
Exit
}

Function Main {

$IP = $IP.Trim()

Set-CurrentManagementPackVersion -MpName "Fujitsu.Servers.PRIMERGY.OutOfBand.RAID"
PrepareLogging -Section $SectionRaidDiscovery -HostTag $TagHostsDiscovery -ServerName $IP -CreateSampleLogFile -MpName "Fujitsu.Servers.PRIMERGY.OutOfBand.RAID"

[IPAddress]$IPAddress = $null
if ([system.net.IPAddress]::tryparse($IP,[ref]$IPAddress)) {
if ($IPAddress.AddressFamily.ToString() -eq "Internetwork") {
$hostURL = "https://" +$IPAddress.ToString() +":$($Port)"
} elseif ($IPAddress.AddressFamily.ToString() -eq "Internetworkv6") {
$hostURL = "https://[" +$IPAddress.ToString() +"]:$($Port)"
}
} else {
LogScriptEventWithEventSource -EventSource "Fujitsu Out-Of-Band" -EventLevel $ERROR_LEVEL -EventNumber $SCRIPT_EVENT_NUMBER -Message ("Fujitsu Out-Of-Band RAID Discovery: Invalid IP Address '$($IP)'")
EarlyExit
}

$ServerName = $IP
try {
$ServerInst = Get-SCOMClassInstance -Id $TargetId
$ServerName = $ServerInst.DisplayName
} catch {}

DebugOut "$IP - Start RAID discovery for Fujitsu Out-Of-Band Server '$($ServerName)'"
DebugOut "$IP - Port=$($Port) NetworkName='$($NetworkName)' TimeoutSeconds=$($TimeoutSeconds) SkipCACheck=$($SkipCACheck) SkipCNCheck=$($SkipCNCheck) RedfishSupported=$($RedfishSupported) UseRedfishSession=$($UseRedfishSession) TargetId=$($bmcObjectId)"
DebugOut "$IP - Include Not Present Enclosure Components: Sensors=$($IncludeNotPresentEnclosureSensors) Fans=$($IncludeNotPresentEnclosureFans) PSU=$($IncludeNotPresentEnclosurePowerSupplies)"

# Not set / not available
if ( [String]::IsNullOrEmpty($RedfishSupported) -or ($RedfishSupported -eq $False)) {
DebugOut "$IP - Redfish or iRMC firmware version not supported"
BailOut
}

$ServiceRoot = $Null
DebugOut "$IP - Get Redfish Root Service Information..."
try {
# Note: According to the specification the ServiceRoot should be available unauthenticated;
# but older firmware versions (e.g. iRMC S4 with firmware 8.4x) do not support this or do not know this URL.
# In order to properly detect these systems (and abort), use the provided/available credentials
#$ServiceRoot = (doWebRequest -url "$hostURL/redfish/v1" -Method "GET" -Credentials $Null -XAuthData $Null) | ConvertFrom-JSON
$ServiceRoot = (doWebRequest -url "$hostURL/redfish/v1" -Method "GET" -Credentials $NetworkCredential -XAuthData $Null) | ConvertFrom-JSON
if ($ServiceRoot) {
DebugOut "$IP - '$($ServiceRoot.Name)' Redfish Version=$($ServiceRoot.RedfishVersion) UUID: $($ServiceRoot.UUID)"
if ($ServiceRoot.'@odata.etag' -eq $Null -or $ServiceRoot.'@odata.etag' -eq '') {
DebugOut "$IP - Seems to be an old Redfish instrumentation, giving up..."
BailOut
}
} else {
DebugOut "$IP - Could not get Service Root, giving up. "
BailOutAndTestForExisting
}
} catch {
DebugWarn "$IP - Error getting Service Root, Exception: $_"
EarlyExit
}

# Get the Redfish Storage Information
try {

$script:RedfishSession = $Null
if ($UseRedfishSession -eq $True) {
DebugOut "$IP - try to create a new Redfish session..."
$SessionEntry = (doWebRequest -url "$hostURL$($ServiceRoot.Links.Sessions.'@odata.id')" -Credentials $Null -XAuthData $Null -Method "POST" -RequestData "{'UserName':'$($UserName)','Password':'$($Password)'}" ) | ConvertFrom-JSON

if (!$SessionEntry) {
DebugOut "$IP - Could not create session"
EarlyExit
}

if ($SessionEntry.Error) {
DebugWarn "$IP - ERROR creating session: ErrorCode='$($SessionEntry.Error.code)' Message='$($SessionEntry.Error.message)'"
EarlyExit
}

if ($SessionEntry.'@odata.id' -ne '') {
DebugOut "`tSession for '$($SessionEntry.UserName)' Id=$($SessionEntry.Id) '$($SessionEntry.'@odata.id')'"
$script:RedfishSession = $SessionEntry.'@odata.id'
} else {
DebugWarn "`tSession for '$($SessionEntry.UserName)' Id=$($SessionEntry.Id) - no link"
}
}

DebugOut "$IP - Get System(s) Information ..."
$Systems = $Null
if ($ServiceRoot -and $ServiceRoot.Systems.'@odata.id') {
$Systems = (doWebRequest -url "$hostURL$($ServiceRoot.Systems.'@odata.id')" -Method "GET" -Credentials $NetworkCredential -XAuthData $script:AuthData) | ConvertFrom-JSON
if ($Systems -and $Systems.'[email protected]' -gt 0) {
if ($Systems.'[email protected]' -gt 1) {
DebugOut "$IP - has Information for $($Systems.'[email protected]') Systems..."
}

for ($SystemIdx = 0; $SystemIdx -lt $Systems.'[email protected]'; $SystemIdx++) {
# Note: Modeling multiple systems under one IP Address is currently not planned
if (($Systems.'[email protected]' -gt 1) -and ($SystemIdx -gt 0)) {
DebugOut "$IP - System $($SystemIdx) : Information"
DebugOut "$IP - Multi System Configurations are currently unsupported - IGNORING"
continue
}

$SystemRoot = (doWebRequest -url "$hostURL$($Systems.Members[$SystemIdx].'@odata.id')" -Method "GET" -Credentials $NetworkCredential -XAuthData $script:AuthData) | ConvertFrom-JSON
if ($SystemRoot) {
# Get iRMC Firmware Version info
if ($SystemRoot.Oem.ts_fujitsu) {
$FirmwareInventory = $SystemRoot.Oem.ts_fujitsu.FirmwareInventory
if ($FirmwareInventory -ne $Null -and $FirmwareInventory.'@odata.id' -ne '') {
$Inventory = (doWebRequest -url "$hostURL$($FirmwareInventory.'@odata.id')" -Method "GET" -Credentials $NetworkCredential -XAuthData $script:AuthData) | ConvertFrom-JSON
if ($Inventory) {
DebugOut "$IP - iRMC Firmware='$($Inventory.BMCFirmware)' BuildDate='$($Inventory.BMCFirmwareBuildDate)' Running='$($Inventory.BMCFirmwareRunning)' SDR Version='$($Inventory.SDRRVersion)' SDRRId='$($Inventory.SDRRId)' BIOS='$($Inventory.SystemBIOS)'"
}
}
}

DebugOut "$IP - is a $($SystemRoot.Manufacturer) '$($SystemRoot.Model)' Description='$($SystemRoot.Description)' AssetTag='$($SystemRoot.AssetTag)' Serial='$($SystemRoot.SerialNumber)' PartNumber='$($SystemRoot.PartNumber)'"
DebugOut "$IP - System HostName='$($SystemRoot.HostName)' UUID='$($SystemRoot.UUID)' Indicator LED is '$($SystemRoot.IndicatorLED)'"
DebugOut "$IP - System Status: Health='$($SystemRoot.Status.Health)' State='$($SystemRoot.Status.State)' HealthRollup='$($SystemRoot.Status.HealthRollup)' PowerState='$($SystemRoot.PowerState)'"

if ($SystemRoot.PowerState -eq 'Off') {
DebugOut "$IP - System Power State is '$($SystemRoot.PowerState)' - aborting discovery"
BailOutAndTestForExisting
}

if ($SystemRoot.Storage.'@odata.id' -ne '') {
DebugOut "$IP - Get 'Storage' Information ..."
$StorageRoot = (doWebRequest -url "$hostURL$($SystemRoot.Storage.'@odata.id')" -Method "GET" -Credentials $NetworkCredential -XAuthData $script:AuthData) | ConvertFrom-JSON
if ($StorageRoot) {
DebugOut "$IP - has $($StorageRoot.'[email protected]') Storage Items:"
if ($StorageRoot.'[email protected]' -gt 0) {
DebugOut "$IP - Found RAID SubSystem"

$raidInstance = $discoveryData.CreateClassInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem']$")

# key(s) of hosting chain object(s)
$raidInstance.AddProperty("$MPElement[Name='iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice']/IP$", $IP) # host
$raidInstance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.Server']/NetworkName$", $NetworkName)

$raidInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem']/ID$", $SubSystemName)

$raidInstance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.HealthCollection']/ServerName$" , $ServerName)
$raidInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $SubSystemName)

# Will be reported later ...
#$raidInstance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.HealthCollection']/Devices$" , $Devices) # TODO:
#$raidInstance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.HealthCollection']/DevicesInfo$", $DevicesInfo) # TODO:
#$discoveryData.AddInstance($raidInstance)

# See http://blogs.technet.com/b/mpauthor/archive/2010/12/02/undiscovering-with-multiple-discoveries.aspx
$serverInstance = $discoveryData.CreateClassInstance("$MPElement[Name='FujitsuOutOfBand!Fujitsu.Servers.PRIMERGY.OutOfBand.Server']$")
$serverInstance.AddProperty("$MPElement[Name='iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice']/IP$", $IP) # key
$serverInstance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.Server']/NetworkName$", $NetworkName)
$discoveryData.AddInstance($serverInstance)

# Server hosts RAID SubSystem
$relationship = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.Server.Hosts.RaidSubSystem']$")
$relationship.Source = $serverInstance
$relationship.Target = $raidInstance
$discoveryData.AddInstance($relationship)

for ($StorageIdx = 0; $StorageIdx -lt $StorageRoot.'[email protected]'; $StorageIdx++) {
$Storage = (doWebRequest -url "$hostURL$($StorageRoot.Members[$StorageIdx].'@odata.id')" -Method "GET" -Credentials $NetworkCredential -XAuthData $script:AuthData) | ConvertFrom-JSON
if ($Storage) {
DebugOut "`t'$($Storage.Name)': ID='$($Storage.'@odata.id')'"
DebugOut "`t'$($Storage.Name)': Health='$($Storage.Status.Health)' State='$($Storage.Status.State)' Rollup='$($Storage.Status.HealthRollup)'"

# See http://redfish.dmtf.org/schemas/Storage.v1_1_1.json (StorageControllers is an Array)
if ($Storage.StorageControllers -and $($Storage.StorageControllers.Count) -ne 0) {
DebugOut "`t'$($Storage.Name)': has $($Storage.StorageControllers.Count) Storage Controller(s)"
for ($ControllerIdx = 0; $ControllerIdx -lt $($Storage.StorageControllers.Count); $ControllerIdx++) {
$Controller = $Storage.StorageControllers[$ControllerIdx]

$AdapterName = $Storage.Name
$AdapterNumber = $Storage.Id # TODO: Check if physical ControllerNumber is better suited

$DevicesInfo += "Adapter $($NumAdapter): '$($Storage.Name)'; "
$NumAdapter++

DebugOut "`t`tStorage Controller $($ControllerIdx) ($($AdapterNumber)): Model='$($Controller.Model)' Manufacturer='$($Controller.Manufacturer)' Serial='$($Controller.SerialNumber)' FirmwareVersion='$($Controller.FirmwareVersion)' SpeedGbps='$($Controller.SpeedGbps)' Health='$($Controller.Status.Health)' State='$($Controller.Status.State)' "
DebugOut "`t`tStorage Controller $($ControllerIdx) ($($AdapterNumber)): SKU='$($Controller.SKU)' AssetTag='$($Controller.AssetTag)' PartNum='$($Controller.PartNumber)' "

# SAS Address
$DevIdentifier = ""
if ($Controller.Identifiers.Count -gt 0) {
for ($j = 0; $j -lt $($Controller.Identifiers.Count); $j++) {
if ($j -ne 0) {$DevIdentifier += ", " }
$DevIdentifier += $Controller.Identifiers[$j].DurableName
}
}
if ([string]$DevIdentifier.StartsWith('0x')) {
$DevIdentifier = [string]$DevIdentifier.TrimStart('0x')
}
DebugOut "`t`tIdentifier: '$($DevIdentifier)'"

# PCIe
$BusType = ""
if ($Controller.SupportedControllerProtocols.Count -gt 0) {
for ($j = 0; $j -lt $($Controller.SupportedControllerProtocols.Count); $j++) {
if ($j -ne 0) {$BusType += ", " }
$BusType += $Controller.SupportedControllerProtocols[$j]
}
}
DebugOut "`t`t`SupportedControllerProtocol: '$($BusType)'"

# SAS/SATA
$DeviceProtocol = ""
if ($Controller.SupportedDeviceProtocols.Count -gt 0) {
for ($j = 0; $j -lt $($Controller.SupportedDeviceProtocols.Count); $j++) {
if ($j -ne 0) {$DeviceProtocol += ", " }
$DeviceProtocol += $Controller.SupportedDeviceProtocols[$j]
}
}
DebugOut "`t`t`SupportedDeviceProtocol: '$($DeviceProtocol)'"

$adapterInstance = $discoveryData.CreateClassInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']$")

# key(s) of hosting chain object(s)
$adapterInstance.AddProperty("$MPElement[Name='iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice']/IP$", $IP) # host host host
$adapterInstance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.Server']/NetworkName$", $NetworkName) # host host
$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem']/ID$", $SubSystemName) # host

$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/AdapterNumber$" , $AdapterNumber) # key

$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/Vendor$" , $Controller.Manufacturer)
$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/Product$" , $Controller.Model)
$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/SerialNumber$" , $Controller.SerialNumber)

$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/BusType$" , $BusType)
$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/SASAddress$" , $DevIdentifier)
$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/Protocol$" , $DeviceProtocol)

# Storage Controller OEM Properties
if ($Controller.Oem.ts_fujitsu) {
$OemCtrlExt = $Controller.Oem.ts_fujitsu
DebugOut "`t`tControllerNumber=$($OemCtrlExt.ControllerNumber) FirmwarePackageVersion='$($OemCtrlExt.FirmwarePackageVersion)' FirmwareBuildDate='$($OemCtrlExt.FirmwareBuildDate)' DriverName='$($OemCtrlExt.DriverName)' DriverVersion='$($OemCtrlExt.DriverVersion)'"
DebugOut "`t`tDriveCount=$($OemCtrlExt.DriveCount) VolumeCount=$($OemCtrlExt.VolumeCount) PatrolRead='$($OemCtrlExt.PatrolRead)' Completed='$($OemCtrlExt.CompletedPatrolReadIterations)'"

$VendorId = [string]$OemCtrlExt.VendorId
try {
if ($VendorId.StartsWith('0x')) {
$VendorId = $VendorId.TrimStart('0x')
} else {
$VendorId = "{0:X4}" -f [int]$VendorId
}
} catch {
DebugOut "`t`tVendorId '$($VendorId)': Exception: $_"
$VendorId = "N/A"
}

$DeviceId = [string]$OemCtrlExt.DeviceId
try {
if ($DeviceId.StartsWith('0x')) {
$DeviceId = $DeviceId.TrimStart('0x')
} else {
$DeviceId = "{0:X4}" -f [int]$DeviceId
}
} catch {
DebugOut "`t`tDeviceId '$($DeviceId)': Exception: $_"
$VendorId = "N/A"
}

$SubsystemVendorId = [string]$OemCtrlExt.SubsystemVendorId
try {
if ($SubsystemVendorId.StartsWith('0x')) {
$SubsystemVendorId = $SubsystemVendorId.TrimStart('0x')
} else {
$SubsystemVendorId = "{0:X4}" -f [int]$SubsystemVendorId
}
} catch {
DebugOut "`t`tSubsystemVendorId '$($SubsystemVendorId)': Exception: $_"
$SubsystemVendorId = "N/A"
}

$SubsystemId = [string]$OemCtrlExt.SubsystemId
try {
if ($SubsystemId.StartsWith('0x')) {
$SubsystemId = $SubsystemId.TrimStart('0x')
} else {
$SubsystemId = "{0:X4}" -f [int]$SubsystemId
}
} catch {
DebugOut "`t`tSubsystemId '$($SubsystemId)': Exception: $_"
$SubsystemId = "N/A"
}

$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/ControllerNumber$" , $OemCtrlExt.ControllerNumber)

$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/DriverName$" , $OemCtrlExt.DriverName)
$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/DriverVersion$" , $OemCtrlExt.DriverVersion)
$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/FWPackageVersion$" , $OemCtrlExt.FirmwarePackageVersion)
$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/FWBuildDate$" , $OemCtrlExt.FirmwareBuildDate)

$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/BiosVersion$" , $OemCtrlExt.BiosVersion)
$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/BiosBuildDate$" , $OemCtrlExt.BiosBuildDate)

$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/VendorID$" , $VendorId)
$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/DeviceID$" , $DeviceId)
$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/SubVendorID$" , $SubsystemVendorId)
$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/SubDeviceID$" , $SubsystemId)

$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/PortCount$" , $OemCtrlExt.PortCount)

$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/SMARTSupport$" , $OemCtrlExt.SmartSupport)
# Add additional instrumented properties here ...

}

$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/AdapterName$", $AdapterName)
$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ManagementUrl$", $hostURL)
$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ServerName$", $ServerName)
$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ODataType$", $Storage.'@odata.type')
$adapterInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ODataId$", $Storage.'@odata.id')

$adapterInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $Storage.Name)
$discoveryData.AddInstance($adapterInstance)

# RAID SubSystem hosts Adapter
$relationship = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem.HostsAdapter']$")
$relationship.Source = $raidInstance
$relationship.Target = $adapterInstance
$discoveryData.AddInstance($relationship)

# Optional BBU / Battery attached to the Adapter
if ($Controller.Oem.ts_fujitsu) {
$OemCtrlExt = $Controller.Oem.ts_fujitsu
if ($OemCtrlExt.BackupUnit) {
$Battery = $OemCtrlExt.BackupUnit
DebugOut "`t`tBattery: '$($Battery.Name)' Model='$($Battery.Model)' Vendor='$($Battery.Manufacturer)' ManufacturingDate='$($Battery.ManufacturingDate)' Serial='$($Battery.SerialNumber)' IntelligentBBU='$($Battery.IntelligentBBU)' Temperature=$($Battery.TemperatureC)C Status='$($Battery.Status)'"
DebugOut "`t`t`tVoltage : Design=$($Battery.DesignVoltageV) / Value=$($Battery.VoltageV) Volt"
DebugOut "`t`t`tCapacity: Design=$($Battery.DesignCapacityJ) / Remaining=$($Battery.RemainingCapacityJ) Joule Capacitance=$($Battery.CapacitancePercent)%"

$DevicesInfo += "Battery '$($Battery.Name)'; "

$DesignVoltage = $DesignCapacity = 'N/A'
if ([string]$Battery.DesignVoltageV -ne '') {
$DesignVoltage = [string]$Battery.DesignVoltageV
try {
if ($DesignVoltage.EndsWith('0000')){
$DesignVoltage = $DesignVoltage.Substring(0, $DesignVoltage.LastIndexOf('0000'))
}
} catch {}
$DesignVoltage += ' Volt'
}

if ([string]$Battery.DesignCapacityJ -ne '') {
$DesignCapacity = ([string]$Battery.DesignCapacityJ +' Joule')
}

$Instance = $discoveryData.CreateClassInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Battery']$")

# key(s) of hosting chain object(s)
$Instance.AddProperty("$MPElement[Name='iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice']/IP$", $IP) # host host host host
$Instance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.Server']/NetworkName$", $NetworkName) # host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem']/ID$", $SubSystemName) # host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/AdapterNumber$", $AdapterNumber) # host

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Battery']/ID$" , $Battery.Name) # key

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Battery']/Vendor$" , $Battery.Manufacturer)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Battery']/Product$" , $Battery.Model)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Battery']/ManufactureDate$" , $Battery.ManufacturingDate)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Battery']/SerialNumber$" , $Battery.SerialNumber)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Battery']/DesignVoltage$" , $DesignVoltage )
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Battery']/DesignCapacity$" , $DesignCapacity )
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Battery']/IntelligentBBU$" , $Battery.IntelligentBBU)

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/AdapterName$", $AdapterName)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ManagementUrl$", $hostURL)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ServerName$", $ServerName)

# Note: there is no official Redfish Storage BBU Schema definition
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ODataType$", $OemCtrlExt.'@odata.type' )
# Note: Use the MemberId / Index into the Array of StorageControllers and not the logical Adapter Number
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ODataId$", ($Storage.'@odata.id' +"#/StorageControllers/$($Controller.MemberId)/Oem/ts_fujitsu/BackupUnit") )
#$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ODataId$", ($Storage.'@odata.id' +"#/StorageControllers/$($Storage.Id)/Oem/ts_fujitsu/BackupUnit") )
$Instance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $Battery.Name)
$discoveryData.AddInstance($Instance)

# Adapter hosts Battery
$relationship = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter.Hosts.Battery']$")
$relationship.Source = $adapterInstance
$relationship.Target = $Instance
$discoveryData.AddInstance($relationship)
}
}
}
}

# Storage Enclosures (we need to read them before the Drives for the enclosure number)
$EnclosureList = @()
if ($Storage.Links.'[email protected]' -gt 0) {
DebugOut "`t'$($Storage.Name)': has $($Storage.Links.'[email protected]') Storage Enclosure(s)"
for ($EnclosureIdx = 0; $EnclosureIdx -lt $($Storage.Links.'[email protected]'); $EnclosureIdx++) {
$Enclosure = (doWebRequest -url "$hostURL$($Storage.Links.Enclosures[$EnclosureIdx].'@odata.id')" -Method "GET" -Credentials $NetworkCredential -XAuthData $script:AuthData) | ConvertFrom-JSON
if ($Enclosure) {
$EnclosureList += $Enclosure

$NumEnclosures++

DebugOut "`t`t$($Enclosure.ChassisType) '$($Enclosure.Name)' Model='$($Enclosure.Model)' from '$($Enclosure.Manufacturer)' AssetTag='$($Enclosure.AssetTag)' Serial='$($Enclosure.SerialNumber)' PartNumber='$($Enclosure.PartNumber)'"
DebugOut "`t`t$($Enclosure.ChassisType) Power State is '$($Enclosure.PowerState)' Indicator LED is '$($Enclosure.IndicatorLED)'"
DebugOut "`t`t$($Enclosure.ChassisType) Status: Health='$($Enclosure.Status.Health)' HealthRollup='$($Enclosure.Status.HealthRollup)' State='$($Enclosure.Status.State)' "
if ($Enclosure.Oem.ts_fujitsu) {
$encNumber = $Enclosure.Oem.ts_fujitsu.EnclosureNumber
DebugOut "`t`t$($Enclosure.ChassisType) EnclosureNumber='$($Enclosure.Oem.ts_fujitsu.EnclosureNumber)' ChainNumber='$($Enclosure.Oem.ts_fujitsu.EnclosureChainNumber)' HardwareVersion='$($Enclosure.Oem.ts_fujitsu.HardwareVersion)' EnclosureLogicalId='$($Enclosure.Oem.ts_fujitsu.EnclosureLogicalId)'"
} else {
$encNumber = $Enclosure.Id
DebugOut "`t`t$($Enclosure.ChassisType) EnclosureNumber='$($Enclosure.Id)'"
}

if ($Enclosure.Manufacturer -match 'FTS Cor') {
$ModifiedName = "FUJITSU"
DebugOut "`t`tChanging Manufacturer Name from '$($Enclosure.Manufacturer)' to '$($ModifiedName)'"
$Enclosure.Manufacturer = $ModifiedName

# Also change enclosure name. Some are reported as 'Unknown' others with a valid product name but FTS Corp
$ModifiedName = "$($Enclosure.Manufacturer) $($Enclosure.Model) ($($encNumber))"
DebugOut "`t`tChanging Enclosure Name from '$($Enclosure.Name)' to '$($ModifiedName)'"
$Enclosure.Name = $ModifiedName
}

# 'FTS Cor Unknown (1)' or similar backplane names, while the Model contains valid information / a better name
if ($Enclosure.Name.Contains('Unknown')) {
$ModifiedName = "$($Enclosure.Manufacturer) $($Enclosure.Model) ($($encNumber))"
DebugOut "`t`tChanging Enclosure Name from '$($Enclosure.Name)' to '$($ModifiedName)'"
$Enclosure.Name = $ModifiedName
}

$EnclosureName = $Enclosure.Name

$DevicesInfo += "Enclosure $($encNumber) '$($Enclosure.Name)'; "

$encInstance = $discoveryData.CreateClassInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure']$")

# key(s) of hosting chain object(s)
$encInstance.AddProperty("$MPElement[Name='iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice']/IP$", $IP) # host host host host
$encInstance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.Server']/NetworkName$", $NetworkName) # host host host
$encInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem']/ID$", $SubSystemName) # host host
$encInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/AdapterNumber$", $AdapterNumber) # host

$encInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure']/EnclosureNumber$", $encNumber) # key

$encInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure']/Vendor$" , $Enclosure.Manufacturer)
$encInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure']/Product$" , $Enclosure.Model)
$encInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure']/HardwareVersion$", $Enclosure.Oem.ts_fujitsu.HardwareVersion)
$encInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure']/SASAddress$" , $Enclosure.Oem.ts_fujitsu.EnclosureLogicalId)

$encInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/AdapterName$", $AdapterName)
$encInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ManagementUrl$", $hostURL)
$encInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ServerName$", $ServerName)
$encInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ODataType$", $Enclosure.'@odata.type')
$encInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ODataId$", $Enclosure.'@odata.id')

$encInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $Enclosure.Name)
$discoveryData.AddInstance($encInstance)

# Adapter hosts Enclosure
$relationship = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter.Hosts.Enclosure']$")
$relationship.Source = $adapterInstance
$relationship.Target = $encInstance
$discoveryData.AddInstance($relationship)

if ($Enclosure -and $Enclosure.Thermal.'@odata.id' -ne '') {
DebugOut "`t`t$($Enclosure.ChassisType) '$($Enclosure.Name)' 'Thermal' Information:"
$EnclosureThermal = (doWebRequest -url "$hostURL$($Enclosure.Thermal.'@odata.id')" -Method "GET" -Credentials $NetworkCredential -XAuthData $script:AuthData) | ConvertFrom-JSON
if ($EnclosureThermal) {

# Enclosure Temperatures
if ($EnclosureThermal.'[email protected]' -gt 0) {
$numSensors = 0
for ($j = 0; $j -lt $EnclosureThermal.'[email protected]'; $j++) {
$Item = $EnclosureThermal.Temperatures[$j]
# Note: Slightly different to Chassis Temperatures, UpperCritical is currently reported as UpperFatal
if ($Item -and $Item.Status.State -ne 'UnavailableOffline') {
if ($Item.Oem.ts_fujitsu) {
DebugOut "`t`t`tTemperature '$($Item.Name)': Location='$($Item.Oem.ts_fujitsu.Location)' Value=$($Item.ReadingCelsius)C Upper Warn=$($Item.UpperThresholdNonCritical)C Fatal=$($Item.UpperThresholdFatal)C Health='$($Item.Status.Health)' State='$($Item.Status.State)'"
} else {
DebugOut "`t`t`tTemperature '$($Item.Name)': Value=$($Item.ReadingCelsius)C Upper Warn=$($Item.UpperThresholdNonCritical)C Crit=$($Item.UpperThresholdCritical)C Health='$($Item.Status.Health)' State='$($Item.Status.State)'"
}
} else {
# N/A - no reading available
if ($Item.Oem.ts_fujitsu) {
DebugOut "`t`t`tTemperature '$($Item.Name)': N/A - Location='$($Item.Oem.ts_fujitsu.Location)' Upper Warn=$($Item.UpperThresholdNonCritical)C Fatal=$($Item.UpperThresholdFatal)C Health='$($Item.Status.Health)' State='$($Item.Status.State)'"
} else {
DebugOut "`t`t`tTemperature '$($Item.Name)': N/A - Upper Warn=$($Item.UpperThresholdNonCritical)C Crit=$($Item.UpperThresholdCritical)C Health='$($Item.Status.Health)' State='$($Item.Status.State)'"
}
}

if ( ($IncludeNotPresentEnclosureSensors -eq $False) -and ($Item.Status.State -eq 'UnavailableOffline') ) {
continue
}
$numSensors++
}
DebugOut "`t`tEnclosure_$($encNumber): '$($Enclosure.Name)' has $($numSensors) Temperature Sensors"

if ($numSensors -ne 0) {
$DevicesInfo += "$($numSensors) Temp Sensors; "

$groupName = "Sensors"
$groupInstance = $discoveryData.CreateClassInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.SensorGroup']$")

# key(s) of hosting chain object(s)
$groupInstance.AddProperty("$MPElement[Name='iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice']/IP$", $IP) # host host host host host
$groupInstance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.Server']/NetworkName$", $NetworkName) # host host host host
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem']/ID$", $SubSystemName) # host host host
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/AdapterNumber$" , $AdapterNumber) # host host
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure']/EnclosureNumber$", $encNumber) # host

$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ID$", $groupName) # key
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ServerName$", $ServerName)
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ODataId$", ($Enclosure.Thermal.'@odata.id' +"#/Temperatures"))
$groupInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $groupName)
$discoveryData.AddInstance($groupInstance)

# Enclosure hosts Temperature Sensors Group
$relationship = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Hosts.SensorGroup']$")
$relationship.Source = $encInstance
$relationship.Target = $groupInstance
$discoveryData.AddInstance($relationship)

for ($j = 0; $j -lt $EnclosureThermal.'[email protected]'; $j++) {
$Item = $EnclosureThermal.Temperatures[$j]

if ( ($IncludeNotPresentEnclosureSensors -eq $False) -and ($Item.Status.State -eq 'UnavailableOffline') ) {
continue
}

if ($Item.Status.State -eq 'UnavailableOffline') {
$Instance = $discoveryData.CreateClassInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Sensor.NotPresent']$")

$Instance.AddProperty("$MPElement[Name='iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice']/IP$", $IP) # host host host host host host
$Instance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.Server']/NetworkName$", $NetworkName) # host host host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem']/ID$", $SubSystemName) # host host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/AdapterNumber$" , $AdapterNumber) # host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure']/EnclosureNumber$", $encNumber) # host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ID$" , $groupName) # host

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Sensor.NotPresent']/EnclosureName$", $EnclosureName)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Sensor.NotPresent']/Location$" , $Item.Oem.ts_fujitsu.Location)

$Instance.AddProperty("$MPElement[Name='FujitsuOutOfBand!Fujitsu.Servers.PRIMERGY.OutOfBand.ComponentNotPresent']/ID$" , $Item.Name) # key
$Instance.AddProperty("$MPElement[Name='FujitsuOutOfBand!Fujitsu.Servers.PRIMERGY.OutOfBand.ComponentNotPresent']/Status$" , 'Not installed' )

$Instance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $Item.Name)
$discoveryData.AddInstance($Instance)

# Group hosts item
$relationship = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.SensorGroup.Hosts.Sensor.NotPresent']$")
$relationship.Source = $groupInstance
$relationship.Target = $Instance
$discoveryData.AddInstance($relationship)

} else {
$Instance = $discoveryData.CreateClassInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Sensor']$")

$Instance.AddProperty("$MPElement[Name='iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice']/IP$", $IP) # host host host host host host
$Instance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.Server']/NetworkName$", $NetworkName) # host host host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem']/ID$", $SubSystemName) # host host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/AdapterNumber$" , $AdapterNumber) # host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure']/EnclosureNumber$", $encNumber) # host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ID$" , $groupName) # host

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Sensor']/ID$" , $Item.Name) # key
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Sensor']/EnclosureName$", $EnclosureName)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Sensor']/Location$" , $Item.Oem.ts_fujitsu.Location)

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/AdapterName$", $AdapterName)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ManagementUrl$", $hostURL)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ServerName$", $ServerName)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ODataType$", $Item.Oem.ts_fujitsu.'@odata.type')
# Build from Scratch
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ODataId$", ($EnclosureThermal.'@odata.id' +"#/Temperatures/$($Item.MemberId)") )

$Instance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $Item.Name)
$discoveryData.AddInstance($Instance)

# Group hosts item
$relationship = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.SensorGroup.Hosts.Sensor']$")
$relationship.Source = $groupInstance
$relationship.Target = $Instance
$discoveryData.AddInstance($relationship)
}
}
}
}

# Enclosure Fans
if ($EnclosureThermal.'[email protected]' -gt 0) {
$numFans = 0
for ($j = 0; $j -lt $EnclosureThermal.'[email protected]'; $j++) {
$Item = $EnclosureThermal.Fans[$j]

if ($Item -and $Item.Status.State -ne 'UnavailableOffline') {
# Note: Slightly different to generic Chassis Fans
if ($Item.Oem.ts_fujitsu) {
DebugOut "`t`t`tFan '$($Item.Name)': Location='$($Item.Oem.ts_fujitsu.Location)' Speed='$($Item.Oem.ts_fujitsu.Speed)' Health='$($Item.Status.Health)' State='$($Item.Status.State)' LegacyStatus='$($Item.Oem.ts_fujitsu.LegacyStatus)'"
} else {
DebugOut "`t`t`tFan '$($Item.Name)': PhysicalContext='$($Item.PhysicalContext)' Value=$($Item.Reading)$($Item.ReadingUnits) (Max=$($Item.MaxReadingRange)) Lower Critical=$($Item.LowerThresholdCritical) Health='$($Item.Status.Health)' State='$($Item.Status.State)'"
}
} else {
DebugOut "`t`t`tFan '$($Item.Name)': N/A - Location='$($Item.Oem.ts_fujitsu.Location)' Health='$($Item.Status.Health)' State='$($Item.Status.State)'"
}

if ( ($IncludeNotPresentEnclosureFans -eq $False) -and ($Item.Status.State -eq 'UnavailableOffline') ) {
continue
}

$numFans++
}

DebugOut "`t`tEnclosure_$($encNumber): '$($Enclosure.Name)' has $($numFans) Fans"
if ($numFans -ne 0) {
$DevicesInfo += "$($numFans) Fans; "

$groupName = "Fans"
$groupInstance = $discoveryData.CreateClassInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.FanGroup']$")

# key(s) of hosting chain object(s)
$groupInstance.AddProperty("$MPElement[Name='iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice']/IP$", $IP) # host host host host host
$groupInstance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.Server']/NetworkName$", $NetworkName) # host host host host
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem']/ID$", $SubSystemName) # host host host
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/AdapterNumber$", $AdapterNumber) # host host

$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure']/EnclosureNumber$", $encNumber) # host

$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ID$", $groupName) # key
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ServerName$", $ServerName)
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ODataId$", ($Enclosure.Thermal.'@odata.id' +"#/Fans"))
$groupInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $groupName)
$discoveryData.AddInstance($groupInstance)

# Enclosure hosts Fan Group
$relationship = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Hosts.FanGroup']$")
$relationship.Source = $encInstance
$relationship.Target = $groupInstance
$discoveryData.AddInstance($relationship)

for ($j = 0; $j -lt $EnclosureThermal.'[email protected]'; $j++) {
$Item = $EnclosureThermal.Fans[$j]

if ( ($IncludeNotPresentEnclosureFans -eq $False) -and ($Item.Status.State -eq 'UnavailableOffline') ) {
continue
}

if ($Item -and $Item.Status.State -ne 'UnavailableOffline') {
$Instance = $discoveryData.CreateClassInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Fan']$")

$Instance.AddProperty("$MPElement[Name='iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice']/IP$", $IP) # host host host host host host
$Instance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.Server']/NetworkName$", $NetworkName) # host host host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem']/ID$", $SubSystemName) # host host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/AdapterNumber$" , $AdapterNumber) # host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure']/EnclosureNumber$", $encNumber) # host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ID$" , $groupName) # host

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Fan']/ID$" , $Item.Name) # key
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Fan']/EnclosureName$", $EnclosureName)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Fan']/Location$" , $Item.Oem.ts_fujitsu.Location)

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/AdapterName$", $AdapterName)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ManagementUrl$", $hostURL)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ServerName$", $ServerName)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ODataType$", $Item.Oem.ts_fujitsu.'@odata.type')
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ODataId$", $Enclosure.Links.CooledBy[$j].'@odata.id')
$Instance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $Item.Name)

$discoveryData.AddInstance($Instance)

# Group hosts item
$relationship = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.FanGroup.Hosts.Fan']$")
$relationship.Source = $groupInstance
$relationship.Target = $Instance
$discoveryData.AddInstance($relationship)

} else {
$Instance = $discoveryData.CreateClassInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Fan.NotPresent']$")

$Instance.AddProperty("$MPElement[Name='iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice']/IP$", $IP) # host host host host host host
$Instance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.Server']/NetworkName$", $NetworkName) # host host host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem']/ID$", $SubSystemName) # host host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/AdapterNumber$" , $AdapterNumber) # host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure']/EnclosureNumber$", $encNumber) # host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ID$" , $groupName) # host

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Fan.NotPresent']/EnclosureName$", $EnclosureName)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Fan.NotPresent']/Location$" , $Item.Oem.ts_fujitsu.Location)

$Instance.AddProperty("$MPElement[Name='FujitsuOutOfBand!Fujitsu.Servers.PRIMERGY.OutOfBand.ComponentNotPresent']/ID$" , $Item.Name) # key
$Instance.AddProperty("$MPElement[Name='FujitsuOutOfBand!Fujitsu.Servers.PRIMERGY.OutOfBand.ComponentNotPresent']/Status$" , 'Not installed' )

$Instance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $Item.Name)
$discoveryData.AddInstance($Instance)

# Group hosts item
$relationship = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.FanGroup.Hosts.Fan.NotPresent']$")
$relationship.Source = $groupInstance
$relationship.Target = $Instance
$discoveryData.AddInstance($relationship)

}
}
}
}

} else {
DebugWarn "$IP - Could not get Enclosure Thermal with ID='$($Enclosure.Thermal.'@odata.id')'"
$discoveryData.IsSnapshot = $False
}
} # End of Enclosure.Thermal

if ($Enclosure -and $Enclosure.Power.'@odata.id' -ne '') {
DebugOut "`t`t$($Enclosure.ChassisType) '$($Enclosure.Name)' 'Power' Information:"
$EnclosurePower = (doWebRequest -url "$hostURL$($Enclosure.Power.'@odata.id')" -Method "GET" -Credentials $NetworkCredential -XAuthData $script:AuthData) | ConvertFrom-JSON
if ($EnclosurePower) {

# Enclosure Voltages
if ($EnclosurePower.'[email protected]' -gt 0) {
for ($j = 0; $j -lt $EnclosurePower.'[email protected]'; $j++) {
$Item = $EnclosurePower.Voltages[$j]
if ($Item -and $Item.Status.State -ne 'UnavailableOffline') {
DebugOut "`t`t`tVoltage '$($Item.Name)': PhysicalContext='$($Item.PhysicalContext)' SensorNumber=$($Item.SensorNumber) Value=$($Item.ReadingVolts)V Health='$($Item.Status.Health)' State='$($Item.Status.State)'"
DebugOut "`t`t`t`tThresholds: UpperWarn=$($Item.UpperThresholdNonCritical) UpperCrit=$($Item.UpperThresholdCritical) / LowerWarn=$($Item.LowerThresholdNonCritical) LowerCrit=$($Item.LowerThresholdCritical)"
} else {
DebugOut "`t`t`tVoltage '$($Item.Name)': N/A - PhysicalContext='$($Item.PhysicalContext)' SensorNumber=$($Item.SensorNumber) LegacyStatus='$($Item.Oem.ts_fujitsu.LegacyStatus)'"
}
}
}

# Enclosure PowerSupplies
if ($EnclosurePower.'[email protected]' -gt 0) {

$numPowerSupplies = 0
for ($j = 0; $j -lt $EnclosurePower.'[email protected]'; $j++) {
$Item = $EnclosurePower.PowerSupplies[$j]

if ($Item -and $Item.Status.State -ne 'UnavailableOffline') {
# Note: Slightly different to Chassis PowerSupplies, only Serial#, Part#, HW Revision available
if ($Item.Oem.ts_fujitsu) {
DebugOut "`t`t`tPSU '$($Item.Name)': Serial='$($Item.SerialNumber)' PartNumber='$($Item.PartNumber)' HardwareVersion='$($Item.Oem.ts_fujitsu.HardwareVersion)' Health='$($Item.Status.Health)' State='$($Item.Status.State)'"
} else {
DebugOut "`t`t`tPSU '$($Item.Name)': Model='$($Item.Model)' Manufacturer='$($Item.Manufacturer)' Serial='$($Item.SerialNumber)' PartNumber='$($Item.PartNumber)' Firmware='$($Item.FirmwareVersion)' Health='$($Item.Status.Health)' State='$($Item.Status.State)'"
}

} else {
DebugOut "`t`t`tPSU '$($Item.Name)': N/A"
}

if ( ($IncludeNotPresentEnclosurePowerSupplies -eq $False) -and ($Item.Status.State -eq 'UnavailableOffline') ) {
continue
}
$numPowerSupplies++
}

DebugOut "`t`tEnclosure_$($encNumber): '$($Enclosure.Name)' has $($numPowerSupplies) Power Supplies"

if ($numPowerSupplies -ne 0) {
$DevicesInfo += "$($numPowerSupplies) Power Supplies; "

$groupName = "Power Supplies"
$groupInstance = $discoveryData.CreateClassInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.PowerSupplyGroup']$")

# key(s) of hosting chain object(s)
$groupInstance.AddProperty("$MPElement[Name='iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice']/IP$", $IP) # host host host host host
$groupInstance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.Server']/NetworkName$", $NetworkName) # host host host host
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem']/ID$", $SubSystemName) # host host host
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/AdapterNumber$" , $AdapterNumber) # host host
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure']/EnclosureNumber$", $encNumber) # host

$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ID$", $groupName) # key
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ServerName$", $ServerName)
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ODataId$", ($Enclosure.Power.'@odata.id' +"#/PowerSupplies"))
$groupInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $groupName)
$discoveryData.AddInstance($groupInstance)

# Enclosure hosts Power Supply Group
$relationship = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.Hosts.PowerSupplyGroup']$")
$relationship.Source = $encInstance
$relationship.Target = $groupInstance
$discoveryData.AddInstance($relationship)

for ($j = 0; $j -lt $EnclosurePower.'[email protected]'; $j++) {
$Item = $EnclosurePower.PowerSupplies[$j]

if ( ($IncludeNotPresentEnclosurePowerSupplies -eq $False) -and ($Item.Status.State -eq 'UnavailableOffline') ) {
continue
}

if ($Item.Status.State -eq 'UnavailableOffline') {
$Instance = $discoveryData.CreateClassInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.PowerSupply.NotPresent']$")

$Instance.AddProperty("$MPElement[Name='iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice']/IP$", $IP) # host host host host host host
$Instance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.Server']/NetworkName$", $NetworkName) # host host host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem']/ID$", $SubSystemName) # host host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/AdapterNumber$" , $AdapterNumber) # host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure']/EnclosureNumber$", $encNumber) # host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ID$" , $groupName) # host

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.PowerSupply.NotPresent']/EnclosureName$", $EnclosureName)
$Instance.AddProperty("$MPElement[Name='FujitsuOutOfBand!Fujitsu.Servers.PRIMERGY.OutOfBand.ComponentNotPresent']/ID$" , $Item.Name) # key
$Instance.AddProperty("$MPElement[Name='FujitsuOutOfBand!Fujitsu.Servers.PRIMERGY.OutOfBand.ComponentNotPresent']/Status$" , 'Not installed' )

$Instance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $Item.Name)
$discoveryData.AddInstance($Instance)

# Group hosts item
$relationship = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.PowerSupplyGroup.Hosts.PowerSupply.NotPresent']$")
$relationship.Source = $groupInstance
$relationship.Target = $Instance
$discoveryData.AddInstance($relationship)

} else {
$Instance = $discoveryData.CreateClassInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.PowerSupply']$")

$Instance.AddProperty("$MPElement[Name='iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice']/IP$", $IP) # host host host host host host
$Instance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.Server']/NetworkName$", $NetworkName) # host host host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem']/ID$", $SubSystemName) # host host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/AdapterNumber$" , $AdapterNumber) # host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure']/EnclosureNumber$", $encNumber) # host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ID$" , $groupName) # host

$PartNumber = 'N/A'
$SerialNumber = 'N/A'
$HardwareVersion = 'N/A'
if (![String]::IsNullOrEmpty($Item.PartNumber)) {
$PartNumber = $Item.PartNumber
}
if (![String]::IsNullOrEmpty($Item.SerialNumber)) {
$SerialNumber = $Item.SerialNumber
}
if (![String]::IsNullOrEmpty($Item.Oem.ts_fujitsu.HardwareVersion)) {
$HardwareVersion = $Item.Oem.ts_fujitsu.HardwareVersion
}

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.PowerSupply']/ID$" , $Item.Name) # key
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.PowerSupply']/EnclosureName$" , $EnclosureName)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.PowerSupply']/SerialNumber$" , $SerialNumber)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.PowerSupply']/PartNumber$" , $PartNumber)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.PowerSupply']/HardwareVersion$" , $HardwareVersion)

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/AdapterName$", $AdapterName)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ManagementUrl$", $hostURL)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ServerName$", $ServerName)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ODataType$", $Item.Oem.ts_fujitsu.'@odata.type')
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ODataId$", $Enclosure.Links.PoweredBy[$j].'@odata.id')

$Instance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $Item.Name)
$discoveryData.AddInstance($Instance)

# Group hosts item
$relationship = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Enclosure.PowerSupplyGroup.Hosts.PowerSupply']$")
$relationship.Source = $groupInstance
$relationship.Target = $Instance
$discoveryData.AddInstance($relationship)

}
}
}
}

} else {
DebugWarn "$IP - Could not get Enclosure Power with ID='$($Enclosure.Power.'@odata.id')'"
$discoveryData.IsSnapshot = $False
}
} # End of Enclosure.Power

} else {
DebugWarn "$IP - Could not get Enclosure with ID='$($Storage.Links.Enclosures[$EnclosureIdx].'@odata.id')'"
$discoveryData.IsSnapshot = $False
}
}
}

# Drives (Collection of Links/Ref Id#s)
# See http://redfish.dmtf.org/schemas/Storage.v1_1_1.json
$DriveList = @()
$DriveInstanceList = @{} # Hashtable with @odata.id as key
DebugOut "`t'$($Storage.Name)': has $($Storage.'[email protected]') Drive(s)"
if (($Storage.'[email protected]' -gt 0) -and ($Storage.'[email protected]' -ne $Storage.Drives.Count)) {
DebugWarn "Number of drives and array size does not match!"
}

if ($Storage.Drives -and $($Storage.Drives.Count) -ne 0) {
for ($DriveIdx = 0; $DriveIdx -lt $($Storage.Drives.Count); $DriveIdx++) {
$Drive = (doWebRequest -url "$hostURL$($Storage.Drives[$DriveIdx].'@odata.id')" -Method "GET" -Credentials $NetworkCredential -XAuthData $script:AuthData) | ConvertFrom-JSON
if ($Drive) {
$DriveList += $Drive
DebugOut "`t`tDrive $($DriveIdx): Name='$($Drive.Name)' Model='$($Drive.Model)' Revision='$($Drive.Revision)' Manufacturer='$($Drive.Manufacturer)' Serial='$($Drive.SerialNumber)' CapableSpeedGbps='$($Drive.CapableSpeedGbs)' Health='$($Drive.Status.Health)' State='$($Drive.Status.State)' "
DebugOut "`t`tDrive $($DriveIdx): Protocol='$($Drive.Protocol)' MediaType='$($Drive.MediaType)' HotspareType='$($Drive.HotspareType)'"

$tmpStr = "`t`tDrive $($DriveIdx): IndicatorLED='$($Drive.IndicatorLED)' Allowable Actions: "
for ($j=0; $j -lt $Drive.'[email protected]'.Count; $j++) {
if ($j -ne 0) {$tmpStr += ", " }
$tmpStr += "'$($Drive.'[email protected]'[$j])'"
}
DebugOut $tmpStr

# OEM
if ($Drive.Oem.ts_fujitsu) {
$OemExt = $Drive.Oem.ts_fujitsu
DebugOut "`t`tDrive $($DriveIdx): EnclosureNum='$($OemExt.EnclosureNumber)' DeviceNum='$($OemExt.DeviceNumber)' SlotNum='$($OemExt.SlotNumber)' ForeignConfig='$($OemExt.ForeignConfiguration)' Temperature=$($OemExt.TemperatureC)C PowerStatus='$($OemExt.PowerStatus)' LegacyStatus='$($OemExt.LegacyStatus)'"
}

if ($Drive.Identifiers.Count -eq 1) {
DebugOut "`t`tDrive $($DriveIdx): Identifier: DurableNameFormat='$($Drive.Identifiers[0].DurableNameFormat)' DurableName='$($Drive.Identifiers[0].DurableName)'"
} else {
for ($j = 0; $j -lt $($Drive.Identifiers.Count); $j++) {
$Prop = $Drive.Identifiers[$j]
DebugOut "`t`tDrive $($i): Identifier_$($j): DurableNameFormat='$($Prop.DurableNameFormat)' DurableName='$($Prop.DurableName)'"
}
}

# $Drive.Location[0].InfoFormat.TrimStart('[').TrimEnd(']').Split(':').Trim()
if ($Drive.Location.Count -eq 1) {
DebugOut "`t`tDrive $($DriveIdx): LocationInfo='$($Drive.Location[0].Info)' LocationFormat='$($Drive.Location[0].InfoFormat)'"
&lt;#
# Extract Location Information if needed into custom PS Object with Properties
#$Names = @($Drive.Location[0].InfoFormat.TrimStart('[').TrimEnd(']').Split(':').Trim())
#$Values = @($Drive.Location[0].Info.TrimStart('[').TrimEnd(']').Split(':').Trim())

$Location = $Drive.Location[0].Info.TrimStart('[').TrimEnd(']').Trim() | ConvertFrom-String -Delimiter ':' -PropertyNames @($Drive.Location[0].InfoFormat.TrimStart('[').TrimEnd(']').Split(':').Trim())

DebugOut "ControllerId=$($Location.Controller_Id) EnclosureId=$($Location.Enclosure_Id) SlotId=$($Location.Slot_Id)"
#&gt;
} else {
for ($j = 0; $j -lt $($Drive.Location.Count); $j++) {
$Prop = $Drive.Location[$j]
DebugOut "`t`tDrive $($DriveIdx): Location_$($j): Info='$($Prop.Info)' Format='$($Prop.InfoFormat)'"
}
}

if ($Drive.Links -and $Drives.Links.'[email protected]' -ne 0) {
DebugOut "`t`tDrive $($DriveIdx): is part of $($Drive.Links.'[email protected]') Volume(s)"
for ($j = 0; $j -lt $Drive.Links.'[email protected]'; $j++) {
$Volume = (doWebRequest -url "$hostURL$($Drive.Links.Volumes[$j].'@odata.id')" -Method "GET" -Credentials $NetworkCredential -XAuthData $script:AuthData) | ConvertFrom-JSON
if ($Volume) {
if ($Volume.Oem.ts_fujitsu) {
$OemExt = $Volume.Oem.ts_fujitsu
DebugOut "`t`t`tVolume '$($Volume.Name)': RaidLevel='$($OemExt.RaidLevel)' VolumeType='$($Volume.VolumeType)' Encrypted=$($Volume.Encrypted) CapacityBytes=$($Volume.CapacityBytes) SizeBytes=$($OemExt.SizeBytes) Health='$($Volume.Status.Health)' State='$($Volume.Status.State)'"
DebugOut "`t`t`tVolume '$($Volume.Name)': ReadMode='$($OemExt.ReadMode)' WriteMode='$($OemExt.WriteMode)' CacheMode='$($OemExt.CacheMode)' VolumeNumber='$($OemExt.VolumeNumber)' IndicatorLED='$($OemExt.IndicatorLED)'"
} else {
DebugOut "`t`t`tVolume '$($Volume.Name)': VolumeType='$($Volume.VolumeType)' Encrypted=$($Volume.Encrypted) CapacityBytes=$($Volume.CapacityBytes) Health='$($Volume.Status.Health)' State='$($Volume.Status.State)'"
}
}
}
}

} else {
DebugWarn "$IP - Could not get Drive with ID='$($Storage.Drives[$DriveIdx].'@odata.id')'"
$discoveryData.IsSnapshot = $False
}
}
}

# We have the drives and optional enclosures, sort drives by enclosure or treat them as internal
if ($DriveList.Count) {
$NumPhysicalDisks += $DriveList.Count
# If we have enclosures some or all drives are within these enclosures.
# Group Drives per enclosure
if ($EnclosureList.Count) {
foreach ($Enclosure in $EnclosureList) {
$EnclosureDriveList = @($DriveList | where {$_.Oem.ts_fujitsu.EnclosureNumber -eq ($Enclosure.Oem.ts_fujitsu.EnclosureNumber) } )
Write-Host "Enclosure '$($Enclosure.Name)' on $($Storage.Name) has $($EnclosureDriveList.Count) Drives"
if ($EnclosureDriveList.Count -gt 0) {

$groupName = "Physical Disks '$($Enclosure.Name)'"
$groupInstance = $discoveryData.CreateClassInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDriveGroup.Enclosure']$")

# key(s) of hosting chain object(s)
$groupInstance.AddProperty("$MPElement[Name='iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice']/IP$", $IP) # host host host host
$groupInstance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.Server']/NetworkName$", $NetworkName) # host host host
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem']/ID$", $SubSystemName) # host host
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/AdapterNumber$", $AdapterNumber) # host

$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ID$", $groupName) # key
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ServerName$", $ServerName)
# TODO: Add enclosure information (Note: all drives are still under the Storage Object)
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ODataId$", ($Storage.'@odata.id' +"#/Drives"))
$groupInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $groupName)
$discoveryData.AddInstance($groupInstance)

# Adapter hosts Physical Disk Group
$relationship = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter.Hosts.PhysicalDriveGroup.Enclosure']$")
$relationship.Source = $adapterInstance
$relationship.Target = $groupInstance
$discoveryData.AddInstance($relationship)

foreach ($Drive in $EnclosureDriveList) {
DebugOut "`t`tEnclosure Drive : $($Drive.Protocol) $($Drive.MediaType) Name='$($Drive.Name)' Model='$($Drive.Model)' Revision='$($Drive.Revision)' Manufacturer='$($Drive.Manufacturer)' Serial='$($Drive.SerialNumber)' CapableSpeedGbps='$($Drive.CapableSpeedGbs)' HotspareType='$($Drive.HotspareType)' Health='$($Drive.Status.Health)' State='$($Drive.Status.State)' "
# OEM
if ($Drive.Oem.ts_fujitsu) {
$OemExt = $Drive.Oem.ts_fujitsu
DebugOut "`t`tEnclosure Drive : EnclosureNum='$($OemExt.EnclosureNumber)' DeviceNum='$($OemExt.DeviceNumber)' SlotNum='$($OemExt.SlotNumber)' ForeignConfig='$($OemExt.ForeignConfiguration)' Temperature=$($OemExt.TemperatureC)C PowerStatus='$($OemExt.PowerStatus)' LegacyStatus='$($OemExt.LegacyStatus)'"
}

# SAS Address of Drive
$DevIdentifier = ""
if ($Drive.Identifiers.Count -gt 0) {
for ($j = 0; $j -lt $($Drive.Identifiers.Count); $j++) {
if ($j -ne 0) {$DevIdentifier += ", " }
$DevIdentifier += $Drive.Identifiers[$j].DurableName
}
}
if ([string]$DevIdentifier.StartsWith('0x')) {
$DevIdentifier = [string]$DevIdentifier.TrimStart('0x')
}
DebugOut "`t`tEnclosure Drive : SAS Address: '$($DevIdentifier)'"

$DriveCapacityBytes = [string]$Drive.CapacityBytes
if ( $DriveCapacityBytes.EndsWith('.000000')) {
#$DriveCapacityBytes = $DriveCapacityBytes.TrimEnd('.000000')
$DriveCapacityBytes = $DriveCapacityBytes.Substring(0, $DriveCapacityBytes.LastIndexOf('.'))
}
try {
if ([int64]$DriveCapacityBytes -le (1024*1024*1024)) {
$DriveCapacity = "{0:d} MB" -f ([int64]$DriveCapacityBytes/(1024*1024))
} else {
$DriveCapacity = "{0:f2} GB" -f ([double]$DriveCapacityBytes/(1024*1024*1024))
}
} catch {
DebugOut "`t`tEnclosure Drive '$($Drive.Name)': CapacityBytes=$($DriveCapacityBytes) Exception: $_"
$DriveCapacity = "N/A"
}

$Instance = $discoveryData.CreateClassInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive.Enclosure']$")

# key(s) of hosting chain object(s)
$Instance.AddProperty("$MPElement[Name='iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice']/IP$", $IP) # host host host host host
$Instance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.Server']/NetworkName$", $NetworkName) # host host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem']/ID$", $SubSystemName) # host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/AdapterNumber$", $AdapterNumber) # host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ID$", $groupName) # host

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/EnclosureNumber$" , $Drive.Oem.ts_fujitsu.EnclosureNumber)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/DeviceNumber$" , $Drive.Oem.ts_fujitsu.DeviceNumber) # key
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/SlotNumber$" , $Drive.Oem.ts_fujitsu.SlotNumber)

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/Vendor$" , $Drive.Manufacturer)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/Product$" , $Drive.Model)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/SerialNumber$" , $Drive.SerialNumber)

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/Type$" , $Drive.Protocol)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/MediaType$" , $Drive.MediaType)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/FirmwareVersion$" , $Drive.Revision)

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/PhysicalSize$" , $DriveCapacity)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/HotSpareType$" , $Drive.HotspareType)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/SASAddress$" , $DevIdentifier)

$TransferSpeed = [string]$Drive.CapableSpeedGbs
try {
if ($TransferSpeed.EndsWith('00000')){
$TransferSpeed = $TransferSpeed.Substring(0, $TransferSpeed.LastIndexOf('0000'))
}
} catch {}

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/TransferSpeed$" , "$($TransferSpeed) Gbs" )
# SSD have no RPM and HDD only when not spun down/stopped
if ($Drive.MediaType -ne 'SSD' ) {
if ($Drive.Oem.ts_fujitsu.PowerStatus -eq 'Activated') {
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/RPM$" , $Drive.RotationSpeedRPM )
}
} else {
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/RPM$" , 'N/A' )
}
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/ForeignConfig$" , $Drive.Oem.ts_fujitsu.ForeignConfiguration)

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/AdapterName$", $AdapterName)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ManagementUrl$", $hostURL)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ServerName$", $ServerName)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ODataType$", $Drive.'@odata.type')
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ODataId$", $Drive.'@odata.id')

$Instance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $Drive.Name)
$discoveryData.AddInstance($Instance)

# Add to Drive List for Volumes
$DriveInstanceList["$($Drive.'@odata.id')"] = $Instance

# Group hosts item
$relationship = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDriveGroup.Enclosure.Hosts.PhysicalDrive.Enclosure']$")
$relationship.Source = $groupInstance
$relationship.Target = $Instance
$discoveryData.AddInstance($relationship)

}
}
}
} else {
# No enclosures on Adapter, all drives are considered internal to the adapter
Write-Host "Adapter '$($Storage.Name)' has $($DriveList.Count) internal Drives"
if ($DriveList.Count -gt 0) {

$disk_types = @{}
&lt;#
foreach ($disk in $DriveList) {
$DiskPhysicalSize = [int64]$disk.PhysicalSize # reported in MebiByte
if ($DiskPhysicalSize -ne 0) {
# Convert MebiByte to GigaByte
$DiskSize = [string]([int64](($DiskPhysicalSize * 1024 * 1024)/1000000000)) +" GB"
if ($disk_types.ContainsKey($DiskSize)) {
$count = $disk_types.Get_Item($DiskSize) + 1
$disk_types.Set_Item($DiskSize, $count)
} else {
$disk_types.Add($DiskSize, 1)
}
}
}

$DevicesInfo += "'$($Storage.Name)': Disk Types: "
foreach ($key in $disk_types.Keys) {
$DevicesInfo += "'$($key)': $($disk_types[$key]), "
}
#&gt;

$groupName = "Physical Disks '$($Storage.Name)'"
$groupInstance = $discoveryData.CreateClassInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDriveGroup.Internal']$")

# key(s) of hosting chain object(s)
$groupInstance.AddProperty("$MPElement[Name='iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice']/IP$", $IP) # host host host host
$groupInstance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.Server']/NetworkName$", $NetworkName) # host host host
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem']/ID$", $SubSystemName) # host host
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/AdapterNumber$", $AdapterNumber) # host

$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ID$", $groupName) # key
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ServerName$", $ServerName)
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ODataId$", ($Storage.'@odata.id' +"#/Drives"))
$groupInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $groupName)
$discoveryData.AddInstance($groupInstance)

# Adapter hosts Group
$relationship = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter.Hosts.PhysicalDriveGroup.Internal']$")
$relationship.Source = $adapterInstance
$relationship.Target = $groupInstance
$discoveryData.AddInstance($relationship)

foreach ($Drive in $DriveList) {
DebugOut "`t`tInternal Drive : $($Drive.Protocol) $($Drive.MediaType) Name='$($Drive.Name)' Model='$($Drive.Model)' Revision='$($Drive.Revision)' Manufacturer='$($Drive.Manufacturer)' Serial='$($Drive.SerialNumber)' CapableSpeedGbps='$($Drive.CapableSpeedGbs)' HotspareType='$($Drive.HotspareType)' Health='$($Drive.Status.Health)' State='$($Drive.Status.State)' "
# OEM
if ($Drive.Oem.ts_fujitsu) {
$OemExt = $Drive.Oem.ts_fujitsu
DebugOut "`t`tInternal Drive : EnclosureNum='$($OemExt.EnclosureNumber)' DeviceNum='$($OemExt.DeviceNumber)' SlotNum='$($OemExt.SlotNumber)' ForeignConfig='$($OemExt.ForeignConfiguration)' Temperature=$($OemExt.TemperatureC)C PowerStatus='$($OemExt.PowerStatus)' LegacyStatus='$($OemExt.LegacyStatus)'"
}

# SAS Address of Drive
$DevIdentifier = ""
if ($Drive.Identifiers.Count -gt 0) {
for ($j = 0; $j -lt $($Drive.Identifiers.Count); $j++) {
if ($j -ne 0) {$DevIdentifier += ", " }
$DevIdentifier += $Drive.Identifiers[$j].DurableName
}
}
if ([string]$DevIdentifier.StartsWith('0x')) {
$DevIdentifier = [string]$DevIdentifier.TrimStart('0x')
}
DebugOut "`t`tInternal Drive : SAS Address: '$($DevIdentifier)'"

$DriveCapacityBytes = [string]$Drive.CapacityBytes
if ( $DriveCapacityBytes.EndsWith('.000000')) { # if reported as double
#$DriveCapacityBytes = $DriveCapacityBytes.TrimEnd('.000000')
$DriveCapacityBytes = $DriveCapacityBytes.Substring(0, $DriveCapacityBytes.LastIndexOf('.'))
}
try {
if ([int64]$DriveCapacityBytes -le (1024*1024*1024)) {
$DriveCapacity = "{0:d} MB" -f ([int64]$DriveCapacityBytes/(1024*1024))
} else {
$DriveCapacity = "{0:f2} GB" -f ([double]$DriveCapacityBytes/(1024*1024*1024))
}
} catch {
DebugOut "`t`tInternal Drive '$($Drive.Name)': CapacityBytes=$($DriveCapacityBytes) Exception: $_"
$DriveCapacity = "N/A"
}

$Instance = $discoveryData.CreateClassInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive.Internal']$")

# key(s) of hosting chain object(s)
$Instance.AddProperty("$MPElement[Name='iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice']/IP$", $IP) # host host host host host
$Instance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.Server']/NetworkName$", $NetworkName) # host host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem']/ID$", $SubSystemName) # host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/AdapterNumber$", $AdapterNumber) # host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ID$", $groupName) # host

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/EnclosureNumber$" , 'N/A') # $Drive.Oem.ts_fujitsu.EnclosureNumber
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/DeviceNumber$" , $Drive.Oem.ts_fujitsu.DeviceNumber) # key
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/SlotNumber$" , $Drive.Oem.ts_fujitsu.SlotNumber)

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/Vendor$" , $Drive.Manufacturer)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/Product$" , $Drive.Model)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/SerialNumber$" , $Drive.SerialNumber)

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/Type$" , $Drive.Protocol)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/MediaType$" , $Drive.MediaType)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/FirmwareVersion$" , $Drive.Revision)

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/PhysicalSize$" , $DriveCapacity)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/HotSpareType$" , $Drive.HotspareType)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/SASAddress$" , $DevIdentifier)


$TransferSpeed = [string]$Drive.CapableSpeedGbs
try {
if ($TransferSpeed.EndsWith('00000')){
$TransferSpeed = $TransferSpeed.Substring(0, $TransferSpeed.LastIndexOf('0000'))
}
} catch {}

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/TransferSpeed$" , "$($TransferSpeed) Gbs" )
# SSD have no RPM and HDD only when not spun down/stopped
if ($Drive.MediaType -ne 'SSD' ) {
if ($Drive.Oem.ts_fujitsu.PowerStatus -eq 'Activated') {
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/RPM$" , $Drive.RotationSpeedRPM )
}
} else {
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/RPM$" , 'N/A' )
}
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDrive']/ForeignConfig$" , $Drive.Oem.ts_fujitsu.ForeignConfiguration)

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/AdapterName$", $AdapterName)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ManagementUrl$", $hostURL)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ServerName$", $ServerName)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ODataType$", $Drive.'@odata.type')
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ODataId$", $Drive.'@odata.id')

$Instance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $Drive.Name)
$discoveryData.AddInstance($Instance)

# Add to list for Volumes
$DriveInstanceList["$($Drive.'@odata.id')"] = $Instance

# Group hosts item
$relationship = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.PhysicalDriveGroup.Internal.Hosts.PhysicalDrive.Internal']$")
$relationship.Source = $groupInstance
$relationship.Target = $Instance
$discoveryData.AddInstance($relationship)
}

}
}
}

# Volumes (is a VolumeCollection, so there is only one)
# See http://redfish.dmtf.org/schemas/Storage.v1_1_1.json
# Note: We handle them after the enclosures and drives in order to
# create relationships between volumes and drives
$VolumeList = @()
if ($Storage.Volumes -and $($Storage.Volumes.'@odata.id') -ne '' ) {
DebugOut "`t'$($Storage.Name)': has a Storage Volume Collection"
$Collection = (doWebRequest -url "$hostURL$($Storage.Volumes.'@odata.id')" -Method "GET" -Credentials $NetworkCredential -XAuthData $script:AuthData) | ConvertFrom-JSON

if ($Collection) {
DebugOut "`t'$($Storage.Name)': has $($Collection.'[email protected]') Volume(s):"
if ($Collection.'[email protected]' -gt 0) {
$DevicesInfo += "$($Collection.'[email protected]') Logical Drive(s); "
$NumLogicalDrives += $Collection.'[email protected]'

$groupName = "Logical Drives"
$groupInstance = $discoveryData.CreateClassInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDriveGroup']$")

# key(s) of hosting chain object(s)
$groupInstance.AddProperty("$MPElement[Name='iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice']/IP$", $IP) # host host host host
$groupInstance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.Server']/NetworkName$", $NetworkName) # host host host
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem']/ID$", $SubSystemName) # host host
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/AdapterNumber$", $AdapterNumber) # host

$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ID$", $groupName) # key
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ServerName$", $ServerName)
$groupInstance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ODataId$", $Storage.Volumes.'@odata.id')
$groupInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $groupName)
$discoveryData.AddInstance($groupInstance)

# Adapter hosts Logical Drive Group
$relationship = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter.Hosts.LogicalDriveGroup']$")
$relationship.Source = $adapterInstance
$relationship.Target = $groupInstance
$discoveryData.AddInstance($relationship)

for ($VolumeIdx = 0; $VolumeIdx -lt $Collection.'[email protected]'; $VolumeIdx++) {
$Volume = (doWebRequest -url "$hostURL$($Collection.Members[$VolumeIdx].'@odata.id')" -Method "GET" -Credentials $NetworkCredential -XAuthData $script:AuthData) | ConvertFrom-JSON
if ($Volume) {
$VolumeList += $Volume

DebugOut "`t`tVolume '$($Volume.Name)': VolumeType='$($Volume.VolumeType)' Encrypted=$($Volume.Encrypted) CapacityBytes=$($Volume.CapacityBytes) Health='$($Volume.Status.Health)' State='$($Volume.Status.State)'"

$Instance = $discoveryData.CreateClassInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive']$")

# key(s) of hosting chain object(s)
$Instance.AddProperty("$MPElement[Name='iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice']/IP$", $IP) # host host host host host
$Instance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.Server']/NetworkName$", $NetworkName) # host host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.SubSystem']/ID$", $SubSystemName) # host host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.Adapter']/AdapterNumber$", $AdapterNumber) # host host
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareGroup']/ID$", $groupName) # host

[string]$VolumeLogicalSize = 'N/A'
[string]$VolumePhysicalSize = 'N/A'
[string]$VolumeStripeSize = 'N/A'

$LogicalSize = [string]$Volume.CapacityBytes
if ( $LogicalSize.EndsWith('.000000')) { # if reported as double
#$LogicalSize = $LogicalSize.TrimEnd('.000000')
$LogicalSize = $LogicalSize.Substring(0, $LogicalSize.LastIndexOf('.'))
}

try {
if ([int64]$LogicalSize -le (1024*1024*1024)) {
$VolumeLogicalSize = "{0:d} MB" -f ([int64]$LogicalSize/(1024*1024))
} else {
$VolumeLogicalSize = "{0:f2} GB" -f ([double]$LogicalSize/(1024*1024*1024))
}
} catch {
DebugOut "`t`tVolume '$($Volume.Name)': LogicalSize='$($LogicalSize)' Exception: $_"
$VolumeLogicalSize = "N/A"
}

# Stripe Size
try {
if ([int]$Volume.OptimumIOSizeBytes -le (1024*1024)) {
$VolumeStripeSize = "{0:d} KB" -f ([int]$Volume.OptimumIOSizeBytes/(1024))
} else {
$VolumeStripeSize = "{0:f2} MB" -f ([double]$Volume.OptimumIOSizeBytes/(1024*1024))
}
} catch {
DebugOut "`t`tVolume '$($Volume.Name)': StripeSize='$($Volume.OptimumIOSizeBytes)' Exception: $_"
$VolumeStripeSize = "N/A"
}

if ($Volume.Oem.ts_fujitsu) {
$OemExt = $Volume.Oem.ts_fujitsu
$DriveNum = $OemExt.VolumeNumber

DebugOut "`t`tVolume '$($Volume.Name)': RaidLevel='$($OemExt.RaidLevel)' VolumeType='$($Volume.VolumeType)' Encrypted=$($Volume.Encrypted) CapacityBytes=$($Volume.CapacityBytes) SizeBytes=$($OemExt.SizeBytes) Health='$($Volume.Status.Health)' State='$($Volume.Status.State)'"
DebugOut "`t`tVolume '$($Volume.Name)': ReadMode='$($OemExt.ReadMode)' WriteMode='$($OemExt.WriteMode)' CacheMode='$($OemExt.CacheMode)' VolumeNumber='$($OemExt.VolumeNumber)'"

$PhysicalSize = [string]$OemExt.SizeBytes
if ( $PhysicalSize.EndsWith('.000000')) { # if reported as double
#$PhysicalSize = $PhysicalSize.TrimEnd('.000000')
$PhysicalSize = $PhysicalSize.Substring(0, $PhysicalSize.LastIndexOf('.'))
}

try {
if ([int64]$PhysicalSize -le (1024*1024*1024)) {
$VolumePhysicalSize = "{0:d} MB" -f ([int64]$PhysicalSize/(1024*1024))
} else {
$VolumePhysicalSize = "{0:f2} GB" -f ([double]$PhysicalSize/(1024*1024*1024))
}
} catch {
DebugOut "`t`tVolume '$($Volume.Name)': PhysicalSize='$($PhysicalSize)' Exception: $_"
$VolumePhysicalSize = "N/A"
}

$tmpStr = "`t`tVolume '$($Volume.Name)': IndicatorLED='$($OemExt.IndicatorLED)' Allowable Actions: "
for ($j=0; $j -lt $Volume.Oem.ts_fujitsu.'[email protected]'.Count; $j++) {
if ($j -ne 0) {$tmpStr += ", " }
$tmpStr += "'$($Volume.Oem.ts_fujitsu.'[email protected]'[$j])'"
}
DebugOut $tmpStr

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive']/RAIDLevel$" , $OemExt.RaidLevel)

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive']/ReadMode$" , $OemExt.ReadMode)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive']/CacheMode$" , $OemExt.CacheMode)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive']/AccessMode$" , $OemExt.AccessMode)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive']/DiskCacheMode$", $OemExt.WriteMode) # ???

} else {
# Only Standard Volume Type Properties
$DriveNum = $Volume.Id
}

if ($Volume.Identifiers.Count -eq 1) {
DebugOut "`t`t`tIdentifier: DurableNameFormat='$($Volume.Identifiers[0].DurableNameFormat)' DurableName='$($Volume.Identifiers[0].DurableName)'"
} else {
for ($j = 0; $j -lt $($Volume.Identifiers.Count); $j++) {
$Prop = $Volume.Identifiers[$j]
DebugOut "`t`t`tIdentifier $($j): DurableNameFormat='$($Prop.DurableNameFormat)' DurableName='$($Prop.DurableName)'"
}
}

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive']/DriveNumber$" , $DriveNum) # key

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive']/LogicalSize$" , $VolumeLogicalSize)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive']/PhysicalSize$" , $VolumePhysicalSize)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive']/StripeSize$" , $VolumeStripeSize)

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive']/VolumeType$" , $Volume.VolumeType)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive']/Encrypted$" , $Volume.Encrypted)

$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/AdapterName$", $AdapterName)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ManagementUrl$", $hostURL)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ServerName$", $ServerName)
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ODataType$", $Volume.'@odata.type')
$Instance.AddProperty("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalHardwareComponent']/ODataId$", $Volume.'@odata.id')
$Instance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $Volume.Name)
$discoveryData.AddInstance($Instance)

# Group hosts item
$relationship = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDriveGroup.Hosts.LogicalDrive']$")
$relationship.Source = $groupInstance
$relationship.Target = $Instance
$discoveryData.AddInstance($relationship)

# (Physical) Drives which make up the (Logical) Volume
if ($Volume.Links.'[email protected]' -gt 0) {
DebugOut "`t`tVolume '$($Volume.Name)': is build from $($Volume.Links.'[email protected]') Drive(s) out of $($DriveInstanceList.Count) Drive Instance(s)"

if ($DriveInstanceList.Count -lt $Volume.Links.'[email protected]') {
DebugOut "`t`tVolume '$($Volume.Name)': WARNING: Insufficient $($DriveInstanceList.Count) Drive Instances for $($Volume.Links.'[email protected]') Drive References (Volume spans multiple Controller???)"
}

for ($j = 0; $j -lt $($Volume.Links.'[email protected]'); $j++) {
$DriveInstance = $DriveInstanceList["$($Volume.Links.Drives[$j].'@odata.id')"]
if ($DriveInstance) {
DebugOut "`t`tVolume '$($Volume.Name)': Found referenced Drive Instance"

# Volume references Drive
$relationship = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Fujitsu.Servers.PRIMERGY.OutOfBand.RAID.LogicalDrive.References.PhysicalDrive']$")
$relationship.Source = $Instance
$relationship.Target = $DriveInstance
$discoveryData.AddInstance($relationship)
}
}
}

} else {
DebugWarn "$IP - Could not get Volume with ID='$($Collection.Members[$VolumeIdx].'@odata.id')'"
$discoveryData.IsSnapshot = $False
}
}

}
} else {
DebugWarn "$IP - Could not get Volume Collection with ID='$($Storage.Volumes.'@odata.id')'"
$discoveryData.IsSnapshot = $False
}
}

# Handle Other OEM specific Storage Extension
if ($Storage.Oem.ts_fujitsu) {
$OemExt = $Storage.Oem.ts_fujitsu
DebugOut "`t'$($Storage.Name)': OEM Storage..."
}

} else {
DebugWarn "$IP - Could not get Storage with ID='$($StorageRoot.Members[$StorageIdx].'@odata.id')'"
$discoveryData.IsSnapshot = $False
}
}
}
} else {
DebugWarn "$IP - Could not get Storage Collection Root with ID='$($SystemRoot.Storage.'@odata.id')'"
$discoveryData.IsSnapshot = $False
}
}

# TODO: Wait for SimpleStorage Implementation in iRMC S5 firmware v1.2 to see what we can use
if ($SystemRoot.SimpleStorage.'@odata.id' -ne '') {
DebugOut "$IP - Get 'SimpleStorage' Information ..."
$Items = (doWebRequest -url "$hostURL$($SystemRoot.SimpleStorage.'@odata.id')" -Method "GET" -Credentials $NetworkCredential -XAuthData $script:AuthData) | ConvertFrom-JSON
if ($Items) {
DebugOut "$IP - Simple Storage with UefiDevicePath='$($Items.UefiDevicePath)' has $($Items.'[email protected]') SimpleStorage Device(s):"

for ($idx = 0; $idx -lt $Items.'[email protected]'; $idx++) {
$Item = (doWebRequest -url "$hostURL$($Items.Members[$idx].'@odata.id')" -Method "GET" -Credentials $NetworkCredential -XAuthData $script:AuthData) | ConvertFrom-JSON
# See SimpleStorage.1.1.1.json
if ($Item) {
DebugOut "`t'$($Item.Name)': Manufacturer='$($Item.Manufacturer)' Model='$($Item.Model)' CapacityBytes=$($Item.CapacityBytes) Health='$($Item.Status.Health)' State='$($Item.Status.State)'"
if ($Item.Oem.ts_fujitsu) {
$OemExt = $Item.Oem.ts_fujitsu
DebugOut "`t'$($Item.Name)': OEM Simple Storage... "
}
} else {
DebugWarn "$IP - Could not get Simple Storage Drive with ID='$($Items.Members[$idx].'@odata.id')'"
# $discoveryData.IsSnapshot = $False
}
}
} else {
DebugWarn "$IP - Could not get Simple Storage Collection with ID='$($SystemRoot.SimpleStorage.'@odata.id')'"
# $discoveryData.IsSnapshot = $False
}
}

if ($raidInstance -ne $Null) {

# Update (Singular vs. Plural)
if ($NumAdapter -eq 1) { $Devices = "$($NumAdapter) Adapter; " }
else { $Devices = "$($NumAdapter) Adapters; " }

if ($NumLogicalDrives -eq 1) { $Devices += "$($NumLogicalDrives) Logical Drive; " }
else { $Devices += "$($NumLogicalDrives) Logical Drives; "}

if ($NumPhysicalDisks -eq 1) { $Devices += "$($NumPhysicalDisks) Physical Disk; " }
else { $Devices += "$($NumPhysicalDisks) Physical Disks; " }

if ($NumEnclosures -ne 0) {
if ($NumEnclosures -eq 1) { $Devices += "$($NumEnclosures) Enclosure" }
else { $Devices += "$($NumEnclosures) Enclosures" }
}
DebugOut "$IP - Devices='$($Devices)'"
DebugOut "$IP - DevicesInfo='$($DevicesInfo)'"
$raidInstance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.HealthCollection']/Devices$" , $Devices)
$raidInstance.AddProperty("$MPElement[Name='FTSLIB!Fujitsu.ServerView.HealthCollection']/DevicesInfo$", $DevicesInfo)
$discoveryData.AddInstance($raidInstance)

}

} else {
DebugWarn "$IP - Could not get System Root"
$discoveryData.IsSnapshot = $False
}
}
}
}

if ($UseRedfishSession -eq $True){
DebugOut "$IP - Delete Redfish session '$($script:RedfishSession)'"
(doWebRequest -url "$hostURL$($script:RedfishSession)" -Method "DELETE" -XAuthData $script:AuthData) | Out-Null
}

} catch {
DebugErr $SCRIPT_EVENT_NUMBER "$IP - RAID Discovery: Exception=$_"
LogScriptEventWithEventSource -EventSource $IP -EventLevel $WARNING_LEVEL -EventNumber $SCRIPT_EVENT_NUMBER -Message ("Fujitsu Out-Of-Band RAID Discovery: Exception=$_")
$discoveryData.IsSnapshot = $False
}

#############################################################################################

DebugOut "$IP - Finished RAID discovery for Fujitsu Out-Of-Band Server"
$discoveryData
}

# This script part contains helper functions to perform web based requests
# and is embedded into the final script via Visual Studio Authoring Extensions

[int]$DEFAULT_REQUEST_TIMEOUT = 30 # seconds
[int]$DEFAULT_RETRY_INCREMENT = 10 # seconds
[int]$MAX_REQUEST_RETRIES = 3

[int]$ERROR_SSL_CA_ERROR = 8399 # is not a prime
[int]$ERROR_SSL_CN_ERROR = 8499 # is not a prime

[int]$ERROR_BMC_NO_RESPONSE = 8599 # is a prime
[int]$ERROR_BMC_NO_ACCESS = 8699 # is a prime
[int]$ERROR_BMC_TIMEOUT = 8799 # is not a prime
[int]$ERROR_BMC_NO_PERMISSION = 8899 # is not a prime
[int]$ERROR_BMC_BUSY = 8999 # is a prime

# Subset of possible HTTP error codes
[int]$HTTP_RC_CONTINUE = 100
[int]$HTTP_RC_OK = 200
[int]$HTTP_RC_CREATED = 201
[int]$HTTP_RC_ACCEPTED = 202
[int]$HTTP_RC_NO_CONTENT = 204
[int]$HTTP_RC_RESET_CONTENT = 205
[int]$HTTP_RC_PARTIAL_CONTENT = 206

[int]$HTTP_RC_MULTIPLE_CHOICES = 300
[int]$HTTP_RC_MOVED_PERMANENTLY = 301
[int]$HTTP_RC_MOVED_TEMPORARILY = 302
[int]$HTTP_RC_NOT_MODIFIED = 304

[int]$HTTP_RC_BAD_REQUEST = 400
[int]$HTTP_RC_UNAUTHORIZED = 401
[int]$HTTP_RC_FORBIDDEN = 403
[int]$HTTP_RC_NOT_FOUND = 404
[int]$HTTP_RC_METHOD_NOT_ALLOWED = 405
[int]$HTTP_RC_NOT_ACCEPTABLE = 406
[int]$HTTP_RC_REQ_TIMEOUT = 408

[int]$HTTP_RC_SERVER_ERROR = 500
[int]$HTTP_RC_NOT_IMPLEMENTED = 501
[int]$HTTP_RC_SERVICE_UNAVAILABLE = 503

[bool]$script:SSL_CA_ERROR = $False
[bool]$script:SSL_CN_ERROR = $False
[bool]$script:SSL_NO_CERT_ERROR = $False

[bool]$script:iRMCDetected = $False
[string]$script:WebServer = ""
[System.Net.HttpStatusCode]$script:httpStatusCode = [System.Net.HttpStatusCode]::OK

[System.Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls

[string]$script:AuthData = $Null
[string]$script:Location = $Null
[string]$script:RedfishSession = $Null


$SslCertificateValidator =
{
Param (
[System.Object] $obj,
[System.Security.Cryptography.X509Certificates.X509Certificate] $certificate,
[System.Security.Cryptography.X509Certificates.X509Chain] $chain,
[System.Net.Security.SslPolicyErrors] $errors
)

if ($errors -eq [System.Net.Security.SslPolicyErrors]::None) {
return $True
}

if (($errors -band [System.Net.Security.SslPolicyErrors]::RemoteCertificateChainErrors) -and ($SkipCACheck -eq $False)) {
$script:SSL_CA_ERROR = $True
return $False
}

if (($errors -band [System.Net.Security.SslPolicyErrors]::RemoteCertificateNameMismatch) -and ($SkipCNCheck -eq $False)) {
$script:SSL_CN_ERROR = $True
return $False
}

# No cert provided
if ($errors -band [System.Net.Security.SslPolicyErrors]::RemoteCertificateNotAvailable) {
$script:SSL_NO_CERT_ERROR = $True
return $False
}

# All checks passed
return $True
}

# Will return $Null on error
Function DoWebRequest(
[String]$url,
[string]$Method = "GET",
[string]$AuthType = "Basic",
[System.Net.NetworkCredential]$Credentials = $NetworkCredential ,
[String]$RequestData = $Null,
[int] $RequestTimeout = $DEFAULT_REQUEST_TIMEOUT,
[switch]$IgnoreNoPermission,
[switch]$IgnoreTimeout,
[int] $MaxRetries = $MAX_REQUEST_RETRIES,

[string]$ContentType = "application/json; charset=UTF-8", # default for Redfish
[string]$XAuthData = $Null,
[string]$Etag = $Null
)
{
[bool]$ToggleProxy = $False
if ($MaxRetries -gt $MAX_REQUEST_RETRIES) { $MaxRetries = $MAX_REQUEST_RETRIES }
[int]$retries = 0;
for ($retries = 0; $retries -lt $MaxRetries; $retries++) {
try {
[string]$errorMsg = $Null

$script:SSL_CN_ERROR = $False
$script:SSL_CA_ERROR = $False
$script:SSL_NO_CERT_ERROR = $False

$webRequest = [System.Net.WebRequest]::Create($url)
if ($Credentials -ne $Null) {
if ($AuthType -eq "Basic") {
# Do not wait for the 401 response, send the credentials with the initial request
$AuthData = [Convert]::ToBase64String([Text.Encoding]::Default.GetBytes($Credentials.UserName + ':' + $Credentials.Password));
$webRequest.Headers.Add('Authorization', "Basic $AuthData")

$webRequest.Credentials = $Null
$webRequest.PreAuthenticate = $False
# $webRequest.UseDefaultCredentials = $False
$webRequest.KeepAlive = $False # make sure the connection is not re-used
} else {
$webRequest.Credentials = $Credentials
$webRequest.PreAuthenticate = $True
}
} else {
$webRequest.Credentials = $Null
$webRequest.PreAuthenticate = $False
}
# $webRequest.PreAuthenticate = $False
# $webRequest.UseDefaultCredentials = $false

$webRequest.Timeout = ($RequestTimeout *1000)
$webRequest.ReadWriteTimeout = ($RequestTimeout *1000)
$webRequest.Method = $Method
# $webRequest.Accept = "application/json"
$webRequest.Accept = "*/*"
$webRequest.KeepAlive = $False # make sure the connection is not re-used
$webRequest.AllowAutoRedirect = $False # Do not follow redirects

$webRequest.Headers.Add("OData-Version", "4.0")

# Add only if there is no regular credential
if ($XAuthData.Length -gt 0) {
$webRequest.Headers.Add("X-Auth-Token", $XAuthData)
}

# Add only if present
if ($Etag.Length -gt 0) {
$webRequest.Headers.Add("If-Match", $Etag)
}

# Discovery and Monitoring workflow scripts typically run without a proxy configured.
# Performance Collection workflow scripts typically run with proxy configuration
$Proxy = $WebRequest.Proxy
if ($Proxy) {
$ProxyBypassed = $Proxy.IsBypassed($url)
if ($ProxyBypassed) {
DebugOut "$IP - $($Method) '$($url)' No Proxy (direct connection) will be used"
} else {
$ProxyAddress = $Proxy.GetProxy($url).AbsoluteUri
DebugOut "$IP - $($Method) '$($url)' Proxy '$($ProxyAddress)' will be used"
}
} else {
DebugOut "$IP - $($Method) '$($url)' No Proxy object (direct connection)"
}
if (!$ProxyBypassed -and $ToggleProxy ) {
DebugOut "$IP - $($Method) '$($url)' (Re)Trying without Proxy..."
$webRequest.Proxy = $Null
$ToggleProxy = $False
}

try {
$webRequest.ServicePoint.ConnectionLimit = 128
$webRequest.ServicePoint.ConnectionLeaseTimeout = 0 # Close Connection after servicing a request
$webRequest.ServicePoint.MaxIdleTime = 1 # in MilliSeconds, close connection afterwards
$webRequest.ServerCertificateValidationCallback = $SslCertificateValidator

# DebugOut "$IP - $($Method) '$url' HASH=$($webRequest.ServicePoint.GetHashCode()) ConnectionLimit=$($webRequest.ServicePoint.ConnectionLimit)"
} catch {
DebugErr 9999 "$IP - $($Method) '$url' - Could not set extended config Exception=$_"
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = $SslCertificateValidator
}

if ($RequestData.Length -gt 0) {
$webRequest.ContentType = $ContentType

[bool]$bSendError = $False
[System.Timespan]$reqTime = Measure-Command {
try {
$buffer = [System.Text.Encoding]::UTF8.GetBytes($RequestData)
$webRequest.ContentLength = $buffer.Length;
$requestStream = $webRequest.GetRequestStream()
if ($requestStream) {
$requestStream.Write($buffer, 0, $buffer.Length)
$requestStream.Flush()
$requestStream.Close()
}
} catch [System.Net.WebException] {
$errorMsg = $_.Exception.Message
$stackTrace = $_.Exception.StackTrace
$innerException = $_.Exception.InnerException
$bSendError = $True
} catch {
DebugOut "$IP - $($Method) '$url' could not send request data. Timeout was $($RequestTimeout) seconds. Exception=$_"
$bSendError = $True
}
}

if ($bSendError) {
# If the connection gets closed during early send we retry
# this is typically within a few seconds, otherwise the configured timeout would have expired
if ($reqTime -ne $Null -and [int]$reqTime.TotalSeconds -lt 5) {
[int]$retryDelay = (($retries +1) * $DEFAULT_RETRY_INCREMENT)
if ($errorMsg -ne $Null) { DebugWarn "$IP - $($Method) '$url' could not send request data within $($reqTime.TotalSeconds) seconds - will retry in $retryDelay seconds ($errorMsg)"}
else { DebugWarn "$IP - $($Method) '$url' could not send request data within $($reqTime.TotalSeconds) seconds - will retry in $retryDelay seconds (no details available)"}
if ($innerException -ne $Null) { DebugWarn "InnerException:`r`n$innerException" }
if ($stackTrace -ne $Null ) { DebugWarn "Stack Trace:`r`n$stackTrace" }
Start-Sleep -Seconds $retryDelay
continue
} else {
DebugOut "$IP - $($Method) '$url' could not send request data within $($reqTime.TotalSeconds) seconds. Timeout was $($RequestTimeout) seconds"
# Note: do no report actual timeout seconds here, or alert suppression will not fully work due to different text
if (!$IgnoreTimeout.IsPresent) {
LogScriptEventWithEventSource -EventSource $IP -EventLevel $WARNING_LEVEL -EventNumber $ERROR_BMC_TIMEOUT -Message ("'$url' could not send request data. Timeout was $($RequestTimeout) seconds")
}
return
}
}
}

[System.Net.HttpWebResponse] $webResponse = $Null

[System.Timespan]$resTime = Measure-Command {

try {
$webResponse= $webRequest.GetResponse()
} catch [System.Net.WebException] {
$webResponse = $_.Exception.Response
$errorMsg = $_.Exception.Message
$stackTrace = $_.Exception.StackTrace
$innerException = $_.Exception.InnerException
# DebugOut "$IP - '$url' ... Web Exception: $_"
} catch {
$webResponse = $Null
# DebugOut "$IP - '$url' ... Generic Exception: $_"
}
}

# No longer needed ...
$webRequest = $Null

if ($webResponse -ne $Null) {
$script:Location = $webResponse.GetResponseHeader("Location") # $webResponse.Headers.Get("Location")
$script:WebServer = $webResponse.GetResponseHeader("Server") # $webResponse.Headers.Get("Server")
$script:httpStatusCode = $($webResponse.StatusCode.value__)

[System.Net.WebHeaderCollection]$Headers = $webResponse.Headers
if ($Headers) {
[string]$Header = $Headers.Get("X-Auth-Token")
if ($Header.Length -gt 0) {
$script:AuthData = $Header
}

# POST/PUT etc. return created object in 'Location' header, also redirects
if ($Method -ne "GET") {
$Header = $Headers.Get("Location")
if ($Header.Length -gt 0) {
$script:Location = $Header
}
}
}

if ( $script:iRMCDetected -eq $False ){
if ($script:WebServer -match "iRMC") {
$script:iRMCDetected = $True
}
}
$responseStream = New-Object System.IO.StreamReader($webResponse.GetResponseStream())
$result = $responseStream.ReadToEnd()
$responseStream.Close()
$webResponse.Close()

$responseStream = $Null
$webResponse = $Null

switch ( [int]$script:httpStatusCode ) {
$HTTP_RC_OK { # 200
DebugOut "$IP - $($Method) '$url' request handled within $($resTime.TotalSeconds) seconds..."
return $result
}
$HTTP_RC_CREATED { # 201
DebugOut "$IP - $($Method) '$url' resource created within $($resTime.TotalSeconds) seconds (201)..."
return $result
}
$HTTP_RC_ACCEPTED { # 202
DebugOut "$IP - $($Method) '$url' request accepted within $($resTime.TotalSeconds) seconds (202)..."
return $result
}
$HTTP_RC_NO_CONTENT { # 204
DebugOut "$IP - $($Method) '$url' request handled within $($resTime.TotalSeconds) seconds (204 no content)..."
return $result
}
$HTTP_RC_MOVED_PERMANENTLY { # 301
DebugOut "$IP - '$url' permanently redirected to '$($script:Location)' (301)"
if ($script:Location -match "login") {
LogScriptEventWithEventSource -EventSource $IP -EventLevel $WARNING_LEVEL -EventNumber $ERROR_BMC_NO_ACCESS -Message ("Invalid credentials")
$script:httpStatusCode = [System.Net.HttpStatusCode]::Unauthorized
}
return
}
$HTTP_RC_MOVED_TEMPORARILY { # 302
DebugOut "$IP - '$url' temporary redirected to '$($script:Location)' (302)"
if ($script:Location -match "login") {
LogScriptEventWithEventSource -EventSource $IP -EventLevel $WARNING_LEVEL -EventNumber $ERROR_BMC_NO_ACCESS -Message ("Invalid credentials")
$script:httpStatusCode = [System.Net.HttpStatusCode]::Unauthorized
}
return
}
$HTTP_RC_UNAUTHORIZED { # 401
LogScriptEventWithEventSource -EventSource $IP -EventLevel $WARNING_LEVEL -EventNumber $ERROR_BMC_NO_ACCESS -Message ("Invalid credentials")
return
}
$HTTP_RC_FORBIDDEN { # 403
DebugOut "$IP - $($Method) '$url' No permission (403)..."
if (!$IgnoreNoPermission.IsPresent) {
LogScriptEventWithEventSource -EventSource $IP -EventLevel $WARNING_LEVEL -EventNumber $ERROR_BMC_NO_PERMISSION -Message ("No permission (403)")
}
return
}
$HTTP_RC_NOT_FOUND { # 404
return
}
$HTTP_RC_SERVER_ERROR { # 500
return
}
$HTTP_RC_NOT_IMPLEMENTED { # 501
return
}
}

# If we get here some other error occurred (e.g. 503 Service unavailable)
# If this was the first attempt and a proxy was active (e.g. performance collection workflow script), try again without proxy
if (!$ProxyBypassed -and $retries -eq 0) {
DebugOut "$IP - $($Method) '$url' iRMC reported HTTP Status Code ($([int]$script:httpStatusCode) / $($script:httpStatusCode)) - will retry without proxy"
$ToggleProxy = $True
continue
}

if ($retries -lt ($MAX_REQUEST_RETRIES)) {
[int]$retryDelay = (($retries +1) * $DEFAULT_RETRY_INCREMENT)
DebugOut "$IP - $($Method) '$url' iRMC reported HTTP Status Code (($([int]$script:httpStatusCode) / $($script:httpStatusCode)) - will retry in $($retryDelay) seconds"
Start-Sleep -Seconds $retryDelay
continue
} else {
DebugErr $ERROR_BMC_BUSY "$IP - $($Method) '$url' - iRMC reported final HTTP Status Code (($([int]$script:httpStatusCode) / $($script:httpStatusCode)), giving up after retries"
return
}

} else {

# Check for SSL related errors
if ($script:SSL_CN_ERROR -eq $True) {
LogScriptEventWithEventSource -EventSource $IP -EventLevel $INFO_LEVEL -EventNumber $ERROR_SSL_CN_ERROR -Message ("Certificate Common Name (CN) Mismatch")
DebugOut "$IP - '$url' Certificate Name (CN) Mismatch ..."
return
} elseif ($script:SSL_CA_ERROR -eq $True) {
LogScriptEventWithEventSource -EventSource $IP -EventLevel $INFO_LEVEL -EventNumber $ERROR_SSL_CA_ERROR -Message ("Certificate Authority (CA) or Certificate Chain Error")
DebugOut "$IP - '$url' Certificate Authority (CA) or Chain Error ..."
return
} elseif ($script:SSL_NO_CERT_ERROR -eq $True) {
LogScriptEventWithEventSource -EventSource $IP -EventLevel $INFO_LEVEL -EventNumber $ERROR_SSL_ERROR -Message ("No Certificate present")
DebugOut "$IP - '$url' No Certificate present ..."
return
}

# no response (object), check for the timeout value.
# If the connection gets closed during early send/receive,
# this is typically within a few seconds, otherwise the configured timeout would have expired
if ($resTime -ne $Null -and [int]$resTime.TotalSeconds -lt 5) {
[int]$retryDelay = (($retries +1) * $DEFAULT_RETRY_INCREMENT)
if ($retries -ne 0) {
# LogScriptEventWithEventSource -EventSource $IP -EventLevel $WARNING_LEVEL -EventNumber $ERROR_BMC_NO_RESPONSE -Message ("'$url' no response / connection closed ")
if ($errorMsg -ne $Null) { DebugWarn "$IP - $($Method) '$url' no response / connection closed within $($resTime.TotalSeconds) seconds - will retry in $retryDelay seconds ($errorMsg)"}
else { DebugWarn "$IP - $($Method) '$url' no response / connection closed within $($resTime.TotalSeconds) seconds - will retry in $retryDelay seconds (no details available)"}
if ($innerException -ne $Null) { DebugWarn "InnerException:`r`n$innerException" }
if ($stackTrace -ne $Null ) { DebugWarn "Stack Trace:`r`n$stackTrace" }
}
Start-Sleep -Seconds $retryDelay
} else {
# Note: do no report actual timeout seconds here, or alert suppression will not fully work due to different text
if (!$IgnoreTimeout.IsPresent) {
LogScriptEventWithEventSource -EventSource $IP -EventLevel $WARNING_LEVEL -EventNumber $ERROR_BMC_TIMEOUT -Message ("'$url' no response. Timeout was $($RequestTimeout) seconds")
}
DebugOut "$IP - $($Method) '$url' no response within $($resTime.TotalSeconds) seconds. Timeout was $($RequestTimeout) seconds"
return
}
}
} catch {
# LogScriptEventWithEventSource -EventSource $IP -EventLevel $WARNING_LEVEL -EventNumber $SCRIPT_EVENT_NUMBER -Message ("'$url' generic Exception=$_")
[int]$retryDelay = (($retries +1) * $DEFAULT_RETRY_INCREMENT)
DebugWarn "$IP - $($Method) '$url' generic Exception. will retry in $retryDelay seconds. Exception=$_"
Start-Sleep -Seconds $retryDelay
}
}
if (!$IgnoreTimeout.IsPresent) {
LogScriptEventWithEventSource -EventSource $IP -EventLevel $WARNING_LEVEL -EventNumber $ERROR_BMC_NO_RESPONSE -Message ("'$url' no response after $retries retries (last error: $errorMsg)")
}
DebugOut "$IP - $($Method) '$url' no response after $retries retries (last error: $errorMsg)"
}



# 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>300</TimeoutSeconds>
<StrictErrorHandling>false</StrictErrorHandling>
<IP>$Target/Host/Property[Type="iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice"]/IP$</IP>
<Port>$Target/Host/Property[Type="iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice"]/Port$</Port>
<UserName>$RunAs[Name="iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.MonitoringProfile"]/UserName$</UserName>
<Password>$RunAs[Name="iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.MonitoringProfile"]/Password$</Password>
<SkipCACheck>$Target/Host/Property[Type="iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice"]/SkipCACheck$</SkipCACheck>
<SkipCNCheck>$Target/Host/Property[Type="iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice"]/SkipCNCheck$</SkipCNCheck>
<RedfishSupported>$Target/Host/Property[Type="iRMC!Fujitsu.Servers.PRIMERGY.OutOfBand.iRMC.iRMCDevice"]/RedfishSupported$</RedfishSupported>
<UseRedfishSession>false</UseRedfishSession>
<NetworkName>$Target/Property[Type="FTSLIB!Fujitsu.ServerView.Server"]/NetworkName$</NetworkName>
<IncludeNotPresentEnclosureSensors>true</IncludeNotPresentEnclosureSensors>
<IncludeNotPresentEnclosureFans>true</IncludeNotPresentEnclosureFans>
<IncludeNotPresentEnclosurePowerSupplies>true</IncludeNotPresentEnclosurePowerSupplies>
</DataSource>
</Discovery>