C# 从Azure Worker角色建立WSManConnection

C# 从Azure Worker角色建立WSManConnection,c#,powershell,azure,azure-worker-roles,wsman,C#,Powershell,Azure,Azure Worker Roles,Wsman,我们正尝试使用azure服务总线队列和azure工作者角色的组合来自动化大量azure/服务维护任务。简言之,概念如下 维护任务已发布到SB队列 工作者角色侦听SB队列上的任务 工作角色连接到所需的VM/Web角色/云服务,并执行远程powershell命令 在实践中,在开发环境中操作时,这与预期一样有效,但是在发布工作角色后,远程powershell连接失败,响应访问被拒绝。建立连接的代码如下所示 PSCredential cred = new PSCredential(config.User

我们正尝试使用azure服务总线队列和azure工作者角色的组合来自动化大量azure/服务维护任务。简言之,概念如下

维护任务已发布到SB队列 工作者角色侦听SB队列上的任务 工作角色连接到所需的VM/Web角色/云服务,并执行远程powershell命令 在实践中,在开发环境中操作时,这与预期一样有效,但是在发布工作角色后,远程powershell连接失败,响应访问被拒绝。建立连接的代码如下所示

PSCredential cred = new PSCredential(config.Username, config.PrimaryPassword);
WSManConnectionInfo connection = new WSManConnectionInfo(true, config.PrimaryServer, 5986, "/wsman", "http://schemas.microsoft.com/powershell/Microsoft.PowerShell", cred);

using (Runspace runspace = RunspaceFactory.CreateRunspace(connection))
{
    runspace.Open();
    using (PowerShell shell = PowerShell.Create())
    {
        shell.Runspace = runspace;
        // DO SOMETHING HERE
        shell.Invoke();
    }
    runspace.Close();
}
起初,我怀疑这是CA证书问题,但后来我通过RDP连接到worker角色,并确认证书已正确部署。此外,我还使用远程桌面连接,通过winrs-r:命令实现了与目标服务器的连接

作为确认,辅助角色也正在使用提升的权限运行

在此方面的任何帮助都将不胜感激


提前感谢

经过大量实验后,运行空间.Open命令似乎需要在具有管理权限的帐户下运行,但运行具有提升权限的工作者角色无法实现这一点,因此为了解决此问题,我执行了以下操作

使用角色上的启动任务,我使用以下命令创建了一个帐户

net user roleusername rolepassword /add
net localgroup Administrators roleusername /add
exit /B 0
然后,我用以下代码模拟该用户,以确保该角色作为新创建的本地管理员帐户运行

[DllImport("advapi32.DLL", SetLastError = true)]
public static extern int LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);

[DllImport("advapi32.DLL")]
public static extern bool ImpersonateLoggedOnUser(IntPtr hToken);  

[DllImport("advapi32.DLL")]
public static extern bool RevertToSelf();

public static object Impersonate(string username, string password)
{
    string domainname = ".";
    if (username.Contains(@"\"))
    {
        domainname = username.Substring(0, username.IndexOf(@"\"));
        username = username.Substring(username.IndexOf(@"\") + 1);
    }

    IntPtr securityToken;

    LogonUser(username, domainname, password, 9, 0, out securityToken);
    if (securityToken != IntPtr.Zero)
    {
        var newIdentity = new WindowsIdentity(securityToken);
        WindowsImpersonationContext impersonationContext = newIdentity.Impersonate();

        return impersonationContext;
    }

    throw new InvalidOperationException("The username or password combination was invalid, please verify your settings");
}

public static void UndoImpersonation(object impersonationContext)
{
    var context = impersonationContext as WindowsImpersonationContext;
    if (context != null) context.Undo();
}
我希望这能帮助其他遇到同样问题的人