Is it possible to have a single PowerShell script that has functions and statements within functions that contain commands specific to both PowerShell versions 2.0 and 5.1?
The reason for this need is that I have a script that needs to be executed on windows 2008 R2 and Windows 2016 operating systems.
I am willing to write version specific code if need be. For ex:-
if(version -eq “5.1”)
#5.1 specific commands or statements
else if(version -eq “2.0”)
#2.0 specific commands or statements
Please let me know how do I achieve this?
If this is not possible let me know if the below scenario is a possibility where I have two helper scripts namely
Execute.PS1 (which is the main PowerShell script) then loads either the 1st file or 2nd file based on PowerShell version installed using the dot sourcing method.
Sure. You would use $PSVersionTable, and if that did not exist then you’re on v1.
But it’s not working. Below is the code snippet I have used on a PowerShell 2.0 environment.
Below is the code snippet. “-in” operator is not present in PS2.0 whereas as valid in the PS5.1 environment. Since I want to use statements from both versions, I used -contains operator for 2.0 environment and -in operator for 5.1 environments as shown below.
Well, in this particular instance, there’s no functional difference between -in and -contains. Just flip the operands and use -contains no matter what version. There’s little sense in making the script harder to read just over that. But I understand that you’re just giving an example.
So, the broader question is, “why doesn’t it work.” Standard debugging would be to confirm what $psver actually contains on both systems. For example, on my system, $PSVersionTable.PSVersion.Major is an integer, not a string. $PSVersionTable definitely works; so if your script isn’t behaving as desired, toss in a breakpoint on line 2, and then step through the remaining lines one at a time. Confirm what the variables actually contain at runtime on each system.
BTW, you can also easily add:
Write-Host "PSVer is $psver"
To quickly confirm just that one variable.
Well, we’ve established that we’re just producing a test-case script, not a production artifact. And Write-Output does have the unfortunate effect of producing output, which isn’t quite the same. Write-Host under v5 is just Write-Information (more or less), which has a capturable, loggable function, which is all to the good ;).
As you said, the reason for using -in, -contains is just to show an example of different commands from both versions. My final goal is to use much more complex PS5.1 APIs/commands and mix them along with PS2.0 commands.
You were also right that $PSVersionTable.PSVersion.Major is Int32 type. even if I change the code to take it into consideration, the code still fails. See the corrected code below
I think the larger issue here is that PS is working like a compiler rather than as an interpreter. During execution, the PS2.0 engine is probably trying to look at all the code and flag any code that it does not understand (for ex:- -in operator) and hence stopping the execution itself.
What I was expecting is that it would not just blindly look at all the code and instead only interpret the code line by line. If this was the case, it would have executed Lines 1,2,4,5,6. Since Line#6 “if($psver -eq 2)” evaluates to TRUE on a PS2.0 environment and it would go ahead and execute lines 8,9 and print the result as TRUE for the line#9 “$myarr -contains $mystr”
Similarly, the same code when executed on the PS5.1 environment would execute lines 1,2,4,5,6. Since Line#6 “if($psver -eq 2)” evaluates to FALSE on a PS5.0, it would execute Line#11 “elseif($psver -eq 5)” which would evaluate to TRUE and thus execute lines 13,14 and print the result as TRUE for the line#14 “$mystr -in $myarr” because -in operator is recognized by PS5.0
However, instead of working the way I expected, it is working like a compiler and flagging an error for the -in operator on PS2.0 environment. Note that if I comment out the line#14 that has the -in operator and execute the code it nicely executes the script and prints the output as TRUE after executing line#9