I'm making a script which made a RestMethod call and export results to CSV On the output I have an object which contain the agentstatus and the last agentstatusmessage but for the last one i saw only System.Object[] How could i expand the value?
Below a snippet of simple code and an example of the output
$r = Invoke-RestMethod @param -Headers $headers -UseBasicParsing
$r.computers | Select-Object hostName,lastIPUsed,platform,computerStatus | ConvertTo-Csv -NoTypeInformation
Output:
"hostName","lastIPUsed","platform","computerStatus"
"srv01","10.1.1.2","Red Hat Enterprise 7 (64 bit)","@{agentStatus=active; agentStatusMessages=System.Object[]}"
"srv02","10.1.2.3","CentOS 7 (64 bit)","@{agentStatus=active; agentStatusMessages=System.Object[]}"
"srv03","10.1.2.4","Microsoft Windows Server 2019 (64 bit)","@{agentStatus=active; agentStatusMessages=System.Object[]}"
Expected:
"hostName","lastIPUsed","platform","AgentStatus","agentStatusMessages"
"srv01","10.1.1.2","Red Hat Enterprise 7 (64 bit)","active","Managed (Online)"
"srv02","10.1.2.3","CentOS 7 (64 bit)","active","Managed (Online)"
"srv03","10.1.2.4","Microsoft Windows Server 2019 (64 bit)","active","Managed (Online)"
Use calculated properties, one to create a separate agentStatus
property (CSV column), and another to create an agentStatusMessages
property, which additionally requires explicitly stringifying the array contained in the original property:
$r.computers |
Select-Object hostName, lastIPUsed, platform,
@{ Name='agentStatus'; Expression={ $_.computerStatus .agentStatus } },
@{ Name='agentStatusMessages'; Expression={ $_.computerStatus.agentStatusMessages -join ';' } } |
ConvertTo-Csv -NoTypeInformation
Note:
Because neither ConvertTo-Csv
nor its file-based cousin, Export-Csv
, meaningfully stringify array-valued properties, you must decide on how to represent arrays as a single string.
The above uses -join
, the string joining operator, to form a single string from the array-valued .agentStatusMessages
property, using self-chosen separator ;
- adjust as needed; if there's only one element in a given array, the separator doesn't come into play.
Also, since .computerStatus.agentStatusMessages
is of type System.Object[]
([object[]]
, in PowerShell terms) rather than an array of strings, applying -join
relies on the implicit stringification of each element, which in essence means calling .ToString()
on each element that isn't already a string.
If the elements are complex objects rather than strings and their .ToString()
stringification is unhelpful, you must explicitly stringify them, such as by choosing a representative / the property of interest:
E.g., speaking hypothetically, if the elements of the .computerStatus.agentStatusMessages
array had a .Text
property, you could rely on member-access enumeration to extract the values and join them:
$_.computerStatus.agentStatusMessages.Text -join ';'