2010-09-18 15 views
41

¿Cuál es la forma más fácil de convertir un PSCustomObject en un Hashtable? Se muestra como uno con el operador de splat, llaves y lo que parecen ser pares de valores clave. Cuando intento enviarlo a [Hashtable], no funciona. También probé .toString() y la variable asignada dice que es una cadena pero no muestra nada, ¿alguna idea?PSCustomObject a Hashtable

+0

PSCustomObjects tienen ventajas sobre las tablas hash. Piensa dos veces antes de convertirlo. http://stackoverflow.com/questions/22002748/hashtables-from-convertfrom-json-have-different-type-from-powershells-built-in-h/22010290#22010290 – spuder

Respuesta

58

No debería ser demasiado difícil. Algo como esto debe hacer el truco:

# 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

Tenga en cuenta que '$ _. Name' ya está una cadena, por lo que '$ ht2 [$ _. Name]' o '$ h. ($ _. Name)' funcionará tan bien como '" $ ($ _. Name) "'. –

+1

Tienes razón. Fue una secuencia de comandos descuidada de mi parte. :-) –

+3

Tenga en cuenta que esto no funciona para PSCustomObjects creados por 'ConvertFrom-Json'. [Esta pregunta] (http://stackoverflow.com/q/22002748/310446) resuelve ese problema. – BenV

18

Keith ya le dio la respuesta, esto es sólo otra forma de hacer lo mismo con una sola línea:

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

Heh, comenzó con algo muy similar, excepto que fue lo suficientemente largo como para invocar la barra de desplazamiento horizontal SO. Por cierto, creo que tus '$ 's' faltan algunos' _'s'. :-) –

+0

Eso es lo que estaba tratando de evitar y finalmente se tragó el signo de subrayado. ¡Gracias! –

+0

@ShayLevy: ¿Cuál es la ventaja de poner todo en la misma línea? – Rubanov

3

Esto funciona para PSCustomObjects creadas por ConvertFrom_Json.

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

Descargo de responsabilidad: Apenas entiendo PowerShell por lo que probablemente no sea tan limpio como podría ser. Pero funciona (solo para un nivel).

+0

Poco más limpio (puede ser más difícil de entender) '$ hash = @ {}; $ obj | Get-Member -MemberType Properties | foreach {$ hash.Add ($ _. Name, $ obj. ($ _. Name))} ' – Adarsha

11

Aquí hay una versión que funciona con anidadas tablas hash/matrices, así (que es útil si usted está tratando de hacer esto con DSC ConfigurationData):

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

Esta es la única versión que funcionó para mis datos con objetos y matrices anidados de varios niveles. –

+1

Solución excelente y elegante para los objetos anidados multinivel. –