如何在 powershell 中创建自定义数组?
How do I create a custom array in powershell?
我正在尝试整理 PS 中的数组。我要解决的问题是 return 复制的虚拟机列表和一些基本统计数据。
阅读了大量的网站和建议后,我能得到的最好的是以下脚本:
$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
这在我只有一个 VM 时有效,但当有多个 VM 时,输出显示在花括号中。
我想我终于走上了正轨。我只需要有人帮我解决剩下的难题。
另一个奇怪的事情是 New-TimeSpan 停止与多个 VM 一起工作。
提前致谢。
布拉登
我认为您可能会在每次 foreach()
迭代中覆盖同一个对象 ($obj
)。
试试这个:
$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
您的脚本最大的问题是:您启动了一个 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 或更高)
我正在尝试整理 PS 中的数组。我要解决的问题是 return 复制的虚拟机列表和一些基本统计数据。
阅读了大量的网站和建议后,我能得到的最好的是以下脚本:
$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
这在我只有一个 VM 时有效,但当有多个 VM 时,输出显示在花括号中。
我想我终于走上了正轨。我只需要有人帮我解决剩下的难题。
另一个奇怪的事情是 New-TimeSpan 停止与多个 VM 一起工作。
提前致谢。
布拉登
我认为您可能会在每次 foreach()
迭代中覆盖同一个对象 ($obj
)。
试试这个:
$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
您的脚本最大的问题是:您启动了一个 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 或更高)