Personally, I favour calling a .bat
script and passing the .ps1
filename to execute as an argument. Obviously this will only work in Windows, so YMMV.
Inside the batch script, you can perform checks on whether PowerShell Core exists before falling back to 'native' PowerShell. You can also put your -NoProfile -ExecutionPolicy
code in the batch script as well so it's a bit cleaner in the package.json
file.
Package.json:
"scripts": {
"test": "build-scripts\RunBuildScript.bat test"
}
RunBuildScript.bat:
@ECHO OFF
REM Check the argument passed in. You could also check if the file actually exists.
SET "NpmBuildScriptName=%1"
IF ["%NpmBuildScriptName%"] == [""] (
ECHO "Could not find the name of the script."
GOTO :TidyUp
)
REM Perform some checks for PowerShell Core in the file system.
FOR %%s IN ("PowerShell\pwsh.exe" "\PowerShellCore\pwsh.exe") DO (
IF EXIST %%s (
ECHO "PowerShell found at %%s"
SET "PowerShellPath=%%s"
GOTO :ExecuteScript
)
)
REM If you can't find PowerShell, use the default.
IF ["%PowerShellPath%"] == [""] (
ECHO "PowerShell Core was not found. Defaulting to native PowerShell"
SET "PowerShellPath=powershell"
GOTO :ExecuteScript
)
:ExecuteScript
%PowerShellPath% -NoProfile -ExecutionPolicy Unrestricted -Command "%NpmBuildScriptName%.ps1"
GOTO :TidyUp
:TidyUp
REM Wipe after using.
SET "NpmBuildScriptName="
ECHO 0
test.ps1
Write-Host "this is only a test"
Obviously a lot of hoops to jump through just to output some text, but this approach makes it a bit more extensible.