PS2EXE-GUI: "Convert" PowerShell Scripts to EXE Files with GUI

Overworking of the great script of Ingo Karstein with GUI support. The GUI output and input is activated with one switch, real windows executables are generated. With Powershell 5.x support and graphical front end. Now here:
4.7 Star
37,250 times
Add to favorites
E-mail Twitter Digg Facebook
  • Get-Credential not returning $null when cancelled
    5 Posts | Last post September 11, 2018
    • Hi,
      Really great script! Had no problems until I tried to work with Get-Credential. I store a Password as an XML file. If the user accidently clicked the "Change Credentials" Button, he should be able to abort by clicking "cancel". However, the Output is not equal to $null...
      I poked around in the script a bit, but i couldn't fix the problem myself.
      Do you know where/why this happens?
      Thank you & Greetings
    • PS:
      This is the code:
      while ($true) {
              $Creds = (Get-Credential -User $env:USERNAME -Message "Please enter your Username and Password:")
              Write-Host "Validating..."
              if (($null -ne $Creds -and $Creds.GetNetworkCredential().password -match "^[0-9]{4,8}$") -or ($null -eq $Creds)){
                  return $Creds
    • Hello Matthias,
      I found the bug in PS2EXE. Quiet easy to correct, but I have to release a new version of PS2EXE. I will do this soon.
    • Hello Matthias,
      I released the new version of PS2EXE today that returns $NULL correctly when aborting the credential window.
    • Hi Markus,
      Thank you for your quick response, works great!
  • Output from called vbs
    2 Posts | Last post August 17, 2018
    • Hi,
      I'm calling a vbs file though
      Invoke-Command -ScriptBlock { cscript "file.vbs"}
      In "console" mode, is there a way to get the standard output from file.vbs?
      Without "compiling" the ps1, i see the output from the vbs.
      Thanks, Nestor.
    • Hello Nestoter,
      I tried your sample code and got the Standard output of a vbs file shown in the compiled script.
      May you have an other error? Can it be your vbs file is not found since you don't supply a path to it?
  • Included ps1 files
    3 Posts | Last post August 07, 2018
    • Hi,
      Works almost perfectly for what I need, just 1 question:
      Is there a way for the script to automatically add the code from imported scripts within the main script?
      I.e. I have a functions.ps1 file that gets imported at the top of the main file. This file will also import ps1 files depending on the function being called. This is being include via the following line:
      . "..\Includes\functions.ps1"
      If I leave this line in, I get an error stating that the command is not recognised.
      Any ideas?
    • Hello Joe,
      dot sourcing works fine with PS2EXE. As you are using a relative path please check that the current directory is what you expect it to be.
      You might use a path relative to the compiled script with:
      f ($MyInvocation.MyCommand.CommandType -eq "ExternalScript")
      { $ScriptPath = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition }
      { $ScriptPath = Split-Path -Parent -Path ([Environment]::GetCommandLineArgs()[0]) }
      . "$Scriptpath\..\Includes\functions.ps1"
      (see "Remarks" sction for an explanation)
    • Hi Markus,
      Thank you for your response, I actually already saw that piece of code, and was using it. For anyone that may have the same issue as I was, I created a script called "combine.ps1", with the following code:
      $includes = @()
      $includes = "..\Includes\file-01.ps1","..\Includes\file-02.ps1","..\Includes\file-03.ps1"
      Clear-Content .\complete-script.ps1
      Foreach ($include in $includes) {
      	$content = Get-Content $include | Where { $_ -notmatch "^\." }
      	$content = $content | Where { $_ -notmatch "^\# SIG" }
      	Add-Content .\complete-script.ps1 $content
      .\PS2EXE-GUI\ps2exe.ps1 -inputFile ".\complete-script.ps1" -outputFile ".\complete-script.exe" -noConfigFile -credentialGUI
      Remove-Item ".\complete-script.ps1" -Force
      It's not ideal, as you have to specify the files in the array in the same order as what they appear in the script, but gets the job done.
      An improvement to this would be to add an "If" statement that finds the lines starting with "." and then automatically import that script in to "complete-script.ps1" file. Obviously, you would need to search recursively for dot sourced scripts to import...
  • -noConsole Secure input
    3 Posts | Last post July 29, 2018
    • Hi Markus,
      First thanks for this wonderful tool. It makes life so easy.
      I am converting a script to exe which reads host as secure string. On converting it to exe with -noConsole, the windows form box show text as "Secure Input". I was hoping it to use the message text from the script like "Enter your password". Any way to fix this? Am I doing something wrong?
    • Hello pghack,
      thank you for pointing to this bug. I will release a new version of PS2EXE soon with this error fixed.
    • Hello pghack,
      I released the new version today that shows the message text for Read-Host.
  • The form doesn't show correctly
    3 Posts | Last post July 28, 2018
    • Hello Markus.
      I have written a ps1 script that show a form containig a label with some text.When i execute ps1 everything is Ok, but if i run exe file, the label is white, overlying the form background and it has no text.I have compiled the script with -x32 -noConsole -Mta -noConfigfile -runtime40 parameters.
      Here is the script:
          Function Generate-Form ($_mesage){
          Add-Type -AssemblyName System.Windows.Forms
          # Build Form
          $objForm = New-Object system.Windows.Forms.Form
          $objForm.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::Fixed3D
          $objForm.ControlBox = $false
          $objForm.StartPosition = "manual"
          $objForm.Location = New-Object System.Drawing.Size(520,320)
          $objForm.AutoSize = $True
          $objForm.AutoSizeMode = "GrowAndShrink"
          # Add Label
          $objLabel = New-Object System.Windows.Forms.Label
          $objLabel.Text = $_mesage
          $objLabel.AutoSize = $True
          $objLabel.Location = New-Object System.Drawing.Size(0,0)
          $objLabel.Font = New-Object System.Drawing.Font("Times New Roman",18,[System.Drawing.FontStyle]::Italic)
          $objLabel.ForeColor = "BlueViolet"
          $objLabel.BackColor = "LightBlue"
          $objLabel.TextAlign = "MiddleCenter"
          $objForm.Show()| Out-Null
          # wait 3 seconds 
          Start-Sleep -Seconds 3
          # destroy form
          $objForm.Close() | Out-Null
          Generate-Form("Operation Completed")
    • Hello Catalin Ivan,
      please remove the Parameter -MTA since Winforms may not work correctly in Multi-Threaded Appartment, you may see here:
      or here:
    • Thank you Markus,
      It works great!
  • "ExternalScript"
    2 Posts | Last post July 27, 2018
    • Please clarify the "ExternalScript" string in the section:
      if ($MyInvocation.MyCommand.CommandType -eq "ExternalScript")
      { $ScriptPath = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition }
      { $ScriptPath = Split-Path -Parent -Path ([Environment]::GetCommandLineArgs()[0]) }
      Am I specifying the Executable generated or any single file residing in the path I'm trying to retrieve?
    • My mistake, it works without modifying the string. 
  • Icon isn't showing in taskar and output box.
    3 Posts | Last post July 26, 2018
    • Hello Markus.
      I compile ps1 file with an icon file successfully. But when I executes it with some outputs, it's not show the compiled icon in taskbar and in message box.
      Please modifing the script to get the compiled icon appear in both taskar and message box, Markus :D
      Maybe adding an option to disable the `-extract:path` feature.
      Is there any script to minifing .PS1 source code?
      Minh Cường
    • Sorry.
      The icon is showing up correctly in Taskbar after I resized it to 48x48 dimension.
      Maybe icon in the title bar of message box is not necessary.
    • Hello Minh Cường,
      it is not the intention of PS2EXE to hide the source code but to make easy-to-use executables from powershell scripts, so I would not like to see the option to disable the extraction parameter (another reason is that there is no encryption in PS2EXE, just encoding to prevent special characters from breaking the script. Disabling the extract option would not really prevent curious eyes from seeing the script).
      If you want to disable this Option anyway, you can do it yourself with the following steps:
      1. Make a security backup of PS2EXE.ps1
      2. Open ps2exe.ps1 in your favorite text Editor (or Notepad)
      3. Search for 's.StartsWith("-extract", StringComparison.InvariantCultureIgnoreCase)' (without the single quotes)
      4. Replace this expression with 'false' (without the single quotes)
      5. Save ps2exe.ps1
      From now on compiled scripts does not have the extract option anymore.
      I do not know any minifying tool for powershell, please ask your favorite search engine.
  • compiled Process does not exit
    3 Posts | Last post July 22, 2018
    • Hi Markus,
      Thanks for this great utility. It is working marvellously.
      There is just one matter disturbing my peace. I wrote a multi runspace WPF gui according to Foxdeploy's blog ( ). That is working all well. However, if I compile my gui, the process.exe remains active after closing the window. I have to kill it manually to get rid of it. 
      Have you got any ideas, why this is so and how I could prevent it?
      Stefan the Scotlandhiker
    • Sorry I forgot. My parameters are like that:
      .\#ps2exe.ps1 -inputFile .\TMMT4K.ps1 -outputFile .\TMMT4K.exe -runtime40 -x64 -Mta -noConsole -iconFile .\Scots.ico -noConfigfile
    • Hello Stefan,
      it took me some time and brain to investigate this!
      There is a continuing bug or better said leak in the script of Foxdeploy's blog. Runspaces are opened but never closed.
      Powershell.exe closes those runspaces forcefully, PS2EXE waits (infinitely) for them to close. To see what I mean start the example from Foxdeploy with
      powershell.exe <PATH>\Powershell_GUI_Template.ps1
      (please provide the correct <PATH>)
      There are two ways to correct this
      1. Remove all appearances of 
        $newRunspace.ThreadOptions = "ReuseThread"
      With this change PS2EXE will close runspaces forcefully.
      2. Correctly close the runspaces after use
      This is more complicated, for the example "Powershell_GUI_Template.ps1" on Foxdeploy you have to insert
      after line 82 (= $runspace.powershell.dispose())
      Change line 169 
      to the three lines
      at the end after 
        $data = $psCmd.BeginInvoke()
      (there is still a "runspace leak" left when closing the window while Update-Window is working, you have to fix it yourself)
  • DOS Errolevel
    2 Posts | Last post July 22, 2018
    • Thanks for your great work!
      I've produced an .exe of a simple script, but I noticed that the dos %errorlevel% is always 0 if the script runs correctly,even when the PS1 is just
      invoke-expression "cmd /c exit 1"
      is there a way for the built .exe to return the last exit code? (%errorlevel%) ?
      Many thanks!
    • Hello MKz991,
      as in powershell.exe there is no automatic return of the last exit code in PS2EXE to the calling shell. According to powershell scripts you have to use
        exit $LASTEXITCODE
      as last command in your script to accomplish this.
  • Hardcoded variables
    3 Posts | Last post July 22, 2018
    • Hello Markus,
      I have hardcoded variables in the compiled .ps1, like:
      $scRoot = $PSScriptRoot
      $csvsource = $scRoot + "\ISO.csv"
      The complied program now it reference the $csvsource to: C:\ISO.csv
      What could be the solution? How can I add the variable into the .exe.config file?
    • isn't that written in the readme?
      You can retrieve the script/executable path independant of compiled/not compiled with the following code (thanks to JacquesFS):
      if ($MyInvocation.MyCommand.CommandType -eq "ExternalScript")
      { $ScriptPath = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition }
      { $ScriptPath = Split-Path -Parent -Path ([Environment]::GetCommandLineArgs()[0]) }
    • Hello Thomeee,
      MKz991 is right, please see the "remarks" section of this web page for a description and a solution.
101 - 110 of 184 Items