简体   繁体   English

与上一个循环比较值

[英]Compare values with previous loop

I made this script to monitor free space of server partitions. 我制作了这个脚本来监视服务器分区的可用空间。 Now I'm trying to compare latest loop with previous one with storing free space values to arrays, but I've never done anything like this. 现在,我试图将最新的循环与上一个循环进行比较,以将可用空间值存储到数组中,但是我从未做过这样的事情。

I don't know how exactly to work with arrays - one has to be erased at the beginning of the loop and second has to store the previous values, then they have to be compared. 我不知道如何精确地使用数组-一个必须在循环开始时删除,第二个必须存储先前的值,然后必须将它们进行比较。

Could you please give me at least a hint? 您能否给我至少一个提示?

#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
}

Copy previous values 复制以前的值

$old_values = $new_values
$new_values.Clear()

The problem with this is $old_values is now referring to the same array as $new_values. 问题在于$ old_values现在与$ new_values指向同一数组。 Use 采用

$old_values = $new_values.Clone()

to create a copy. 创建副本。

Compare 相比

You don't want to use -eq to compare the contents of container objects. 您不想使用-eq比较容器对象的内容。 You can loop through the arrays and compare each element 您可以遍历数组并比较每个元素

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

Or you can use Compare-Object 或者您可以使用Compare-Object

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

Compare-Object returns a list of differences. Compare-Object返回差异列表。 If the contents you compare are the same, then it returns an empty (and boolean false) value. 如果您比较的内容相同,那么它将返回一个空值(布尔值为false)。

If you want to compare current values to those of a previous run you need to store the current values somewhere at the end of the script (in a CSV file for instance), and read that file (if it exists) at the beginning of the script. 如果要将当前值与先前运行的值进行比较,则需要将当前值存储在脚本末尾的某个位置(例如,在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

Build $new_values as a list of custom objects by selecting the relevant properties of the WMI data. 通过选择WMI数据的相关属性,将$new_values构建$new_values自定义对象的列表。 Avoid formatting the diskspace data unless it's for output to the user. 除非将其输出给用户,否则请避免格式化磁盘空间数据。

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

You can use calculated properties for adding derived information (like the free disk space ratio): 您可以使用计算出的属性来添加派生信息(例如可用磁盘空间比率):

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

Use Compare-Object for comparing old and new data: 使用Compare-Object比较旧数据和新数据:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM