Powershell: Export a custom object to a CSV file - extract a single property value with Select-Object

独自空忆成欢 提交于 2019-11-27 05:39:19
zdan

The expression:

Select-Object {$_.LastWriteTime}

outputs an object with a single property with name $_.LastWriteTime. The simplest way to fix it is to use the -ExpandProperty parameter which will only output the value that you are interested in. e.g.:

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

Note that I've also removed the script block from the Select-Object command, as it wasn't necessary.

To complement zdan's helpful answer[1] with alternatives:

If you just want the value of a given object's property, simply wrap the command in (...) and use .<propertyName>:

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

In PSv3+, the above also works with commands returning multiple items (arrays), in which case an array of the input items' individual property values is output - this feature is called member enumeration.


PSv3 introduced a shortcut syntax for % / ForEach-Object (and also ? / Where-Object) that can be leveraged here as well :

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

This is the equivalent of the more verbose (which also works in PSv2-):

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

These two pipeline-based syntax forms are slower, but have two advantages:

  • Large input collections are better processed in pipelines one by one in order to keep memory use constant (if feasible; if you need to collect the entire output in memory, there is no advantage).

  • This syntax unambiguously references an individual item's property rather than a property of the collection as a whole.

    • E.g., (Get-ChildItem -File C:\Windows).Length returns the count of files in C:\Windows, because Length is interpreted as the collection's (array's) property;
      by contrast, Get-ChildItem -File C:\Windows | % Length returns an array of the individual files' .Length (file-size) property values.

Finally, in PSv4+, you may also use the .ForEach() collection method, which doesn't use the pipeline and is therefore faster (though slightly slower than member enumeration), but, like member enumeration, requires that the input collection be in memory in full:

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

[1] A quick overview of Select-Object's behavior:

  • Select-Object [-Property] <string[]> returns a custom object for each input object, containing only the specified properties; even with only a single property specified, the results are custom objects with that single property, not the property values themselves.

  • By contrast, using -ExpandProperty <string> returns the given, single property's value from each input object (typed as-is) instead.

A simple example: extract the Year property value from a Get-Date call:

# 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*
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!