我是stackoverflow的新手,我并不是真正的PowerShell破解。也许你可以帮我解决我的问题。出于监控原因,我想从" vmstat 1 10"获得ssh结果。在Linux服务器上。我需要获得我拥有的10个值的Avarage值。通常" vmstat 1 10"结果如下:
procs -----------memory---------- ---swap-- -----io---- -system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 42352 599980 315860 2488096 0 0 2606 794 5 2 3 0 94 2 0
0 0 42352 600044 315860 2488096 0 0 64 84 1107 2107 0 1 99 1 0
0 0 42352 596820 315860 2488096 0 0 280 4 1218 2179 7 1 91 2 0
0 0 42352 589240 315860 2488096 0 0 32 7 1322 2366 1 1 95 3 0
0 0 42352 588620 315860 2488096 0 0 144 37 1161 2181 1 0 96 3 0
0 0 42352 588620 315860 2488096 0 0 0 24 1074 2075 0 0 100 0 0
0 0 42352 588620 315860 2488096 0 0 0 0 1081 2081 0 1 100 0 0
0 0 42352 588628 315860 2488096 0 0 128 32 1133 2091 1 0 96 3 0
0 0 42352 588652 315860 2488100 0 0 0 0 1077 2058 0 0 100 0 0
0 0 42352 588528 315860 2488100 0 0 0 5 1137 2147 0 0 99 0 0
因此,为了获得像swpd,free,buff等值的AVG,我的计划是在Object中获取整个值,然后制作类似$tab.swpd | Measure-Object -avg
但我得到错误。
这是我在Script中获取值的脚本。 (我知道这不是很好 - 对不起。我还在学习......):
$runs = 10
#Get the Values via plink (putty)
$vmstat = .\plink.exe -ssh USER@SERVER -batch -pw "PASSWORD-YES-I-KNOW-THIS-IS-BAD" vmstat 1 $runs
$vmstat
##########################
#Get the Values in somthing like a csv
$vmstat = $vmstat.replace(" ", ";")
#replace alle double ";;" with single ";"
while ($vmstat -match ";;"){
$vmstat = $vmstat.replace(";;", ";")
}
#Delete ";" at the beginning (and at the end. Just to be sure. normally there arent ";" 's)
$vmstat = $vmstat.Trim(";")
#Save Columnames
$tabhead = $vmstat[1].split(";")
#Delete first and second row
$vmstat = $vmstat[2..($runs+1)]
##########################
#Split Values and Store it in an two-dimensional array
$values = New-Object system.Array[][] $tabhead.Length, $runs
for ($i=0;$i -lt ($vmstat.Length); $i++){
$tmp = $vmstat[$i].split(";")
for ($j=0;$j -lt ($tmp.Length); $j++){
$values[$j][$i] = $tmp[$j]
}
}
##########################
# Make an Object for Measurement!
$tab = New-Object System.Object
for ($i=0;$i -lt $tabhead.Length; $i++){
$tab | Add-Member -type NoteProperty -name $tabhead[$i] -Value $values[$i]
}
所以在那之后我的所有值都像我想要的数组或对象。我可以选择我想看的值:
PS C:\> $tab
r : {1, 0, 0, 0...}
b : {0, 0, 0, 0...}
swpd : {42352, 42352, 42352, 42352...}
free : {599980, 600044, 596820, 589240...}
buff : {315860, 315860, 315860, 315860...}
cache : {2488096, 2488096, 2488096, 2488096...}
si : {0, 0, 0, 0...}
so : {0, 0, 0, 0...}
bi : {2606, 64, 280, 32...}
bo : {794, 84, 4, 7...}
in : {5, 1107, 1218, 1322...}
cs : {2, 2107, 2179, 2366...}
us : {3, 0, 7, 1...}
sy : {0, 1, 1, 1...}
id : {94, 99, 91, 95...}
wa : {2, 1, 2, 3...}
st : {0, 0, 0, 0...}
PS C:\> $tab.in
5
1107
1218
1322
1161
1074
1081
1133
1077
1137
但是,当我尝试类似:$tab.swpd | Measure-Object -Average
时,我收到以下错误:
Measure-Object : Das Eingabeobjekt "System.Object[]" ist nicht numerisch.
In Zeile:1 Zeichen:13
+ $tab.swpd | Measure-Object -Average
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidType: (System.Object[]:Object[]) [Measure-Object], PSInvalidOperationException
+ FullyQualifiedErrorId : NonNumericInputObject,Microsoft.PowerShell.Commands.MeasureObjectCommand
我想我甚至不需要Object,我认为做$values[0] | Measure-Object -Average
这样的事情也必须是可行的,但也有同样的错误。我知道问题是值不是int值。但我不知道如何转换它们以便我可以进行测量。
答案 0 :(得分:-1)
我无法访问相同的资源,因此我无法完美地重现问题。你是对的。 Measure-Object
试图告诉您它无法使用非数值。我认为PowerShell的新版本可以更好地处理这个问题,但是演员可能会对你做得很好。
[int[]]($tab.swpd) | Measure-Object -Average
这应该将System.Object[]
数组投射到System.Int32[]
提高效率
您正在用分号分隔空白区域并将其合并,直到您拥有分号。正则表达式可能会保存整个循环。这将占用一组空白并将它们转换为分号。这可能会将您的问题保存到最后。这可能会解决您对Measure-Object的问题,因为这应该删除所有空格,假设您没有在其他地方添加任何其他空格。您仍然需要像现在这样处理由此创建的前导和尾随半冒号。
$vmstat = $vmstat.replace("\s+", ";")
根据评论进行修改
所以我看到演员表失败了。您的数组值中有空格,我最初没有注意到。也许这就是你拥有和发行的原因。你似乎有一个字符串数组。我将再次查看您的代码,并找出它们的来源。还有其他方法可以解决这个问题,但一个简单的方法可能是更新代码底部的这一行
$tab | Add-Member -type NoteProperty -name $tabhead[$i] -Value $values[$i].Trim()