Сетевая аутентификация при запуске exe из WMI - PullRequest
11 голосов
/ 09 марта 2010

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

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

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

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

Я вижу в записи MSDN для Directory.Exists () он заявляет "Метод Exists не выполняет сетевую аутентификацию. Если вы запрашиваете существующий сетевой ресурс без предварительной аутентификации, метод Exists будет вернуть ложь. " Я полагаю, это связано? Как я могу убедиться, что пользователь аутентифицирован правильно в сеансе 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);
}

Ответы [ 4 ]

2 голосов
/ 16 марта 2010

Пройдя по ссылке, предложенной Исаламоном выше (спасибо), я последовал совету Джестро и переписал с помощью 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();
1 голос
/ 23 мая 2012

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

  • Флаг EnablePrivileges
  • установка Олицетворение на ImpersonationLevel.Impersonate

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

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

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


Получает или задает уровень олицетворения COM, который будет использоваться для операций в этом соединении.

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

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

1 голос
/ 15 октября 2010

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

0 голосов
/ 10 мая 2011

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

...