2010-09-18 15 views
41

Quelle est la manière la plus simple de convertir un PSCustomObject en un Hashtable? Il s'affiche comme un avec l'opérateur splat, les accolades et ce qui semble être des paires de valeurs clés. Lorsque j'essaie de le lancer sur [Hashtable], cela ne fonctionne pas. J'ai également essayé .toString() et la variable assignée dit c'est une chaîne mais n'affiche rien - aucune idée?PSCustomObject to Hashtable

+0

PSCustomObjects ont des avantages sur hashtables. Réfléchissez à deux fois avant de le convertir. http://stackoverflow.com/questions/22002748/hashtables-from-convertfrom-json-have-different-type-from-powershells-built-in-h/22010290#22010290 – spuder

Répondre

58

Ne devrait pas être trop dur. Quelque chose comme ça devrait faire l'affaire:

# 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

Notez que '$ _. Name' est déjà une chaîne, donc '$ ht2 [$ _. Name]' ou '$ h. ($ _. Name)' fonctionnera aussi bien que '" $ ($ _. Name) "'. –

+1

Vous avez raison. C'était un script bâclé de ma part. :-) –

+3

Notez que cela ne fonctionne pas pour PSCustomObjects créé par 'ConvertFrom-Json'. [Cette question] (http://stackoverflow.com/q/22002748/310446) résout ce problème. – BenV

18

Keith vous a déjà donné la réponse, cela est juste une autre façon de faire la même chose avec une seule ligne:

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

Heh, a commencé avec quelque chose de très similaire, sauf qu'il était juste assez long pour invoquer la barre de défilement horizontale SO. BTW Je pense que vos '$ 's manquent certains' _'s'. :-) –

+0

C'est ce que j'essayais d'éviter et finalement il a avalé le signe de soulignement. Merci! –

+0

@ShayLevy: Quel est l'avantage de tout mettre sur la même ligne? – Rubanov

3

Cela fonctionne pour PSCustomObjects créé par ConvertFrom_Json. Clause de non-responsabilité: Je comprends à peine PowerShell donc ce n'est probablement pas aussi propre qu'il pourrait l'être. Mais cela fonctionne (pour un seul niveau).

+0

Un peu plus propre (peut être plus difficile à comprendre) '$ hash = @ {}; $ obj | Get-Member -MemberType Propriétés | foreach {$ hash.Add ($ _. Name, $ obj. ($ _. Name))} ' – Adarsha

11

est ici une version qui fonctionne avec Hashtables imbriqués/tableaux et (ce qui est utile si vous essayez de le faire avec DSC DonnéesConfiguration):

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

Ceci est la seule version qui a fonctionné pour mes données avec des objets et des tableaux imbriqués à plusieurs niveaux. –

+1

Solution excellente et élégante pour les objets imbriqués à plusieurs niveaux. –