IanB
IanB

Reputation: 271

PowerShell -ExpandProperty and correct date format

I am attempting to use the -ExpandProperty feature in PowerShell to stop the header appearing in the output and format the date without minutes and seconds. This is just to get the created date for an AD Object:

Get-ADComputer -Server $Server -Identity BlahBlah -Properties Created |
  Select-Object -ExpandProperty @{Name="Created";Expression={$_.Created.ToString("yyyy-MM-dd")}} 

This does not produce a result, only if I exclude the "-ExpandProperty" part will it produce the right date format BUT includes the header "Created" which I don't want.

Any ideas please?

Upvotes: 4

Views: 6479

Answers (3)

user6811411
user6811411

Reputation:

In PowerShell there nearly always is more than one solution to a problem-

(Get-ADComputer -Server $Server -Identity BlahBlah -Properties Created | 
  Select-Object @{N="Created";E{$_.Created.ToString("yyyy-MM-dd")}} ).Created

or

Get-ADComputer -Server $Server -Identity BlahBlah -Properties Created | 
  Select-Object @{N="Created";E{$_.Created.ToString("yyyy-MM-dd")}} |
    Select-Object -Expand Created

Parameter names can be shorted as long as they are uniquely identifiable and there are also shortcuts (uppercase letters) so -EA is -ErrorAction

A calculated property does IMO make no sense here as it is the only output, so this should do also:

Get-ADComputer -Server $Server -Identity BlahBlah -Properties Created | 
  ForEach-Object {$_.Created.ToString("yyyy-MM-dd")}

Upvotes: 2

mklement0
mklement0

Reputation: 437110

To complement LotPings' helpful answer, which offers effective solutions:

As for why your code didn't work:

While Select-Object's -Property parameter accepts hashtables that define calculated properties (such as in your code), the -ExpandProperty parameter only accepts a property name, as a string.

Therefore, your hashtable is simply stringified, resulting in string literal System.Collections.Hashtable, causing Select-Object to complain, given that there is no property by that name.

The purpose of -ExpandProperty is to output just a property value rather than a custom object with that property.
You therefore do not need a detour via Select-Object, and can just use the value-outputting script block - { $_.Created.ToString("yyyy-MM-dd") } - directly with ForEach-Object instead, as shown at the bottom of LotPings' answer.


However, there is an obscure feature that you forgo by using ForEach-Object: Select-Object allows combining -ExpandProperty with -Property, in which case the properties specified via -Property are added as NoteProperty members to the value of the property specified via -ExpandProperty:

PS> $val = [pscustomobject] @{ one = 'uno'; two = 2 } |
      Select-Object -ExpandProperty one -Property two; $val; $val.two
uno
2

Note how the output string value, 'uno' has a copy of the input object's .two property attached to it.

To emulate that with ForEach requires more work:

PS> $val = [pscustomobject] @{ one = 'uno'; two = 2 } | ForEach-Object {
      $_.one + '!' | Add-Member -PassThru two $_.two
    }; $val; $val.two
uno!
2

Upvotes: 1

Mötz
Mötz

Reputation: 1722

I don't have access to an AD at the moment, but this could be what you are after

Updated

Get-ADComputer -Server $Server -Identity BlahBlah -Properties Created | Select-Object Created | ForEach-Object {$_.Created.ToString("yyyy-MM-dd")}

Upvotes: 2

Related Questions