且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

从 C# 远程连接到 powershell

更新时间:2023-02-08 14:49:01

好吧,你说两台机器都在同一个域中,但我看到你正在尝试使用本地管理员帐户.这可能是一个问题,但不一定.为了复制这一点,我在虚拟机上设置了 Win2k8R2 并按照以下步骤操作:

Ok so you said that both machines are on the SAME domain, but I see you are trying to use the local admin account. That may be an issue but not necessarily. To replicate this, I set up Win2k8R2 on a VM and followed the following steps:

步骤 1 和 2 适用于 Server 2008 R2 核心安装.如果您有完整安装,只需跳到 #3.

  1. 运行以下命令来安装 .NET2 &PowerShell(在 cmd.exe 中)
    • DISM/Online/Enable-Feature/Featurename:NetFx2-ServerCore
    • DISM/Online/Enable-Feature/FeatureName:MicrosoftWindowsPowerShell
  • DISM/online/enable-feature/featurename=ServerManager-PSH-Cmdlets
  • DISM/online/enable-feature/featurename=BestPractices-PSH-Cmdlets
  • Set-Excutionpolicy RemoteSigend
  • Configure-SMRemoting.ps1 -force -enable

然后我拿走了你的示例代码,我并没有对它做任何实质性的改变

And then I took your sample code, I didn't really make any substantial changes to it

        Console.Write("Target: ");
        var target = Console.ReadLine();
        Console.Write("User: ");
        var user = Console.ReadLine();
        user = string.Format("{0}\\{1}", target, user);
        string shell = "http://schemas.microsoft.com/powershell/Microsoft.PowerShell";
        var targetWsMan = new Uri(string.Format("http://{0}:5985/wsman", target));

        using (var passing = new SecureString())
        {
            Console.Write("Password: ");
            var cki = default(ConsoleKeyInfo);
            do
            {
                cki = Console.ReadKey(true);
                if (cki.Key == ConsoleKey.Enter)
                    Console.Write(cki.KeyChar);
                else
                    passing.AppendChar(cki.KeyChar);
            }
            while (cki.Key != ConsoleKey.Enter);
            passing.MakeReadOnly();

            var cred = new PSCredential(user, passing);

            var connectionInfo = new WSManConnectionInfo(targetWsMan, shell, cred);
            connectionInfo.OperationTimeout = 4 * 60 * 1000; // 4 minutes.
            connectionInfo.OpenTimeout = 1 * 60 * 1000;
            using (var runSpace = RunspaceFactory.CreateRunspace(connectionInfo))
            {
                var p = runSpace.CreatePipeline();
                runSpace.Open();
                Console.WriteLine("Connected to {0}", targetWsMan);
                Console.WriteLine("As {0}", user);
                Console.Write("Command to run: ");
                var cmd = Console.ReadLine();
                p.Commands.Add(cmd);
                var returnValue = p.Invoke();
                foreach (var v in returnValue)
                    Console.WriteLine(v.ToString());
            }
        }

        Console.WriteLine("End...");
        Console.ReadLine();

我确实添加了对 C:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\System.Management.Automation.dll 的 dll 引用,以防万一它不是您使用的.

I did add a dll reference to C:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\System.Management.Automation.dll just in case its not what you are using.

然后它起作用了.所以我的感觉是这不是你的代码,而是你的凭据,或者目标机器上的远程设置.

And then it worked. So my feeling is that its not your code but either your credentials, or the remote setup on the target machine.