【问题标题】:Runspace credentials Powershell运行空间凭据 Powershell
【发布时间】:2018-07-08 05:54:29
【问题描述】:

我有一个 Powershell 脚本,我想通过 C# 作为另一个用户运行。

这是从当前会话调用 ps 脚本的代码:

using (PowerShell PowerShellInstance = PowerShell.Create())
{
    PowerShellInstance.AddScript(RemoveUser);
    PowerShellInstance.AddParameter("GID", GID);
    try
    {
        PowerShellInstance.Invoke();
        return true;
    }
    catch (Exception e)
    {
        Debug.WriteLine(e.StackTrace);
    }
    return false;
}

此代码完美运行。但现在我想以另一个用户的身份执行它。我看到很多代码示例都在谈论 WSManConnectionInfo,所以我尝试了在另一个问题中找到的这段代码:

var password = new SecureString();
Array.ForEach("myStup1dPa$$w0rd".ToCharArray(), password.AppendChar);
PSCredential credential = new PSCredential("anotherUser", password);
WSManConnectionInfo connectionInfo = new WSManConnectionInfo() { Credential = credential };

using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo))
{
    runspace.Open();
    using (PowerShell PowerShellInstance = PowerShell.Create())
    {
        PowerShellInstance.Runspace = runspace;
        PowerShellInstance.AddScript(RemoveUser);
        PowerShellInstance.AddParameter("GID", GID);
        try
        {
            PowerShellInstance.Invoke();
            return true;
        }
        catch (Exception e)
        {
            Debug.WriteLine(e.StackTrace);
        }
        return false;
    }
}

但在我添加 WSManConnectionInfo 的那一刻,我得到一个“PSRemotingTransportException”,说连接到远程服务器 localhost 失败。 这似乎很正常,因为没有任何东西在等待连接到我的本地主机,而且我不想添加一个。当我像这样实现它时,运行空间可以工作:

using (Runspace runspace = RunspaceFactory.CreateRunspace())
{
    runspace.Open();
    using (PowerShell PowerShellInstance = PowerShell.Create())
    {
        PowerShellInstance.Runspace = runspace;
        PowerShellInstance.AddScript(RemoveUser);
        PowerShellInstance.AddParameter("GID", GID);
        try
        {
            PowerShellInstance.Invoke();
            return true;
        }
        catch (Exception e)
        {
            Debug.WriteLine(e.StackTrace);
        }
        return false;
    }
}

似乎没有实现任何远程连接,即使我们在本地主机中。那么我可以为其他用户添加一些凭据来执行此代码并避免远程连接吗?

【问题讨论】:

  • 为什么要以其他用户身份运行它?我经常以另一个用户身份在 PowerShell 中运行命令。这适合你的情况吗?
  • 如果我可以通过 C# 传递以避免提示,则可以。事实上,我们有一个普通的用户帐户和一个具有管理员权限的重复帐户。对于几个 PS 脚本,应用程序必须以管理员用户身份执行,因此需要另一个帐户(例如:普通帐户:12aaa,管理员帐户:12aaa-admin)
  • 您正在运行的 powershell 脚本的内容是什么?整个脚本必须以其他用户身份运行还是只有特定命令?我想知道您是否可以将凭据推送到 powershell 脚本中并将它们传递给相关 cmdlet 的 -Credentials 参数。
  • 它只包含一个 RemoveADUser 命令。在这种情况下,整个脚本可以作为另一个用户运行。例如,我可以在 C# 脚本的开头询问并存储密码并将其传递给我的所有 Powershell 脚本,而无需使用 -Credentials 向用户提示任何内容吗?

标签: c# powershell credentials runspace


【解决方案1】:

您可以使用以下方式将凭证变量存储在 XML 文件中:

$credential = Get-Credential
$credential | Export-Clixml -Path C:\path\to\credential.xml

使用normal account 执行此操作。只有normal account 才能使用以下命令加载凭据:

$credential = Import-Clixml -Path C:\path\to\credential.xml

加载后,您可以像这样执行 Cmdlet

Remove-ADUser -Identity GlenJohn -Credential $credential -Confirm:$false

如果其他用户尝试导入文件,则会显示以下错误:

Import-Clixml : Key not valid for use in specified state.

我建议您观看视频https://www.youtube.com/watch?v=Ta2hQHVKauo,它将让您深入了解存储凭据。

韩语 冈瑟

【讨论】:

  • 感谢您的回答。我可以在 C# 脚本的开头请求它而不是 xml 文件,然后通过 param 将它传递给我的 Powershell 脚本吗?原因是这个应用程序会有很多不同的用户,所以我更喜欢在使用开始时询问密码,而不是将其存储在应用程序之外。第二个原因是我们的密码必须每月更改一次,因此不必将其存储在应用程序之外
  • 如果您在脚本中运行$credential = Get-Credential,系统将提示用户输入它们。无需在 C# 中询问它们并将它们传递给 PowerShell 恕我直言。
  • 问题是我的 C# 调用多次多次不同的 Powershell 脚本。如果用户只输入一次密码而不是每次调用 ps 脚本时都提示重新输入密码会更好
猜你喜欢
  • 2010-11-14
  • 2015-11-17
  • 2013-07-08
  • 2012-07-29
  • 2015-06-29
  • 1970-01-01
  • 1970-01-01
  • 2015-03-31
  • 1970-01-01
相关资源
最近更新 更多