在PowerShell中自动展开Invoke-RestMethod中的所有数组并保存为CSV



我使用Invoke-RestMethod从REST API获取数据。响应是字符串和哈希表的数组。我需要将响应保存到CSV文件中。我知道我可以使用显式选择对象。这是我现在的代码:

$response = Invoke-RestMethod -Method Get -Uri $url -Headers $requestHeaders
$response | select-object `
@{Name="HashTable1_Column1"; Expression={ $_.HashTable1.Column1}},
@{Name="HashTable1_Column2"; Expression={ $_.HashTable1.Column2}},
NormalStringColumn1,
NormalStringColumn2,
@{Name="HashTable2_Column1"; Expression={ $_.HashTable2.Column1}},
@{Name="HashTable2_Column2"; Expression={ $_.HashTable2.Column2}}, | Export-Csv $filePath -NoTypeInformation -Encoding utf8 -Delimiter ";"

但是有任何方法如何动态扩展所有哈希表,而不需要键入所有字段,并保存所有扩展属性的响应,如果我不知道响应的结构?

这是JSON示例:
{
"HistoricalProperties":{
"PropertyName":"Name",
"IsProductive":"true",
"time":"09:00-17:00",
"Id":"id",
"Sum":"8.0000"
},
"Date":"2021-01-25T00:00:00",
"Email":"email",
"EmployeeId":"id",
"Number":1,
"ActualProperties":{
"PropertyName":"Name",
"IsProductive":"true",
"time":"09:00-17:00",
"Id":"id",
"Sum":"9.0000"
}
}

,这是想要的CSV:

"HistoricalProperties_PropertyName";"HistoricalProperties_IsProductive";"HistoricalProperties_time";"HistoricalProperties_Id";"HistoricalProperties_Sum";"Date";"Email";"EmployeeId";"EmployeePosKey";"Number";"ActualProperties_PropertyName";"ActualProperties_IsProductive";"ActualProperties_time";"ActualProperties_Id";"ActualProperties_Sum"
"Name";"true";"09:00-17:00";"id";"8.0000";"2021-01-25T00:00:00";"email";"id";"010D570CB5";1;"Name";"true";"09:00-17:00";"id";"8.0000"

Thanks a lot

使用反射检查从Invoke-RestMethod调用返回的[pscustomobject]实例,使用.psobject成员的.Properties集合,它允许您以编程方式检查任何对象的属性。

请注意,下面的解决方案仅限于一个级别的嵌套,适合处理示例数据。更深的嵌套需要一个递归的解决方案(尽管在CSV中表示更深嵌套的对象可能不切实际)。
# Simulate an Invoke-RestMethod call
# by parsing a JSON string literal.
$fromJson = ConvertFrom-Json @'
[
{
"HistoricalProperties": {
"PropertyName": "Name",
"IsProductive": "true",
"time": "09:00-17:00",
"Id": "id",
"Sum": "8.0000"
},
"Date": "2021-01-25T00:00:00",
"Email": "email",
"EmployeeId": "id",
"Number": 1,
"ActualProperties": {
"PropertyName": "Name",
"IsProductive": "true",
"time": "09:00-17:00",
"Id": "id",
"Sum": "9.0000"
}
}
]
'@
# Loop over all [pscustomobject] instances that the JSON objects
# inside the array were parsed into.
# Note: The assumption is that if there are multiple instances,
#       they all have the same internal structure (properties).
$fromJson | ForEach-Object {
# Convert the object at hand to a flat representation,
# using an aux. ordered hashtable.
$oht = [ordered] @{}
foreach ($prop in $_.psobject.Properties) {
if ($prop.Value -is [System.Management.Automation.PSCustomObject]) { # nested object
foreach ($nestedProp in $prop.Value.psobject.Properties) {
$oht[($prop.Name + '_' + $nestedProp.Name)] = $nestedProp.Value
}
}
else { # primitive value, such as a string
$oht[$prop.Name] = $prop.Value
}
}
# Output the hashtable as a [pscustomobject].
# Note: This [pscustomobject] cast (conversion) is no longer required 
#       in PowerShell (Core) 7+, where you can output $oht directly.
[pscustomobject] $oht
} | ConvertTo-Csv -NoTypeInformation -Delimiter ';' # ./o.csv

上面的输出如下:

"HistoricalProperties_PropertyName";"HistoricalProperties_IsProductive";"HistoricalProperties_time";"HistoricalProperties_Id";"HistoricalProperties_Sum";"Date";"Email";"EmployeeId";"Number";"ActualProperties_PropertyName";"ActualProperties_IsProductive";"ActualProperties_time";"ActualProperties_Id";"ActualProperties_Sum"
"Name";"true";"09:00-17:00";"id";"8.0000";"1/25/2021 12:00:00 AM";"email";"id";"1";"Name";"true";"09:00-17:00";"id";"9.0000"

注意:

  • 若要将CSV文件保存为文件,请使用Export-Csv代替ConvertTo-Csv。一定要指定编码,比如-Encoding utf8,因为在Windows PowerShell中默认是ASCII(!)

  • PowerShell (Core) 7+解决方案可以简化为两种方式:

    • 您不需要在$oht之前强制转换[pscustomobject],因为ConvertTo-Csv现在也接受(有序和无序)哈希表作为输入。

    • 你不再需要-NoTypeInformation开关了。

因为您没有提供任何示例xml数据,所以我无法验证您是否可以使用此方法来检查对象结构。但是试着掌握你想要保存的结构…

Install-Module PowerShellCookbook
$response = Invoke-RestMethod -Method Get -Uri $url -Headers $requestHeaders
[xml]$response | Show-Object

编辑:Show-Object是真的老,我实际上有一些问题导航XML对象。此外,当安装它时,会与这些已经存在的cmdlet发生冲突:Format-Hex,Send-File,Get-Clipboard,New-SelfSignedCertificate,Send-MailMessage,Set-Clipboard

我不得不做Save-Module PowerShellCookbook,而不是从模块文件中提取单个函数Show-Object。

编辑2:为了探索数据结构,我同意下面的讨论,即管道到Format-Custom是更合适的选项。

最新更新