Leaving my original answer below but I've since found a more effective way without the file copy:
# 2>NUL & @powershell -nop -ep bypass "(gc '%~f0')-join[Environment]::NewLine|iex" && @EXIT /B 0
This is to be included as your first line of the powershell script, saved as a .cmd
file.
Breakdown:
# 2>NUL &
This handles the batch part of our file so we can get that click-execution functionality. Since #
isn't a filename or command, it throws an error we ignore with 2>NUL
and skip to the next command with &
.
@powershell ...
This is our call to powershell, grabbing the contents of the file (gc
: Get-Content
) and executing them (iex
: Invoke-Expression
). We use @
so the command isn't echoed to the cli.
&& EXIT /B 0
This will exit the script gracefully if no errors were thrown.
If your only goal is to have a shortcut-clickable link for users to run your powershell script, you can accomplish that with this by pasting your script contents under this header (saved as myscript.cmd
or whatever you want to name it):
::<#
@ECHO OFF
REM https://stackoverflow.com/questions/3759456/create-a-executable-exe-file-from-powershell-script#answer-4629494
REM https://blogs.msdn.microsoft.com/zainala/2008/08/05/using-0-inside-the-batch-file-to-get-the-file-info/
SET "pwsh=%SYSTEMROOT%System32WindowsPowerShellv1.0powershell.exe"
SET "args=-NoProfile -NoLogo -ExecutionPolicy Bypass -Command"
SET "cmd="@(Get-Content -Path '%~f0') -replace '^^::'^|Set-Content -Path '%~dpn0.ps1';. '%~dpn0.ps1' %*""
%pwsh% %args% %cmd%
DEL "%~dpn0.ps1" /Q /F
EXIT
::#>
Simply put, it handles the execution policy and saves itself as a powershell script after replacing the batch-parts as a block comment.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…