我正在尝试从C# .NET WinForms应用程序连接到远程PowerShell。我的目标是创建自己的Microsoft PowerShell ISE版本。因此,我需要一种在远程机器上从我的应用程序执行PowerShell脚本的方法。我已经创建了几种方法,并在我的应用程序中对本地计算机进行了测试。如果我不使用WSManConnectionInfo,而是使用using (Runspace remoteRunspace = RunspaceFactory.CreateRunspace()),我可以像真正的powershell一样在本地执行脚本(小脚本,使用变量,使用ft,fl输出数据,做许多其他我通常使用powershell的事情)。但是当我添加WSManConnectionInfo并将其指向我的Exchange服务器而不是使用本地连接时,问题就开始了。它似乎能够执行基本操作,例如“get-mailbox”,但只要我尝试管道操作,使用一些脚本功能,例如$variables,它就会报错说不支持。
同样,当不在本地使用时,我必须禁用powershell.AddCommand("out-string");。
有什么建议是为什么会这样发生以及如何解决它的方法?我看到了很多像这个的博客,但定义每一个简单的命令对我来说没有意义。我还看到了一种选项,即创建本地连接,然后在其中执行远程连接,但这得是最后的选择,因为它依赖于多种其他因素。
同样,当不在本地使用时,我必须禁用powershell.AddCommand("out-string");。
如果我不强制远程连接而只是在本地执行,则不会出现完全相同的错误。似乎SchemaUri使其非常严格,仅执行基本命令。我看到其他人使用非常直接的信息,例如:类型为'System.Management.Automation.RemoteException'的未处理异常出现在System.Management.Automation.dll中。
附加信息:未能识别“Out-String”作为命令、函数、脚本文件或可操作程序的名称。请检查名称的拼写,或者如果包含路径,请验证该路径是否正确,然后重试。
powershell.AddCommand("Get-Users");
powershell.AddParameter("ResultSize", count);
但是这种方法需要定义大量可能的选项,而且我不想去定义参数和其他东西。我只想像在PowerShell窗口中一样加载“脚本”并执行它。这是我现在使用的一个例子。
public static WSManConnectionInfo PowerShellConnectionInformation(string serverUrl, PSCredential psCredentials)
{
var connectionInfo = new WSManConnectionInfo(new Uri(serverUrl), "http://schemas.microsoft.com/powershell/Microsoft.Exchange", psCredentials);
//var connectionInfo = new WSManConnectionInfo(new Uri(serverUrl), "http://schemas.microsoft.com/powershell", psCredentials);
connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Basic;
connectionInfo.SkipCACheck = true;
connectionInfo.SkipCNCheck = true;
connectionInfo.SkipRevocationCheck = true;
connectionInfo.MaximumConnectionRedirectionCount = 5;
connectionInfo.OperationTimeout = 150000;
return connectionInfo;
}
public static PSCredential SecurePassword(string login, string password)
{
SecureString ssLoginPassword = new SecureString();
foreach (char x in password) { ssLoginPassword.AppendChar(x); }
return new PSCredential(login, ssLoginPassword);
}
public static string RunScriptPs(WSManConnectionInfo connectionInfo, string scriptText)
{
StringBuilder stringBuilder = new StringBuilder();
// Create a remote runspace using the connection information.
//using (Runspace remoteRunspace = RunspaceFactory.CreateRunspace())
using (Runspace remoteRunspace = RunspaceFactory.CreateRunspace(connectionInfo))
{
// Establish the connection by calling the Open() method to open the runspace.
// The OpenTimeout value set previously will be applied while establishing
// the connection. Establishing a remote connection involves sending and
// receiving some data, so the OperationTimeout will also play a role in this process.
remoteRunspace.Open();
// Create a PowerShell object to run commands in the remote runspace.
using (PowerShell powershell = PowerShell.Create())
{
powershell.Runspace = remoteRunspace;
powershell.AddScript(scriptText);
//powershell.AddCommand("out-string");
powershell.Commands.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);
Collection<PSObject> results = powershell.Invoke();
foreach (PSObject result in results) {
stringBuilder.AppendLine(result.ToString());
}
}
// Close the connection. Call the Close() method to close the remote
// runspace. The Dispose() method (called by using primitive) will call
// the Close() method if it is not already called.
remoteRunspace.Close();
}
// convert the script result into a single string
return stringBuilder.ToString();
}
有什么建议是为什么会这样发生以及如何解决它的方法?我看到了很多像这个的博客,但定义每一个简单的命令对我来说没有意义。我还看到了一种选项,即创建本地连接,然后在其中执行远程连接,但这得是最后的选择,因为它依赖于多种其他因素。
serverUrl
是什么样子? - Aziz Kabyshev