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.
Related
When trying to update Powershell Core with scoop via scoop update pwsh, I get the following error:
ERROR Application "pwsh" is still running. Close all instances and try again.
I tried closing PowerShell and updating via cmd, but it still throws that error.
Scoop uses pwsh.exe to execute the PowerShell scripts that scoop runs on. (scoop is 96% PowerShell) Even if run in cmd.exe, it will still use pwsh.exe to execute the scripts needed to scoop update pwsh. This problem is solved by using Windows PowerShell, (a.k.a. PowerShell 5 / powershell.exe) so scoop will execute the PowerShell scripts using that instead of pwsh.
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).
I am using PowerShell and PowerShell Core in parallel.
Not all my scripts which I have wrote for the "big" PowerShell are working in PowerShell Core and vice versa.
To avoid chaos, I was thinking if I should use two file-extensions:
.ps1: PowerShell
.pwsh: PowerShell Core
In Windows the extension is more important then in Unix systems where the shebang (#!/bin/mytool) would help to solve the problem.
Is the usage of two extension "best practice" or there are better options?
Additional: I am not sure if a .pwsh script will be executed by PowerShell when I call a script from command line / terminal.
I found a similar question in Unix / Linux context.
https://unix.stackexchange.com/questions/182882/use-sh-or-bash-extension-for-bash-scripts
Add a line
#requires -PSEdition Core
at the beginning of your scripts for PowerShell Core, and a line
#requires -PSEdition Desktop
at the beginning of your scripts for regular PowerShell.
For scripts that run in both editions just omit the line.
From the documentation:
-PSEdition <PSEdition-Name>
Specifies a PowerShell edition that the script requires. Valid values are Core for PowerShell Core and Desktop for Windows PowerShell.
Do not use different extensions, as that will impact functionality. For instance, PowerShell will not dot-source scripts with an extension other than .ps1.
I have created a package in SCCM 2012 that should deploy and run a powershell script. I have looked at a previous post on here Other Post but there wasn't any information.
In the Program Command Line, I have the following command:
powershell.exe -ExecutionPolicy Bypass -force -WindowStyle Hidden .\PowershellUpdateScript.ps1
I am targeting a test group and setting it to deploy immediately however when I check the deployment status, it shows as status "In Progress" and Description "Received". It has been that way for over 2 hours. I am not sure where the issue is.
I know that the Scripts feature is there and super convenient but the client powershell version needs to be a minimum version 3. The irony is that this package will update client powershell versions.
Any suggestions or advise would be greatly appreciated.
Since you are updating the powershell version, instead of using a powershell script you should download the MS update package for the version of powershell.
You can then use the wusa.exe command to deploy the update. Then use this ps command as a detection method
Get-WmiObject Win32_QuickFixEngineering -filter "HotFixID='KB#######'"
I understand that the new PowerShell 6/core lacks support for Windows GUI libraries, I have developed some important projects in PS-5.1 using the Windows.Forms .NET classes.
Problem:
We are planning to upgrade to PowerShell 6 this summer, which means I will lose all the GUI functionalities (developed using Windows.Forms).
Question:
What should we do in this situation in order to retain the GUI functionality in our PS apps. Do you envisage Microsoft will provide any alternatives for GUI support going forward?
TIA
thanks to all who added informative comments.
After a bit of research I discovered that the XAML UI is going to be available in the .NET Core, its support has been added the Universal Windows Platform and Xamarin applications, hence it will be available in PowerShell core/6 for GUI solution development.
Development in XAML appears to be very straight forwards, in fact, in some aspects - easier and quicker than other APIs (especially if you have to hand code the UI components).
One question I have is what you mean by "Upgrading" to PowerShell 6? On Windows there is no upgrade. You will run PowerShell 6 side-by-side with your existing version of PowerShell. So, if you want to keep running your old scripts that use GUI stuff, keep doing so in PowerShell 3, 4 or 5.1. If you want to start using PowerShell 6 in order to write scripts that will function on all platforms, then use PowerShell 6 for that. The good news is, you will continue to have both. (for now at least)
It's a russian method, but you can use for the non-PowerShell Core compatible part the default PowerShell "powershell.exe" instead of PowerShell Core "pwsh.exe" in your PowerShell Core script:
Test.ps1:
<# Here you start your script code with your called PowerShell/PowerShell Core: #>
$PSVersionTable
chcp.com 65001;
<# Pause the PowerShell Core code execution and run here a temporary default PowerShell session
(Non-PowerShell Core) for the Non-PowerShell Core compatible code part: #>
powershell -NoProfile -ExecutionPolicy Bypass -Command {
$PSVersionTable
chcp.com 65001;
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing");
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms");
$objForm = New-Object System.Windows.Forms.Form;
[void] $objForm.ShowDialog();
<# Exit the temporary default Non-PowerShell Core session: #>
exit
}
<# And continue here the PowerShell Core script code #>
$PSVersionTable
This works fine for me with Visual Studio Code and also CLI-only execution with System PowerShell (currently: v5.1) and with the PowerShell Core (currently: v6.1.2).
It's not the best solution and Windows only, but a workaround for Windows systems with installed PowerShells.