4

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?

mklement0
  • 382,024
  • 64
  • 607
  • 775
IanB
  • 271
  • 3
  • 13
  • Could you share the desired output you want? It is a bit unclear at the moment. To you just want the value from that field and nothing else? I mean - Do you want a list of objects or something else? – Mötz Nov 10 '18 at 11:31
  • Mi Motz, I just want output from that field that looks like: 2018-07-03 not Created ------- 2018-07-03 – IanB Nov 10 '18 at 11:38
  • An no other objects, details or nothing? – Mötz Nov 10 '18 at 11:40

3 Answers3

2

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")}
Mötz
  • 1,682
  • 11
  • 17
2

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")}
  • Thanks LotPings - that last one worked perfectly. I should have realized that using a for-each object made more sense than using a calculated property, as you say. – IanB Nov 10 '18 at 13:48
1

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
mklement0
  • 382,024
  • 64
  • 607
  • 775