PowerShell - PS2EXE 0.5.0.0 by Ingo Karstein

Utiliser le script PowerShell PS2EXE

Upgrade du 17/12/2019: Rajout de la version de Markus Scholtes.

Dans un précèdent article, j'avais parlé de ma solution pour intégré un script PowerShell dans un exécutable avec le script de package NSIS.

Cependant, il y a toujours la solution PS2EXE crée par Ingo Karstein qui peut être télécharger par ici.

Une fois que l'on aura récupéré le zip, il faudra l'extraire dans un dossier.

Une fois que l'on aura ouvert le dossier, on va tomber sur un script PowerShell qui est sous licence MS-PL, ps2exe.ps1, ce script va compiler traduire en bytecode pour qu’ensuite, il soit compilé à la volée dans l’environnement d’exécution – le CLR Common Language Runtime – du Framework .Net.


PS2EXE; v0.5.0.0 by Ingo Karstein (http://blog.karstein-consulting.com)

Usage:

    powershell.exe -command "&'.\ps2exe.ps1' [-inputFile] ''
                   [-outputFile] ''
                   [-verbose] [-debug] [-runtime20] [-runtime30]"

       inputFile = PowerShell script that you want to convert to EXE
      outputFile = destination EXE file name
         verbose = Output verbose informations - if any
           debug = generate debug informations for output file
           debug = generate debug informations for output file
       runtime20 = this switch forces PS2EXE to create a config file for
                   the generated EXE that contains the "supported .NET
                   Framework versions" setting for .NET Framework 2.0
                   for PowerShell 2.0
       runtime30 = this switch forces PS2EXE to create a config file for
                   the generated EXE that contains the "supported .NET
                   Framework versions" setting for .NET Framework 4.0
                   for PowerShell 3.0
       runtime40 = this switch forces PS2EXE to create a config file for
                   the generated EXE that contains the "supported .NET
                   Framework versions" setting for .NET Framework 4.0
                   for PowerShell 4.0
            lcid = Location ID for the compiled EXE. Current user
                   culture if not specified.
             x86 = Compile for 32-bit runtime only
             x64 = Compile for 64-bit runtime only
             sta = Single Thread Apartment Mode
             mta = Multi Thread Apartment Mode
       noConsole = The resulting EXE file starts without a console window just like a Windows Forms app.

You are using PowerShell 5.0.
INPUT FILE AND OUTPUT FILE NOT SPECIFIED!

Par exemple, pour on peut l'utiliser, avec le fichier fourni dans l'archive ZIP, test.ps1:

./ps2exe.ps1 -inputFile test.ps1 -outputFile test.exe -icon PSEXE.ico
Pour faciliter le fichier callPS2EXE.bat qui s’utilise de la manière suivante, en mode ligne de commandes :

callPS2EXE.bat test.ps1 test.exe -runtime50 -x64
Avec cette commande, l'exécutable sera donc compilé avec la librairie runtime5.0 et dans un environnement 64 bits. Il faudra faire attention, il y a des cmdlets ou variables qui peuvent ne pas fonctionner. Par exemple, si l'on veut utiliser "$MyInvocation.MyCommand.Definition", on arrivera dans une impasse car il ne fonctionnera pas, mais avec ce bout de code, on peut retomber sur nos pattes dans ce cas-là.

$FullPathToEXE = [System.Diagnostics.Process]::GetCurrentProcess().MainModule.FileName

$DirectoryContainingEXE = [System.IO.Path]::GetDirectoryName($FullPathToEXE)
Ou

# Get the parent process.
# (`gps` is a built-in alias of `Get-Process`)
$pp = gps -Id (Get-CimInstance win32_process -Filter "ProcessId = $PID").ParentProcessId

# Output the parent process executable's directory path:
Split-Path $pp.Path
Si vous avez d'autre remarque merci de m'en faire part, je serais ravis de vous lire.

Le module de Markus Scholtes

Cela faisait longtemps que la version n'avait pas évolué, c'est pour cela que cette année 2019 à donner l'envie à un certain Markus Scholtes de faire une évolution en 1.0.1.

Si on se rend sur son Github ou Gallery technet, on peut trouver une fiche détaillé pour utilisation de son travail (en anglais).
Comme il a bien fait les choses, c'est un module que l'on peut retrouver dans powershellgallery
Ce module vous proposera aussi une version graphique que l'on peut invoquer avec la commande :

win-ps2exe

Si vous avez besoin d'utiliser le chemin racine de votre script, je vous conseille de suivre son conseil et même de rajouter une détection via le ficher exécutable

if ($MyInvocation.MyCommand.CommandType -eq "ExternalScript")
 { $ScriptPath = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition }
 else
 { $ScriptPath = Split-Path -Parent -Path ([Environment]::GetCommandLineArgs()[0]) 
     if (!$ScriptPath){ $ScriptPath = "." } }
If (!$ScriptPath){
 $FullPathToEXE = [System.Diagnostics.Process]::GetCurrentProcess().MainModule.FileName
 $ScriptPath = [System.IO.Path]::GetDirectoryName($FullPathToEXE)
}

La sécurité

Il ne faut pas stocker des mots de passes dans votre script car l'exécutable peut être extrait via la commande "-extract" comme ceci:

Output.exe -extract:C:\Output.ps1
Il est possible d'éviter cette action via la suppression des lignes suivantes dans le fichier ps2exe.ps1:

   else if (s.StartsWith("-extract", StringComparison.InvariantCultureIgnoreCase))
                           {
                               string[] s1 = s.Split(new string[] { ":" }, 2, StringSplitOptions.RemoveEmptyEntries);
                               if (s1.Length != 2)
                               {
                                   Console.WriteLine("If you specify the -extract option you need to add a file for extraction in this way\r\n   -extract:\"\"");
                                   return 1;
                               }
                               extractFN = s1[1].Trim(new char[] { '\"' });
                           }

Commentaires

Posts les plus consultés de ce blog

Powershell - Supprimer Teams sur l'ensemble des profils utilisateurs

Powershell - Comment tester les ports TCP ?

Powershell - Utiliser les requêtes WMI