Library / SDK
MScholtes/PS2EXE avatar
MScholtes/PS2EXE

PS2EXE for Compiling PowerShell Scripts on Windows

Module to compile powershell scripts to executables

1,795 stars248 forksPowerShellNOASSERTION

At a glance

What is it?
PS2EXE converts compatible PowerShell 5.1 scripts into Windows .NET Framework executables, with optional console, GUI, metadata, elevation, and embedded-file support. It suits Windows script distribution but is not a modern PowerShell 7 or cross-platform publishing tool.
Who is it for?
Adopt PS2EXE when the target is Windows, the source is PowerShell 5.1 compatible, and executable delivery is more useful than shipping the script directly. Do not adopt it for cross-platform .NET Core publishing or scripts that require unsupported cmdlets.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 139 days ago.
What is it written in?
Mainly PowerShell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

PS2EXE Packaging for Windows Script Distribution

PS2EXE addresses executable packaging rather than adding new scripting capabilities. It converts a compatible PowerShell script into a Windows executable, allowing the result to be distributed as `target.exe` instead of as a `.ps1` file that users must run through PowerShell. The repository offers a PowerShell module and an optional graphical front end called Win-PS2EXE.

The intended environment is Windows. Although PS2EXE can be invoked from PowerShell Core, the README says it uses the .NET Framework compiler because .NET Core does not include that compiler. This creates an explicit compatibility boundary. The input must be compatible with PowerShell 5.1, while the generated executable is a .NET 4.x binary. PowerShell Core can therefore act as the command environment, but it does not change the language compatibility or binary format of the output.

This boundary matters when selecting a packaging strategy. PS2EXE is appropriate when a Windows executable is required, when a script should have Windows file metadata, or when GUI execution is desired without a normal console window. It is not a general converter for every script supported by a current PowerShell edition. A project that must target Linux, macOS, PowerShell 7, or a current cross-platform .NET runtime needs a different publishing approach.

PS2EXE also preserves characteristics of script distribution inside an executable wrapper. Users still receive the behavior of the original script, subject to PS2EXE compatibility changes. An `.exe` extension can simplify delivery, but it does not establish that the application is portable across operating systems, PowerShell editions, processor architectures, or Windows security policies.

PS2EXE Compilation and Generated Executable Parameters

The central compilation operation accepts an input PowerShell file and produces an executable. According to the parameter reference, the source file must be UTF8 or UTF16 encoded. If the output path is omitted, PS2EXE uses the input file's base name with an `.exe` extension. The output argument can name either an executable file or a destination folder.

The generated program can retain console behavior or use Windows Forms mode through `-noConsole`. Additional switches control that interface. `-noVisualStyles` disables visual styles, `-exitOnCancel` changes how cancellation or closing the window affects execution, and `-DPIAware` requests scaling of GUI controls when Windows display scaling is active. These options configure the wrapper and generated application mode. They do not automatically turn arbitrary console-only logic into a graphical interface.

Runtime switches cover several distinct concerns. `-x86` and `-x64` constrain the generated executable to a 32-bit or 64-bit runtime. `-STA` and `-MTA` select single-threaded or multithreaded apartment behavior. `-requireAdmin` restricts execution to an elevated context and produces a UAC prompt when required. `-conHost` forces `conhost` rather than Windows Terminal, although the README says it disables redirections. Other switches include `-lcid` for a location ID, `-UNICODEEncoding` for Unicode console output, `-credentialGUI` for graphical credential prompting, and `-virtualize` for application virtualization with forced x86 behavior.

The executable wrapper reserves command-line parameters that are not passed to the script by default. `-?` shows PowerShell help and supports combinations such as `-? -detailed`, `-? -examples`, and `-? -full`. `-debug` calls `System.Diagnostics.Debugger.Launch()`. `-extract:<FILENAME>` writes the contained PowerShell script to a file without running it. The `-end` parameter separates wrapper options from script options, because every argument after it is passed into the embedded script. Script authors must account for this reserved namespace when defining their own command-line interface.

Installing PS2EXE and Running the First Conversion

The README documents installation through the PowerShell Gallery package named `ps2exe`. Run the following command in the Windows environment where compilation will occur:

powershell
Install-Module ps2exe

The README also directs users to the PowerShell Gallery for manual downloading. It does not document an offline installation command, so readers who cannot access the gallery would need to follow the package page rather than assume another installation method.

After installation, the first documented conversion can use either the full cmdlet name or the shorter `ps2exe` invocation. This command creates `target.exe` from `source.ps1`:

powershell
Invoke-ps2exe .\source.ps1 .\target.exe

The README gives the equivalent short form as:

powershell
ps2exe .\source.ps1 .\target.exe

If the output argument is omitted, the README says the executable is written with the input file's base name and the `.exe` extension. This documented form compiles `source.ps1` and produces `source.exe` in the current directory:

powershell
ps2exe .\source.ps1

A practical first test should use a small UTF8 or UTF16 script whose console output is easy to recognize, then run the generated executable from Windows. The README does not provide a named smoke-test script with guaranteed output, so no specific output string can be promised here. If the script behaves correctly, that confirms the basic conversion path. It does not confirm that the script is free of unsupported cmdlets or that the executable will behave correctly under UAC, GUI mode, redirection, or another processor architecture.

