PowerShell中的If / Else结构存在问题。我们的脚本可在以前的Windows版本(最高Windows Server 2012 R2)上运行,而不能在较新的版本上运行。
为简化起见,让我们以PowerShell帮助(Get-Help about_If
)为例:
if ($a -gt 2)
{
Write-Host "The value $a is greater than 2."
}
else
{
Write-Host "The value $a is less than or equal to 2, is not created or is not initialized."
}
在Windows Server 2012 R2(基于$PSVersionTable.PSVersion
的PowerShell版本为5.1.14409.1018)上,结果如预期的那样:
The value is less than or equal to 2, is not created or is not initialized.
但是,较新的PowerShell版本,例如5.1.14393.2879(Windows Server 2016)或5.1.17763.503(Windows Server 2019)似乎不理解相同的语法:
else : The term 'else' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
请注意,如果这些较新的PowerShell版本具有与If / Then完全相同的示例,那么在正式情况下应该没有任何更改。
是的,我知道我可以轻松地将条件重写为:
if ($a -gt 2) {
Write-Host "The value $a is greater than 2."
} else {
Write-Host "The value $a is less than or equal to 2, is not created or is not initialized."
}
但是我们有很多脚本,如果有办法让PowerShell可以理解其他格式,我真的很想避免重新访问,修复和测试所有脚本。此行为是在PowerShell语言规范中正式记录的,还是我们应该将其视为错误?
我们目前在web-based documentation中使用的示例具有另一种格式,但在较新的版本中也不起作用(相同的错误):
if ($a -gt 2) {
Write-Host "The value $a is greater than 2."
}
else {
Write-Host ("The value $a is less than or equal to 2," + " is not created or is not initialized.")
}
我发现page正在讨论类似的问题,但与我们的情况不完全相同。
非常烦人。感谢您的提前帮助。
更新1 :如果我将脚本保存到.ps1文件中并执行该文件,那么它似乎可以工作。我只有一个问题,如果我从编辑器中复制/粘贴代码块(本例中为记事本)。
更新2 :
$PSVersionTable
个结果:
Name Value
---- -----
PSVersion 5.1.17763.503
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.17763.503
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
通过将条件从记事本复制粘贴到PowerShell控制台中,在较新的版本中出现此错误(Windows Server 2012 R2没有错误):
if ($a -gt 2)
>> {
>> Write-Host "The value $a is greater than 2."
>> }
PS C:\Scripts> else
else : The term 'else' is not recognized as the name of a cmdlet, function, script file, or operable program. Check
the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ else
+ ~~~~
+ CategoryInfo : ObjectNotFound: (else:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
更新3 :
与往常一样,细节决定成败。我已使用鼠标右键将内容粘贴到控制台中,因为在WS2012R2(及更低版本)中,用于粘贴Ctrl+V
的标准组合键不起作用,并导致了^V
。因此,我习惯于通过单击鼠标右键(在WS2012R2上从上下文菜单中选择“粘贴”)将脚本粘贴到控制台中。显然,粘贴功能的实现方式有所不同,右键单击将内容逐行插入,但是使用Ctrl+V
粘贴时,将其解释为块。真好又学到了新东西。谢谢大家的支持和想法!
答案 0 :(得分:1)
在命令提示符下运行时,在任何版本中都是如此,但是在脚本中运行时应该可以正常工作。我已经在Server 2016中用脚本(甚至在其他行之前用空行)和unicode,utf8或ansi格式对此进行了确认。
在命令提示符处演示,通过单击鼠标右键进行粘贴。
好吧,如果我在ISE中粘贴控件v,它实际上可以正常工作。
PS C:\Users\js> if (0) { 'ran if' }
PS C:\Users\js> else { 'ran else' }
else : The term 'else' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify
that the path is correct and try again.
At line:1 char:1
+ else { 'else' }
+ ~~~~
+ CategoryInfo : ObjectNotFound: (else:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
答案 1 :(得分:0)
我将测试结果发布为答案,因为评论部分没有足够的空间(希望对社区来说还可以)。
在Windows Server 2019上的PowerShell控制台中进行了测试(版本1809 OS Build 17763.107)。
> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.17763.1
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.17763.1
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
PowerShell提示符上的一个例子:
> if ($a -gt 2)
>> {
>> Write-Host "The value $a is greater than 2."
>> }
>> else
>> {
>> Write-Host "The value $a is less than or equal to 2, is not created or is not initialized."
>> }
The value is less than or equal to 2, is not created or is not initialized.
代码有效。
更新1
也在Windows Server 2016(版本1607,操作系统内部版本14393.2969)中进行了测试:
PS C:\> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.14393.2969
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.14393.2969
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
PowerShell提示符上的一个例子:
PS C:\> if ($a -gt 2)
>> {
>> Write-Host "The value $a is greater than 2."
>> }
>> else
>> {
>> Write-Host "The value $a is less than or equal to 2, is not created or is not initialized."
>> }
The value is less than or equal to 2, is not created or is not initialized.
更新2
问题出在如何将代码粘贴到PowerShell控制台中。如果使用Ctr+V
(在标准PowerShell主机的较新版本中添加),则代码将粘贴为整个块:
PS C:\> if ($a -gt 2)
>> {
>> Write-Host "The value $a is greater than 2."
>> }
>> else
>> {
>> Write-Host "The value $a is less than or equal to 2, is not created or is not initialized."
>> }
但是如果您是通过right click - edit - paste
将代码粘贴到PowerShell控制台,则似乎在操作中粘贴了if块和else块。是在CRLF
块之后“ if
”注入的。因此,if
得到了计算,然后*之后* else
块被粘贴到控制台,这当然会触发错误:
PS C:\> if ($a -gt 2)
>> {
>> Write-Host "The value $a is greater than 2."
>> }
PS C:\> else
else : The term 'else' is not recognized as the name of a cmdlet, function, script file, or operable program. Check
the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ else
+ ~~~~
+ CategoryInfo : ObjectNotFound: (else:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
PS C:\> {
>> Write-Host "The value $a is less than or equal to 2, is not created or is not initialized."
>> }
由于在PS C:\>
以及else
范围内都有新的提示else
,因此也可以看到问题。
此问题与“标准” PowerShell控制台主机有关(与PowerShell引擎无关)。如果您在PowerShell ISE中执行复制操作(通过鼠标或快捷方式),则不会发生此问题。
希望有帮助。
答案 2 :(得分:-2)
我发现Ctrl + V可以正常工作& 鼠标右键单击地址栏>编辑>粘贴不