You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中以其他用户身份执行PowerShell脚本且避免远程连接?

问题:在C#中以其他用户身份本地执行PowerShell脚本(无需远程连接)

我现在需要在C#里以另一个用户的身份执行PowerShell脚本,当前用默认方式执行的代码是可以正常运行的:

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传入其他用户凭证时,触发了PSRemotingTransportException,提示连接本地服务器失败,但我不想启用远程连接。如果不使用WSManConnectionInfo直接创建Runspace,代码是可以正常运行的:

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; 
    } 
}

请问有没有办法只添加其他用户凭证,在不使用远程连接的情况下执行该脚本?


解决方案:通过独立进程以目标用户身份执行

没问题,我来帮你搞定这个!首先得明确:直接在当前进程的Runspace里切换用户是做不到的——Runspace依赖当前进程的安全上下文,没法直接跨用户。而你之前用的WSManConnectionInfo是专门给远程PowerShell会话用的,所以才会要求启用远程连接,完全不适合本地场景。

正确的思路是启动一个全新的PowerShell进程,用目标用户的凭证来运行,这样既不需要远程连接,又能切换身份。下面是具体的实现代码:

using System.Diagnostics;
using System.Security;
using System.Management.Automation;

public bool ExecutePowerShellAsAnotherUser(string removeUserScript, string gid, string targetUsername, SecureString targetPassword)
{
    // 构建PowerShell执行命令:把脚本和参数整合进去
    string psCommand = $"-Command \"& {{ {removeUserScript} -GID {gid} }}\"";

    // 配置进程启动信息
    ProcessStartInfo startInfo = new ProcessStartInfo
    {
        FileName = "powershell.exe",
        Arguments = psCommand,
        UseShellExecute = false, // 必须设为false才能指定凭证,这是关键
        Credentials = new System.Net.NetworkCredential(targetUsername, targetPassword),
        RedirectStandardOutput = true, // 可选:捕获输出用于调试
        RedirectStandardError = true,  // 可选:捕获错误信息
        CreateNoWindow = true // 可选:不弹出PowerShell窗口
    };

    try
    {
        using (Process psProcess = Process.Start(startInfo))
        {
            // 读取输出和错误(如果需要调试的话)
            string output = psProcess.StandardOutput.ReadToEnd();
            string error = psProcess.StandardError.ReadToEnd();
            
            psProcess.WaitForExit();

            // 如果有错误输出,记录下来
            if (!string.IsNullOrEmpty(error))
            {
                Debug.WriteLine($"PowerShell执行出错: {error}");
                return false;
            }

            // 进程退出码为0表示执行成功
            return psProcess.ExitCode == 0;
        }
    }
    catch (Exception ex)
    {
        Debug.WriteLine($"启动PowerShell进程失败: {ex.StackTrace}");
        return false;
    }
}

关键说明:

  • UseShellExecute = false:这个属性必须设为false,否则无法指定Credentials——这是Windows进程启动的规则,shell启动模式下不支持跨用户凭证。
  • 脚本传递方式:如果你的RemoveUser是外部脚本文件(不是字符串形式的脚本),可以把-Command换成-File,比如$"-File \"C:\\Scripts\\RemoveUser.ps1\" -GID {gid}"。
  • 输出捕获:重定向标准输出和错误可以帮你排查执行过程中的问题,如果你不需要调试,也可以去掉这部分代码。

这种方式完全是本地运行,不需要启用任何PowerShell远程服务,完美符合你的需求!

内容的提问来源于stack exchange,提问作者M. Ozn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:54:21