Users who prefer a graphical conversion interface can start the documented front end:

powershell
Win-PS2EXE

This command starts Win-PS2EXE. The README does not explain the fields or conversion settings displayed by the graphical interface, so the parameter reference remains the more precise source for exact compilation options.

Embedded Files and Windows Executable Properties

PS2EXE can place supporting files inside the generated executable with `-embedFiles`. The parameter takes a hashtable whose keys are target paths and whose values are source paths. The README requires unique source file names. At program startup, the executable writes those files to the requested destinations and creates directories when necessary.

Destination path rules are explicit. A target beginning with `.\` is interpreted as relative to the executable. A target without that prefix is interpreted as relative to the current path at runtime. Environment variables in `cmd.exe` notation, including `%TEMP%` and `%APPDATA%`, are expanded during execution. This allows an executable to extract a companion file into a user or temporary directory, but it also means that the result depends on runtime permissions and the accuracy of the resolved path. If any embedded file cannot be created, the executable stops immediately.

The module can add Windows file information through `-title`, `-description`, `-company`, `-product`, `-copyright`, `-trademark`, and `-version`. The README says some values are displayed on Windows Explorer's properties dialog, while others are embedded without being displayed. The `-iconFile` option supplies an icon for the generated executable. These settings affect the executable container, not script behavior unless the script reads equivalent information itself.

`-configFile` writes a configuration file with the generated executable's name and the `.exe.config` extension. This provides the application configuration associated with a .NET Framework executable. PS2EXE does not document signing parameters, an installer, an automatic update channel, or rollback behavior, so its repository and README are not evidence of an end-to-end distribution system.

The `LICENSE` file must be reviewed before distributing generated executables. GitHub classifies the license as Other because it is a custom license that GitHub could not categorize. The README does not reproduce its terms, so this review cannot state whether modification, redistribution, or bundled-file conditions are permissive. That is a license question, not a legal conclusion.

Unsupported Cmdlets, Wrapper Behavior, and Direct Distribution

PS2EXE rewrites basic input and output commands in C# for use by the generated executable. The README explicitly lists `Write-Progress` in console mode as not implemented. It also lists `Start-Transcript` and `Stop-Transcript` as not implemented because the project says Microsoft provides no proper reference implementation for them. A script that depends on these commands should be reviewed before packaging, even if compilation completes.

Wrapper options create additional behavioral boundaries. Selecting `-conHost` can disable console redirection according to the README, which may affect callers that capture standard output or standard error. Selecting `-noConsole` changes the interface to Windows Forms and affects options such as `-exitOnCancel` and `-DPIAware`. Selecting `-requireAdmin` changes privilege requirements and introduces a UAC prompt. These switches are appropriate only when the script's deployment model matches them.

For scripts that need transcript capture, console progress, redirection, or full PowerShell 7 compatibility, the direct alternative is to distribute the `.ps1` file and invoke it through the required PowerShell executable. The difference is architectural. Direct script delivery retains access to the selected PowerShell runtime and its cmdlets, while PS2EXE places the script inside a Windows .NET Framework executable wrapper. The wrapper can simplify `.exe` delivery, but it narrows supported behavior and produces a Windows-specific binary format.

For cross-platform or current .NET publishing, the repository does not document a compatible PS2EXE path. The README says PS2EXE produces .NET 4.x binaries even when invoked from PowerShell Core. A project targeting non-Windows systems or modern .NET deployment therefore needs the publishing tools associated with its selected runtime instead of PS2EXE.

The repository is not archived and its last push was on 2026-06-06. It has no GitHub releases, so the repository listing documents no release cadence or release-specific upgrade notes. The README identifies module version `1.0.18` and gives the date `2026-06-06`. Upgrading requires rebuilding affected executables and checking changed scripts, embedded files, Windows behavior, and runtime assumptions on every supported target system.

Editorial conclusion

Adopt PS2EXE when the target is Windows, the source is PowerShell 5.1 compatible, and executable delivery is more useful than shipping the script directly. Do not adopt it for cross-platform .NET Core publishing or scripts that require unsupported cmdlets. Verify the custom LICENSE file, source encoding, runtime options, and generated executable on every target system first. The repository's last push was on 2026-06-06, but it has no GitHub releases.

Frequently asked questions

Can PS2EXE compile a PowerShell Core script into a modern .NET Core executable?

No. The README says PS2EXE can be used from PowerShell Core, but it uses the .NET Framework compiler, accepts only PowerShell 5.1-compatible scripts, and produces .NET 4.x binaries.

How do I install PS2EXE and compile my first PowerShell script?

Run `Install-Module ps2exe`, then use `Invoke-ps2exe .\source.ps1 .\target.exe` or the shorter `ps2exe` form. The source file must be UTF8 or UTF16 encoded.

Which PowerShell cmdlets does PS2EXE not support?

The README says `Write-Progress` is not implemented in console mode. It also says `Start-Transcript` and `Stop-Transcript` are not implemented, so scripts using them should be reviewed before packaging.

Official sources

  1. Issues
  2. MScholtes/PS2EXE on GitHub
  3. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/mscholtes-ps2exe.svg)](https://hysenlabs.com/projects/mscholtes-ps2exe)

Was this useful?