【问题标题】:Averaging temperature within a nested loop嵌套循环内的平均温度
【发布时间】:2021-03-15 21:26:10
【问题描述】:

我正在尝试编写一个脚本,该脚本使用 OpenHardwareMonitor 获取 CPU 温度,如果它在给定的持续时间内平均高于某个阈值,则会发出警报。

获取当前温度工作正常,但我很难将它们平均起来,因为在某些系统上可能有一个或多个 CPU,所以我不能每分钟记录一次温度并除以经过的分钟数,下面是我所拥有的最好的(这不起作用),请一些好心人帮我看看我哪里出错了?

$tempThreshold = 80 # Will alert if average temperature is above this
$minutes = 3 # Duration in minutes to test for

start-process "$env:SystemRoot\TEMP\OpenHardwareMonitor\openhardwaremonitor.exe"

# Loop each minute
for ($i=1; $i -le $minutes; $i++) {

    $arrSensors=@{}
    if ((Get-WmiObject -Namespace "Root\OpenHardwareMonitor" -Query "SELECT * FROM Sensor WHERE Sensortype='Temperature'" | ? {$_.Name -match 'CPU Package'}).value) {
        Get-WmiObject -Namespace "Root\OpenHardwareMonitor" -Query "SELECT * FROM Sensor WHERE Sensortype='Temperature'" | ? {$_.Name -Match "CPU Package"} | % {$arrSensors[$_.Name]=$_.Value}
    } else {
        Get-WmiObject -Namespace "Root\OpenHardwareMonitor" -Query "SELECT * FROM Sensor WHERE Sensortype='Temperature'" | ? {$_.Identifier -match 'cpu/'} | % {$arrSensors[$_.Name]=$_.Value}
    }


    $temps = foreach ($sensor in $arrSensors.getEnumerator()) {
        Start-Sleep -Seconds 60
        $temp = $temp+$sensor.value
        }
}

# Alert if average above threshold
if ($temps/$minutes -gt $tempThreshold) {
    Write-Host "Alert function here"
    }

【问题讨论】:

  • 顺便说一句,如果您将 Get-WmiObject -Namespace "Root\OpenHardwareMonitor" -Query "SELECT * FROM Sensor WHERE Sensortype='Temperature'" 分配给 for 循环内的临时变量,您将不需要执行 3 次并进一步加热您的 CPU :-)。跨度>

标签: powershell loops average monitor temperature


【解决方案1】:

我也在寻找监控 Windows 上的 CPU 温度。我的后端是带有 influxdb 的 grafana。使用 ohm 和 wmi 的 CPU 强度很高,我发现 https://github.com/nickbabcock/OhmGraphite#influxdb-configuration。这个应用程序基于 ohm,但将数据直接发送到 influxdb(不需要昂贵的 wmi 调用)。也许这对你也很感兴趣。使用 grafana,您可以平均该值并在那里设置阈值。

但是 - 也许这不是你的选择,所以这里的脚本使用 ohm 应用程序获取平均值。 这个脚本的缺点是,脚本运行 2 分钟 - 所以你不会每分钟都收到警报(除非你用一分钟的 appart 运行它两次(可以使用计划任务轻松设置)。

$tempThreshold = 80 # Will alert if average temperature is above this
$minutes = 3 # Duration in minutes to test for

start-process "$env:SystemRoot\TEMP\OpenHardwareMonitor\openhardwaremonitor.exe"

$counter = 0
$sum = 0

while($counter -lt $minutes) {
    $cpuArray = Get-WmiObject -Namespace "Root\OpenHardwareMonitor" -Query "SELECT * FROM Sensor WHERE Sensortype='Temperature'"
    
    if($cpuArray | where name -like 'cpu package*') {
        $cpuTempArray = $cpuArray | where name -like 'cpu package*'
    } else {
        $cpuTempArray = $cpuArray | where name -like 'cpu core*'
    }
    
    foreach($cpuTemp in $cpuTempArray){
        $sum += $cpuTemp.value
    }
    
    $counter++
    if($counter -ne $minutes) {
        Start-Sleep -Seconds 60
    }
}

$average = $sum/($counter*$cpuTempArray.Count)

# Alert if average above threshold
if($average -gt $tempThreshold) {
    Write-Host "Alert function here"
}

【讨论】:

    【解决方案2】:

    正如我的另一个答案所提到的,其他脚本运行一次,恕我直言,不能被视为“监控”——就像“每当达到阈值时发出警报”一样——就像每分钟一样。

    以下脚本在无限循环中运行。它以每分钟的平均值收集设定数量的数据 ($minutes)。您可能想更改它以将所有 cpu 的最大值存储在 $valueArray 中,然后取其平均值。

    $tempThreshold = 80 # Will alert if average temperature is above this
    $minutes = 3 # Duration in minutes to test for
    
    Start-Process -FilePath "$env:SystemRoot\TEMP\OpenHardwareMonitor\openhardwaremonitor.exe"
    $valueArray = [System.Collections.ArrayList]@()
    
    while($true) {
        # keep only #no of values in array specified in $minutes
        if($valueArray.Count -gt $minutes) {
            # remove oldest entry from array
            $valueArray.RemoveAt(0)
        }
    
        if($valueArray.Count -eq $minutes) {
            $average = ($valueArray | Measure-Object -Sum).Sum/$minutes
    
            # Alert if average above threshold
            if($average -gt $tempThreshold) {
                Write-Host "Alert function here"
            }
        }
    
        $sensorArray = Get-WmiObject -Namespace "Root\OpenHardwareMonitor" -Query "SELECT * FROM Sensor WHERE Sensortype='Temperature'"
    
        if($sensorArray | where name -like 'asdf cpu package*') {
            $cpuTempArray = $sensorArray | where name -like 'cpu package*'
        } else {
            $cpuTempArray = $sensorArray | where name -like 'cpu core*'
        }
    
        $counter = 0
        $sum = 0
        foreach($cpuTemp in $cpuTempArray) {
            $counter++
            $sum += $cpuTemp.value
        }
        $currentAverageTemp = $sum/$counter
    
        $valueArray.Add($currentAverageTemp)
    
        Start-Sleep -Seconds 60
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-27
      • 2018-08-15
      相关资源
      最近更新 更多