PowerCLI 性能
PowerCLI performance
我已经编写了一个 PowerCLI 脚本来检索我们 VM 上个月的相关信息和使用情况统计信息,并将其输出为 csv,但速度非常慢。谁能提出有助于加快报告速度的改进建议。
我是 powershell/PowerCLI 的新手,所以如有任何帮助,我们将不胜感激
$todayMidnight = (Get-Date -Hour 0 -Minute 0 -Second 0).AddMinutes(-1)
$EndOfLastMonth = (Get-Date -Year (get-date).Year -Month (get-date).Month -Day 1 -Hour 0 -Minute 0 -Second 0).AddMinutes(-1)
$FirstofLastMonth = $EndOfLastMonth.AddMonths(-1)
$workingDays = "Monday","Tuesday","Wednesday","Thursday","Friday"
$dayStart = New-Object DateTime(1,1,1,8,0,0)
$dayEnd = New-Object DateTime(1,1,1,18,0,0)
$CSVFile = Read-Host "Enter Filename for csv"
$Report = @()
Connect-VIServer "VCServer" | Out-Null
$ServerList = Get-VM | Where-Object {$_.VMHost.Name -ne "192.168.106.161" -and $_.PowerState -eq "PoweredOn" } | Sort-Object Name
$Counter = 1
foreach ($Server in $ServerList) {
$VMInfo = {} | select Name, OS, VMHost, IPAddress, NumCPU, TotalMemMB, AvgMemPcnt, MaxMemPcnt, AvgCPUMhz, AvgCPUPcnt, MaxCPUPcnt
$VMInfo.name = $Server
$MaxCPUPcnt = get-vm $Server | Get-Stat -Stat cpu.usage.average -IntervalSecs 1 |
Where-Object { $workingDays -contains $_.Timestamp.DayOfWeek -and $_.Timestamp.TimeOfDay -gt $dayStart.TimeOfDay -and $_.Timestamp.TimeOfDay -lt $dayEnd.TimeOfDay} |
Measure-Object value -Max | select Maximum
$MaxMemPcnt = get-vm $Server | Get-Stat -Stat mem.usage.average -IntervalSecs 1 |
Where-Object { $workingDays -contains $_.Timestamp.DayOfWeek -and $_.Timestamp.TimeOfDay -gt $dayStart.TimeOfDay -and $_.Timestamp.TimeOfDay -lt $dayEnd.TimeOfDay} |
Measure-Object value -Max | select Maximum
$AvgCPUMhz = get-vm $Server | Get-Stat -Stat cpu.usagemhz.average -IntervalMins 5 |
Where-Object { $workingDays -contains $_.Timestamp.DayOfWeek -and $_.Timestamp.TimeOfDay -gt $dayStart.TimeOfDay -and $_.Timestamp.TimeOfDay -lt $dayEnd.TimeOfDay} |
Measure-Object value -Average | select Average
$AvgCPUPcnt = get-vm $Server | Get-Stat -Stat cpu.usage.average -IntervalMins 5 |
Where-Object { $workingDays -contains $_.Timestamp.DayOfWeek -and $_.Timestamp.TimeOfDay -gt $dayStart.TimeOfDay -and $_.Timestamp.TimeOfDay -lt $dayEnd.TimeOfDay} |
Measure-Object value -Average | select Average
$AvgMemPcnt = get-vm $Server | Get-Stat -Stat mem.usage.average -IntervalMins 5 |
Where-Object { $workingDays -contains $_.Timestamp.DayOfWeek -and $_.Timestamp.TimeOfDay -gt $dayStart.TimeOfDay -and $_.Timestamp.TimeOfDay -lt $dayEnd.TimeOfDay} |
Measure-Object value -Average | select Average
$VMinfo.MaxCPUPcnt = [math]::round($MaxCPUPcnt.Maximum,2)
$VMinfo.MaxMemPcnt = [math]::round($MaxMemPcnt.Maximum,2)
$VMinfo.AvgCPUMhz = [math]::round($AvgCPUMhz.Average,2)
$VMInfo.AvgCPUPcnt = [math]::round($AvgCPUPcnt.Average,2)
$VMInfo.AvgMemPcnt = [math]::round($AvgMemPcnt.Average,2)
$TotalMemMB = get-vm $Server | select MemoryMB
$VMInfo.TotalMemMB = $TotalMemMB.MemoryMb
$VMInfo.VMHost = (get-vm gbvc0007 | Get-VMHost).name
$VMInfo.OS = (Get-VM $Server | Get-View).summary.config.GuestFullName
$VMInfo.IPAddress = (Get-VM $Server | Get-VIew).summary.guest.ipaddress
$VMInfo.NumCPU = (Get-VM $Server | Get-VIew).summary.config.NumCPU
$Report += $VMInfo
$Counter++
}
clear
$Report | ft -AutoSize
$Report | Export-Csv -Path $CSVFile
Disconnect-VIServer -Server * -Confirm:$false
嗯,首先,你会想要做的:
$vm = get-vm $Server
然后再使用它,这样您就不需要为每个操作额外查询一次服务器。另外,我不知道 get-stat 是如何工作的,但是如果你可以在一次调用服务器时将 VM 所需的所有统计信息提取到一个变量中,你以后可以轻松地过滤掉你需要的一切,保存很多时间可能是这样的:
$vm = get-vm $Server
$vm | Get-Stat -Stat mem.usage.average,cpu.usage.average,cpu.usagemhz.average
你可以很容易地从你已有的变量中得到一些东西,比如:
$vm.MemoryMB 或者类似 $vm.GuestID
至于一般方法,我建议您使用类似 PoshRSJob 的东西来并行执行您的 foreach 循环,这将显着缩短您的脚本 运行 所需的时间,唯一的警告是您需要在每个 RSJob 中进行身份验证,这可能是个问题。
非常感谢您的回复和这么快的回复。它为我指明了正确的方向。
我填充了一个变量,然后通过这样做从中选择。
$VM = Get-VM $Server
$AvgStats = $VM | Get-Stat -Stat mem.usage.average,cpu.usage.average,cpu.usagemhz.average -IntervalMins 5 |
Where-Object { $workingDays -contains $_.Timestamp.DayOfWeek -and $_.Timestamp.TimeOfDay -gt $dayStart.TimeOfDay -and $_.Timestamp.TimeOfDay -lt $dayEnd.TimeOfDay}
$AvgMemPcnt = $AvgStats | Where-Object {$_.metricid -eq "mem.usage.average"} | Measure-Object value -Average | select Average
然后重复使用每个指标的实际答案填充变量的行。
我已经编写了一个 PowerCLI 脚本来检索我们 VM 上个月的相关信息和使用情况统计信息,并将其输出为 csv,但速度非常慢。谁能提出有助于加快报告速度的改进建议。
我是 powershell/PowerCLI 的新手,所以如有任何帮助,我们将不胜感激
$todayMidnight = (Get-Date -Hour 0 -Minute 0 -Second 0).AddMinutes(-1)
$EndOfLastMonth = (Get-Date -Year (get-date).Year -Month (get-date).Month -Day 1 -Hour 0 -Minute 0 -Second 0).AddMinutes(-1)
$FirstofLastMonth = $EndOfLastMonth.AddMonths(-1)
$workingDays = "Monday","Tuesday","Wednesday","Thursday","Friday"
$dayStart = New-Object DateTime(1,1,1,8,0,0)
$dayEnd = New-Object DateTime(1,1,1,18,0,0)
$CSVFile = Read-Host "Enter Filename for csv"
$Report = @()
Connect-VIServer "VCServer" | Out-Null
$ServerList = Get-VM | Where-Object {$_.VMHost.Name -ne "192.168.106.161" -and $_.PowerState -eq "PoweredOn" } | Sort-Object Name
$Counter = 1
foreach ($Server in $ServerList) {
$VMInfo = {} | select Name, OS, VMHost, IPAddress, NumCPU, TotalMemMB, AvgMemPcnt, MaxMemPcnt, AvgCPUMhz, AvgCPUPcnt, MaxCPUPcnt
$VMInfo.name = $Server
$MaxCPUPcnt = get-vm $Server | Get-Stat -Stat cpu.usage.average -IntervalSecs 1 |
Where-Object { $workingDays -contains $_.Timestamp.DayOfWeek -and $_.Timestamp.TimeOfDay -gt $dayStart.TimeOfDay -and $_.Timestamp.TimeOfDay -lt $dayEnd.TimeOfDay} |
Measure-Object value -Max | select Maximum
$MaxMemPcnt = get-vm $Server | Get-Stat -Stat mem.usage.average -IntervalSecs 1 |
Where-Object { $workingDays -contains $_.Timestamp.DayOfWeek -and $_.Timestamp.TimeOfDay -gt $dayStart.TimeOfDay -and $_.Timestamp.TimeOfDay -lt $dayEnd.TimeOfDay} |
Measure-Object value -Max | select Maximum
$AvgCPUMhz = get-vm $Server | Get-Stat -Stat cpu.usagemhz.average -IntervalMins 5 |
Where-Object { $workingDays -contains $_.Timestamp.DayOfWeek -and $_.Timestamp.TimeOfDay -gt $dayStart.TimeOfDay -and $_.Timestamp.TimeOfDay -lt $dayEnd.TimeOfDay} |
Measure-Object value -Average | select Average
$AvgCPUPcnt = get-vm $Server | Get-Stat -Stat cpu.usage.average -IntervalMins 5 |
Where-Object { $workingDays -contains $_.Timestamp.DayOfWeek -and $_.Timestamp.TimeOfDay -gt $dayStart.TimeOfDay -and $_.Timestamp.TimeOfDay -lt $dayEnd.TimeOfDay} |
Measure-Object value -Average | select Average
$AvgMemPcnt = get-vm $Server | Get-Stat -Stat mem.usage.average -IntervalMins 5 |
Where-Object { $workingDays -contains $_.Timestamp.DayOfWeek -and $_.Timestamp.TimeOfDay -gt $dayStart.TimeOfDay -and $_.Timestamp.TimeOfDay -lt $dayEnd.TimeOfDay} |
Measure-Object value -Average | select Average
$VMinfo.MaxCPUPcnt = [math]::round($MaxCPUPcnt.Maximum,2)
$VMinfo.MaxMemPcnt = [math]::round($MaxMemPcnt.Maximum,2)
$VMinfo.AvgCPUMhz = [math]::round($AvgCPUMhz.Average,2)
$VMInfo.AvgCPUPcnt = [math]::round($AvgCPUPcnt.Average,2)
$VMInfo.AvgMemPcnt = [math]::round($AvgMemPcnt.Average,2)
$TotalMemMB = get-vm $Server | select MemoryMB
$VMInfo.TotalMemMB = $TotalMemMB.MemoryMb
$VMInfo.VMHost = (get-vm gbvc0007 | Get-VMHost).name
$VMInfo.OS = (Get-VM $Server | Get-View).summary.config.GuestFullName
$VMInfo.IPAddress = (Get-VM $Server | Get-VIew).summary.guest.ipaddress
$VMInfo.NumCPU = (Get-VM $Server | Get-VIew).summary.config.NumCPU
$Report += $VMInfo
$Counter++
}
clear
$Report | ft -AutoSize
$Report | Export-Csv -Path $CSVFile
Disconnect-VIServer -Server * -Confirm:$false
嗯,首先,你会想要做的:
$vm = get-vm $Server
然后再使用它,这样您就不需要为每个操作额外查询一次服务器。另外,我不知道 get-stat 是如何工作的,但是如果你可以在一次调用服务器时将 VM 所需的所有统计信息提取到一个变量中,你以后可以轻松地过滤掉你需要的一切,保存很多时间可能是这样的:
$vm = get-vm $Server
$vm | Get-Stat -Stat mem.usage.average,cpu.usage.average,cpu.usagemhz.average
你可以很容易地从你已有的变量中得到一些东西,比如:
$vm.MemoryMB 或者类似 $vm.GuestID
至于一般方法,我建议您使用类似 PoshRSJob 的东西来并行执行您的 foreach 循环,这将显着缩短您的脚本 运行 所需的时间,唯一的警告是您需要在每个 RSJob 中进行身份验证,这可能是个问题。
非常感谢您的回复和这么快的回复。它为我指明了正确的方向。
我填充了一个变量,然后通过这样做从中选择。
$VM = Get-VM $Server
$AvgStats = $VM | Get-Stat -Stat mem.usage.average,cpu.usage.average,cpu.usagemhz.average -IntervalMins 5 |
Where-Object { $workingDays -contains $_.Timestamp.DayOfWeek -and $_.Timestamp.TimeOfDay -gt $dayStart.TimeOfDay -and $_.Timestamp.TimeOfDay -lt $dayEnd.TimeOfDay}
$AvgMemPcnt = $AvgStats | Where-Object {$_.metricid -eq "mem.usage.average"} | Measure-Object value -Average | select Average
然后重复使用每个指标的实际答案填充变量的行。