如何在PowerShell中创建自定义数组?

时间:2015-11-06 20:34:05

标签: powershell virtual-machine replication powershell-v3.0 windows-server-2012-r2

我正在尝试在PS中整理数组。我试图解决的问题是返回一个复制的虚拟机列表和一些基本统计数据。

通过阅读大量网站和建议,我能得到的最好的是以下脚本:

$myArray = @()

$vms = get-vm | where-object { $_.replicationstate -ne "Disabled" }

foreach ($vm in $vms)
{
    $vmRepl = Get-VMReplication

    $replfreq = (New-TimeSpan -seconds $vmRepl.replicationfrequencysec)
    $lastrepl = $vmRepl.lastreplicationtime
    $nextrepl = $lastrepl + $replfreq
    $secfrom = [math]::Round((New-TimeSpan -start     $vmRepl.lastreplicationtime).TotalSeconds)
    $secto = [math]::Round((New-TimeSpan -end ($vmRepl.lastreplicationtime + $replfreq)).TotalSeconds)

    $obj = New-Object System.Object
    $obj | Add-Member -MemberType NoteProperty -Name Name -Value $vmRepl.Name
    $obj | Add-Member -MemberType NoteProperty -Name ReplicationFrequencySec -Value $vmRepl.replicationfrequencysec
    $obj | Add-Member -MemberType NoteProperty -Name SecondsSinceLastRepl -Value $secfrom
    $obj | Add-Member -MemberType NoteProperty -Name SecondsUntilNextRepl -Value $secto
    $obj | Add-Member -MemberType NoteProperty -Name LastReplication -Value $lastrepl
    $obj | Add-Member -MemberType NoteProperty -Name NextReplication -Value $nextrepl

    $myArray += $obj

}

write-output $myArray | ft -AutoSize

当我只有一个虚拟机时,这种方法有效,但当有多个虚拟机时,输出会显示在大括号内。

我认为我最终走上正轨。我只需要有人帮我解决这个难题的其余部分。

另一个奇怪的事情是New-TimeSpan停止使用多个虚拟机。

提前致谢。

布雷登

2 个答案:

答案 0 :(得分:0)

我认为您可能会在每次$obj次迭代中覆盖同一个对象(foreach())。

请改为尝试:

$VMs = Get-Vm | Where-Object {$_.ReplicationState -ne 'Disabled'}
$MyVmReplicationStatus = foreach ($VM in $VMs){
  $VMReplStatus = Get-VMReplication 
  $LastRepTime = $VMReplStatus.LastReplicationTime
  $ReplFreqSecs = $VMReplStatus.ReplicationFrequencySec
  $ReplFrequency = (New-TimeSpan -Seconds $ReplFreqSecs)

  $Props = @{
    Name                    = $VMReplStatus.Name
    ReplicationFrequencySec = $ReplFreqSecs
    SecondsSinceLastRepl    = [System.Math]::Round((New-TimeSpan -Start $LastRepTime).TotalSeconds)
    SecondsUntilNextRepl    = [System.Math]::Round((New-TimeSpan -End ($LastRepTime + $ReplFrequency)).TotalSeconds)
    LastReplication         = $LastRepTime
    NextReplication         = $LastRepTime + $ReplFrequency
  }

  New-Object -TypeName psobject -Property $Props
}

Write-Output -InputObject $MyVmReplicationStatus | Format-Table -AutoSize

答案 1 :(得分:0)

你的脚本最大的探测器是:你启动一个foreach循环,但你不使用你循环的数组中的任何元素。您只需遍历数组中每个项目的相同数据。

基本上,当前脚本会检索VM列表,然后对于每个条目,您将获取阵列中所有计算机的复制状态。然后,您对此集进行一些处理,然后将此集添加到新对象(对于列表中的每个条目,这都会继续)。有关foreach的用法的详细解释,请参阅 http://blogs.technet.com/b/heyscriptingguy/archive/2014/04/28/basics-of-powershell-looping-foreach.aspx

我还建议使用[PSCustomObject]而不是new-object / add-member:它更容易使用,代码更容易阅读,它还维护你用它设置的属性的顺序(因为你'重新使用get-vm我假设你有PS3或更高版本)