简体   繁体   English

从Azure Worker角色建立WSManConnection

[英]Establish WSManConnection from Azure Worker Role

We are attempting to automate a large number of our azure/service maintenance tasks using a combination of Azure Service Bus queues and Azure Worker Roles. 我们正在尝试使用Azure Service Bus队列和Azure Worker角色的组合来自动化大量的Azure /服务维护任务。 In short, the concept is as follows.... 简而言之,概念如下。

  1. Maintenance task is posted to SB Queue 维护任务已过帐到SB Queue
  2. Worker role listens for tasks on the SB Queue 辅助角色侦听SB队列上的任务
  3. Worker role connects to desired VM/Web Role/Cloud service and executes a remote powershell command 辅助角色连接到所需的VM / Web角色/云服务并执行远程Powershell命令

In practice, this works as expected when operating within a development environment, however after the worker role is published, the remote powershell connection fails with the response "Access is denied". 实际上,这在开发环境中操作时可以按预期工作,但是在发布辅助角色后,远程Powershell连接将失败,并显示响应“拒绝访问”。 The code to establish the connection is as follows... 建立连接的代码如下...

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

Initially, I had suspected that this was a CA certificate issue, however I have since connected to the worker role via RDP and confirmed that the certificates are being deployed correctly. 最初,我怀疑这是CA证书问题,但是此后我已通过RDP连接到辅助角色,并确认证书已正确部署。 In addition I have also managed to acheive a connection to the target server via a "winrs -r:" command also using the remote desktop connection. 另外,我还设法使用远程桌面连接通过“ winrs -r:”命令实现了到目标服务器的连接。

As confirmation, the worker role is also running with elevated permissions. 作为确认,辅助角色也正在以提升的权限运行。

Any help with this would be much appreciated 任何帮助,将不胜感激

Thanks in advance 提前致谢

After lots of experimentation, it would appear that the Runspace.Open() command needs to run under an account with administrative access (running the worker role with elevated permissions doesn't achieve this), therefore in order to resolve the issue, I did the following... 经过大量实验,似乎Runspace.Open()命令需要在具有管理访问权限的帐户下运行(以提升的权限运行worker角色无法实现这一点),因此为了解决此问题,我做了下列...

Using a startup task on the role, I created an account using the following command... 使用角色上的启动任务,我使用以下命令创建了一个帐户...

net user roleusername rolepassword /add
net localgroup Administrators roleusername /add
exit /B 0

I then impersonated the user with the following code, to ensure the role was running as the newly created local administrator account. 然后,我用以下代码模拟了用户,以确保该角色作为新创建的本地管理员帐户运行。

[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();
}

I hope this helps anybody else running into the same problem. 我希望这可以帮助其他遇到相同问题的人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM