PowerShell,从变量中提取多个数组以生成单个变量

Posted

技术标签:

【中文标题】PowerShell,从变量中提取多个数组以生成单个变量【英文标题】:PowerShell, Pulling out multiple arrays from an variable to make a single variable 【发布时间】:2022-01-09 09:25:22 【问题描述】:

我有一个变量$metrics,由于缺乏确定性,我将其称为数组数组?我可能错了,但这是我能想到的最好的。

这是变量。

PS C:\Windows\system32> $metrics


Id         : cpuUtil01
Label      : CPUUtilization
Messages   : 
StatusCode : Complete
Timestamps : 11/27/2021 7:00:00 PM, 11/27/2021 7:05:00 PM, 11/27/2021 7:10:00 PM, 11/27/2021 7:15:00 PM...
Values     : 51.22, 31.3833333333333, 31.4116666666667, 31.5283333333333...

我想将$metrics.timestamps$metrics.values 提取出来,以便将它们导出到CSV 文件中,这样我就可以使用Excel 的折线图。我不知道如何将它们两个提取到一个变量中。

我可以一次做一个,如下所示,但是我如何加入他们以便我有一个可以使用的 CSV。

$o = ""
$out = @()

foreach ($GetMetric in $Metrics.timestamps) 

$o = New-Object -TypeName PSCustomObject -Property  ([ordered]@
            
            TimeStampUTC = $GetMetric;
                        
                           )
$out += $o


$out

TimeStampUTC          
------------          
11/27/2021 7:00:00 PM 
11/27/2021 7:05:00 PM 
11/27/2021 7:10:00 PM 
11/27/2021 7:15:00 PM 
11/27/2021 7:20:00 PM 
11/27/2021 7:25:00 PM 
11/27/2021 7:30:00 PM 
11/27/2021 7:35:00 PM 
11/27/2021 7:40:00 PM 
11/27/2021 7:45:00 PM 
$o = ""
$out = @()

foreach ($GetMetric in $Metrics.values) 

$o = New-Object -TypeName PSCustomObject -Property  ([ordered]@
            
            Values = $GetMetric;
                        
                           )
$out += $o


$out

          Values
          ------
           51.22
31.3833333333333
31.4116666666667
31.5283333333333
31.4166666666667
          31.425
31.4916666666667
31.4166666666667
          31.325
31.5916666666667

我想要的是一个具有两个值的变量,如下所示,因此我可以将其输出到 csv 文件。

PS C:\Windows\system32> $output

TimeStampUTC              Values
------------              ------
11/27/2021 7:00:00 PM     51.22
11/27/2021 7:05:00 PM     31.3833333333333
11/27/2021 7:10:00 PM     31.4116666666667
11/27/2021 7:15:00 PM     31.5283333333333
11/27/2021 7:20:00 PM     31.4166666666667
11/27/2021 7:25:00 PM     31.425
11/27/2021 7:30:00 PM     31.4916666666667
11/27/2021 7:35:00 PM     31.4166666666667
11/27/2021 7:40:00 PM     31.325
11/27/2021 7:45:00 PM     31.5916666666667

你会怎么做?

非常感谢任何帮助。

-橄榄球

这是我对 .GetType() 和 Get-Member 的输出

PS C:\Windows\system32> $metrics.GeTtype()

