【问题标题】:Compare values with previous loop将值与前一个循环进行比较
【发布时间】:2017-08-13 15:34:48
【问题描述】:

我制作了这个脚本来监控服务器分区的可用空间。现在我正在尝试将最新的循环与之前的循环进行比较,并将可用空间值存储到数组中,但我从未做过这样的事情。

我不知道如何使用数组——一个必须在循环开始时被擦除,第二个必须存储以前的值,然后它们必须进行比较。

能否请您至少给我一个提示?

#play star-wars imperial march
function play-alarm {    
    Start-Job {
        [Console]::Beep(440,500)
    }
}
$cred = Get-Credential domain\username

$hostname = "server1"

#if free space lower, then play alarm
$low_level = "10"

#get drives letters
$partitions = Get-WmiObject Win32_LogicalDisk -Computername $hostname -Credential $cred | foreach DeviceID

#create arrays
$old_values = New-Object System.Collections.ArrayList
$new_values = New-Object System.Collections.ArrayList

#noob loop
$repeat = "2"

while ($i -lt $repeat) {
    Write-Host "        ***        " -ForegroundColor Yellow
    Write-Host "        ***        " -ForegroundColor Yellow
    Write-Host "        ***        " -ForegroundColor Yellow
    Write-Host "Free space at server:" -BackgroundColor Black

    #backup previouse values and clear array for new ones
    $old_values = $new_values
    $new_values.Clear()

    foreach ($partition in $partitions) {
        $device = "DeviceID='" + $partition + "'"

        $size = Get-WmiObject Win32_LogicalDisk -Credential $cred -ComputerName $hostname -Filter $device |
                ForEach-Object {$_.Size}
        $size = [Math]::Round($size/1GB)
        $free = Get-WmiObject Win32_LogicalDisk -Credential $cred -ComputerName $hostname -Filter $device |
                ForEach-Object {$_.FreeSpace}
        $free = [Math]::Round($free/1GB)
        Write-Host $free
        #add value rounded to GB
        $new_values.Add($free)

        #if device is CD-ROM, the size or space is zero - this cause error when calculating percentage of free space
        if ($size -eq "0") {
            Write-Host "disk " $partition "is CD-ROM" -ForegroundColor Yellow
        } else {
            $perc = ($free/$size)*100
            $perc = [Math]::Round($perc, 3)

            if ($perc -le $low_level) {
                Write-Host "Not enough free space at partition " $partition "!!!" $perc "%" -BackgroundColor Red #| play-alarm
                Start-Sleep -s 15
            } else {
                Write-Host "disk " $partition "is OK - " $perc "%" -ForegroundColor Green
            }
        }
    }

    if ($old_values -eq $new_values) {
        Write-Host "no change..."
    } else {
        Write-Host "Attention - change!!!" -BackgroundColor Red
    }

    $time = $((Get-Date).ToString())
    Write-Host "Loop finished..." $time -BackgroundColor Black
    Write-Host "        ***        " -ForegroundColor Yellow
    Write-Host "        ***        " -ForegroundColor Yellow
    Write-Host "        ***        " -ForegroundColor Yellow
    Start-Sleep -s 300
}

【问题讨论】:

    标签: arrays powershell compare


    【解决方案1】:

    复制以前的值

    $old_values = $new_values
    $new_values.Clear()
    

    这个问题是 $old_values 现在引用 与 $new_values 相同的 数组。使用

    $old_values = $new_values.Clone()
    

    创建一个副本。

    比较

    您不想使用-eq 来比较容器对象的内容。您可以遍历数组并比较每个元素

    for ($index=0;$index -lt $old_values.count;$index+=1) {
        if ($old_values[$index] -ne $new_values[$index]) {
            write-host "Changed!"
            break
        }
    }
    

    或者你可以使用Compare-Object

        if (Compare-Object $old_values $new_values) {
            write-host "No Change!"
        } else {
            write-host "Changed!"
        }
    

    Compare-Object 返回差异列表。如果您比较的内容相同,则返回一个空值(并且布尔值为 false)。

    【讨论】:

      【解决方案2】:

      如果要将当前值与之前运行的值进行比较,则需要将当前值存储在脚本末尾的某个位置(例如,在 CSV 文件中),并在脚本的开头。

      $csv = 'C:\path\to\data.csv'
      
      if (Test-Path -LiteralPath $csv) {
          $old_values = Import-Csv $csv
      } else {
          # initialize $old_values as an empty array if the file doesn't exist (yet)
          $old_values = @()
      }
      
      ...
      
      $new_values | Export-Csv $csv -NoType
      

      通过选择 WMI 数据的相关属性,将 $new_values 构建为自定义对象列表。避免格式化磁盘空间数据,除非它是为了输出给用户。

      $new_values = Get-WmiObject Win32_LogicalDisk -Computer $hostname -Credential $cred |
                    Select-Object DeviceID, Size, FreeSpace
      

      您可以使用calculated properties 添加派生信息(如可用磁盘空间比率):

      ... | Select-Object DeviceID, Size, FreeSpace, @{n='Ratio';e={$_.FreeSpace/$_.Size}}
      

      使用Compare-Object 比较新旧数据:

      Compare-Object -ReferenceObject $old_values -DifferenceObject $new_values -Property DeviceID, Size, FreeSpace
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-24
        • 1970-01-01
        相关资源
        最近更新 更多