[英]PowerShell Remoting with .Net Core and Hyper-V
I am attempting to write a .NET Core program that remotely connects to a Windows 2019 server running in Hyper-V.我正在尝试编写一个远程连接到在 Hyper-V 中运行的 Windows 2019 服务器的 .NET 核心程序。 I've poured through the literature and I finally got my code to compile and run but receive no output.我翻阅了文献,终于得到了可以编译和运行的代码,但没有收到 output。 It seems that it is just running the commands in a local PowerShell isntance.它似乎只是在本地 PowerShell 实例中运行命令。 Any guidance would be helpful.任何指导都会有所帮助。
string password = "password123";
var securePassword = new SecureString();
foreach (char c in password)
{
securePassword.AppendChar(c);
}
string userName = "Administrator";
PSCredential creds = new PSCredential(userName, securePassword);
Runspace runspace = RunspaceFactory.CreateRunspace();
PowerShell powershell = PowerShell.Create();
PSCommand command = new PSCommand();
command.AddCommand("New-PSSession");
command.AddParameter("VMName", "PSRemote");
command.AddParameter("Credential", creds);
powershell.Commands = command;
runspace.Open();
Collection<PSSession> result = powershell.Invoke<PSSession>();
Console.WriteLine(result);
powershell = PowerShell.Create();
command = new PSCommand();
command.AddCommand("Set-Variable");
command.AddParameter("Name", "ra");
command.AddParameter("Value", result[0]);
powershell.Commands = command;
powershell.Runspace = runspace;
powershell.Invoke();
powershell = PowerShell.Create();
command = new PSCommand();
command.AddScript("Import-PSSession -Session $ra");
powershell.Commands = command;
powershell.Runspace = runspace;
powershell.Invoke();
powershell = PowerShell.Create();
command = new PSCommand();
command.AddScript("Get-WUList");
powershell.Commands = command;
powershell.Runspace = runspace;
var results = powershell.Invoke();
foreach (var psobject in results)
{
Console.WriteLine(psobject);
}
runspace.Close();
There are people much, much better with C# here than myself here, but here is a quick sample that I have used to demo using PowerShell.有人在这里使用 C# 比我自己要好得多,但这里有一个快速示例,我曾经使用 PowerShell 进行演示。 Your main issue here I think is creating a new instance of PowerShell every time you run a new command.我认为您的主要问题是每次运行新命令时都会创建 PowerShell 的新实例。 Hope that helps.希望有帮助。
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
namespace PoshSample {
public class AD {
// Properties
public PowerShell Posh;
public string[] PSModule = new string[] { "activedirectory" };
public Init() {
Posh = NewPowerShellSession(PSModule);
// Calling Functions - Add multiple ones with parameters if you need to chain commands like you would via the pipeline
IDictionary<String, Object> functions = new Dictionary<String, Dictionary<String, Object>>();
IDictionary<String, Object> parameters = new Dictionary<String, Object>();
parameters.Add("Filter", "*");
parameters.Add("SearchBase", "OU=SomeOtherOU,OU=topOU,DC=blah,DC=com");
functions.Add("Get-ADGroup", parameters)
var adGroups = RunPosh(function, "Name", true);
// Other commands here.
}
private PowerShell NewPowerShellSession(String[] PSModule = null)
{
// Define our PowerShell Session
PowerShell powerShell = PowerShell.Create();
Runspace runspace;
// Add the PSModule if required
if (PSModule != null)
{
InitialSessionState initial = InitialSessionState.CreateDefault();
initial.ImportPSModule(PSModule);
runspace = RunspaceFactory.CreateRunspace(initial);
}
else
{
runspace = RunspaceFactory.CreateRunspace();
}
runspace.Open();
powerShell.Runspace = runspace;
return powerShell;
}
// Run a PowerShell function - Set Async to true to wait for output. False is for functions where you are not expecting anything to be returned.
private Collection<PSObject> RunPosh(Dictionary<String, Dictionary<String, Object>> Commands, String Property = null, bool Async = false)
{
// Sleep two seconds before proceeding - this is important, but I am not sure why. Stumbled on it a long time ago.
Posh.AddCommand("Start-Sleep").AddParameter("Seconds", 2).AddStatement();
// Run our command adding the parameters one by one and then pipe in to Out-String.
foreach (KeyValuePair<String, Dictionary<String, Object>> c in Commands)
{
string PoshCommand = c.Key;
Posh.AddCommand(PoshCommand);
Dictionary<String, Object> Parameters = c.Value;
if (Parameters != null)
{
foreach (var key in Parameters.Keys)
{
Posh.AddParameter(key, Parameters[key]);
}
}
}
// List a selected property
if (Property != null)
{
Posh.AddCommand("Select-Object").AddParameter("ExpandProperty", Property);
}
if (Async)
{
// Invoke our command asynchronously and return the objects.
IAsyncResult async = Posh.BeginInvoke();
var returnCollection = new Collection<PSObject>();
foreach (PSObject obj in Posh.EndInvoke(async))
{
returnCollection.Add(obj);
}
Posh.Commands.Clear();
return returnCollection;
}
else
{
Posh.Invoke();
Posh.Commands.Clear();
return null;
}
}
}
}
By the way, I am not 100% sure on this one, but you may be able to set your variable via the Runspace rather than running another command.顺便说一句,我不是 100% 确定这一点,但您可以通过运行空间设置变量,而不是运行另一个命令。 SessionStateProxy . 会话状态代理。
Posh.Runspace.SessionStateProxy.SetVariable(string, object)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.