2016-11-08 3 views
8

Ich möchte eine JSON Darstellung einer Hashtable wie diese bekommen:Powershell Hashtable von JSON

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

ConvertTo-Json Ergebnisse in:

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

Wenn Sie jedoch konvertieren, dass JSON-String zurück mit ConvertFrom-Json Sie erhalten keine HashTable, sondern ein PSCustomObject.

Also wie kann man die obige Hashmap zuverlässig serialisieren?

+0

Mögliche Duplikat [PSCustomObject zu Hashtable] (http://stackoverflow.com/questions/3740128/pscustomobject-to-hashtable) –

Antwort

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

$hashtable = @{} 

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

Angepasst von PSCustomObject to Hashtable

+0

das ist ziemlich cool, danke! – 4c74356b41

4

JavaScriptSerializer seit NET3.5 verfügbar ist (kann auch auf XP, enthalten in Win7 und neuere installiert werden), ist es mehrmals schneller als Convert-FromJSON und parst richtig verschachtelten Objekten , Arrays usw.

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

In PowerShell 5.1 habe ich festgestellt, dass '$ parser.DeserializeObject ($ text)' zu einem .NET Dictionary deserialisiert wurde, keine Hashtable. Die Deserialize-Methode deserialisiert im Gegensatz zur DeserializeObject-Methode eine Hashtable: $ parser. Deserialize ($ text, @ {}. GetType()) '. –

2

Die Antwort für diesen Beitrag ist ein guter Start, aber es ist ein wenig naiv, wenn Sie immer komplexe json Darstellungen beginnen.

Der folgende Code analysiert verschachtelte JSON-Arrays und JSON-Objekte.

[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

Dies war der einzige Weg, wie es für mich voll funktionierte. – FEST

0

Ich glaube, die in Converting JSON to a hashtable präsentierte Lösung näher an die Umsetzung Powershell 6.0 ist von ConvertFrom-Json

ich mit mehreren JSON Quellen versucht, und ich habe immer die richtige Hash-Tabelle.

$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