从 Azure 辅助角色建立 WSManConnection
Establish WSManConnection from Azure Worker Role
我们正在尝试使用 Azure 服务总线队列和 Azure 辅助角色的组合来自动执行大量 azure/service 维护任务。简而言之,概念如下....
- 维护任务已发布到 SB 队列
- 工作者角色侦听 SB 队列上的任务
- 工作者角色连接到所需的 VM/Web Role/Cloud 服务并执行远程 powershell 命令
实际上,这在开发环境中运行时按预期工作,但是在发布辅助角色后,远程 powershell 连接失败并响应 "Access is denied"。建立连接的代码如下...
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 连接到工作者角色并确认证书部署正确。此外,我还设法通过 "winrs -r:" 命令也使用远程桌面连接实现了与目标服务器的连接。
作为确认,工作者角色也是 运行 提升的权限。
如有任何帮助,我们将不胜感激
提前致谢
经过大量实验,Runspace.Open() 命令似乎需要 运行 在具有管理访问权限的帐户下(运行使用提升权限的工作者角色无法实现此目的),因此为了解决该问题,我执行了以下操作...
在角色上使用启动任务,我使用以下命令创建了一个帐户...
net user roleusername rolepassword /add
net localgroup Administrators roleusername /add
exit /B 0
然后我使用以下代码模拟用户,以确保角色 运行ning 作为新创建的本地管理员帐户。
[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();
}
我希望这可以帮助 运行遇到同样问题的其他人。
我们正在尝试使用 Azure 服务总线队列和 Azure 辅助角色的组合来自动执行大量 azure/service 维护任务。简而言之,概念如下....
- 维护任务已发布到 SB 队列
- 工作者角色侦听 SB 队列上的任务
- 工作者角色连接到所需的 VM/Web Role/Cloud 服务并执行远程 powershell 命令
实际上,这在开发环境中运行时按预期工作,但是在发布辅助角色后,远程 powershell 连接失败并响应 "Access is denied"。建立连接的代码如下...
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 连接到工作者角色并确认证书部署正确。此外,我还设法通过 "winrs -r:" 命令也使用远程桌面连接实现了与目标服务器的连接。
作为确认,工作者角色也是 运行 提升的权限。
如有任何帮助,我们将不胜感激
提前致谢
经过大量实验,Runspace.Open() 命令似乎需要 运行 在具有管理访问权限的帐户下(运行使用提升权限的工作者角色无法实现此目的),因此为了解决该问题,我执行了以下操作...
在角色上使用启动任务,我使用以下命令创建了一个帐户...
net user roleusername rolepassword /add
net localgroup Administrators roleusername /add
exit /B 0
然后我使用以下代码模拟用户,以确保角色 运行ning 作为新创建的本地管理员帐户。
[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();
}
我希望这可以帮助 运行遇到同样问题的其他人。