3

I’ve come across something with PS and I don’t know if I’m doing something wrong or maybe it is just a bug in PS (and I can’t find the answer anywhere)? I’ve tested this with PS v4, v5.0 and v5.1 using different Windows OS’s. First, it seems that no matter what the OS is and no matter what the PS version is, when I run the following code snippet below either directly via a PS window or via a PS script, I receive no errors and everything appears to be OK:

$error.clear()
If ($error -ne $null) { $error }

However, on specific types of systems (seeming to be an OS-based issue), I run the following code and sometimes I receive an error:

$error.clear()
If ($error -ne $null)
{
$error
}

I can run the above error-generating code on Windows 10 and Windows 2016 servers and everything is OK (no errors are reported). If I run the exact same code on Windows 2008 R2 or Windows 2012 R2, I receive the following error message:

Missing statement block after If ( condition ).

It doesn’t seem to matter whether I have PS 4, 5 or 5.1.1 installed on the Windows 2008 R2 and Windows 2012 R2 systems, I still get the error. And it doesn’t seem to matter whether I am running as Admin or not, same results. And it doesn't seem to make a difference whether they are domain-joined or workgroup systems. All of our systems are patched as of the May 2017 patch Tuesday updates.

Is it a PS requirement (on Windows 2008 R2 and Windows 2012 R2 systems) that the opening curly bracket of a PS “IF” statement must be on the same line as the IF statement itself? It doesn’t seem to be that way for Windows 10 and Windows 2016 server.

Thanks in advance,

UCG

SOSidb
  • 533
  • 4
  • 13
  • 27
  • What happens if your starting curly bracket is on the same line as your if condition, rather than on the next line? I know PowerShell, in theory, doesn't care about placement around curly brackets, but for completeness to rule out anything like strange new line characters etc. Are you using Notepad, PowerShell IDE or another editor? – Kinnectus Jun 14 '17 at 14:50
  • this depends entirely on the parser in use. I would expect the powershell parser to be internal, but since it will work with a dozen differant script dialects, perhaps that is not entirely correct. Either way, I recommend using RKR formatting, and put the opening curly on the line with the control statement. I've never liked wasting an entire line with an opening curly. – Frank Thomas Jun 14 '17 at 15:38
  • @Kinnectus - When the starting curly bracket is on the same line, we receive no errors (but that only applies to Windows 2008 R2 and Windows 2012 R2). Windows 10 and Windows 2016 don’t seem to mind if the bracket in on a new line or not. – SOSidb Jun 14 '17 at 16:57
  • @Frank Thomas – Running it directly from a PS window (the one built into the Windows OS) produces the error. I deployed a clean server OS in a workgroup (directly from MS ISO media), got the same results on the new 2012 R2 server (nothing “extra” was installed on it and the OS was not patched). It definitely seems to be OS related though. – SOSidb Jun 14 '17 at 16:57
  • A lot of our (existing) scripts are formatted that way (with the opening IF statement curly bracket on a new line) for readability. The other day, I wanted to add in some error trapping to an existing script and when testing, I noticed that this error was being reported (and trapped), so the script was exiting out. I assume this has been occurring for a while now and we never knew that it was until I tried to add in some error trapping stuff. Thank you both for your replies. – SOSidb Jun 14 '17 at 16:57
  • What happens when you run from the ISE? From the ISE, this completed without error on Win 10 x64 v5.1, Win 7 x86 v2.0, and Win 2008 r2 x86 v2.0. If typed directly into Powershell, I get the "Missing statement" error on the Win7 machine, but not on the Win10 machine. – root Jun 14 '17 at 18:13
  • @root - Yes, same results. No errors on Windows 10 or 2016 yet I get the error on 2008 R2 and 2012 R2 in ISE – SOSidb Jun 15 '17 at 23:04
  • Can you confirm what language these server with the affected problem or configured and setup for. Have you tested with [TRY... CATCH](https://ss64.com/ps/try.html) logic to see if it works any differently with the error checking logic you are trying to incorporate? There is also [Trap](https://ss64.com/ps/trap.html) so I just wanted to point that out. – Vomit IT - Chunky Mess Style Jun 16 '17 at 02:08
  • @McDonald's - Good idea, thanks. I tested the Try/Catch and got an error with it as well (the error seemed to follow the same pattern as the other error, not Win10/2016 but 2008R2/2012R2). The only difference is that with Try/Catch, the error message is different. The error I get is "The Try statement is missing its statement block". They are all set up for English language. – SOSidb Jun 19 '17 at 16:37
  • Might be best to make the 2008 R2/2012 R2 code compatible so making the change to all applicable scripts. Perhaps you could get the code and scripts setup to run from a 2016 server and remotely execute against the 2008 and 2012 servers and see if the same behavior exists or if it happens at this level as well with the curly bracket. I know the pain of maintaining scripts across multiple platforms and not everything being standard across the board for all environments you automate scripting and so forth, so I know the feeling too – Vomit IT - Chunky Mess Style Jun 19 '17 at 16:44
  • What's up with this? Have you had any new findings, etc.? Have you figured out another solution such as updating the scripts? This may be worth a 50 point bounty to gain more attention if you absolutely need it. – Vomit IT - Chunky Mess Style Jul 02 '17 at 04:26

3 Answers3

0

When PowerShell is fed a line (or block) of code - it evaluates that block (or line) as a whole

In this case, your first line is: If ($error -ne $null)

PowerShell knows how to interperate the line, but its invalid syntax because PowerShell doesn't have a "what to do" block in the event that the criteria is met.

enter image description here

If you feed PowerShell the block as a whole - it recognises the "what to do block" and knows where it needs to go next:

enter image description here

Are you able to elabourate more on which systems and platforms you are finding that accept the single lines? I have just tested this on Win10 (PowerShell 5), 2012R2 (Powershell 4 and 5), Windows 7 (PowerShell 4 and 5) and they all behave exactly the same.

Fazer87
  • 12,520
  • 1
  • 36
  • 48
0

I had this same problem when my statement block included a here-string

If ($error -ne $null)
{
 $query = @" 
 do some sql;
 do more sql; 
 "@
}

When I changed it to one line without the here-string it worked

If ($error -ne $null)
{
 $query = "do some sql;do more sql;"
}

You may have something in your statement block that powershell doesn't allow as multiline too.

tgrignon
  • 1
  • 2
  • Your first example throws an error because your ending "@ does not start at the beginning of the line. There is a space in front of it. Therefore the whole code after @", including the closing curly bracket four lines later, is considered to be part of that string. – Joachim Otahal Aug 05 '23 at 13:15
0

Powershell has two ways to parse commands, Expression mode and Argument mode. (see https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_parsing?view=powershell-7.1)

Without having the different operating systems to test on, my best guess is that these commands changed from Expression mode to Argument mode (or vice versa depending on which way you go) between your OS'es.

The simplest work around (best practice) is to always leave the opening curly bracket on the top line. This allows the command/script to work regardless of which mode the parser is using.

You could also force the line to continue by adding a backtick ` to the end of the line. These are hard to see though and may introduce other issues, so your mileage may vary.

DBADon
  • 473
  • 4
  • 11