提问人:Arthur Durand 提问时间:2/21/2023 最后编辑:mklement0Arthur Durand 更新时间:3/6/2023 访问量:432
如何在 PowerShell 中正确获取系统模型并将其设置为参数?
How to properly get System Model in PowerShell and set it as a parameter?
问:
我需要使用 PowerShell 正确获取电脑的系统型号,并将型号用作参数,以便可以运行特定于型号的任务。
我的代码有点复杂,因为某些方法返回的值如“不可用”、“由 O.E.M. 填充”或“系统产品制造商”——在这些情况下,我不希望$Model参数为“不可用”、“由 O.E.M. 填充”或“系统产品制造商”。
我有以下内容,但它不能按预期工作
$BaseBoardManufacturer = Get-WmiObject Win32_BaseBoard | Select Manufacturer
if ((-not ([string]::IsNullOrWhiteSpace($BaseBoardManufacturer))) -and ($BaseBoardManufacturer.Manufacturer -ne 'Not Available') -or ($BaseBoardManufacturer.Manufacturer -ne 'System manufacturer'))
{
[String]$Manufacturer = ($BaseBoardManufacturer.Manufacturer).ToString()
}
$ProductManufacturer = Get-WmiObject -Class:Win32_ComputerSystemProduct | select Vendor
if ((-not ([string]::IsNullOrWhiteSpace($ProductManufacturer))) -and ($ProductManufacturer.Vendor -ne 'Not Available') -or ($ProductManufacturer.Vendor -ne 'System manufacturer') -or ($ProductManufacturer.Vendor -ne 'To be filled by O.E.M.'))
{
[String]$Manufacturer = ($ProductManufacturer.Vendor).ToString()
}
$SystemManufacturer = Get-WmiObject -Class:Win32_ComputerSystem | select Manufacturer
if ((-not ([string]::IsNullOrWhiteSpace($SystemManufacturer))) -and ($SystemManufacturer.Manufacturer -ne 'Not Available') -or ($SystemManufacturer.Manufacturer -ne 'System manufacturer') -or ($SystemManufacturer.Manufacturer -ne 'To be filled by O.E.M.'))
{
[String]$Manufacturer = ($SystemManufacturer.Manufacturer).ToString()
}
$BaseBoardProduct = Get-WmiObject Win32_BaseBoard | Select Product
if ((-not ([string]::IsNullOrWhiteSpace($BaseBoardProduct))) -and ($BaseBoardProduct.Product -ne 'Not Available'))
{
[String]$Model = ($BaseBoardProduct.Product).ToString()
}
$ProductVersion = Get-WmiObject -Class:Win32_ComputerSystemProduct | select Version
if ((!($ProductVersion.Version -ne 'System Version')) -xor (!($ProductVersion.Version -ne 'To be filled by O.E.M.')) -and (-not ([string]::IsNullOrWhiteSpace($ProductVersion))))
{
[String]$Model = ($ProductVersion.Version).ToString()
}
$SystemModel = Get-WmiObject -Class:Win32_ComputerSystem | select Model
if ((-not ([string]::IsNullOrWhiteSpace($SystemModel))) -and ($SystemModel.Model -ne 'System Product Name') -or ($SystemModel.Model -ne 'To be filled by O.E.M.'))
{
[String]$Model = ($SystemModel.Model).ToString()
}
$SystemManufacturer = Get-WmiObject -Class:Win32_ComputerSystem | select Manufacturer
if ((-not ([string]::IsNullOrWhiteSpace($SystemManufacturer))) -and ($SystemManufacturer.Manufacturer -ne 'Not Available') -or ($SystemManufacturer.Manufacturer -ne 'System manufacturer') -or ($SystemManufacturer.Manufacturer -ne 'To be filled by O.E.M.'))
{
[String]$Manufacturer = ($SystemManufacturer.Manufacturer).ToString()
}
if ($Manufacturer -like '*Lenovo*')
{
$ProductVersion = Get-WmiObject -Class:Win32_ComputerSystemProduct | select Version
[String]$Model = ($ProductVersion.Version).ToString()
}
例如,我想要
((!($ProductVersion.Version -ne 'System Version')) -or (!($ProductVersion.Version -ne 'To be filled by O.E.M.')) -and (-not ([string]::IsNullOrWhiteSpace($ProductVersion))))
当 ProductVersion 返回“To be filled by O.E.M.”或“System Version”时返回 false,但它返回 true!
我试过了
((!($ProductVersion.Version -ne 'System Version')) -xor (!($ProductVersion.Version -ne 'To be filled by O.E.M.')) -and (-not ([string]::IsNullOrWhiteSpace($ProductVersion))))
和
if ((-not ($SystemModel.Model -eq 'System Product Name')) -or (-not ($SystemModel.Model -eq 'To be filled by O.E.M.')) -and (-not ([string]::IsNullOrWhiteSpace($SystemModel))))
但是我将“系统版本”设置为参数而不是型号,换句话说,当参数应该返回false时,该参数返回true
答:
首先,我建议简化您的属性检索命令:
使用
Select-Object
从调用发出的对象中提取单个属性Get-WmiObject
也许令人惊讶的是,类似(缩写:)的东西不会返回输入对象属性的值,它为每个输入对象返回一个新对象,该对象是类型并且本身具有属性。
... | Select Product
... | Select-Object -Property Product
.Product
[pscustomobject]
Product
若要仅提取属性值,请使用
Select-Object
的-ExpandProperty
参数,而不是 (位置隐含) 参数;
例如... |Select-Object -ExpandProperty 产品
。-Property
有关更多信息和更有效的替代方案,请参阅这篇文章。
其次,布尔逻辑存在问题,将在下一节中解释。
但是,我建议简化您的条件如下:
# Sample input objects.
@(
$null
[pscustomobject] @{ Version = $null }
[pscustomobject] @{ Version = '' }
[pscustomobject] @{ Version = 'System Version' }
[pscustomobject] @{ Version = 'To be filled by O.E.M.' }
[pscustomobject] @{ Version = '1' }
) | ForEach-Object {
$ProductVersion = $_
# Output $true only if $ProductVersion is an object that has
# a .Version property whose value is neither $null, the empty string
# nor 'System Version' nor 'To be filled by O.E.M.'
$ProductVersion.Version -notlike '' -and
$ProductVersion.Version -notin 'System Version', 'To be filled by O.E.M.'
}
$ProductVersion.Version -notlike ''
确保属性值既不是空字符串,也不是空字符串(甚至确保本身不是空字符串,尽管在您的情况下不应发生这种情况)。.Version
$null
$ProductVersion
$null
-notin
运算符提供了一种方便的方法来测试 LHS 字符串值是否不等于 RHS 数组的任何元素。
输出:
False
False
False
False
False
True
至于你试过的:
((!($ProductVersion.Version -ne 'System Version')) -or (!($ProductVersion.Version -ne 'To be filled by O.E.M.'))
这可以简化为:
$ProductVersion.Version -eq 'System Version' -or $ProductVersion.Version -eq 'To be filled by O.E.M.'
并且与您想要的相反,即如果找到任何一个字符串值,它将返回。$true
您可以将表达式作为一个整体来否定( 和 -not
是同一个运算符):!
-not ($ProductVersion.Version -eq 'System Version' -or $ProductVersion.Version -eq 'To be filled by O.E.M.')
或 use 代替 ,这需要您更改为:-ne
-eq
-or
-and
$ProductVersion.Version -ne 'System Version' -and $ProductVersion.Version -ne 'To be filled by O.E.M.'
-xor
,仅当正好一个操作数为 时才返回 true,这里不需要,因为它需要计算两个操作数,这里不需要。$true
评论
$BaseBoardProduct = Get-WmiObject Win32_BaseBoard | Where-Object {$_.Product -ne 'Not Available'} | Select-Object -ExpandProperty Product
if (-not ([string]::IsNullOrWhiteSpace($BaseBoardProduct)))
{
$Model = $BaseBoardProduct
}
$ProductVersion = Get-WmiObject -Class:Win32_ComputerSystemProduct | Where- Object {$_.Version -ne 'System Version' -and $_.Version -ne 'To be filled by O.E.M.'} | Select-Object -ExpandProperty Version
if (-not ([string]::IsNullOrWhiteSpace($ProductVersion)))
{
$Model = $ProductVersion
}
$SystemModel = Get-WmiObject -Class:Win32_ComputerSystem | Where-Object {$_.Model -ne 'System Product Name' -and $_.Model -ne 'To be filled by O.E.M.'} | Select-Object -ExpandProperty Model
if (-not ([string]::IsNullOrWhiteSpace($SystemModel)))
{
$Model = $SystemModel
}
$SystemManufacturer = Get-WmiObject -Class:Win32_ComputerSystem | Where- Object {$_.Manufacturer -ne 'Not Available' -and $_.Manufacturer -ne 'System manufacturer' -and $_.Manufacturer -ne 'To be filled by O.E.M.'} | Select-Object -ExpandProperty Manufacturer
if (-not ([string]::IsNullOrWhiteSpace($SystemManufacturer)))
{
$Manufacturer = $SystemManufacturer
}
if ($Manufacturer -like '*Lenovo*')
{
$ProductVersion = Get-WmiObject -Class:Win32_ComputerSystemProduct |
Select-Object -ExpandProperty Version
$Model = $ProductVersion
}
解决了我的问题!然而,ChatGPT 想出了
$ExcludedManufacturers = 'Not Available', 'System Manufacturer', 'To be filled by O.E.M.'
$Filter = "Manufacturer!='Not Available' AND Manufacturer!='System Manufacturer' AND Manufacturer!='To be filled by O.E.M.'"
$SystemInfo = Get-CimInstance -ClassName Win32_ComputerSystem -Property Model, Manufacturer -Filter $Filter | Sort-Object Manufacturer
$BaseBoardProduct = Get-CimInstance -ClassName Win32_BaseBoard -Property Product -Filter "Product!='Not Available'" | Sort-Object Product | Select-Object -First 1
$ProductVersion = $SystemInfo | Where-Object { $_.Version -notin 'System Version', 'To be filled by O.E.M.' } | Sort-Object Manufacturer | Select-Object -First 1 -ExpandProperty Version
$Model = ($BaseBoardProduct.Product, $SystemInfo.Model) | Where-Object { $_ -notin 'System Product Name', 'To be filled by O.E.M.' } | Select-Object -First 1
$Manufacturer = $SystemInfo[0].Manufacturer
if ($Manufacturer -like '*Lenovo*') {
$Model = $ProductVersion
}
或
$BaseBoardProduct = Get-WmiObject -Class Win32_BaseBoard | Select-Object -ExpandProperty Product | Where-Object {$_ -ne 'Not Available'} | Select-Object -First 1
$ProductVersion = Get-WmiObject -Class Win32_ComputerSystemProduct | Select-Object -ExpandProperty Version | Where-Object {$_ -notin ('System Version', 'To be filled by O.E.M.')} | Select-Object -First 1
$SystemModel = Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty Model | Where-Object {$_ -notin ('System Product Name', 'To be filled by O.E.M.')} | Select-Object -First 1
$SystemManufacturer = Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty Manufacturer | Where-Object {$_ -notin ('Not Available', 'System Manufacturer', 'To be filled by O.E.M.')} | Select-Object -First 1
if ($SystemManufacturer -like '*Lenovo*') {
$Model = $ProductVersion
} else {
$Model = $BaseBoardProduct ?? $SystemModel ?? $ProductVersion
}
适用于旧版本的 PowerShell!
评论
-ExpandProperty
((!($ProductVersion.Version -ne 'System Version')) -or (!($ProductVersion.Version -ne 'To be filled by O.E.M.')) -and (-not ([string]::IsNullOrWhiteSpace($ProductVersion))))
)
下一个:理解异或和与零的比较
评论
Get-CimInstance
Get-WmiObject