私は、ギャラリーにあるHPRESTCmdletsモジュールを使用してHPサーバー上のファームウェアバージョンを収集する機能を持つモジュールを持っています。この関数はオブジェクトに 'Hardware.Firmware'という型名を割り当てます。私はカスタム表示のためにps1xmlを使用しています。カスタムタイプ名前低速出力
この機能は、Begin
,Process
およびEnd
scriptblockで構成されています。オブジェクトのセットに対して(foreach
を介して)関数を実行すると、最初のオブジェクトは常にコンソールへの出力が遅れますが、実際にはブロックが実行された後に表示されます(End
)。すべてのシーケンシャルオブジェクトは期待どおりに実行されます。私はまた、単一のオブジェクトに対して実行している場合、同じ遅延を受け取ります。
カスタムの型名を削除すると、最初のオブジェクトに遅延がなく正しく処理されます。カスタムタイプを使用しているときに最初のオブジェクトを処理するのが遅れている理由とその回避方法は何ですか?ここで
は、関数のコードです:ここで
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
}
}
}
はPS1XMLです:ここでは
<?xml version="1.0" encoding="utf-8" ?>
<Configuration>
<ViewDefinitions>
<View>
<Name>Hardware.Firmware</Name>
<ViewSelectedBy>
<TypeName>Hardware.Firmware</TypeName>
</ViewSelectedBy>
<TableControl>
<TableHeaders>
<TableColumnHeader>
<Label>Name</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>Version</Label>
</TableColumnHeader>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<PropertyName>ElementName</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>VersionString</PropertyName>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
</ViewDefinitions>
</Configuration>
は、サンプル冗長な出力です:PetSerAlのクレジットに
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
形式ファイルに明示的な列幅を設定します。あるいは、あなたのタイプのデフォルトフォーマットとしてテーブルフォーマットを使用しないでください。 – PetSerAl
幅を追加すると助けになりましたが、なぜですか? msdnによると、widthはオプションです。 – jrob24
それがなければ、format-tableは各列の幅を評価する必要があります。これは通常、出力を受け取る前に*すべての処理が完了するのを待たなければならないことを意味します。また、関数を使用する前にインポートモジュールを取り出して実行することもできますが、遅延の原因にもなります。 – brendan62269