Arrays 将字符串转换为PSCustomObjects数组

Arrays 将字符串转换为PSCustomObjects数组,arrays,powershell,Arrays,Powershell,我正在寻找一种将以下字符串转换为PSCustomObjects数组的智能方法: Name : AdtAgent DisplayName : Microsoft Monitoring Agent Audit Forwarding Status : Stopped StartType : Disabled Name : AeLookupSvc DisplayName : Application Experience Status : Runni

我正在寻找一种将以下字符串转换为PSCustomObjects数组的智能方法:

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

有什么好主意吗

您可以使用convertfromstringdata命令

$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 ":"

您可以使用ConvertFromStringData命令

$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 ":"

我注意到分隔文本块的空行实际上并不是空的,但它包含一个空格字符

一种方法是使用
convertfromstringdata

$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
输出:

Status  DisplayName                                 StartType Name       
------  -----------                                 --------- ----       
Stopped Microsoft Monitoring Agent Audit Forwarding Disabled  AdtAgent   
Running Application Experience                      Automatic AeLookupSvc
Name        DisplayName                                 Status  StartType
----        -----------                                 ------  ---------
AdtAgent    Microsoft Monitoring Agent Audit Forwarding Stopped Disabled 
AeLookupSvc Application Experience                      Running Automatic
但是,这并不能保持属性的顺序(如果这很重要),而且,如果您的值可能包含“:”字符,这可能会给您带来糟糕的结果

当然,您可以像这样“手动”执行此操作,如果值具有冒号字符,则保持顺序,并且不会混淆:

$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
输出:

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

我注意到分隔文本块的空行实际上并不是空的,但它包含一个空格字符

一种方法是使用
convertfromstringdata

$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
输出:

Status  DisplayName                                 StartType Name       
------  -----------                                 --------- ----       
Stopped Microsoft Monitoring Agent Audit Forwarding Disabled  AdtAgent   
Running Application Experience                      Automatic AeLookupSvc
Name        DisplayName                                 Status  StartType
----        -----------                                 ------  ---------
AdtAgent    Microsoft Monitoring Agent Audit Forwarding Stopped Disabled 
AeLookupSvc Application Experience                      Running Automatic
但是,这并不能保持属性的顺序(如果这很重要),而且,如果您的值可能包含“:”字符,这可能会给您带来糟糕的结果

当然,您可以像这样“手动”执行此操作,如果值具有冒号字符,则保持顺序,并且不会混淆:

$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
输出:

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

在数据被格式化为列表之前,您能从中获取原始数据吗?如果是这样,这可能比将其转换为文本,然后再转换回来更有用。感谢@zett42的建议

考虑以下几点:

$svc = Get-Service | Select-Object -property Name, Displayname, Status, StartType
现在,如果您这样做:

$svc | Format-List
$svc | gm
您将得到与您提供的示例相似的文本

但如果你这样做了:

$svc | Format-List
$svc | gm

您会注意到这是一个ServiceController数组。这可能与PSCustomObject数组一样有用。或者,您可以直接将其转换为PSCustomObject数组,而无需再进行文本转换。

在将此数据格式化为列表之前,您可以从中获取原始数据吗?如果是这样,这可能比将其转换为文本,然后再转换回来更有用。感谢@zett42的建议

考虑以下几点:

$svc = Get-Service | Select-Object -property Name, Displayname, Status, StartType
现在,如果您这样做:

$svc | Format-List
$svc | gm
您将得到与您提供的示例相似的文本

但如果你这样做了:

$svc | Format-List
$svc | gm

您会注意到这是一个ServiceController数组。这可能与PSCustomObject数组一样有用。或者,您可以直接将其转换为PSCustomObject数组,而无需再返回文本。

这看起来像是
格式列表的输出,在这种情况下,您已经有了对象,并且不需要从字符串转换回对象。请共享生成此输出的代码。强烈同意@zett42的这一点。Powershell将所有内容转换为某种文本格式,然后再将其放在控制台上。格式列表就是其中一种可能性。你说得对,它实际上是格式列表的输出。但该输出是由SCOM(系统中心运营经理)任务生成的。当我导入该任务的输出时,我只收到一个大字符串。这看起来像是
格式列表
的输出,在这种情况下,您已经有了对象,不需要从字符串转换回对象。请共享生成此输出的代码。强烈同意@zett42的这一点。Powershell将所有内容转换为某种文本格式,然后再将其放在控制台上。格式列表就是其中一种可能性。你说得对,它实际上是格式列表的输出。但该输出是由SCOM(系统中心运营经理)任务生成的。当我导入该任务的输出时,我只收到一个大字符串。@ААцСц&西奥:非常感谢您的帮助!因为我使用的是PS V5.1,所以我实现了Theo的解决方案。@АцСц&Theo:非常感谢您的帮助!因为我使用的是PSV5.1,所以我实现了Theo的解决方案;
-Delimeter
参数是PowerShell 7.x的新参数,因此在早期版本中不起作用。对于这些,您需要使用一个等于的
=
替换delimeter,使用类似于
-replace'(?m)^(++):(.+)$',“$1=$2'
”的方法来澄清;
-Delimeter
参数是PowerShell 7.x的新参数,因此在早期版本中不起作用。对于这些,您需要使用一个等于的
=
替换delimeter,使用类似于
-replace'(?m)^(+):(.+)$,“$1=$2”
。您是对的,数据是由:Get Service | Select Object Name,DisplayName,Status,StartType | fl生成的。此代码在SCOM任务中执行。在执行之后,我使用comman Get SCOMTaskResult获取输出,输出总是以字符串的形式传递。管道末尾的fl导致它以文本的形式传递数据。如果你不用做fl就能得到数据,你就得到了你想要的。不,我没有。我在没有fl的情况下开始测试,但是Get-SCOMTaskResult命令总是提供一个字符串。Get Service命令在另一台服务器上执行。如果我可以在这里使用winrm,实际上会容易得多,但这受到我们的安全设置的限制。因此,我必须使用SCOM任务,但结果总是一个字符串。您是对的,数据是由以下内容生成的:Get Service | Select Object Name、DisplayName、Status、StartType | fl此代码在SCOM任务中执行。在执行之后,我使用comman Get SCOMTaskResult获取输出,输出总是以字符串的形式传递。管道末尾的fl导致它以文本的形式传递数据。如果你不用做fl就能得到数据,你就得到了你想要的。不,我没有。我在没有fl的情况下开始测试,但是Get-SCOMTaskResult命令总是提供一个字符串。Get Service命令在另一台服务器上执行。如果我可以在这里使用winrm,实际上会容易得多,但这受到我们的安全设置的限制。所以我必须使用SCOM任务,但结果总是一个字符串。