【问题标题】:How do I replace credential parameters in a power-shell script with a PSCredential object?如何用 PSCredential 对象替换 power-shell 脚本中的凭据参数?
【发布时间】:2018-07-09 21:38:09
【问题描述】:

我正在使用 C# 将以下脚本添加到 PowerShell 实例。我想自动执行此操作,那么如何将 -Credential 参数替换为我创建的 PSCredential 对象?另外,我可以为我的 LocalCredential 使用不同的 PSCredential 对象吗?我知道如何创建一个 PSCredential 对象。我只是不知道如何将它插入到我的 ps.AddScript 方法中。

Add-Computer -ComputerName '"+ strMachineName + @"' -LocalCredential '.\Administrator' -DomainName 'MyDomain' -Credential MyDomain\MyUserName -Restart -Force");

我的确切代码:

WSManConnectionInfo connectionInfo = new WSManConnectionInfo();
connectionInfo.ComputerName = strMachineName;

Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo);

PowerShell ps = PowerShell.Create()
ps.AddScript(@"Add-Computer -ComputerName '"+ strMachineName + @"' -LocalCredential '.\Administrator' -DomainName 'MyDomain' -Credential MyDomain\Username -Restart -Force");

ps.Runspace = runspace;

ps.Invoke();

我根据 Mathias R. Jessen 的建议更改了我的代码。我的目标是将同一局域网上的新机器添加到域中。我尝试从 Invoke 方法中捕获 ObjectModelCollection 集合,以查看是否可以通过返回的集合了解任何内容。 调用invoke方法后,收集计数为0,远程机器没有重启。请看我修改后的代码。

修改后的代码

        using (PowerShell ps = PowerShell.Create())
        {
            //secureString for a Domain user on the domain that I want to 
             join the remote PC to
            System.Security.SecureString secureString1 = new 
            NetworkCredential("DomainAdminUserName", DomainPassword").SecurePassword; 

            //secureString for a loca Administrator on the remote machine
            System.Security.SecureString secureString2 = new NetworkCredential("Administrator", "AdminPassword").SecurePassword;

            ps.Runspace = runspace;

            PSCredential localCred = new PSCredential("Administrator", secureString2);
            PSCredential domainCred = new PSCredential("DomainAdminUserName", secureString1); //UNDONE Should not be Greer
            ps.AddCommand("Add-Computer")
              .AddParameter("ComputerName", strMachineName)
              .AddParameter("LocalCredential", localCred)
              .AddParameter("DomainName", "MyDomain")
              .AddParameter("Credential", domainCred)
              .AddParameter("Restart")
              .AddParameter("Force");

            try
            {
                //INVOKE
                System.Collections.ObjectModel.Collection<PSObject> coll = ps.Invoke();
                blnSuccess = true;                    
            }
            catch
            {
                blnSuccess = false;
            }
            finally
            {
                runspace.Close();
            }
            return blnSuccess;

更新

现在一切正常。我被远程 PC 上的防火墙阻止了。我知道在远程机器上禁用防火墙的唯一方法是使用 Sysinternals 的 PSEXEC,如下所示:

        Process p = new Process();
        p.StartInfo.FileName = @"C:\PsExec.exe"; 

        p.StartInfo.UseShellExecute = true;
        p.StartInfo.RedirectStandardOutput = false;     

        p.StartInfo.Arguments = @"\\<REMOTEPCNAME> -u Administrator -p <PASSWORD> netsh firewall set opmode disable";


        p.Start();
        p.WaitForExit();

如果有办法在不使用 PSEXEC 的情况下在 Powershell 中完成此操作,我很想听听。

【问题讨论】:

    标签: c# powershell automation


    【解决方案1】:

    使用AddCommand() 后跟AddParameter() 而不是AddScript()

    PSCredential localCred = ...;
    PSCredential domainCred = ...;
    
    ps.AddCommand("Add-Computer")
      .AddParameter("ComputerName", strMachineName)
      .AddParameter("LocalCredential", localCred)
      .AddParameter("DomainName", "MyDomain")
      .AddParameter("Credential", domainCred)
      .AddParameter("Restart")
      .AddParameter("Force");
    

    【讨论】:

    • 我更改了代码以反映您的建议。我没有收到任何错误,但远程机器没有加入域也没有重新启动。我尝试获取 Invoke 方法的结果以了解更多信息,但集合计数为 0。任何进一步的建议
    • 可能是远程机器上的防火墙。我将尝试通过从代码中调用 PSEXEC 来禁用它。不确定它是否适用于 Server 2012 的实例,但我会试一试(psexec \\ComputerHostname netsh firewall set opmode disable)。
    • 我从我的 C# 程序中调用了 PSEXEC,并用它来禁用远程 PC 上的防火墙。更新了我的帖子,让所有人都知道什么是有效的。
    • @BillGreer 很酷,很高兴你知道了!
    • 现在我要做的就是弄清楚如何在同一个项目中为另一种方法禁用域网络防火墙。我的代码仅禁用专用网络的防火墙。 :)
    【解决方案2】:

    您可能应该使用 AddCommand() 和 AddParameter() 方法而不是 AddScript()。

    然后,您可以在代码中创建一个 PSCredential 对象并将其传递给 AddParameter()。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-04
      • 1970-01-01
      • 2014-12-03
      • 1970-01-01
      • 1970-01-01
      • 2016-01-21
      • 1970-01-01
      • 2018-09-05
      相关资源
      最近更新 更多