0

警告-私は過去に同様の質問をしましたが、これは少し異なります。

tl; dr; さまざまな数のプロパティを持つオブジェクトをエクスポートしたいと思います。例えば; オブジェクト1には3つのIPアドレスと2つのNICがありますが、オブジェクト2には7つのIPアドレスと4つのNICがあります(ただし、この量に限定されません。N個のプロパティである可能性があります)。

必要なすべての情報を含むオブジェクトを楽しくキャプチャして構築できます。配列をコンソールに出力するだけの場合、各オブジェクトはそのすべてのプロパティとともに表示されます。out-fileまたはexport-csvを実行したい場合は、見出しを取り巻く問題が発生し始めます。

以前、 JPBlancは、プロパティの量に基づいてオブジェクトを並べ替えることを推奨していました。つまり、最も多くのプロパティを持つオブジェクトが最初に来るため、最も多くのプロパティの見出しが出力されます。

IPアドレスとNICカードに基づいてさまざまなプロパティを持つサーバーのオブジェクトを構築したとします。例えば;

ServerName: Mordor
IP1: 10.0.0.1
IP2: 10.0.0.2
NIC1: VMXNET
NIC2: Broadcom

ServerName: Rivendell
IP1: 10.1.1.1
IP2: 10.1.1.2
IP3: 10.1.1.3
IP4: 10.1.1.4
NIC1: VMXNET

最初に、これらのオブジェクトの配列をexport-csvすると、ヘッダーは最初のオブジェクトに基づいて構築されます(つまり、ServerName、IP1、IP2、NIC1、NIC2のみを取得します)。つまり、2番目のオブジェクトでは後続のオブジェクトが失われます。 IP(IP3やIP4など)。これを修正するために、エクスポートの前に、IPプロパティの数(tada)に基づいて並べ替えます。これで、最初のオブジェクトのIPが配列内で最も多くなり、後続のオブジェクトのIPが失われることはありません。

欠点は、2番目に変化するプロパティ(NICなど)がある場合です。IPに基づいて並べ替えが完了すると、ServerName、IP1-IP4、NIC1という見出しが表示されます。これは、NIC2の後続のオブジェクトプロパティが失われることを意味します。

このようなオブジェクトをエクスポートするときにデータが失われないようにするためのスケーラブルな方法はありますか?

4

3 に答える 3

0

これが私の解決策の試みです。私は今とても疲れているので、それが理にかなっていることを願っています. 基本的に、最大量の NIC および IP メモ プロパティを計算し、それらの量のプロパティを持つプレース ホルダー オブジェクトを作成し、それを CSV の最初の項目として追加してから、CSV から削除します。

# Create example objects
$o1 = New-Object psobject -Property @{
  ServerName="Mordor"
  IP1="10.0.0.1"
  IP2="10.0.0.2"
  NIC1="VMXNET"
  NIC2="Broadcom"
}

$o2 = New-Object psobject -Property @{
  ServerName="Rivendell"
  IP1="10.1.1.1"
  IP2="10.1.1.2"
  IP3="10.1.1.3"
  IP4="10.1.1.4"
  NIC1="VMXNET"
}

# Add to an array
$servers = @($o1, $o2)

# Calculate how many IP and NIC properties there are
$IPColSize = ($servers | Select IP* | %{($_ | gm -MemberType NoteProperty).Count} | Sort-Object -Descending)[0]
$NICColSize = ($servers | Select NIC* | %{($_ | gm -MemberType NoteProperty).Count} | Sort-Object -Descending)[0]

# Build a place holder object that will contain enough properties to cover all of the objects in the array.
$cmd = '$placeholder = "" | Select ServerName, {0}, {1}' -f (@(1..$IPColSize | %{"IP$_"}) -join ", "), (@(1..$NICColSize | %{"NIC$_"}) -join ", ")
Invoke-Expression $cmd

# Convert to CSV and remove the placeholder
$csv = $placeholder,$servers | %{$_ | Select *} | ConvertTo-Csv -NoTypeInformation
$csv | Select -First 1 -Last ($csv.Count-2) | ConvertFrom-Csv | Export-Csv Solution.csv -NoTypeInformation
于 2013-01-10T04:20:39.327 に答える
0

すべての一意のプロパティ ヘッダーのリストを取得してから、すべてのオブジェクトを選択するのはどうでしょうか。存在しないプロパティのオブジェクトを選択すると、空白のプロパティが作成されます。

$allHeaders = $arrayOfObjects | % { Get-Member -inputobject $_ -membertype noteproperty | Select -expand Name } | Select -unique
$arrayOfObjects | Select $allHeaders

確かに、ヘッダーを取得するためにオブジェクトをループしているため、非常に大量のオブジェクトの場合、時間がかかる場合があります。

于 2013-01-09T16:32:54.317 に答える
0

試す:

$o1 = New-Object psobject -Property @{
ServerName="Mordor"
IP1="10.0.0.1"
IP2="10.0.0.2"
NIC1="VMXNET"
NIC2="Broadcom"
}

$o2 = New-Object psobject -Property @{
ServerName="Rivendell"
IP1="10.1.1.1"
IP2="10.1.1.2"
IP3="10.1.1.3"
IP4="10.1.1.4"
NIC1="VMXNET"
}

$arr = @()
$arr += $o1
$arr += $o2

#Creating output
$prop = $arr | % { Get-Member -InputObject $_ -MemberType NoteProperty | Select -ExpandProperty Name } | Select -Unique | Sort-Object
$headers = @("ServerName")
$headers += $prop -notlike "ServerName"

$arr | ft -Property $headers    

出力:

ServerName IP1      IP2      IP3      IP4      NIC1   NIC2    
---------- ---      ---      ---      ---      ----   ----    
Mordor     10.0.0.1 10.0.0.2                   VMXNET Broadcom
Rivendell  10.1.1.1 10.1.1.2 10.1.1.3 10.1.1.4 VMXNET         

タイプ (NICS、IPS など) はわかっているが、カウント (NICS の数など) がわからない場合は、以下を試してみてください。

#Creating output
$headers = $arr | % { Get-Member -InputObject $_ -MemberType NoteProperty | Select -ExpandProperty Name } | Select -Unique
$ipcount = ($headers -like "IP*").Count
$niccount = ($headers -like "NIC*").Count

$format = @("ServerName")
for ($i = 1; $i -le $ipcount; $i++) { $format += "IP$i" }
for ($i = 1; $i -le $niccount; $i++) { $format += "NIC$i" }

$arr | ft -Property $format
于 2013-01-09T09:30:35.510 に答える