有时候我们编写了一个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的版本才行。
在网上找的一个代码
function Convert-PS1ToExe
{
param(
[Parameter(Mandatory=$true)]
[ValidateScript({$true})]
[ValidateNotNullOrEmpty()]
[IO.FileInfo]$ScriptFile
)
if( -not $ScriptFile.Exists)
{
Write-Warning "$ScriptFile not exits."
return
}
[string]$csharpCode = @'
using System;
using System.IO;
using System.Reflection;
using System.Diagnostics;
namespace LoadXmlTestConsole
{
public class ConsoleWriter
{
private static void Proc_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
Process pro = sender as Process;
Console.WriteLine(e.Data);
}
static void Main(string[] args)
{
// Set title of console
Console.Title = "Powered by PSTips.Net";
// read script from resource
Assembly ase = Assembly.GetExecutingAssembly();
string scriptName = ase.GetManifestResourceNames()[0];
string scriptContent = string.Empty;
using (Stream stream = ase.GetManifestResourceStream(scriptName))
using (StreamReader reader = new StreamReader(stream))
{
scriptContent = reader.ReadToEnd();
}
string scriptFile = Environment.ExpandEnvironmentVariables(string.Format("%temp%\\{0}", scriptName));
try
{
// output script file to temp path
File.WriteAllText(scriptFile, scriptContent);
ProcessStartInfo proInfo = new ProcessStartInfo();
proInfo.FileName = "PowerShell.exe";
proInfo.CreateNoWindow = true;
proInfo.RedirectStandardOutput = true;
proInfo.UseShellExecute = false;
proInfo.Arguments = string.Format(" -File {0}",scriptFile);
var proc = Process.Start(proInfo);
proc.OutputDataReceived += Proc_OutputDataReceived;
proc.BeginOutputReadLine();
proc.WaitForExit();
Console.WriteLine("Hit any key to continue...");
Console.ReadKey();
}
catch (Exception ex)
{
Console.WriteLine("Hit Exception: {0}", ex.Message);
}
finally
{
// delete temp file
if (File.Exists(scriptFile))
{
File.Delete(scriptFile);
}
}
}
}
}
'@
# $providerDict
$providerDict = New-Object 'System.Collections.Generic.Dictionary[[string],[string]]'
$providerDict.Add('CompilerVersion','v4.0')
$codeCompiler = [Microsoft.CSharp.CSharpCodeProvider]$providerDict
# Create the optional compiler parameters
$compilerParameters = New-Object 'System.CodeDom.Compiler.CompilerParameters'
$compilerParameters.GenerateExecutable = $true
$compilerParameters.GenerateInMemory = $true
$compilerParameters.WarningLevel = 3
$compilerParameters.TreatWarningsAsErrors = $false
$compilerParameters.CompilerOptions = '/optimize'
$outputExe = Join-Path $ScriptFile.Directory "$($ScriptFile.BaseName).exe"
$compilerParameters.OutputAssembly = $outputExe
$compilerParameters.EmbeddedResources.Add($ScriptFile.FullName) > $null
$compilerParameters.ReferencedAssemblies.Add( [System.Diagnostics.Process].Assembly.Location ) > $null
# Compile Assembly
$compilerResult = $codeCompiler.CompileAssemblyFromSource($compilerParameters,$csharpCode)
# Print compiler errors
if($compilerResult.Errors.HasErrors)
{
Write-Host 'Compile faield. See error message as below:' -ForegroundColor Red
$compilerResult.Errors | ForEach-Object {
Write-Warning ('{0},[{1},{2}],{3}' -f $_.ErrorNumber,$_.Line,$_.Column,$_.ErrorText )
}
}
else
{
Write-Host 'Compile succeed.' -ForegroundColor Green
"Output executable file to '$outputExe'"
}
}
这个代码在csdn找的,试用了会报错,无论是在powershell5,还是powershell7中都是会报错的,由于我现在并不熟悉C#所以暂时无法解决这个问题
PS2EXE
PS2EXE是一个powershell的库,在GitHub上面开源免费,首先需要安装Install-Module ps2exe
然后打开PowerShell5,powershell7运行是会报错的,无法识别cmdlet
Invoke-PS2EXE -inputFile C:\Users\Lenovo\Documents\PowerShell\Word_replace.ps1 -outputFile C:\Users\Lenovo\Desktop\uu.exe
- inputfile是需要打包的powershell脚本路径
- outputfile是打包后的exe文件存放的路径