How to force a Powershell Script to run a specific Version - powershell

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

Related

Scheduling powershell script to run on server - finding powershell.exe

I'm trying to schedule a powershell script to run on a server. I used $env:PSModulePath and one of the powershell locations is c:\windows\system32\windowsPowerShell\v1.0\Modules. When I look in that location, there is no Powershell.exe there. I wanted to use that for the Application name in the system scheduler. How can I verify that Powershell.exe is there? I also wanted to find which version each one is for all of the powershell versions seen with $env command above to verify which would be the 5.1 version that I tested on my computer with.
env:PSModulePath
c:\windows\system32\windowsPowerShell\v1.0\Modules is the Modules directory
$psHome returns the .exe location

How to choose which Powershell version Jenkins should use?

I am using this Powershell plugin for my Jenkins build server. As you can see, one of the recent updates allows for selection of a Powershell version:
The version I have running on my server is 1.7. The problem arises when I try to actually change the version of Powershell, since the example given uses a scripted pipeline, whereas my project uses a declarative one, so the built-in option for version selection is missing. How can I force Jenkins to use Powershell 7.2 instead of the default 5.*?
The only solution I can think of is using Powershell 5 to start Powershell 7 and to then run my .ps1 script like that, but that seems stupid.
In both declarative and scripted pipeline you can use the pwsh step to run a script in PS 7.x.
Declarative:
pipeline {
agent any
stages {
stage('Test') {
steps {
pwsh '''
Write-Host "foo"
'''
}
}
}
}
Scripted:
node {
pwsh '''
Write-Host "foo"
'''
}
You can make it conditional. This script re-launches itself with version 7.2 only if the version is greater than 5.0.
if ($PSVersionTable.PSVersion -gt [Version]"5.0") {
powershell -Version 7.2 -File $MyInvocation.MyCommand.Definition
exit
}
'run some code'
Read-Host -Prompt "Scripts Completed : Press any key to exit"
This worked for me:
install the latest powershell-plugin for Jenkins
find the file ".\Jenkins\hudson.plugins.powershell.PowerShellInstallation.xml"
replace "powershell.exe" by "pwsh.exe" (see example below) -- providing a full path may also work
restart Jenkins
<hudson.plugins.powershell.PowerShellInstallation>
<name>DefaultWindows</name>
<home>powershell.exe</home>
<properties/>

.Bat file unable to run powershell 7

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).

Powershell not finding PNPUTIL when script launched from shortcut

I have a Powershell script to install TCP/IP printers on Windows 10 that uses PNPUTIL to load drivers. When the script is run from a Powershell window, everything works great.
When I launch the script from a shortcut using the format
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -file MyScript.PS1
I get an error 'The term 'pnputil.exe' is not recognized as the name of a cmdlet, function, script file, or operable program' when PNPUTIL is called. The rest of the script runs fine.
Relevant code:
Write-Host `n 'Installing printer driver..'
pnputil.exe /add-driver "\\myServer\HP UPD PCL 5\hpcu180t.inf"
Any ideas as to why this won't work when launched from a shortcut?
EDIT:I tried using
& pnputil.exe /add-driver "\\myServer\HP UPD PCL 5\hpcu180t.inf"
as referenced in
Running CMD command in PowerShell
but I still get the error. I also tried
start-process pnputil.exe /add-driver "\\myServer\HP UPD PCL 5\hpcu180t.inf"
but got a similar error that pnputil.exe could not be found.
Both of these options work from a Powershell prompt, but again, fail when launched from a shortcut.
Thank you in advance.
You're invoking a 32-bit instance of PowerShell on a 64-bit system, and that instance doesn't see pnputil.exe (by filename only).
Instead of:
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -file MyScript.PS1
use:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -file MyScript.PS1
Folder C:\Windows\SysWOW64 is where the 32-bit executables live.
Paradoxically, for historical reasons, it is C:\Windows\System32 that houses the 64-bit executables.
If, for some reason, you do need to run a 32-bit instance of PowerShell, you can invoke pnputil.exe by its full path:
It only exists as a 64-bit executable in the 64-bit system folder, which 32-bit processes can access as C:\Windows\SysNative:
C:\Windows\SysNative\pnputil.exe

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).