.Bat file unable to run powershell 7 - powershell

I have set up a very simple .bat file to execute a couple of commands to save me typing them out every time, however the processes need to be run in powershell 7.
If i manually run powershell 7.0.3 and then run the commands everything work, however running the .bat script starting
powershell -Version 7.0.3 -Command {XXXXX};
presents me with a message "Cannot start Windows PowerShell version 7.0.3 because it is not installed."
If i try and run it without the version number then it runs in 5.1.x and this then fails as it requires 6+.

tl;dr
As Lee_Dailey notes, you must use pwsh.exe, not powershell.exe, to start a version of PowerShell [Core] v6+ and you must invoke the desired version's specific executable.
In the simplest case:
pwsh -Command "XXXXX"
Note that I've replaced {XXXXX} with "XXXXX", because you cannot directly execute script blocks ({...}) from outside PowerShell - just supply the commands as a string.
Given that - unlike with Windows PowerShell - you can install multiple PowerShell [Core] versions side by side:
Run pwsh -version (sic; see below) to report the version in your system's path (the instance that comes first among the directories listed in the PATH environment variable, $env:PATH).
If it is not the one you want to target, you'll have to invoke it via its full path:
If you want to rely on the standard installation location, you can use the following on Windows for version 7.0: "C:\Program Files\PowerShell\7\pwsh.exe"
To determine the target version's executable location reliably, open an interactive console for it and run (Get-Process -Id $PID).Path
The -Version parameter of powershell.exe, the Windows PowerShell CLI, does not allow you to start just any PowerShell version, only an older version of Windows PowerShell:
In fact, the only supported argument is -Version 2, and even that will only succeed if you have previously installed the required legacy versions of .NET Framework.
Caveat: While versions higher than v5.1 - the latest and last Windows PowerShell version - sensibly result in an error (the one you saw), unsupported lower versions are quietly ignored; in effect, -Version 1 and -Version 2 will both start version 2.0, whereas -Version 3, -Version 4 and -Version 5 are effectively ignored and run v5.1 - verify with $PSVersionTable.PSVersion
While a -Version parameter still exists in pwsh.exe, the PowerShell [Core] v6+ CLI, its meaning has changed:
It now simply reports a version number, namely the targeted executable's own (and therefore takes no argument).

Related

Why does ansible win_shell module use powershell 5 when powershell 7 is set as the default?

I'm running a packer build of windows using ansible to provision the VM.
I connect to the VM via OpenSHH. I have powershell 7 set as the default shell for OpenSSH. When I connect to the VM over ssh on the command line, the banner says PowerShell 7.1.3.
I run the following code via ansible-playbook:
- name: Check powershell version
ansible.windows.win_shell: |
Get-Host | Select-Object Version
- name: Check powershell version
ansible.windows.win_shell: |
Get-Host | Select-Object Version
args:
executable: pwsh
The first task returns 5.1.19041.1023
The second task returns 7.1.3
So when I don't specify the executable, win_shell is running powershell.exe, aka powershell 5.
When I do specify the executable as pwsh, aka powershell 7, it behaves correctly.
I can't figure out why the win_shell module is ignoring the default set in the registry. Does anyone know what I have done wrong?

Azure Batch Needs to be Updated to PowerShell Version 7+

I am running a Custom Activity in Azure Data Factory. We are using the Test-Json command to validate JSON data against a schema. This command works perfectly find in PowerShell version 7+ but will fail in version 5.1.
For testing purposes, if I run the below command (directly from the Microsoft documentation) it fails when using the Custom Activity in Data Factory.
"{'name': 'Ashley', 'age': 25}" | Test-Json
If I run the below command, it show that we are using PowerShell version 5.1.
$PSVersionTable
Is there anyway to upgrade to version 7.1 so these batch file will process successfully?
Two potential options:
Modify your task to use ConvertFrom-Json with a try-catch block instead of Test-Json, as described here.
As you've already pointed out, Test-Json comes with PowerShell 7.1 (part of PowerShell Core), but it doesn't come with PowerShell 5.1 (part of Windows PowerShell), which many Windows images have installed by default. ConvertFrom-Json, however, does come with PowerShell 5.1 and can provide the same functionality as Test-Json with a few tweaks.
Install PowerShell Core 7.1 as a start task, and then invoke your command as normal.
The start task syntax to complete this installation would be cmd /c "powershell.exe -c "iex ""&" { $(irm https://aka.ms/install-powershell.ps1) } -UseMSI -Quiet""", based off the one-liner described here and modified to fit the Batch syntax described here. This will install the latest version of PowerShell Core, which will have Test-Json included. When creating tasks, be sure to invoke PowerShell Core using pwsh.exe, and not powershell.exe, which is for Windows PowerShell.

