PowerShell - The Wrapper!

powershell.bash is a Bash wrapper script that calls PowerShell.Exe for use in Cygwin. When used as a shebang in a PowerShell.Exe .ps1 script, Cygwin will run the PowerShell.Exe script using the interpreter specified like any other script in Linux/Cygwin. With Cygwin python, perl, ruby, and even DOS batch scripts are all executable in the shell. With this wrapper script, PowerShell.Exe .ps1 scripts are also executable using powershell.exe as the interpreter.


  1. Download the powershell.bash wrapper script.
  2. Make powershell.bash executable in Cygwin: chmod 755 powershell.bash
  3. (optional) make symlink "powershell" to point to powershell.bash.


The powershell.bash script can be used to make a PowerShell.Exe script executable in Cygwin or called directly on the Cygwin terminal's session.

Calling powershell.bash from a powershell .ps1 script as a shebang:

Add #!/path/to/powershell.bash as first line in any PowerShell.Exe .ps1 scripts you will be running from Cygwin. This will be ignored as a comment in PowerShell.Exe but Cygwin will call the specified program as the interpreter for the script.

Example test.ps1 script:

#!/path/to/powershell.bash --bypass -NoProfile
# this is a powershell script
write-Host "Hello from my PowerShell script"

This will call the powershell wrapper to call PowerShell.Exe for Cygwin. PowerShell.exe will be called with the -noprofle option and the setexecutionpolicy set to bypass. See --bypass option described later in this document.

$ ./test.ps1
Hello from my PowerShell script

Note: You may need to chmod 755 ./test.ps1 to execute this script in Cygwin's shell.

Calling powershell.bash directly and passing a command to PowerShell.Exe

You can have the powershell wrapper script pass a command to the PowerShell.Exe Windows executable.


Call powershell.bash script:

$ powershell.bash write-host "Hello Cygwin from PowerShell!"

Equivilent Windows CMD.EXE Command Prompt window call of PowerShell.Exe

In Cygwin it would be easier to have "powershell" as a symlink to "powershell.bash" and be located in your Cygwin $PATH before the PowerShell.Exe program's PATH entry. If you have done this correctly, the following will work

C> powershell -Command write-host "Hello DOS from PowerShell"

Windows PowerShell.Exe run a DOS Console Window:

C> powershell
Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.

PS C:\path> Write-Host "Hello from PowerShell"

This has called powershell.bash via the symlink "powershell" instead of powershell.exe


Wrapper Name

Calling "powershell.bash" as "powershell" by either making a symlink or renaming the wrapper to plain "powershell" without an extension requires extra attention to the order of when Cygwin's bash finds powershell (the wrapper script) vs. powershell (the windows executable) as Cygwin will run PowerShell.exe when called just "powershell"

Recommendation: 1. powershell wrapper should be found before windows PowerShell.Exe 2. PowerShell.Exe should be in bash's $PATH too, just after powershell wrapper.

The PowerShell.Exe program should already be in the windows %PATH% env variable which is inherited for the Cygwin bash PATH enviroment so make sure you do PATH=/path/to/script/folder/containing/powershell:$PATH in your .bash_profile.


If you haven't already dealt with this in powershell scripts, you can tell the powershell wrapper script to pass the ExecutionPolicy arg to the PowerShell.Exe command.

$ powershell ./test.ps1
File C:\test.ps1 cannot be loaded because the execution of scripts is disabled 
on this system. Please see "get-help about_signing" for more details.
At line:1 char:11
+ ./test.ps1 <<<< 
    + CategoryInfo          : NotSpecified: (:) [], PSSecurityException
    + FullyQualifiedErrorId : RuntimeException

when running powershell scripts, pass the -b (or --bypass=) option or alternately pass -e "policy" (--execpol=) option if you want to use a different policy than "bypass".

$ ./powershell --execpol=remotesigned ./test.ps1
Hello from PowerShell script test.ps1

This can be done in the shebang: #!/path/to/powershell.bash -b

Interactive Powershell sessions

If you call the powershell.bash wrapper from an interactive shell session without and arguments, you probably want to go interactive with the powershell prompt. *See ISSUE-1. The only solution I've found is to use Proxy32's proxywinconsole.exe program. If this program is in the path, poweshell.bash will call it to go interactive into PowerShell.exe.