Аутентификация сети при запуске exe из WMI

У меня есть С# exe, который нужно запустить с помощью WMI и получить доступ к сетевому ресурсу. Однако, когда я получаю доступ к ресурсу, я получаю UnauthorizedAccessException. Если я запускаю exe напрямую, доступ к нему доступен. Я использую одну и ту же учетную запись пользователя в обоих случаях.

В моем приложении есть две части: клиент GUI, который работает на локальном ПК и бэкэнд-процесс, который работает на удаленном ПК. Когда клиент должен подключиться к бэкэнд, он сначала запускает удаленный процесс с использованием WMI (код воспроизводится ниже). Удаленный процесс выполняет ряд действий, включая доступ к сетевому ресурсу с помощью Directory.GetDirectories() и отчёт для клиента.

Когда удаленный процесс запускается автоматически клиентом с использованием WMI, он не может получить доступ к сетевому ресурсу. Однако, если я подключаюсь к удаленному компьютеру с помощью удаленного рабочего стола и запускаю серверный процесс вручную, доступ к сетевому ресурсу успешно завершается.

Пользователь, указанный в вызове WMI, и пользователь, зарегистрированный для сеанса удаленного рабочего стола, одинаковый, поэтому разрешения должны быть одинаковыми, не так ли?

В записи MSDN для Directory.Exists() указано, что "метод Exists не выполняет сетевую проверку подлинности. Если вы запрашиваете существующий сетевой ресурс без предварительной аутентификации, метод Exists возвращает false." Я полагаю, это связано? Как я могу гарантировать правильность аутентификации пользователя на сеансе WMI?

ConnectionOptions opts = new ConnectionOptions();

opts.Username = username;
opts.Password = password;

ManagementPath path = new ManagementPath(string.Format("\\\\{0}\\root\\cimv2:Win32_Process", remoteHost));

ManagementScope scope = new ManagementScope(path, opts);

scope.Connect();

ObjectGetOptions getOpts = new ObjectGetOptions();
using (ManagementClass mngClass = new ManagementClass(scope, path, getOpts))
{
    ManagementBaseObject inParams = mngClass.GetMethodParameters("Create");
    inParams["CommandLine"] = commandLine;
    ManagementBaseObject outParams = mngClass.InvokeMethod("Create", inParams, null);
}

Ответ 1

Следуя ссылке, предложенной Исаламоном выше (спасибо), я пошел за советом Jestro и переписал с помощью psexec.exe(который можно скачать из http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx) вместо WMI. Похоже, что это так много, но это похоже на работу.

Новый код для тех, кто испытывает подобные проблемы:

Process proc = new Process();
proc.StartInfo.FileName = "PsExec.exe";
proc.StartInfo.Arguments = string.Format("\\\\{0} -d -u {1}\\{2} -p {3} {4}",
                                         remoteHost,
                                         domain,
                                         username,
                                         password,
                                         commandLine);
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.UseShellExecute = false;
proc.Start();

Ответ 2

WMI использует олицетворение при выполнении удаленного процесса, что не дает вам доступа к сети. Если вы согласны выйти за пределы управляемого кода, вы можете просто наметить путь UNC в удаленном процессе. WMI начал использовать любые учетные данные, которые вы хотите. Затем у вас есть доступ к сети, который вы хотите. Я использую NetUseAdd и NetUseDel из netapi32.dll для сопоставления пути UNC. Подробнее об использовании API-интерфейсов см. http://pinvoke.net/.

Ответ 3

Я знаю, что вы отсортировали его, используя PSEXEC, что является фантастической программой, но если вы хотите вернуться к WMI, попробуйте ли вы включить следующее в ConnectionOptions:

  • Флаг EnablePrivileges
  • настройка олицетворения для олицетворения уровня личности .Impersonate

Что делает следующее:

http://msdn.microsoft.com/en-us/library/system.management.connectionoptions.impersonation.aspx

http://msdn.microsoft.com/en-us/library/system.management.connectionoptions.enableprivileges.aspx

Я думаю, что они должны сообщить вашему WMI, чтобы на самом деле разрешить программе иметь правильные учетные данные и, таким образом, получить доступ к вашему сетевому ресурсу

Ответ 4

Вы можете написать все свои команды для пакетного файла на удаленный компьютер, который включает использование сети (без необходимости использовать букву диска) для аутентификации. Отлично работает. Я все еще работаю над альтернативой.