2017-08-16 26 views
-1

私は、ギャラリーにある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 
+1

形式ファイルに明示的な列幅を設定します。あるいは、あなたのタイプのデフォルトフォーマットとしてテーブルフォーマットを使用しないでください。 – PetSerAl

+0

幅を追加すると助けになりましたが、なぜですか? msdnによると、widthはオプションです。 – jrob24

+0

それがなければ、format-tableは各列の幅を評価する必要があります。これは通常、出力を受け取る前に*すべての処理が完了するのを待たなければならないことを意味します。また、関数を使用する前にインポートモジュールを取り出して実行することもできますが、遅延の原因にもなります。 – brendan62269

答えて

1

上記のps1xml内の列幅を設定することで問題は解決しました。理由は、カスタム書式があり、幅を指定しないと、PowerShellはすべてのオブジェクトが表示されるまで待たなければならないため、各列を試してみるとどのくらい幅が広いかがわかります。

アウト幅を指定すると、コマンドはパイプライン上で次のようになります。Get-HPFwareware |フォーマット - テーブル - 自動化|アウト・デフォルト。 Autosizeは、Out-Defaultに達するまで、パイプライン上の出力をブロックします。

関連する問題