Powershell OS 计数值不正确
Powershell OS Count Value Incorrect
代码背后的想法是获取所有计算机。然后它通过计算机过滤并提取 OS 和 OS 版本。然后它会测试 OS 版本是否在数组中。如果该值存在,它将增加 1。如果该项目不在数组中,它将添加该项目并将值设置为 1。但是,结果并不像预期的那样。该网络上有 1000 多台计算机,但是,结果仅显示每个 OS 中的 2 台。对于其他用途,结果需要达到 table。
$Adomains = @{}
$Computers = Get-ADComputer -Filter * -Properties *
foreach ($ADPC in $Computers) {
if ($ADPC.OperatingSystem -eq $null) { $os = 'NULL'}
else { $os = $ADPC.OperatingSystem }
if ($ADPC.OperatingSystemVersion -eq $null) { $osver = 'NULL'}
else { $osver = $ADPC.OperatingSystemVersion }
if ($Adomains."$os - $osver"){
$Adomains."$os - $osver"++
} else {
$Adomains | Add-Member -MemberType NoteProperty -Name "$os - $osver" -Value 1
}
}
$Adomains
以上代码的结果如下:
Name Value
---- -----
Windows Embedded Standard -... 2
Windows 10 Enterprise - 10.... 2
Windows 10 Pro - 10.0 (17134) 2
Windows 10 Enterprise - 10.... 2
Windows 8.1 Pro - 6.3 (9600) 2
Windows 10 Pro - 10.0 (16299) 2
unknown - unknown 2
Windows 10 Enterprise - 10.... 2
Windows 10 Pro - 10.0 (14393) 2
Windows 10 Pro - 10.0 (15063) 2
Windows 7 Professional - 6.... 2
Windows 10 Pro - 10.0 (10586) 2
我想找出我的逻辑错误在哪里。
集中代码并仅按独特的操作系统排序,并放置一个解决“$Null”对象的 if 语句。
$OSes = Get-ADComputer -Filter {enabled -eq $true} -Properties operatingsystem | sort operatingsystem
$Unique = ($OSes | select operatingsystem -Unique).Operatingsystem
$Return = @()
foreach ($U in $Unique) {
$ADOScounting = ($OSes | Where-Object {$_.OperatingSystem -like "$U"}).count
$return += [pscustomobject][ordered] @{
Name = $U
Count = if ($ADOScounting -eq $null) {"0"} else {$ADOScounting}
}
}
$Return
你原来的错误是多方面的。首先,您使用的是哈希表,而不是数组(这似乎是有意为之,您只是用错了术语)。
问题的主要原因是,当您第一次尝试添加新的 OS 时,您添加的不是新的 key/value 对,而是添加 属性 到哈希表对象本身。
您使用 .
访问这两个属性,如果是哈希表,则访问条目。
所以在你第一次添加 属性 之后会发生什么,当代码来检查 if ($Adomain."$os - $osver")
是否存在时,结果是 $true
;到目前为止一切顺利。
然后你 $Adomains."$os - $osver"++
这就是它变得奇怪的地方。
值的读取来自属性,所以是1
。 write 在哈希表中创建一个值为 2 的新条目(来自 属性 的 1
加上 1
)。现在 属性 是 1
,输入值是 2
.
虽然下一次,这种情况再次发生,读取来自 属性,写入进入条目,所以你永远写入 2
。
要在您的代码中轻松解决它,请更改:
} else {
$Adomains | Add-Member -MemberType NoteProperty -Name "$os - $osver" -Value 1
}
对此:
} else {
$Adomains."$os - $osver" = 1
}
但更好的是使用 Group-Object
,它已经可以满足您的需求:
$Computers = Get-ADComputer -Filter * -Properties OperatingSystem,OperatingSystemVersion |
Group-Object -Property {"$($_.OperatingSystem) - $($_.OperatingSystemVerson)"}
它不会将空值转换为更漂亮的字符串,但如果需要,您可以将该逻辑放在脚本块中。
它 returns 分组对象,但如果你想返回一个真正的哈希表,你可以添加 -AsHashTable -AsString
。
你的方法在我看来过于复杂。
$Adomains = Get-ADComputer -Filter * -Properties OperatingSystem,OperatingSystemVersion |
Group-Object OperatingSystem,OperatingSystemVersion -NoElement
$Adomains | Format-Table -Autosize
根据Bacon Bits 有用的提示编辑
代码背后的想法是获取所有计算机。然后它通过计算机过滤并提取 OS 和 OS 版本。然后它会测试 OS 版本是否在数组中。如果该值存在,它将增加 1。如果该项目不在数组中,它将添加该项目并将值设置为 1。但是,结果并不像预期的那样。该网络上有 1000 多台计算机,但是,结果仅显示每个 OS 中的 2 台。对于其他用途,结果需要达到 table。
$Adomains = @{}
$Computers = Get-ADComputer -Filter * -Properties *
foreach ($ADPC in $Computers) {
if ($ADPC.OperatingSystem -eq $null) { $os = 'NULL'}
else { $os = $ADPC.OperatingSystem }
if ($ADPC.OperatingSystemVersion -eq $null) { $osver = 'NULL'}
else { $osver = $ADPC.OperatingSystemVersion }
if ($Adomains."$os - $osver"){
$Adomains."$os - $osver"++
} else {
$Adomains | Add-Member -MemberType NoteProperty -Name "$os - $osver" -Value 1
}
}
$Adomains
以上代码的结果如下:
Name Value
---- -----
Windows Embedded Standard -... 2
Windows 10 Enterprise - 10.... 2
Windows 10 Pro - 10.0 (17134) 2
Windows 10 Enterprise - 10.... 2
Windows 8.1 Pro - 6.3 (9600) 2
Windows 10 Pro - 10.0 (16299) 2
unknown - unknown 2
Windows 10 Enterprise - 10.... 2
Windows 10 Pro - 10.0 (14393) 2
Windows 10 Pro - 10.0 (15063) 2
Windows 7 Professional - 6.... 2
Windows 10 Pro - 10.0 (10586) 2
我想找出我的逻辑错误在哪里。
集中代码并仅按独特的操作系统排序,并放置一个解决“$Null”对象的 if 语句。
$OSes = Get-ADComputer -Filter {enabled -eq $true} -Properties operatingsystem | sort operatingsystem
$Unique = ($OSes | select operatingsystem -Unique).Operatingsystem
$Return = @()
foreach ($U in $Unique) {
$ADOScounting = ($OSes | Where-Object {$_.OperatingSystem -like "$U"}).count
$return += [pscustomobject][ordered] @{
Name = $U
Count = if ($ADOScounting -eq $null) {"0"} else {$ADOScounting}
}
}
$Return
你原来的错误是多方面的。首先,您使用的是哈希表,而不是数组(这似乎是有意为之,您只是用错了术语)。
问题的主要原因是,当您第一次尝试添加新的 OS 时,您添加的不是新的 key/value 对,而是添加 属性 到哈希表对象本身。
您使用 .
访问这两个属性,如果是哈希表,则访问条目。
所以在你第一次添加 属性 之后会发生什么,当代码来检查 if ($Adomain."$os - $osver")
是否存在时,结果是 $true
;到目前为止一切顺利。
然后你 $Adomains."$os - $osver"++
这就是它变得奇怪的地方。
值的读取来自属性,所以是1
。 write 在哈希表中创建一个值为 2 的新条目(来自 属性 的 1
加上 1
)。现在 属性 是 1
,输入值是 2
.
虽然下一次,这种情况再次发生,读取来自 属性,写入进入条目,所以你永远写入 2
。
要在您的代码中轻松解决它,请更改:
} else {
$Adomains | Add-Member -MemberType NoteProperty -Name "$os - $osver" -Value 1
}
对此:
} else {
$Adomains."$os - $osver" = 1
}
但更好的是使用 Group-Object
,它已经可以满足您的需求:
$Computers = Get-ADComputer -Filter * -Properties OperatingSystem,OperatingSystemVersion |
Group-Object -Property {"$($_.OperatingSystem) - $($_.OperatingSystemVerson)"}
它不会将空值转换为更漂亮的字符串,但如果需要,您可以将该逻辑放在脚本块中。
它 returns 分组对象,但如果你想返回一个真正的哈希表,你可以添加 -AsHashTable -AsString
。
你的方法在我看来过于复杂。
$Adomains = Get-ADComputer -Filter * -Properties OperatingSystem,OperatingSystemVersion |
Group-Object OperatingSystem,OperatingSystemVersion -NoElement
$Adomains | Format-Table -Autosize
根据Bacon Bits 有用的提示编辑