Skip to content

Instantly share code, notes, and snippets.

@Jaykul
Last active January 24, 2024 05:27
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Jaykul/4b4610142cc20bb55f1616cbcf8e9574 to your computer and use it in GitHub Desktop.
Save Jaykul/4b4610142cc20bb55f1616cbcf8e9574 to your computer and use it in GitHub Desktop.
Executable PowerShell (wrap a ps1 and name it cmd)

This is always my answer to all those "compile your .ps1" solutions that are floating around. Why would you wrap your PowerShell in an exe and some custom host?

Just paste this header on the top of your PowerShell script, and then before you share it, rename it with the .cmd extension. While you're writing, it's a nice syntax-highlighted PowerShell script, and when you rename it, *poof* it's double-clickable. Drop it in the PATH and you can execute it from the Run dialog or from PowerShell, batch, whatever.

Because there are still people around who actually use CMD, I've updated it to show how to handle passing parameters.

A couple of notes:

  1. It runs with ExecutionPolicy unrestricted because if you're still using CMD you probably haven't configured your ExecutionPolicy
  2. It uses -NoProfile to make sure the environment is the same on everyone's PC...
  3. It only creates function :: {} because that allows us to ignore the :: on the first line

We could add a check for pwsh and run that instead if it's available, and I have still not written a .sh version of this...

:: <# BEGIN POWERSHELL AS BATCH HEADER
@ECHO OFF
copy %~s0 %~s0.ps1 >nul
PowerShell.exe -ExecutionPolicy Unrestricted -NoProfile -Command function :: {}; %~s0.ps1 '%1' '%2'
del %~s0.ps1 >nul
:: To avoid potentially leaving a window hanging, you could EXIT
:: This is much nicer if you're calling this from an existing cmd window
GOTO :EOF
:: END POWERSHELL AS BATCH HEADER #>
## Write whatever PowerShell script you want ...
## The dot-source plus @Args is a hack to let you use a param block even though the first line of the file is ::
. {
param($User, $Greeting)
Write-Host "$Greeting, $User! How are you?"
} @Args
:: <# BEGIN POWERSHELL AS BATCH HEADER
@ECHO OFF
copy %~s0 %~s0.ps1 >nul
PowerShell.exe -ExecutionPolicy Unrestricted -NoProfile -Command function :: {}; %~s0.ps1 '%1' '%2'
del %~s0.ps1 >nul
:: To avoid potentially leaving a window hanging, you could EXIT
:: This is much nicer if you're calling this from an existing cmd window
GOTO :EOF
:: END POWERSHELL AS BATCH HEADER #>
## Write whatever PowerShell script you want ...
## The dot-source plus @Args is a hack to let you use a param block even though the first line of the file is ::
. {
param($User, $Greeting)
Write-Host "$Greeting, $User! How are you?"
} @Args
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment