C# 从C调用powershell脚本文件(例如.ps1)#
我尝试使用以下代码从C#运行脚本localwindows.ps1:C# 从C调用powershell脚本文件(例如.ps1)#,c#,powershell,powershell-remoting,C#,Powershell,Powershell Remoting,我尝试使用以下代码从C#运行脚本localwindows.ps1: PSCredential credential = new PSCredential(userName, securePassword); WSManConnectionInfo connectionInfo = new WSManConnectionInfo(false, "machineName", 5985, "/wsman", shellUri, creden
PSCredential credential = new PSCredential(userName, securePassword);
WSManConnectionInfo connectionInfo = new WSManConnectionInfo(false, "machineName", 5985, "/wsman", shellUri, credential);
using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo))
{
runspace.Open();
String file = "C:\\localwindows.ps1";
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript(file);
pipeline.Commands.Add("Out-String");
Collection<PSObject> results = pipeline.Invoke();
}
实际上,您的调用样式应该可以工作。但在这两个示例中,脚本
c:\localwindows.ps1
必须驻留在本地计算机上。在调用命令的情况下,它将从本地计算机复制到远程计算机
如果在调用命令的情况下,远程计算机上已经存在脚本,并且您不需要复制它,请删除FilePath
参数并添加以下内容:
new1.AddParameter("Scriptblock", ScriptBlock.Create(file));
我有一篇文章介绍了一种通过WinRM从.NET运行Powershell的简单方法 如果您只想复制代码,那么代码将位于单个文件中,并且它也是一个NuGet包,其中包含对System.Management.Automation的引用 它可以自动管理受信任的主机,可以运行脚本块,还可以发送文件(这实际上不受支持,但我创建了一个解决方案)。返回的总是来自Powershell的原始对象
// this is the entrypoint to interact with the system (interfaced for testing).
var machineManager = new MachineManager(
"10.0.0.1",
"Administrator",
MachineManager.ConvertStringToSecureString("xxx"),
true);
// for your specific issue I think this would be easier
var results = machineManager.RunScript(
File.ReadAllText("C:\\LocalWindows.ps1"));
// will perform a user initiated reboot.
machineManager.Reboot();
// can run random script blocks WITH parameters.
var fileObjects = machineManager.RunScript(
"{ param($path) ls $path }",
new[] { @"C:\PathToList" });
// can transfer files to the remote server (over WinRM's protocol!).
var localFilePath = @"D:\Temp\BigFileLocal.nupkg";
var fileBytes = File.ReadAllBytes(localFilePath);
var remoteFilePath = @"D:\Temp\BigFileRemote.nupkg";
machineManager.SendFile(remoteFilePath, fileBytes);
如果这有帮助,请标记为答案。我已经在自动化部署中使用了一段时间了。如果发现问题,请留下评论。我尝试了case pipeline.Commands.AddScript(System.IO.File.ReadAllText(File));。我收到错误:“意外令牌”�WinNT://machineName�' 而同一脚本使用with invoke命令创建本地用户帐户。我尝试了这个解决方案-pipeline.Commands.AddScript(System.IO.File.ReadAllText(“.”+文件));程序无法找到该文件。我尝试了-new1.AddParameter(“Scriptblock”,“{.+file+”});我收到错误-'无法绑定参数'ScriptBlock'。无法将类型为“System.String”的“{C:\localwindows.ps1}”值转换为类型为“System.Management.Automation.ScriptBlock”。请参阅更新的答案。我相信问题的症结在于脚本不在本地计算机上的
c:\localwindows.ps1
。我使用了命令“new1.AddParameter(“Scriptblock”,Scriptblock.Create(file));”。我仍然收到以下错误-'无法绑定参数'ScriptBlock'。无法使用命令-pipeline.Commands.AddScript(System.IO.File.ReadAllText(File)),将类型为“System.String”的“C:\localwindows.ps1”值转换为类型为“System.Management.Automation.ScriptBlock”。-它工作得很好。问题在于剧本。我用了单引号而不是双引号,这很有效。
new1.AddParameter("Scriptblock", ScriptBlock.Create(file));
// this is the entrypoint to interact with the system (interfaced for testing).
var machineManager = new MachineManager(
"10.0.0.1",
"Administrator",
MachineManager.ConvertStringToSecureString("xxx"),
true);
// for your specific issue I think this would be easier
var results = machineManager.RunScript(
File.ReadAllText("C:\\LocalWindows.ps1"));
// will perform a user initiated reboot.
machineManager.Reboot();
// can run random script blocks WITH parameters.
var fileObjects = machineManager.RunScript(
"{ param($path) ls $path }",
new[] { @"C:\PathToList" });
// can transfer files to the remote server (over WinRM's protocol!).
var localFilePath = @"D:\Temp\BigFileLocal.nupkg";
var fileBytes = File.ReadAllBytes(localFilePath);
var remoteFilePath = @"D:\Temp\BigFileRemote.nupkg";
machineManager.SendFile(remoteFilePath, fileBytes);