PowerShell2.0で連想配列をPSCustomObjectに変換する

PowerShell2.0では連想配列[PSCustomObject]をつけて直接オブジェクトに変換することができません。
なので出来るようにする高度な関数を車輪の再発明します。
PSv3以降が使える環境ならまるで意味が無いものですので読むだけ時間の無駄です。

PSv2で連想配列をオブジェクトに変換したい時*1は以下の様な糞めんどくさい事になります。 Add-MemberにNotePropertyMembersも無いのでオブジェクトに直接メンバを追加することもできません。

#連想 配列
@{name='neko';type='cat';age=3;long='loooooooong';color='black'};

#v2(一番めんどくさい書き方したとき)
$obj = New-Object PSCustomObject;
Add-Member -InputObject $obj -MemberType NoteProperty -Name name  -Value 'neko';
Add-Member -InputObject $obj -MemberType NoteProperty -Name type  -Value 'cat' ;
Add-Member -InputObject $obj -MemberType NoteProperty -Name age   -Value 3;
Add-Member -InputObject $obj -MemberType NoteProperty -Name long  -Value 'loooooooong';
Add-Member -InputObject $obj -MemberType NoteProperty -Name color -Value 'black';

#v3以降
$obj = [pscustomobject]@{name='neko';type='cat';age=3;long='loooooooong';color='black'};

こんなものをまじめにやってると読みにくく書きにくいめんどくさいものが出来上がるのでほぼ同じようにやれるようにしましょう。
やっていることは単純で、PSCustomObjectをNew-Objectしてからforeachで連想配列の各キーをAdd-Memberしているだけです。

function New-PSCustomObject
{
    [CmdletBinding()]
    [OutputType([PSCustomObject])]
    Param
    (
        #入力
        [Parameter(
            Mandatory=$true, 
            ValueFromPipeline=$true,
            Position=0
        )]
        $InputObject
    )

    Begin
    {
        #PSv1には$PSVersionTableが存在しない
        #PSv3以降だと直接キャスト可能なので使う意味が無い
        if(!$PSVersionTable)
        {
            $IsPSVersion2 = $true;
        }
        else
        {
            $IsPSVersion2 = $PSVersionTable.PSVersion.Major -le 2;
        }
    }
    Process
    {$IsPSVersion2 = $true
        foreach($item in $InputObject)
        {
            #型チェック
            if($item -isnot [System.Collections.Hashtable])
            {
                Write-Host '入力オブジェクトがHashtableではありません。';
                continue;
            }
      #変換
            if($IsPSVersion2)
            {
                $obj = New-Object PSCustomObject;
                foreach($key in $item.keys)
                {
                    $value = $item.$key;
                    Add-Member -InputObject $obj -MemberType NoteProperty -Name $key -Value $value;
                }
                $obj;
            }
            else
            {
                #v3以降なら直接キャスト可能なうえ速いのでそうする
                [PSCustomObject]$item;
            }
        }
    }
    End
    {
        return;
    }
}
New-Alias -Name psco -Value New-PSCustomObject;

使い方

$hash = @{name='neko';type='cat';age=3;length='loooooooong';color='black'};
New-PSCustomObject -InputObject $hash;
$hash|New-PSCustomObject;
psco $hash

こういう無駄な努力が必要になるのでMSはとっとと2008・Win7向けにPSv5をWindowsUpdateで提供しやがれ。*2

*1:Export-CSVとかに突っ込みたい

*2:多分こない