Мы пытаемся автоматизировать большое количество наших задач обслуживания лазером/обслуживанием, используя комбинацию очередей Azure Service Bus и Azure Worker Roles. Короче говоря, концепция такова:
На практике это работает так, как ожидалось, при работе в среде разработки, однако после публикации рабочей роли удаленное соединение 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 и подтвердил правильность развертывания сертификатов. Кроме того, мне также удалось установить соединение с целевым сервером с помощью команды "winrs -r:", также используя соединение удаленного рабочего стола.
В качестве подтверждения рабочая роль также выполняется с повышенными разрешениями.
Любая помощь с этим будет высоко оценена
заранее спасибо
После многих экспериментов оказалось бы, что команда Runspace.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();
}
Надеюсь, это поможет кому-то еще столкнуться с той же проблемой.