web-dev-qa-db-ja.com

配列からPowerShellオブジェクトにプロパティを追加する方法

プロパティ名と値の2次元配列があります。これをPowerShellオブジェクトに追加する必要があります。

New-Object および Add-Member を使用してこのようなオブジェクトを作成および表示することに問題はありません。

$obj = New-Object PSObject
$obj | Add-Member NoteProperty IName($fiel.IName)
$obj | Add-Member NoteProperty SName($fiel.SName)
$obj | Add-Member NoteProperty Taggy($fiel.Taggy)
$obj | Add-Member NoteProperty Title($fiel.Title)

Write-Output $obj

Enter image description here

しかし、私がこのようなことをしようとすると:

for ($k=0; $k -lt $fieldsArray.Count; $k++)
{
    $itemobj | Add-Member –MemberType NoteProperty –Name $fieldsArray[$k].InternalName –Value $itemki[$j][$fieldsArray[$k].InternalName]
    #Write-Host $k
    #Write-Host $fieldsArray[$k].InternalName.ToString()
    #Write-Host $itemki[$j][$fieldsArray[$k].InternalName]
}

Write-Output $itemobj

Write-Output $ itemobjは、適切な列名なしで追加する必要があるプロパティメンバーを1つだけ返します。
コメントアウトされたパーツはテスト目的で追加され、すべてのアイテムに対して正しい値を返します。

私も試しました

$itemobj | Add-Member NoteProperty $fieldsArray[$k].InternalName.ToString()($fieldsArray[$k].InternalName)

改善なし。

他のプロパティメンバーが追加されないのはなぜですか?

必要なデータがあります。私が書いた場合:

for ($k=0; $k -lt $fieldsArray.Count; $k++)
{
    Write-Host $k
    Write-Host $fieldsArray[$k].InternalName.ToString()
    Write-Host $itemki[$j][$fieldsArray[$k].InternalName]
}

私は得ます:

ID 1
1ContentTypeId 0x0108007345CD807822EA4E85691E5C642F3A27
2ContentType
3タイトルタスク0
4変更済み2014/11/24 12:29:30 PM

そして、これらはまさに私が期待し、望んでいる値です。問題は、それらをプロパティとしてオブジェクトに追加することです。私は変数をNotePropertyNameとして持つことはできないと思いますが、それは私が得ている結果に基づいたワイルドな推測です。

$ itemki [$ j] [$ fieldsArray [$ k] .InternalName]の値の一部が空です-それは可能ですか?

すべての配列を忘れてください。彼らは単に文脈のためでした:

Write-Host $fieldsArray[$k].InternalName.ToString() # Writes out the correct value
Write-Host $itemki[$j][$fieldsArray[$k].InternalName] # writes out the correct value
$itemobj | Add-Member NoteProperty $fieldsArray[$k].InternalName.ToString()($fieldsArray[$k].InternalName) # The values/property are not added

問題は、なぜそうではないのかです。変数として値を渡すことについて、Add-Memberに制限はありますか?空の値?

9
grisha

私はまだ完全にはわかりませんが、_Add-Member_にのみ焦点を当てている場合は、以下を検討してください。

_$fieldsarray = "ID", "ContentTypeID", "ContentType", "Title", "Modified"
$itemki = "1", "0x0108007345CD807822EA4E85691E5C642F3A27", "", "Task0", "11/24/2014 12:29:30 PM"
$itemobj = New-Object pscustomobject
for($k=0;$k -lt $fieldsArray.Count ; $k++)
{
    $itemobj | Add-Member NoteProperty $fieldsarray[$k] $itemki[$k]
}

$itemobj
_

配列_$itemki_の空の文字列エントリに注意してください。これにより出力が生成されます。

_ID            : 1
ContentTypeID : 0x0108007345CD807822EA4E85691E5C642F3A27
ContentType   :
Title         : Task0
Modified      : 11/24/2014 12:29:30 PM
_

_""_を空の要素__"1","0x0108007345CD807822EA4E85691E5C642F3A27",,"Task0","11/24/2014 12:29:30 PM"_に変更すると、次の出力が得られます。

_ID            : 1
ContentTypeID : 0x0108007345CD807822EA4E85691E5C642F3A27
ContentType   : {Task0}
Title         : 11/24/2014 12:29:30 PM
Modified      :
_

それは間違っています。次に、空の要素を_$null_に変更すると、出力は最初のようになります。

_ID            : 1
ContentTypeID : 0x0108007345CD807822EA4E85691E5C642F3A27
ContentType   :
Title         : Task0
Modified      : 11/24/2014 12:29:30 PM
_

出力について

ループの外で_$itemobj_を実行した場合にのみ、最後の要素を取得すると言います。各パスの後に_$itemobj_はどのように見えますか? for(;;){}ループは、_ForEach-Object{}_と同じ方法でデータを出力ストリームに送信しません。

12
Matt

Forループではなく、ForEach-Objectループを実行します。何かのようなもの:

$Object = New-Object PSObject
$Array | ForEach{
    Add-Member -InputObject $Object -NotePropertyName $_[0] -NotePropertyValue $_[1]
}

それはあなたが探していることだと思います。

2

2つの配列の代わりにハッシュテーブルを使用できます。ハッシュテーブルからオブジェクトを作成するのは非常に簡単です。次に例を示します。

$hash = @{
    ID            = '1'
    ContentTypeID = '0x0108007345CD807822EA4E85691E5C642F3A27'
    ContentType   = ''
    Title         = 'Task0'
    Modified      = '11/24/2014 12:29:30 PM'
}

$Object = New-Object PSObject -Property $hash
2
campbell.rw