Run/deposit C# 中的 Powershell 脚本
Run/deposit a Powershell Script in C#
我正在尝试从 c#
中的资源文件夹中 运行 一个 ps1 脚本
.NET Get embedded Resource File
离我更近了。
改变
private void button1_Click_1(object sender, EventArgs e)
{
PowerShell ps = PowerShell.Create();
string skriptpfad = $@"C:\Users\username\DesktopTool_Final\WinformsTool\bin\Debug\zuordnung.ps1";
ps.AddCommand(skriptpfad);
ps.AddParameter("Source", folderBrowserDialog1.SelectedPath);
ps.AddParameter("Destination", folderBrowserDialog2.SelectedPath);
ps.Invoke();
}
到
private void button1_Click_1(object sender, EventArgs e)
{
var assembly = Assembly.GetExecutingAssembly();
var resourceName = "zuordnung_test.Resources.zuordnung.ps1";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream))
{
string skriptpfad = reader.ReadToEnd();
PowerShell ps = PowerShell.Create();
//string skriptpfad = $@"C:\zuordnung.ps1";
ps.AddCommand(skriptpfad);
ps.AddParameter("Source", folderBrowserDialog1.SelectedPath);
ps.AddParameter("Destination", folderBrowserDialog2.SelectedPath);
ps.Invoke();
}
}
这只会引发整个 ps 脚本的异常 - 不称为 cmdlet - 虽然它确实读取了它但 addcommand
运行 之前的脚本。现在只是简单的 AddScript 还是我仍然在接近它?
提前致谢
private void button1_Click_1(object sender, EventArgs e)
{
var assembly = Assembly.GetExecutingAssembly();
var resourceName = "%projectname%.Resources.%script.ps1%";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream))
{
string skriptpath = reader.ReadToEnd();
PowerShell ps = PowerShell.Create();
ps.AddScript(skriptpath);
//ps.AddParameter...
ps.Invoke();
}
}
是我的问题的解决方案。
我包含了上述线程的解决方案并将 AddCommand 更改为 AddScript(我知道为什么 addcommand 可以从本地文件读取它,但在这种情况下却没有)
让我添加一些背景信息 :
注意:您的问题归结为必须从 .AddCommand()
切换到脚本-file 执行 (.ps1
) 到 .AddScript()
用于 source-code string 执行(来自资源)。下面主要关注脚本-file执行时,什么时候使用.AddCommand()
vs. .AddScript()
。
.AddCommand()
是调用 脚本文件的正确 PowerShell SDK 方法 (.ps1
) 和其他 命令形式 ,即 cmdlet、函数和外部程序。
一个潜在的问题是 有效的 PowerShell execution policy 可能 阻止 脚本文件的执行 。在原始机器 运行 Windows desktop 版本中,script-file 执行默认完全禁用 (Restricted
),而 RemoteSigned
在 服务器 机器上。
假设有效的执行策略不会阻止 script-file 通过 GPO 执行 (组策略对象),您可以通过 SDK为当前 PowerShell 会话(仅)设置执行策略来解决此问题; RemoteSigned
(browser-downloaded 文件必须具有有效签名)通常是安全的选择:
// Create an initial default session state.
var iss = InitialSessionState.CreateDefault2();
// Set its script-file execution policy (for the current session only).
iss.ExecutionPolicy = Microsoft.PowerShell.ExecutionPolicy.RemoteSigned;
// Create a PowerShell instance with a runspace based on the
// initial session state.
PowerShell ps = PowerShell.Create(iss);
// ...
// Now, .AddCommand() should work fine.
ps.AddCommand(skriptpfad);
// ...
- 如果 GPO-controlled 执行策略阻止您设置会话的执行策略(或者您只是想避免显式设置会话执行策略),您可以使用
.AddScript()
作为 解决方法,如下所述 - 但请注意它具有 限制 和 副作用 .
名称有点令人困惑的 .AddScript()
方法用于调用 直接作为字符串 [=103= 提供的 PowerShell 源代码],可以说,脚本文件的 内容,或者,在您的情况下,从程序集中嵌入的资源中检索到的一段 PowerShell 代码。
因此,只要给定脚本文件的内容(代码)不(直接或间接[1])调用其他脚本文件,你可以使用.AddScript()
来绕过 PowerShell的执行策略(只适用于脚本文件).
也就是说,如您的回答所示,您可以将 .ps1
文件的内容 读入内存中的字符串 前面,并将该字符串传递给 .AddScript()
;最简单的打点方法是使用 System.IO.File.ReadAllText
:
ps.AddScript(File.ReadAllText(skriptpath));
// Call ps.AddParameter() as needed.
警告:此技术的副作用是script-file主体以这种方式调用将不知道脚本文件的原始文件名和位置。
[1] 请注意,某些模块在导入期间会自动执行 .ps1
文件,并且模块导入本身可能会自动发生。
我正在尝试从 c#
中的资源文件夹中 运行 一个 ps1 脚本.NET Get embedded Resource File
离我更近了。
改变
private void button1_Click_1(object sender, EventArgs e)
{
PowerShell ps = PowerShell.Create();
string skriptpfad = $@"C:\Users\username\DesktopTool_Final\WinformsTool\bin\Debug\zuordnung.ps1";
ps.AddCommand(skriptpfad);
ps.AddParameter("Source", folderBrowserDialog1.SelectedPath);
ps.AddParameter("Destination", folderBrowserDialog2.SelectedPath);
ps.Invoke();
}
到
private void button1_Click_1(object sender, EventArgs e)
{
var assembly = Assembly.GetExecutingAssembly();
var resourceName = "zuordnung_test.Resources.zuordnung.ps1";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream))
{
string skriptpfad = reader.ReadToEnd();
PowerShell ps = PowerShell.Create();
//string skriptpfad = $@"C:\zuordnung.ps1";
ps.AddCommand(skriptpfad);
ps.AddParameter("Source", folderBrowserDialog1.SelectedPath);
ps.AddParameter("Destination", folderBrowserDialog2.SelectedPath);
ps.Invoke();
}
}
这只会引发整个 ps 脚本的异常 - 不称为 cmdlet - 虽然它确实读取了它但 addcommand
运行 之前的脚本。现在只是简单的 AddScript 还是我仍然在接近它?
提前致谢
private void button1_Click_1(object sender, EventArgs e)
{
var assembly = Assembly.GetExecutingAssembly();
var resourceName = "%projectname%.Resources.%script.ps1%";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream))
{
string skriptpath = reader.ReadToEnd();
PowerShell ps = PowerShell.Create();
ps.AddScript(skriptpath);
//ps.AddParameter...
ps.Invoke();
}
}
是我的问题的解决方案。 我包含了上述线程的解决方案并将 AddCommand 更改为 AddScript(我知道为什么 addcommand 可以从本地文件读取它,但在这种情况下却没有)
让我添加一些背景信息
注意:您的问题归结为必须从 .AddCommand()
切换到脚本-file 执行 (.ps1
) 到 .AddScript()
用于 source-code string 执行(来自资源)。下面主要关注脚本-file执行时,什么时候使用.AddCommand()
vs. .AddScript()
。
.AddCommand()
是调用 脚本文件的正确 PowerShell SDK 方法 (.ps1
) 和其他 命令形式 ,即 cmdlet、函数和外部程序。一个潜在的问题是 有效的 PowerShell execution policy 可能 阻止 脚本文件的执行 。在原始机器 运行 Windows desktop 版本中,script-file 执行默认完全禁用 (
Restricted
),而RemoteSigned
在 服务器 机器上。假设有效的执行策略不会阻止 script-file 通过 GPO 执行 (组策略对象),您可以通过 SDK为当前 PowerShell 会话(仅)设置执行策略来解决此问题;
RemoteSigned
(browser-downloaded 文件必须具有有效签名)通常是安全的选择:// Create an initial default session state. var iss = InitialSessionState.CreateDefault2(); // Set its script-file execution policy (for the current session only). iss.ExecutionPolicy = Microsoft.PowerShell.ExecutionPolicy.RemoteSigned; // Create a PowerShell instance with a runspace based on the // initial session state. PowerShell ps = PowerShell.Create(iss); // ... // Now, .AddCommand() should work fine. ps.AddCommand(skriptpfad); // ...
- 如果 GPO-controlled 执行策略阻止您设置会话的执行策略(或者您只是想避免显式设置会话执行策略),您可以使用
.AddScript()
作为 解决方法,如下所述 - 但请注意它具有 限制 和 副作用 .
- 如果 GPO-controlled 执行策略阻止您设置会话的执行策略(或者您只是想避免显式设置会话执行策略),您可以使用
名称有点令人困惑的
.AddScript()
方法用于调用 直接作为字符串 [=103= 提供的 PowerShell 源代码],可以说,脚本文件的 内容,或者,在您的情况下,从程序集中嵌入的资源中检索到的一段 PowerShell 代码。因此,只要给定脚本文件的内容(代码)不(直接或间接[1])调用其他脚本文件,你可以使用
.AddScript()
来绕过 PowerShell的执行策略(只适用于脚本文件).也就是说,如您的回答所示,您可以将
.ps1
文件的内容 读入内存中的字符串 前面,并将该字符串传递给.AddScript()
;最简单的打点方法是使用System.IO.File.ReadAllText
:ps.AddScript(File.ReadAllText(skriptpath)); // Call ps.AddParameter() as needed.
警告:此技术的副作用是script-file主体以这种方式调用将不知道脚本文件的原始文件名和位置。
[1] 请注意,某些模块在导入期间会自动执行 .ps1
文件,并且模块导入本身可能会自动发生。