Authentification réseau lors de l’exécution d’exe à partir de WMI

J’ai un exe C # qui doit être exécuté à l’aide de WMI et accéder à un partage réseau. Cependant, lorsque j’accède au partage, je reçois une exception UnauthorizedAccessException. Si je lance directement l’exe, le partage est accessible. J’utilise le même compte d’utilisateur dans les deux cas.

Mon application comporte deux parties: un client d’interface graphique qui s’exécute sur un PC local et un processus backend qui s’exécute sur un PC distant. Lorsque le client doit se connecter au serveur, il lance d’abord le processus distant à l’aide de WMI (code reproduit ci-dessous). Le processus distant effectue un certain nombre de choses, notamment accéder à un partage réseau à l’aide de Directory.GetDirectories () et en rendre compte au client.

Lorsque le processus distant est lancé automatiquement par le client à l’aide de WMI, il ne peut pas accéder au partage réseau. Cependant, si je me connecte à la machine distante à l’aide de Remote Desktop et que je lance manuellement le processus backend, l’access au partage réseau est réussi.

L’utilisateur spécifié dans l’appel WMI et l’utilisateur connecté pour la session Bureau à distance sont identiques, les permissions doivent donc être identiques, n’est-ce pas?

Je vois dans l’entrée MSDN de Directory.Exists () qu’elle indique “La méthode Exists n’effectue pas l’authentification réseau. Si vous interrogez un partage réseau existant sans être pré-authentifié, la méthode Exists retournera false.” Je suppose que c’est lié? Comment puis-je m’assurer que l’utilisateur est correctement authentifié dans une session WMI?

ConnectionOptions opts = new ConnectionOptions(); opts.Username = username; opts.Password = password; ManagementPath path = new ManagementPath(ssortingng.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); } 

Après avoir suivi le lien suggéré par Isalamon ci-dessus (merci), j’ai suivi les conseils de Jestro et ai réécrit en utilisant psexec.exe (qui peut être téléchargé à partir de http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx ) au lieu de WMI. Cela ressemble un peu à un kludge de le faire de cette façon, mais cela semble fonctionner.

Nouveau code pour toute personne rencontrant des problèmes similaires:

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

WMI utilise uniquement l’emprunt d’identité lors de l’exécution du processus distant, ce qui ne vous donne pas access au réseau. Si vous êtes prêt à sortir du code géré, vous pouvez simplement mapper un chemin UNC dans le processus distant que WMI a démarré à l’aide des informations d’identification souhaitées. Ensuite, vous disposez de l’access réseau souhaité. J’utilise NetUseAdd et NetUseDel de netapi32.dll pour mapper le chemin UNC. Voir http://pinvoke.net/ pour plus de détails sur l’utilisation des API.

Je sais que vous avez sortingé le problème en utilisant PSEXEC, un programme fantastique, mais si vous souhaitez revenir à WMI, avez-vous essayé d’activer les éléments suivants dans vos ConnectionOptions:

  • Le drapeau EnablePrivileges
  • définir l’emprunt d’identité sur ImpersonationLevel.Impersonate

Qui fait ce qui suit:

Obtient ou définit une valeur indiquant si les privilèges de l’utilisateur doivent être activés pour l’opération de connexion. Cette propriété ne doit être utilisée que lorsque l’opération effectuée nécessite l’activation de certains privilèges utilisateur (par exemple, un redémarrage de la machine).

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


Obtient ou définit le niveau d’emprunt d’identité COM à utiliser pour les opérations de cette connexion.

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

Je pense qu’ils devraient dire à votre WMI de permettre au programme de disposer des informations d’identification correctes et d’accéder ainsi à votre partage réseau

Vous pouvez écrire toutes vos commandes dans un fichier de traitement par lots sur la machine distante, ce qui inclut une utilisation du réseau (inutile d’utiliser une lettre de lecteur) pour effectuer une authentification. Fonctionne bien de cette façon. Je travaille toujours sur une alternative.