代码之家  ›  专栏  ›  技术社区  ›  Bill Greer

如何用PSCredential对象替换power shell脚本中的凭据参数?

  •  0
  • Bill Greer  · 技术社区  · 8 年前

    我正在使用C#将以下脚本添加到PowerShell实例。我想自动执行此操作,因此如何用我创建的PSCredential对象替换-Credential参数?此外,我可以为我的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();
    

    如果有一种方法可以在Powershell中实现这一点,而不必使用PSEXEC,我很想听听它。

    2 回复  |  直到 8 年前
        1
  •  1
  •   Mathias R. Jessen    8 年前

    使用 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");
    
        2
  •  1
  •   Mike Shepard    8 年前

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

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

    推荐文章