2016-11-08 4 views
8

Я хочу, чтобы получить JSON представление Hashtable, таких, как это:PowerShell Hashtable из JSON

@{Path="C:\temp"; Filter="*.js"} 

ConvertTo-Json приводит:

{ 
    "Path": "C:\\temp", 
    "Filter": "*.js" 
} 

Однако, если преобразовать, что JSON строку обратно с ConvertFrom-Json вы не получаете HashTable, а PSCustomObject.

Итак, как можно надежно сериализовать вышеуказанный Hashmap?

+0

Возможный дубликат [PSCustomObject в Hashtable] (http://stackoverflow.com/questions/3740128/pscustomobject-to-hashtable) –

ответ

14
$json = @{Path="C:\temp"; Filter="*.js"} | ConvertTo-Json 

$hashtable = @{} 

(ConvertFrom-Json $json).psobject.properties | Foreach { $hashtable[$_.Name] = $_.Value } 

адаптировано из PSCustomObject to Hashtable

+0

тот довольно круто, спасибо! – 4c74356b41

4

JavaScriptSerializer доступен, начиная с .NET3.5 (может быть установлен на XP, включены в Win7 и выше), это в несколько раз быстрее, чем Преобразовать-FromJSON и правильно разбирает вложенные объекты , массивы и т.д.

function Parse-JsonFile([string]$file) { 
    $text = [IO.File]::ReadAllText($file) 
    $parser = New-Object Web.Script.Serialization.JavaScriptSerializer 
    $parser.MaxJsonLength = $text.length 
    Write-Output -NoEnumerate $parser.DeserializeObject($text) 
} 
+0

В PowerShell 5.1 я обнаружил, что '$ parser.DeserializeObject ($ text)' десериализуется в .NET Dictionary, а не в Hashtable. Однако метод Deserialize, в отличие от метода DeserializeObject, десериализуется в парсер Hashtable: '$. Deserialize ($ text, @ {}. GetType()) '. –

2

ответ на этот пост является отличным началом, но немного наивная, когда вы начнете получать более сложные JSon представления.

Приведенный ниже код будет анализировать вложенные json-массивы и json-объекты.

[CmdletBinding] 
function Get-FromJson 
{ 
    param(
     [Parameter(Mandatory=$true, Position=1)] 
     [string]$Path 
    ) 

    function Get-Value { 
     param($value) 

     $result = $null 
     if ($value -is [System.Management.Automation.PSCustomObject]) 
     { 
      Write-Verbose "Get-Value: value is PSCustomObject" 
      $result = @{} 
      $value.psobject.properties | ForEach-Object { 
       $result[$_.Name] = Get-Value -value $_.Value 
      } 
     } 
     elseif ($value -is [System.Object[]]) 
     { 
      $list = New-Object System.Collections.ArrayList 
      Write-Verbose "Get-Value: value is Array" 
      $value | ForEach-Object { 
       $list.Add((Get-Value -value $_)) | Out-Null 
      } 
      $result = $list 
     } 
     else 
     { 
      Write-Verbose "Get-Value: value is type: $($value.GetType())" 
      $result = $value 
     } 
     return $result 
    } 


    if (Test-Path $Path) 
    { 
     $json = Get-Content $Path -Raw 
    } 
    else 
    { 
     $json = '{}' 
    } 

    $hashtable = Get-Value -value (ConvertFrom-Json $json) 

    return $hashtable 
} 
+0

Это был единственный способ, которым он полностью работал для меня. – FEST

0

Я считаю, что решение, представленное в Converting JSON to a hashtable ближе к 6.0 реализации PowerShell из ConvertFrom-Json

Я попытался с несколькими источниками JSON, и я всегда получал право Hashtable.

$mappings = @{ 
    Letters = ( 
     "A", 
     "B") 
    Numbers  = (
     "1", 
     "2", 
     "3") 
    Yes = 1 
    False = "0" 
} 

# TO JSON 
$jsonMappings = $mappings | ConvertTo-JSON 
$jsonMappings 

# Back to hashtable 
# In PowerShell 6.0 would be: 
# | ConvertFrom-Json -AsHashtable 
$jsonMappings | ConvertFrom-Json -As hashtable 
Смежные вопросы