I'll say first that I'm not very experienced with PowerShell, so many things are not obvious to me.
I've got the following command:
$JSON = Get-ADUser -Filter "SAMAccountName -eq 'jdray'" -Properties SAMAccountName,
Name,
DisplayName,
Manager,
SAMAccountType,
pwdLastSet,
Created,
AccountExpirationDate,
lastLogonTimestamp,
DistinguishedName|Select-object -Property SAMAccountName,
Name,
@{name='Manager';expression={ ([ADSI]"LDAP://$($_.manager)").displayname }},
Enabled,
DistinguishedName,
Created,
AccountExpirationDate,
LastLogonTimestamp,
PasswordLastSet|ConvertTo-Json
The output of this is:
{
"SAMAccountName": "jdray",
"Name": "Ray, James",
"Manager": "Lady, Boss",
"Enabled": true,
"DistinguishedName": "CN=Ray\\, James,OU=...[yadda yadda yadda]...DC=com",
"Created": "\/Date(1554387070000)\/",
"AccountExpirationDate": "\/Date(1643702400000)\/",
"LastLogonTimestamp": 132732539928955494,
"pwdLastSet": 132729945927805005
}
First of all, I'm confused why AccountExpirationDate
and Created
have one format, but LastLogonTimestamp
and pwdLastSet
are formatted differently.
What I really want is to have all the DateTime
objects output in a human-readable DateTime
format. I tried -ExpandProperty
, but couldn't figure out how to make it work. It appears to add a property named DateTime
to the end of the output, formatted reasonably: "DateTime": "Thursday, April 4, 2019 7:11:10 AM"
, but it doesn't name it. The Microsoft documentation on the subject is very light on useful examples, as is the rest of the web.
I tried following the @{}
format for the Manager expression, which I copied from someone else's script. Unfortunately my PowerShell isn't strong enough to figure out a reasonable expression. In C#, something like Created.ToShortDateString()
would suffice (presuming Created
is a DateTime
).
So, how do I consistently output named, human-readable DateTime
property values in a JSON array?
EDIT
Using a proposed answer below, I modified the four timestamp fields using the same pattern:
@{n='Created';e={[DateTime]::FromFileTime($_.Created)}},
@{n='AccountExpirationDate';e={[DateTime]::FromFileTime($_.AccountExpirationDate)}},
@{n='LastLogonTimestamp';e={[DateTime]::FromFileTime($_.lastLogonTimestamp)}},
@{n='pwdLastSet';e={[DateTime]::FromFileTime($_.pwdLastSet)}}
Here's the (frustrating) result I got:
"Created": "\/Date(1554387070000)\/",
"AccountExpirationDate": "\/Date(1643702400000)\/",
"LastLogon": {
"value": "\/Date(1628780392895)\/",
"DateTime": "Thursday, August 12, 2021 7:59:52 AM"
},
"pwdLastSet": 132729945927805005
Also of note, here's the output for the four DateTime
fields before it gets translated to JSON:
Created : 4/4/2019 7:11:10 AM
AccountExpirationDate : 2/1/2022 12:00:00 AM
LastLogonTimestamp : 8/12/2021 7:59:52 AM
PasswordLastSet : 8/9/2021 7:56:32 AM
Why does that formatting work for one DateTime
instance but not the rest?
How do I extract DateTime
from the format of the pwdLastSet
field, which is clearly a different animal?
How do I get a simple property:value
pair, such as "LastLogonTimestamp": "Thursday, August 12, 2021 7:59:52 AM"
?