I have a module with a function that collects the firmware versions on HP servers using the HPRESTCmdlets module found on the gallery. The function assigns the object a custom typename of ‘Hardware.Firmware’ and I am using a ps1xml for custom viewing. The function consists of a begin, process, and end scriptblock. When running the function against a set of objects (via foreach) the first object is always delayed in the output to the console, it actually is displayed after the END block runs. Every sequential object runs as expected. I also receive the same delay if running against a single object. If I remove the custom typename, the first object has no delay and is process correctly. Any ideas on why there is a delay on processing the first object when using a custom type and how can I avoid it? Here is the code for the function:
function Get-HPFirmware { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 0)] [Alias('Name', 'Server', 'Ip')] [string]$iLoName, [Parameter(Mandatory = $true)] [ValidateNotNullorEmpty()] [Alias('User')] [System.Management.Automation.PSCredential][System.Management.Automation.Credential()] $Credential, [switch]$IgnoreCertFailures ) BEGIN { $DefaultVariables = $(Get-Variable).Name try { Import-Module -Name HPRESTCmdlets -Force -ErrorAction Stop -Verbose:$false } catch { throw } Write-Verbose -Message "Splatting parameters for Connect-HPREST" $ConnectParams = @{ 'Address' = $PSBoundParameters['iLoName'] 'Credential' = $PSBoundParameters['Credential'] } if ($PSBoundParameters.ContainsKey('IgnoreCertFailures')) { $ConnectParams.DisableCertificateAuthentication = $true } } PROCESS { try { Write-Verbose -Message "Connecting to $($ConnectParams['Address'])" $Session = Connect-HPREST @ConnectParams -ErrorAction Stop } catch { throw } try { $Systems = Get-HPRESTDataRaw -Href '/rest/v1/Systems' -Session $Session -ErrorAction Stop foreach ($Sys in $Systems.links.member.href) { $Data = Get-HPRESTDataRaw -Href $Sys -Session $Session -ErrorAction Stop $FirmwareUri = ($Data.Oem.Hp.links.PSObject.Members | Where-Object -FilterScript { $_.Name -match 'Firmware' }).Value.href Write-Verbose -Message "Firmware Uri ($FirmwareUri) discovered" if ($FirmwareUri) { $FirmwareData = Get-HPRESTDataRaw -Href $FirmwareUri -Session $Session -ErrorAction Stop if ($FirmwareData) { $Firmware = $FirmwareData.Current | ForEach-Object -Process { ($_.PSObject.Members | Where-Object -FilterScript { $_.MemberType -eq 'NoteProperty' }).Value } Write-Verbose -Message "$($Firmware.Count) components discovered" } else { Write-Warning -Message "No firmware data available via $FirmwareUri for $($PSBoundParameters['iLoName'])" break } } else { Write-Warning -Message "Unable to locate the firmware uri" break } $PCIDevicesUri = ($Data.Oem.Hp.links.PSObject.Members | Where-Object -FilterScript { $_.Name -match 'PCIDevices' }).Value.href Write-Verbose -Message "PCI Device Uri ($PCIDevicesUri) discovered" if ($PCIDevicesUri) { $PCIData = Get-HPRESTDataRaw -Href $PCIDevicesUri -Session $Session -ErrorAction Stop if (!$PCIData) { Write-Warning -Message "No PCI device data available via $PCIDevicesUri for $($PSBoundParameters['iLoName'])" break } Write-Verbose -Message "$($PCIData.Items.Count) devices discovered" } else { Write-Warning -Message "Unable to locate the PCI device uri" break } foreach ($i in $Firmware) { if ($i.UEFIDevicePaths) { $Device = $PCIData.Items | Where-Object -FilterScript { $_.UEFIDevicePath -eq $i.UEFIDevicePaths } $Props = @{ 'ElementName' = $i.Name 'Location' = $i.Location 'VersionString' = $i.VersionString 'FQDD' = if ($i.Name -match 'FC') { $Device.StructuredName -replace "^\w{3}", "FC" } else { $Device.StructuredName -replace "\s", "" } 'DeviceId' = $Device.DeviceId 'SubDeviceId' = $Device.SubsystemDeviceID 'VendorId' = $Device.VendorID 'SubVendorId' = $Device.SubsystemVendorID } } else { $Props = @{ } switch -wildcard ($i.Name) { '*Power Supply*' { $Props.ElementName = "$($i.Name).$($i.Location)" $Props.Location = $i.Location $Props.VersionString = $i.VersionString $Props.FQDD = "PSU.$($i.Location -replace '\s', '')" } '*iLo*' { $Props.ElementName = "Integrated Lights Out" $Props.Location = $i.Location $Props.VersionString = $i.VersionString.Split(' ')[0] $Props.FQDD = "$($i.Name).$($i.Location -replace '\s', '')" } '*System ROM*' { $Props.ElementName = $i.Name $Props.Location = $i.Location $Props.VersionString = $i.VersionString.Split(' ')[1] $Props.FQDD = "BIOS.$($i.Location -replace '\s', '')" } '*Intelligent*' { $Props.ElementName = $i.Name $Props.Location = $i.Location $Props.VersionString = $i.VersionString $Props.FQDD = "DriverPack.$($i.Location -replace '\s', '')" } '*Power Management*' { $Props.ElementName = $i.Name $Props.Location = $i.Location $Props.VersionString = $i.VersionString $Props.FQDD = "DriverPack.$($i.Location -replace '\s', '')" } '*Server Platform*' { $Props.ElementName = $i.Name $Props.Location = $i.Location $Props.VersionString = $i.VersionString $Props.FQDD = "SPS.$($i.Location -replace '\s', '')" } '*Logic Device*' { $Props.ElementName = $i.Name $Props.Location = $i.Location $Props.VersionString = $i.VersionString.Split(' ')[-1] $Props.FQDD = "SPLD.$($i.Location -replace '\s', '')" } default { $Props.ElementName = $i.Name $Props.Location = $i.Location $Props.VersionString = $i.VersionString $Props.FQDD = "Unknown.$($i.Location -replace '\s', '')" } } } $Object = New-Object -TypeName System.Management.Automation.PSObject -Property $Props $Object.PSObject.TypeNames.Insert(0,'Hardware.Firmware') $Object } } Write-Verbose -Message "Disconnecting from iLo" Disconnect-HPREST -Session $Session } catch { Disconnect-HPREST -Session $Session throw } } END { Write-Verbose -Message "Cleaning up variables created by cmdlet" ((Compare-Object -ReferenceObject (Get-Variable).Name -DifferenceObject $DefaultVariables).InputObject) | ForEach-Object -Process { Remove-Variable -Name $_ -Force -ErrorAction Ignore } } }
Here is the ps1xml:
Hardware.Firmware
Hardware.Firmware
Name
Version
ElementName
VersionString
Here is the sample Verbose output:
VERBOSE: Splatting parameters for Connect-HPREST
VERBOSE: Connecting to x.x.x.x
VERBOSE: Firmware Uri (/rest/v1/Systems/1/FirmwareInventory) discovered
VERBOSE: 19 components discovered
VERBOSE: PCI Device Uri (/rest/v1/Systems/1/PCIDevices) discovered
VERBOSE: 13 devices discovered
VERBOSE: Disconnecting from iLo
VERBOSE: Cleaning up variables created by cmdlet (This is the END block)
Name Version
Smart HBA H240ar 4.52
HP StorageWorks 82Q 8Gb PCI-e Dual Port FC HBA 08.02.00
HP StorageWorks 82Q 8Gb PCI-e Dual Port FC HBA 08.02.00
HP Ethernet 1Gb 4-port 331i Adapter 17.4.41
HP Ethernet 10Gb 2-port 530T Adapter 7.14.79
Any help would be greatly appreciated!