How to force a Powershell Script to run a specific Version

I have both Powershell 5.1 and Powershell 7.0 on my computer and I'm try to run a script that has to be run in Powershell 7.0. How do I make the script run in a specific version.
If it's a script being invoked in a PS shell, you could relaunch it if it's not the correct version.
# At beginning of .ps1
if ($PSVersionTable.PSVersion -ne [Version]"5.1") {
# Re-launch as version 5 if we're not already
powershell -Version 5.1 -File $MyInvocation.MyCommand.Definition
exit
}
# Your script code
If the scripts are launched via Task Scheduler, you could just use the full path to the .exe in the "Actions -> Start a program" section, as they have separate install locations.
another option is to use #Requires statement
#Requires -Version 7.0
here is the reference from Microsoft support
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_requires

PowerShell Version check prior to script execution

I'm just asking the communitty if they have come across a way to have the a script check what version of POSH is running prior to the execution of the script. Currently, my work around is the following code:
#region Final Checks
#//Check to make sure that version of PowerShell is at least 3.0 before preceding.
If($PSVersionTable.PSVersion.Major -le 2) {
Throw "This script has not been tested with version 2.0 or older of PowerShell. Please execute this script from a system that has PowerShell 3.0 or newer installed. Windows 8/Server 2012 and newer has it installed by default. Windows 7/Server 2008 R2 can be patched to have 3.0 installed."
}
#endregion Final Checks
I have this right after defining my parameters. However, for my own crazy sake, I want the script to preform this check automatically prior to getting into the meat and potato of the script. A good comparison is using Validate[X] for a parameter. If an operator tries to provide data that doesn't fit my user, an error is thrown prior to the execution of the script. Any ideas? I know that there is nothing in [CmdletBinding()] that does it. Thanks!
You can use #Requires at the top of your script as a way of telling PowerShell what your script needs to do it's thing.
In your specific case you would put
#Requires -Version 3
This will tell PowerShell that at least PowerShell Version 3 is needed, if someone tries to run the script with PowerShell Version 2 they will receive the following message:
The script 'version3.ps1' cannot be run because it contained a "#requires" statement at line 1 for Windows PowerShell version 3.0. The version required by the script does not match the currently running version of Windows PowerShell version 2
.0.
At line:1 char:2
+ & <<<< C:\Users\testuser\Desktop\version3.ps1
+ CategoryInfo : ResourceUnavailable: (version3.ps1:String) [], ScriptRequiresException
+ FullyQualifiedErrorId : ScriptRequiresUnmatchedPSVersion
In addition to Version you can require other things as well, all of which are listed in about_Requires on TechNet: https://technet.microsoft.com/en-us/library/hh847765.aspx
#Requires -Version 4
#Requires -Module MyCmdlets
Write-Host "If you see this, you are running Version 4 and have the MyCmdlets Module available"
#Requires was added in PowerShell 5 Will not work in earlier versions.

How to determine which version of PowerShell is installed on a PC

I am writing a script which check the version of PowerShell. If it's version 4 then proceed, otherwise stop the execution. What I am trying to achieve here is I have five scripts in a folder which are run in order. I would like to put a PowerShell script right at the top which checks the version.
Here is my code:
$psversion= $psversiontable
if($psversion -eq 4.0)
{
./01. Run All Script.ps1
}
"Run All Script" runs the rest of the scripts in order, so I would like to give PowerShell script as 02. check_psversion.ps1
requires -version 4
write-host "this is your version"
You don't need to write any if tests; use the requires directive in all of your scripts (never assume or depend upon execution order, be explicit in each script).
#requires -version 4
If you attempt to execute the script on version 3 or earlier, it will stop because of the requires directive.
Edit: To get the Powershell version number, use $psversiontable.psversion.major, unless you need finer resolution (exact build number).