2024年6月現在、PowerShellのConvertFrom-Jsonに大文字と小文字のみが異なるキーを持つJSONを読み込ませるとエラーが発生します。
下記例ではfoo と Foo がキーとなるJsonをシリアライズしようとしている。
# here-string で文字列を変数jsonに
$json = @"
{
"foo": "bar",
"Foo": "bar"
}
"@
$json | ConvertFrom-Json
今回試している環境
- Windows 11 23H2
- Windows PowerShell 5.1.22621.3672
- PowerShell 7.5.0-preview.2
Windows PowerShell のケース
PowerShell 7 のケース
事象について
RFC 8259 - The JavaScript Object Notation (JSON) Data Interchange Format
JSONフォーマットについては、RFC 8259で文書がありますが、こちらのRFCでは大文字小文字を区別する仕様となっていますが、PowerShellのConvertFrom-Jsonコマンドレットをオプションを指定せずに実行すると、PSCustomObjectが出力されますが、PSCustomObjectのプロパティ名は大文字区別を区別しない仕様となっているため、齟齬が発生してエラーとなるようです。
# 下記のようにfooとFooが混在したpscustomobjectを作成しようとしてもエラーになる
$obj = New-Object -TypeName PSObject
$obj | Add-Member -MemberType NoteProperty -Name 'foo' -Value 'bar'
$obj | Add-Member -MemberType NoteProperty -Name 'Foo' -Value 'bar'
PowerShell 7での対応方法について
PowerShellのgithubに上記のissueがあり、-AsHashTable
オプションを利用する回避策が紹介されています。
-AsHashTable
オプションを利用する事でPSCustomObjectではなく、HashTableで出力されエラーになりません。
# here-string で文字列を変数jsonに
$json = @"
{
"foo": "bar",
"Foo": "bar"
}
"@
# AsHashTableオプションはWindows PowerShellでは利用できない
$json | ConvertFrom-Json -AsHashTable
Windows PowerShellでの対応方法について
issueにはWindows PowerShellでは.Net Frameworkで提供されている、System.Web.Script.Serialization.JavaScriptSerializerクラスを利用して回避する方法が紹介されていました。
$json = @"
{
"foo": "bar",
"Foo": "bar"
}
"@
Add-Type -AssemblyName System.Web.Extensions
$obj = (New-Object -TypeName System.Web.Script.Serialization.JavaScriptSerializer -Property @{MaxJsonLength=67108864}).DeserializeObject($json)
JavaScriptSerializerクラスを利用してhashテーブルが取得できました。
総評
ConvertFrom-JsonがデフォルトだとPSCusotmObjectで出力するため、その制約からエラーになっていてなかなかつらい感じですね。
この制約はPSCustomOBjectではなくHashTableで出力する事にて回避できますが、ひと手間かかりますね。