We have an issue with the If / Else structure in PowerShell. Our scripts that work on former Windows versions (up to Windows Server 2012 R2), do not work on the newer versions.
To simplify things, let's take an example from the PowerShell help (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."
}
On Windows Server 2012 R2 (PowerShell version based on $PSVersionTable.PSVersion
is 5.1.14409.1018) the result is, as expected:
The value is less than or equal to 2, is not created or is not initialized.
However, newer PowerShell Versions, like 5.1.14393.2879 (Windows Server 2016) or 5.1.17763.503 (Windows Server 2019) seem not to understand the same syntax:
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.
Note, that event these newer PowerShell versions have the very same example for If / Then, so officially nothing should have been changed.
Yes, I know I could easily re-write the condition as:
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."
}
But we have a lot of scripts, and I really would like to avoid to revisit, and fix and test all of them, if there is a way to have PowerShell to understand the other format either. Is this behavior documented officially in the PowerShell language specification, or should we consider it to be a bug?
The example we currently have in the web-based documentation, has another format, but it does not work either (same error) with the newer versions:
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.")
}
I've found a page discussing a similar issue, but it does not match exactly our case.
Very annoying. Thanks for your help in advance.
Update 1: If I save the script into a .ps1 file, and execute the file, then it seems to work. I have only the problem, if I copy / paste the code block from the editor (Notepad in my case).
Update 2:
$PSVersionTable
results:
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
By copy-pasting the condition from Notepad into the PowerShell console I have this error in the newer versions (I had no error with 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
Update 3:
As always, the devil is in the details. I've pasted the content into the console by using the right mouse button, since in WS2012R2 (and older) the standard key combination for pasting Ctrl+V
did not work, and resulted in a ^V
. So I got used to pasting the script into the console by clicking the right mouse button (and on WS2012R2 selecting Paste from the context menu). Apparently, the paste funtionality has been implemented differently, and the content is interpeted line-by-line for the right-click, but interpreted as a block when pasted using Ctrl+V
. Nice. Have learned something new again. Thank you all for your support, and for the ideas!
This is true in any version when run at the command prompt, but when run in a script it should work fine. I've confirmed this in Server 2016, with a script, even with a blank line before else, and in unicode, utf8, or ansi format.
Demo at the command prompt, pasting by clicking right mouse button. Using control v to paste works.
Ok, if I paste with control v in the ISE, it actually works without error.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With