2010-09-18 15 views
41

Qual è il modo più semplice per convertire un PSCustomObject in un Hashtable? Viene visualizzato come uno con l'operatore splat, le parentesi graffe e quelle che sembrano essere coppie di valori chiave. Quando provo a trasmetterlo a [Hashtable], non funziona. Ho anche provato .toString() e la variabile assegnata dice che è una stringa ma non mostra nulla - qualche idea?PSCustomObject a Hashtable

+0

PSCustomObjects hanno vantaggi rispetto hashtables. Pensaci due volte prima di convertirlo. http://stackoverflow.com/questions/22002748/hashtables-from-convertfrom-json-have-different-type-from-powershells-built-in-h/22010290#22010290 – spuder

risposta

58

Non dovrebbe essere troppo difficile. Qualcosa del genere dovrebbe fare il trucco:

# Create a PSCustomObject (ironically using a hashtable) 
$ht1 = @{ A = 'a'; B = 'b'; DateTime = Get-Date } 
$theObject = new-object psobject -Property $ht1 

# Convert the PSCustomObject back to a hashtable 
$ht2 = @{} 
$theObject.psobject.properties | Foreach { $ht2[$_.Name] = $_.Value } 
+0

Nota che '$ _. Name' è già una stringa, quindi '$ ht2 [$ _. Nome]' o '$ h. ($ _. Nome)' funzionerà altrettanto bene come '" $ ($ _. Nome) "'. –

+1

Hai ragione. È stato uno script sciatto da parte mia. :-) –

+3

Si noti che questo non funziona per PSCustomObjects creato da 'ConvertFrom-Json'. [Questa domanda] (http://stackoverflow.com/q/22002748/310446) risolve questo problema. – BenV

18

Keith già ti ha dato la risposta, questo è solo un altro modo di fare la stessa cosa con una battuta:

$psobject.psobject.properties | foreach -begin {[email protected]{}} -process {$h."$($_.Name)" = $_.Value} -end {$h} 
+0

Heh, ha iniziato con qualcosa di molto simile, tranne che era sufficiente per invocare la barra di scorrimento orizzontale SO. A proposito, penso che i tuoi '$ 's manchino alcuni' _'s'. :-) –

+0

Questo è quello che stavo cercando di evitare e alla fine ha ingoiato il segno di sottolineatura. Grazie! –

+0

@ShayLevy: Qual è il vantaggio di mettere tutto sulla stessa linea? – Rubanov

3

Questo funziona per PSCustomObjects creati da ConvertFrom_Json.

Function ConvertConvertFrom-JsonPSCustomObjectToHash($obj) 
{ 
    $hash = @{} 
    $obj | Get-Member -MemberType Properties | SELECT -exp "Name" | % { 
       $hash[$_] = ($obj | SELECT -exp $_) 
     } 
     $hash 
} 

Disclaimer: Comprendo a malapena PowerShell, probabilmente non è così pulito come potrebbe essere. Ma funziona (solo per un livello).

+0

Poco più pulito (potrebbe essere più difficile da capire) '$ hash = @ {}; $ obj | Get-Member -MemberType Proprietà | foreach {$ hash.Add ($ _. Name, $ obj. ($ _. Name))} ' – Adarsha

11

Ecco una versione che funziona con hashtables nidificate/matrici così (che è utile se si sta cercando di fare questo con DSC Dati di configurazione):

function ConvertPSObjectToHashtable 
{ 
    param (
     [Parameter(ValueFromPipeline)] 
     $InputObject 
    ) 

    process 
    { 
     if ($null -eq $InputObject) { return $null } 

     if ($InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [string]) 
     { 
      $collection = @(
       foreach ($object in $InputObject) { ConvertPSObjectToHashtable $object } 
      ) 

      Write-Output -NoEnumerate $collection 
     } 
     elseif ($InputObject -is [psobject]) 
     { 
      $hash = @{} 

      foreach ($property in $InputObject.PSObject.Properties) 
      { 
       $hash[$property.Name] = ConvertPSObjectToHashtable $property.Value 
      } 

      $hash 
     } 
     else 
     { 
      $InputObject 
     } 
    } 
} 
+2

Questa è l'unica versione che ha funzionato per i miei dati con gli oggetti e gli array nidificati a più livelli. –

+1

Soluzione eccellente ed elegante per gli oggetti nidificati a più livelli. –