该控制台应用程序只是重现 PowerShell Remoting 正在执行的操作或 MS SysInternals psexec 正在执行的操作。
为什么要重新创建这个?
我知道这是一项要求,但从长远来看,这是一个您不必管理的过于复杂的问题。
这听起来像是未启用 PSRemoting,因此是此控制台应用程序的原因。
无论如何,您仍将实例化 PowerShell 主机以运行 PowerShell 内容。因此,您只是在 C# 应用程序中托管 PowerShell。
从 C# 运行 PowerShell 是一件很常见的事情,并且有据可查。快速搜索将为您提供大量的点击和示例。
How to run PowerShell scripts from C#
Calling C# code in Powershell and vice versa
添加以下“使用”语句以导入所需的类型:
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
以下代码块显示了执行所有操作的 RunScript 方法
努力工作。它接受脚本文本,执行它,然后返回
结果为字符串。
private string RunScript(string scriptText)
{
// create Powershell runspace
Runspace runspace = RunspaceFactory.CreateRunspace();
// open it
runspace.Open();
// create a pipeline and feed it the script text
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript(scriptText);
// add an extra command to transform the script
// output objects into nicely formatted strings
// remove this line to get the actual objects
// that the script returns. For example, the script
// "Get-Process" returns a collection
// of System.Diagnostics.Process instances.
pipeline.Commands.Add("Out-String");
// execute the script
Collection<psobject /> results = pipeline.Invoke();
// close the runspace
runspace.Close();
// convert the script result into a single string
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject obj in results)
{
stringBuilder.AppendLine(obj.ToString());
}
return stringBuilder.ToString();
}
如何让脚本与您的程序交互
在使用 pipeline.Invoke() 调用执行脚本之前,它是
可以通过使用将程序的对象公开给脚本
方法 runspace.SessionStateProxy.SetVariable("someName",
一些对象)。
这将创建一个脚本可以访问的命名变量
(获取/设置属性,甚至调用方法)。
例如,假设我们将示例的主要形式暴露给
通过像这样添加 SetVariable() 调用来编写脚本:
...
// open it
runspace.Open();
runspace.SessionStateProxy.SetVariable("DemoForm", this);
....
Then, the following script would print the caption of the window:
$DemoForm.Text
The following script would show all the properties and methods of the window:
$DemoForm | Get-Member
但是请注意,脚本对您的对象进行的任何调用
将来自另一个线程上下文,因为 pipeline.Invoke() 似乎
启动自己的工作线程。这意味着您暴露的对象将
必须是线程安全的。
这甚至可以被视为此问答的副本
Run PowerShell-Script from C# Application
OP 更新
至于……
c# 控制台应用程序需要像中心一样处理
几个 .ps1 脚本文件,
因此,C# 应用程序是 C&C,取代了 PSRemoting / PSExec 会话。
但是,您没有说明脚本文件在哪里,或者您打算如何将它们传送到远程系统。
但首先它需要先访问远程机器。
这是什么PSRemoting...
$s = New-PSSession -ComputerName (Get-Content Servers.txt) -Credential Domain01\Admin01
Invoke-Command -Session $s -ScriptBlock {
# Run these PowerShell commands or scripts.
Get-Process PowerShell
}
或作为后台作业
$s = New-PSSession -ComputerName (Get-Content Servers.txt) -Credential Domain01\Admin01
Invoke-Command -Session $s -ScriptBlock {
# Run these PowerShell commands or scripts.
Get-Process PowerShell
} -AsJob
PSExec 可以。
psexec \RemotePCName [-u 用户名[-p 密码]] 命令[参数]
至于……
只有在所有 .ps1 文件成功运行后,才应注销
从远程机器返回任何输出到控制台。
同样,PSRemoting 和 PSExec 所做的正是如此。
这就是为什么我想先使用 c# 连接远程,然后
然后调用所有的 .ps1 文件。
您的控制台应用只需执行上述操作。这是可行的,正如这些问答所指出的那样,只是使用命令,而不是调用脚本,但同样的规则适用......
Execute powershell script on a remote computer using C#
Invoke remote powershell command from C#
例子:
InitialSessionState initial = InitialSessionState.CreateDefault();
Runspace runspace = RunspaceFactory.CreateRunspace(initial);
runspace.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = runspace;
ps.AddCommand("invoke-command");
ps.AddParameter("ComputerName", "mycomp.mylab.com");
ScriptBlock filter = ScriptBlock.Create("Get-childitem C:\\windows");
ps.AddParameter("ScriptBlock", filter);
foreach (PSObject obj in ps.Invoke())
{
// Do Something
}
但同样,它只是复制上述内容。所以,是的,这是一个选择。使用 PSRemoting,使用 PSExec,构建不同的解决方案。