Powershell-如何用字符串替换操作系统版本号

Powershell-如何用字符串替换操作系统版本号,powershell,if-statement,Powershell,If Statement,我正在查询远程服务器的操作系统。我知道我可以返回版本,但我想用友好名称替换这些值。到目前为止,我掌握的代码是: $Computer = (gc c:\servers.txt) $BuildVersion = Get-WmiObject -Class Win32_OperatingSystem -Property Version, CSName -ComputerName $Computer -ErrorAction SilentlyContinue $Build=$BuildVersion.ve

我正在查询远程服务器的操作系统。我知道我可以返回版本,但我想用友好名称替换这些值。到目前为止,我掌握的代码是:

$Computer = (gc c:\servers.txt)
$BuildVersion = Get-WmiObject -Class Win32_OperatingSystem -Property Version, CSName -ComputerName $Computer -ErrorAction SilentlyContinue
$Build=$BuildVersion.version
   If ({$BuildVersion.Version -match "5.2.3790"}) 
          {$Build="2003"}
   Elseif ({$BuildVersion.Version -match "6.1.7601"}) 
           {$Build="2008"}
   Elseif ({$BuildVersion.Version -like "6.3.9600"}) 
          {$Build="2012"} 
但这似乎不起作用,不管怎样,只返回“2003”。请帮忙,我对PS和编码相当陌生

谢谢

您可以使用:

Get-WmiObject -Class Win32_OperatingSystem | Select-Object -ExpandProperty Caption
此外,您可以看到此WMI对象包含的所有内容,如下所示:

Get-WmiObject -Class Win32_OperatingSystem | fl *
编辑:如果要从字符串中删除某些文本,可以使用
-replace

(Get-WmiObject -Class Win32_OperatingSystem |
    Select-Object -ExpandProperty Caption) -replace "Microsoft Windows Server ",""

我本来是这么说的,但后来我改变了主意

之所以只返回
2003
,是因为您只在列表中的单个条目上运行If代码

错误

正如Tessellingheckler所说,if不起作用的原因是你有太多的花括号,因此PowerShell实际上没有评估你的逻辑

然而,你仍然需要一步一步地通过每台计算机来完成你想做的事情。我们将通过添加ForEach循环来实现这一点。我还用一个
Switch
语句替换了
If{}
逻辑,我认为对于这样一个有多个子句的场景,这更容易理解。如果你说得太冗长了

最后,我假设您也想输出结果,所以我在这里添加了一个自定义对象,这只是选择要显示哪些属性的一种方法

$Computer = (gc c:\servers.txt)
ForEach ($system in $computer){
    $BuildVersion = Get-WmiObject -Class Win32_OperatingSystem -Property Version, CSName -ComputerName $system -ErrorAction SilentlyContinue 
    $Build=$BuildVersion.version

    switch ($build){
        "5.2.3790" {$Build="2003"}
        "6.1.7601" {$Build="2008"}
        "6.3.9600" {$Build="2012"}

    }

    #output results
    [pscustomobject]@{Server=$system;OSVersion=$build;CSName=$buildVersion.CSname}        
}#EndOfForEach
输出
问题在于您的
if
语句。将布尔表达式放在弯曲的括号内,使其成为脚本块,在转换为布尔表达式之前,将转换为字符串。强制转换为布尔值的字符串总是求值为true,除非它们为空

PS C:\> {$BuildVersion.Version -match "5.2.3790"}
$BuildVersion.Version -match "5.2.3790"
PS C:\> ({$BuildVersion.Version -match "5.2.3790"}) -as [bool]
True
PS C:\> $BuildVersion.Version -match "5.2.3790"
False
PS C:\> ($BuildVersion.Version -match "5.2.3790") -as [bool]
False
因此,您正在运行的基本上是:

if ([bool]'$BuildVersion.Version -match "5.2.3790"') [...]
这永远都是真的

尝试:

底线是,弯曲的括号不是括号,你不能像现在这样使用它们


然而,这里还有一个主要的逻辑错误。您可能正在为
$BuildVersion
获取一个数组,因为您正在从一个文件读取,但随后将其视为单个值。您从不循环使用
$BuildVersion
。但是,我没有足够的信息来说明您实际试图对脚本执行的操作(比如您对
$Build
所做的操作)能够解决这个问题。

{无需{将{一切}{包装在
if()
位中。@TessellatingHeckler不平衡括号:}}}内。@TessellatingHeckler:“这只返回2003的原因是您只在列表中的一个条目上运行If代码”-真的吗?我确信这是因为
If({scriptblock}){}
返回true,因为脚本块是真实的,不管它们里面的代码是什么。例如
If({$true-eq$false}{“hi”}
输出
“hi hi“
,所以第一个总是触发…?”。。。?但没人这么说,所以我觉得我错过了什么。我想你是对的!我最终删除了他的整个if结构,因为它对我来说太卷曲了。
{$false}
的计算结果是
$false
。但是,
if({$false}).
对我来说简直是疯了!杰出的谢谢,这很有效!!有一件事,我需要删除“Microsoft Windows Server”(及其后面的空格)一词,这样它就会说:“2012 R2数据中心”等。谢谢你应该阅读所有其他答案。他们解释了你为什么错了,而我的回答只允许你回避这个问题。
if ([bool]'$BuildVersion.Version -match "5.2.3790"') [...]
$Computer = (gc c:\servers.txt)
$BuildVersion = Get-WmiObject -Class Win32_OperatingSystem -Property Version, CSName -ComputerName $Computer -ErrorAction SilentlyContinue
$Build=$BuildVersion.version
If ($BuildVersion.Version -match "5.2.3790") 
{
    $Build = "2003"
}
Elseif ($BuildVersion.Version -match "6.1.7601") 
{
    $Build = "2008"
}
Elseif ($BuildVersion.Version -like "6.3.9600") 
{
    $Build = "2012"
}