尝试通过类似这样的方式进行管道传输,这有助于处理具有未知属性名称的日期时间:
foreach-object {$_.Psobject.properties | foreach-object {if ($_.value -ne $null -and $_.value.gettype() -match '.*datetime'){$_.value=$_.value.toString("o")}};$_}
例如对于原始问题:
Get-Process | Select-Object Id,ProcessName,CPU,StartTime | foreach-object {$_.Psobject.properties | foreach-object {if ($_.value -ne $null -and $_.value.gettype() -match '.*datetime'){$_.value=$_.value.toString("o")}};$_} | convertto-json
这里的 StartTime 是一个日期时间字段,因此它在输出 JSON 中转换为 ISO 日期。
{
"Id": 7192,
"ProcessName": "ZeroConfigService",
"CPU": 19.703125,
"StartTime": "2020-04-20T16:59:44.1843370+01:00"
}
...而不是:
{
"Id": 7192,
"ProcessName": "ZeroConfigService",
"CPU": 19.71875,
"StartTime": "\/Date(1587398384184)\/"
}
类似的方法适用于可能不知道字段名称的数据库结果:
Invoke-Sqlcmd -Query "SELECT GETDATE() AS TimeOfQuery, getDate() anotherDate,'test' string" -ServerInstance "localhost" | Select-Object * -ExcludeProperty ItemArray, Table, RowError, RowState, HasErrors | convertto-json
...给出:
{
"TimeOfQuery": "\/Date(1587646812587)\/",
"anotherDate": "\/Date(1587646812587)\/",
"string": "test"
}
而这个:
Invoke-Sqlcmd -Query "SELECT GETDATE() AS TimeOfQuery, getDate() anotherDate,'test' string" -ServerInstance "localhost" | Select-Object * -ExcludeProperty ItemArray, Table, RowError, RowState, HasErrors | foreach-object {$_.Psobject.properties | foreach-object {if ($_.value -ne $null -and $_.value.gettype() -match '.*datetime'){$_.value=$_.value.toString("o")}};$_} | convertto-json
...给出 ISO 格式的日期:
{
"TimeOfQuery": "2020-04-23T13:53:59.1230000",
"anotherDate": "2020-04-23T13:53:59.1230000",
"string": "test"
}
可以通过更改getString方法toString("o")的参数来更改日期格式。 “o”代表 ISO 日期格式。有关详细信息,请参阅(我认为)https://docs.microsoft.com/en-us/dotnet/api/system.datetime.tostring 的示例。
注意管道中的select-object是必须的,否则foreach-object子句会尝试更新原始对象的属性,这可能是只读的,你可能不想这样做。 (有人知道更好的方法吗?)