有时候我们编写了一个powershell脚本但是需要给其他人使用,如果那个人时电脑的小白的,那么无论我们的脚本写得如何精妙,在无法运行的情况下也是无用武之地的(很多人就是不知道有powershell这个东西,甚至时程序员都不一定知道,更别说其他工作的人了)
如果希望大家能使用我们编写的脚本,打包称为exe文件是一个好选择,这里有几个方法对Powershell文件进行打包

VsCode的Powershell pro tool插件

这个插件需要授权才行,到官网中可以获得一个十四天的免费试用,提交邮箱后会收到一个邮件,邮件里面有一个txt文件保存到本地,这个txt文件就是license,在vscode中ctrl+shift+p然后输入install license选中已经保存到本地的txt文件,就可以激活powershell pro tool了,在vscode的右上角有一个package to exe,这样就可以打包称为exe文件。需要注意的时这个插件打包ps1脚本为exe需要.NET sdk 4的版本才行。

在网上找的一个代码

  1. function Convert-PS1ToExe
  2. {
  3. param(
  4. [Parameter(Mandatory=$true)]
  5. [ValidateScript({$true})]
  6. [ValidateNotNullOrEmpty()]
  7. [IO.FileInfo]$ScriptFile
  8. )
  9. if( -not $ScriptFile.Exists)
  10. {
  11. Write-Warning "$ScriptFile not exits."
  12. return
  13. }
  14. [string]$csharpCode = @'
  15. using System;
  16. using System.IO;
  17. using System.Reflection;
  18. using System.Diagnostics;
  19. namespace LoadXmlTestConsole
  20. {
  21. public class ConsoleWriter
  22. {
  23. private static void Proc_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
  24. {
  25. Process pro = sender as Process;
  26. Console.WriteLine(e.Data);
  27. }
  28. static void Main(string[] args)
  29. {
  30. // Set title of console
  31. Console.Title = "Powered by PSTips.Net";
  32. // read script from resource
  33. Assembly ase = Assembly.GetExecutingAssembly();
  34. string scriptName = ase.GetManifestResourceNames()[0];
  35. string scriptContent = string.Empty;
  36. using (Stream stream = ase.GetManifestResourceStream(scriptName))
  37. using (StreamReader reader = new StreamReader(stream))
  38. {
  39. scriptContent = reader.ReadToEnd();
  40. }
  41. string scriptFile = Environment.ExpandEnvironmentVariables(string.Format("%temp%\\{0}", scriptName));
  42. try
  43. {
  44. // output script file to temp path
  45. File.WriteAllText(scriptFile, scriptContent);
  46. ProcessStartInfo proInfo = new ProcessStartInfo();
  47. proInfo.FileName = "PowerShell.exe";
  48. proInfo.CreateNoWindow = true;
  49. proInfo.RedirectStandardOutput = true;
  50. proInfo.UseShellExecute = false;
  51. proInfo.Arguments = string.Format(" -File {0}",scriptFile);
  52. var proc = Process.Start(proInfo);
  53. proc.OutputDataReceived += Proc_OutputDataReceived;
  54. proc.BeginOutputReadLine();
  55. proc.WaitForExit();
  56. Console.WriteLine("Hit any key to continue...");
  57. Console.ReadKey();
  58. }
  59. catch (Exception ex)
  60. {
  61. Console.WriteLine("Hit Exception: {0}", ex.Message);
  62. }
  63. finally
  64. {
  65. // delete temp file
  66. if (File.Exists(scriptFile))
  67. {
  68. File.Delete(scriptFile);
  69. }
  70. }
  71. }
  72. }
  73. }
  74. '@
  75. # $providerDict
  76. $providerDict = New-Object 'System.Collections.Generic.Dictionary[[string],[string]]'
  77. $providerDict.Add('CompilerVersion','v4.0')
  78. $codeCompiler = [Microsoft.CSharp.CSharpCodeProvider]$providerDict
  79. # Create the optional compiler parameters
  80. $compilerParameters = New-Object 'System.CodeDom.Compiler.CompilerParameters'
  81. $compilerParameters.GenerateExecutable = $true
  82. $compilerParameters.GenerateInMemory = $true
  83. $compilerParameters.WarningLevel = 3
  84. $compilerParameters.TreatWarningsAsErrors = $false
  85. $compilerParameters.CompilerOptions = '/optimize'
  86. $outputExe = Join-Path $ScriptFile.Directory "$($ScriptFile.BaseName).exe"
  87. $compilerParameters.OutputAssembly = $outputExe
  88. $compilerParameters.EmbeddedResources.Add($ScriptFile.FullName) > $null
  89. $compilerParameters.ReferencedAssemblies.Add( [System.Diagnostics.Process].Assembly.Location ) > $null
  90. # Compile Assembly
  91. $compilerResult = $codeCompiler.CompileAssemblyFromSource($compilerParameters,$csharpCode)
  92. # Print compiler errors
  93. if($compilerResult.Errors.HasErrors)
  94. {
  95. Write-Host 'Compile faield. See error message as below:' -ForegroundColor Red
  96. $compilerResult.Errors | ForEach-Object {
  97. Write-Warning ('{0},[{1},{2}],{3}' -f $_.ErrorNumber,$_.Line,$_.Column,$_.ErrorText )
  98. }
  99. }
  100. else
  101. {
  102. Write-Host 'Compile succeed.' -ForegroundColor Green
  103. "Output executable file to '$outputExe'"
  104. }
  105. }

这个代码在csdn找的,试用了会报错,无论是在powershell5,还是powershell7中都是会报错的,由于我现在并不熟悉C#所以暂时无法解决这个问题image.png

PS2EXE

PS2EXE是一个powershell的库,在GitHub上面开源免费,首先需要安装
Install-Module ps2exe
然后打开PowerShell5,powershell7运行是会报错的,无法识别cmdlet

  1. Invoke-PS2EXE -inputFile C:\Users\Lenovo\Documents\PowerShell\Word_replace.ps1 -outputFile C:\Users\Lenovo\Desktop\uu.exe
  • inputfile是需要打包的powershell脚本路径
  • outputfile是打包后的exe文件存放的路径

image.png