2

I'm looking for a smart way to convert the following string to an array of PSCustomObjects:

Name        : AdtAgent
DisplayName : Microsoft Monitoring Agent Audit Forwarding
Status      : Stopped
StartType   : Disabled
 
Name        : AeLookupSvc
DisplayName : Application Experience
Status      : Running
StartType   : Automatic

Any ideas appriciated!!

3
  • 2
    This looks like the output of Format-List, in which case you already have objects and there would be no need to convert from string back to objects. Please share the code that produces this output. Commented Mar 2, 2021 at 10:55
  • Strongly agree with @zett42 on this one. Powershell converts everything to some text format before putting it on the console. Format-List is one of those possibilities. Commented Mar 2, 2021 at 11:33
  • You are right, it is in fact output of format-list. But this output is produced by a SCOM (System Center Operations Manager) task. When I import the output of that task, I only recieve a large string. Commented Mar 2, 2021 at 12:53

3 Answers 3

3

I noticed the empty line separating the text blocks is not really empty, but it contains a space character.

One way of doing this is to use ConvertFrom-StringData:

$str = @"
Name        : AdtAgent
DisplayName : Microsoft Monitoring Agent Audit Forwarding
Status      : Stopped
StartType   : Disabled

Name        : AeLookupSvc
DisplayName : Application Experience
Status      : Running
StartType   : Automatic
"@ 

$result = $str -split '\r?\n\s*\r?\n' | ForEach-Object {
    # for PowerShell 7 you can use 
    # $_ | ConvertFrom-StringData -Delimiter ':'
    [PsCustomObject](($_ -replace ':', '=') | ConvertFrom-StringData)
}

$result

Output:

Status  DisplayName                                 StartType Name       
------  -----------                                 --------- ----       
Stopped Microsoft Monitoring Agent Audit Forwarding Disabled  AdtAgent   
Running Application Experience                      Automatic AeLookupSvc

This however does not keep the order of the properties if that matters, but also, if your values may contain a ':' character, this could give you bad results.

You can do this 'manually' of course like this, keeping the order and not getting confused if values have a colon character:

$result = $str -split '\r?\n\s*\r?\n' | ForEach-Object {
    $hash = [ordered]@{}
    foreach ($line in ($_ -split '\r?\n')) {
        $name, $value = ($line -split ':', 2).Trim()
        $hash[$name] = $value
    }
    # cast to PsCustomObject for output
    [PsCustomObject]$hash 
}

$result

Output:

Name        DisplayName                                 Status  StartType
----        -----------                                 ------  ---------
AdtAgent    Microsoft Monitoring Agent Audit Forwarding Stopped Disabled 
AeLookupSvc Application Experience                      Running Automatic
Sign up to request clarification or add additional context in comments.

1 Comment

@ Алексей & Theo: Thank you very much for your assistance! Since I use PS V5.1 I implemented Theo's solution.
1

you can use convertfrom-stringdata commandlet

$array = (@"
Name        : AdtAgent
DisplayName : Microsoft Monitoring Agent Audit Forwarding
Status      : Stopped
StartType   : Disabled

Name        : AeLookupSvc
DisplayName : Application Experience
Status      : Running
StartType   : Automatic
"@ -split "`r`n`r`n") | ConvertFrom-StringData -Delimiter ":"

1 Comment

Just to clarify; the -Delimeter parameter is new to PowerShell 7.x so will not work in earlier versions. For those, you would need to replace the delimeter with an equals = using something like -replace '(?m)^(.+):(.+)$','$1=$2'.
1

Can you obtain this data in its original from, before it got formatted like a list? If so, that may be more useful to you than converting it to text, and then back again. Thanks to @zett42 for this suggestion.

Consider the following:

$svc = Get-Service | Select-Object -property Name, Displayname, Status, StartType

Now, if you do:

$svc | Format-List

you will get text that looks like the sample you gave us.

But if you do:

$svc | gm

You will notice that this is an array of ServiceController. This may be just as useful to you as an array of PSCustomObject. Or, you may be able to convert it directly to an array of PSCustomObject, without going to text and back again.

3 Comments

You are right, the data is produced by: Get-Service | Select-Object Name, DisplayName, Status, StartType | fl This code is executed within a SCOM task. After execution I use comman Get-SCOMTaskResult to get the output, which is always delivered as a string.
And its the fl at the end of that pipeline that caused it to deliver the data as text. If you can get the data without doing the fl, you've got what you waant, pretty much.
No, I don't. I started testing without the fl but the Get-SCOMTaskResult command always delivers a string. The Get-Service command is executed on another server. If I could use winrm here, it would be in fact much easier, but this is restricted by our security settings. So I have to use SCOM tasks, but the result is always a string.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.