IsPublic IsSerial Name                                     BaseType                                                                                                          
-------- -------- ----                                     --------                                                                                                          
True     True     List`1                                   System.Object                                                                                                     



PS C:\Windows\system32> $metrics.Values.GetType()

IsPublic IsSerial Name                                     BaseType                                                                                                          
-------- -------- ----                                     --------                                                                                                          
True     True     Object[]                                 System.Array                                                                                                      



PS C:\Windows\system32> $metrics | Get-Member


   TypeName: Amazon.CloudWatch.Model.MetricDataResult

Name        MemberType Definition                                                                              
----        ---------- ----------                                                                              
Equals      Method     bool Equals(System.Object obj)                                                          
GetHashCode Method     int GetHashCode()                                                                       
GetType     Method     type GetType()                                                                          
ToString    Method     string ToString()                                                                       
Id          Property   string Id get;set;                                                                    
Label       Property   string Label get;set;                                                                 
Messages    Property   System.Collections.Generic.List[Amazon.CloudWatch.Model.MessageData] Messages get;set;
StatusCode  Property   Amazon.CloudWatch.StatusCode StatusCode get;set;                                      
Timestamps  Property   System.Collections.Generic.List[datetime] Timestamps get;set;                         
Values      Property   System.Collections.Generic.List[double] Values get;set; 

【问题讨论】:

【参考方案1】:

您尝试执行的操作通常称为“合并数组”“连接数组”。有很多方法可以解决这个问题,例如,使用 for 循环。

回答您的第一个问题,$metrics 是一个object,并且作为任何对象,它可以具有属性和方法。在这种情况下,您的 object 有 3 个属性,它们是 arrays。为了对将来如何处理此问题提供一些看法,了解.GetType() 方法和Get-Member 的关键。

这是使用[PSCustomObject] 重新创建的对象:

$metrics = [pscustomobject]@
    Id         = 'cpuUtil01'
    Label      = 'CPUUtilization'
    Messages   = @()
    StatusCode = 'Complete'
    Timestamps = '11/27/2021 7:00:00 PM','11/27/2021 7:05:00 PM','11/27/2021 7:10:00 PM'
    Values     = '51.22','31.3833333333333','31.4116666666667','31.5283333333333'

现在我们可以付诸实践了:

PS /> $metrics.GeTtype()

IsPublic IsSerial Name             BaseType
-------- -------- ----             --------
True     False    PSCustomObject   System.Object

PS /> $metrics.Values.GetType()

IsPublic IsSerial Name             BaseType
-------- -------- ----             --------
True     True     Object[]         System.Array

PS /> $metrics | Get-Member

   TypeName: System.Management.Automation.PSCustomObject

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
Id          NoteProperty string Id=cpuUtil01
Label       NoteProperty string Label=CPUUtilization
Messages    NoteProperty Object[] Messages=System.Object[]
StatusCode  NoteProperty string StatusCode=Complete
Timestamps  NoteProperty Object[] Timestamps=System.Object[]
Values      NoteProperty Object[] Values=System.Object[]

现在回答主要问题,如何合并两个数组?

首先我们需要知道两者是否具有相同的length,否则我们会丢失信息:
$maxCount = [math]::Max($metrics.TimeStamps.Count, $metrics.Values.Count)

然后使用 for 循环遍历每个数组的每个元素,从它们的值中创建一个新对象:

$result = for($i = 0; $i -lt $maxCount; $i++)

    [pscustomobject]@
        TimeStamps = $metrics.TimeStamps[$i]
        Values = $metrics.Values[$i]
    

PS /> $result

TimeStamps            Values
----------            ------
11/27/2021 7:00:00 PM 51.22
11/27/2021 7:05:00 PM 31.3833333333333
11/27/2021 7:10:00 PM 31.4116666666667
11/27/2021 7:15:00 PM 31.5283333333333

【讨论】:

这就像一个魅力,感谢您提供有关我正在使用的内容的信息。我每天都在努力学习新东西!这是我的输出 @Rugbyball 很乐意为您提供帮助,也很高兴您能学到新东西 :) 我编辑了问题以包括我的 .GetType() 和 Get-Member。我和你的唯一区别在于$metrics.GeTtype() 我的是True for IsSerial 而你的是False 不确定这是否会改变任何东西。刚好注意到它。 另外,不是什么大不了的,马上拿起它。但是对于任何其他后续。我注意到一行中有一个错字。 $maxCount = [math]::Max($matrics.TimeStamps.Count, $metrics.Values.Count) 应该是 $maxCount = [math]::Max($metrics.TimeStamps.Count, $metrics.Values.Count) 同样,没什么大不了的,只是指出可能使用它的其他人。再次感谢Santiago Squarzon @Rugbyball 很好,感谢您指出这一点。我会编辑我的答案。 IsSerial 来自Type.IsSerializable Property

以上是关于PowerShell,从变量中提取多个数组以生成单个变量的主要内容,如果未能解决你的问题,请参考以下文章

在powershell中展平数组

如何使用 powershell 和电子邮件地址从 AD 中提取用户名

风控建模之单变量分析

以数组编号为变量返回循环内数组的内容

PowerShell - 递归提取特定文件夹的内容

如何编写Powershell脚本以提取.iso文件并通过创建文件夹将其复制到文件夹中