powershell export-to-csv select-object

Powershell: exporte un objeto personalizado a un archivo CSV: extraiga un solo valor de propiedad con Select-Object



export-to-csv (2)

La expresion:

Select-Object {$_.LastWriteTime}

genera un objeto con una sola propiedad con el nombre $_.LastWriteTime . La forma más sencilla de solucionarlo es usar el parámetro -ExpandProperty que solo generará el valor que le interesa. Por ejemplo:

$date86 = Get-ItemProperty ''C:/Program Files (x86)/McAfee''| Select-Object -ExpandProperty LastWriteTime

Tenga en cuenta que también eliminé el bloque de secuencia de comandos del comando Select-Object , ya que no era necesario.

Escribí un script que construye un objeto personalizado y lo exporta a un archivo CSV:

$reg = Get-ItemProperty HKLM:/SOFTWARE/McAfee/DLP/Agent | Select-Object agentversion $date = Get-ItemProperty ''C:/Program Files/McAfee'' | Select-Object {$_.LastWriteTime} $date86 = Get-ItemProperty ''C:/Program Files (x86)/McAfee''| Select-Object {$_.LastWriteTime} New-Object -TypeName pscustomobject -Property @{ "Number1"=$reg "Number2"=$date86 "Number3"=$date } | export-csv -Path C:/****/desktop/stuff.csv -NoTypeInformation

y la fila de datos en el archivo CSV resultante es:

"@ {AgentVersion = 9.4.112.22}", "@ {$ .LastWriteTime = 5/6/2016 6:02:32 AM}", "@ {$ .LastWriteTime = 7/5/2016 8:34:01 PM } "

¿Es posible deshacerse de los envoltorios no deseados @{<name>=...} ?


Para complementar la útil respuesta de zdan [1] con alternativas:

Si solo desea el valor de la propiedad de un objeto dado, simplemente envuelva el comando en (...) y use .<propertyName> :

(Get-ItemProperty ''C:/Program Files/McAfee'').LastWriteTime # returns a [datetime] instance

En PSv3 +, lo anterior también funciona con comandos que devuelven múltiples elementos (matrices), en cuyo caso se genera una matriz de valores de propiedad individuales de los elementos de entrada; esta característica se denomina enumeración de miembros .

PSv3 introdujo una sintaxis de acceso directo para % / ForEach-Object (y también ? / Where-Object ) que también se puede aprovechar aquí:

Get-ItemProperty ''C:/Program Files/McAfee'' | % LastWriteTime # ditto

Este es el equivalente del más detallado (que también funciona en PSv2-):

Get-ItemProperty ''C:/Program Files/McAfee'' | % { $_.LastWriteTime }

Estas dos formas de sintaxis basadas en canalizaciones son más lentas, pero tienen dos ventajas:

  • Las colecciones de entradas grandes se procesan mejor en canalizaciones una por una para mantener el uso constante de la memoria (si es posible; si necesita recopilar toda la salida en la memoria, no hay ninguna ventaja).

  • Esta sintaxis hace referencia inequívocamente a la propiedad de un elemento individual en lugar de a una propiedad de la colección como un todo .

    • Por ejemplo, (Get-ChildItem -File C:/Windows).Length devuelve el recuento de archivos en C:/Windows , porque Length se interpreta como la propiedad de la colección (matriz);
      por el contrario, Get-ChildItem -File C:/Windows | % Length Get-ChildItem -File C:/Windows | % Length devuelve una matriz de los valores de propiedad .Length (tamaño de archivo) de los archivos individuales.

Finalmente, en PSv4 +, también puede usar el método de colección .ForEach() , que no usa la canalización y, por lo tanto, es más rápido (aunque un poco más lento que la enumeración de miembros), pero, al igual que la enumeración de miembros, requiere que la colección de entrada esté en memoria completa:

(Get-ItemProperty ''C:/Program Files/McAfee'').ForEach(''LastWriteTime'')

[1] Una descripción rápida del comportamiento de Select-Object :

  • Select-Object [-Property] <string[]> devuelve un objeto personalizado para cada objeto de entrada, que contiene solo las propiedades especificadas; incluso con una sola propiedad especificada, los resultados son objetos personalizados con esa única propiedad, no los valores de propiedad en sí.

  • Por el contrario, el uso de -ExpandProperty <string> devuelve el valor de propiedad individual dado de cada objeto de entrada (escrito como está) en su lugar.

Un ejemplo simple: extraiga el valor de la propiedad Year de una llamada Get-Date :

# WRONG: with (implied) -Property PS> $val = Get-Date | Select-Object Year; "$val" @{Year=2018} # !! # A custom object with a Year property was returned and the above is its # string representation, the equivalent of: # "$([pscustomobject] @{ Year = 2018 })" # CORRECT: with -ExpandProperty PS> $val = Get-Date | Select-Object -ExpandProperty Year; "$val" 2018 # OK: -ExpandProperty extracted just the property''s *value*