Mapper un lecteur réseau à utiliser par un service

213

Supposons que certains services Windows utilisent du code qui souhaite des lecteurs réseau mappés et aucun chemin UNC. Comment puis-je rendre le mappage de lecteur disponible pour la session du service lorsque le service est démarré? La connexion en tant qu'utilisateur du service et la création d'un mappage persistant n'établira pas le mappage dans le contexte du service réel.

VoidPointer
la source
6
Voir la réponse de ForcePush, sa solution de contournement fonctionne.
Ubikuity

Réponses:

44

Vous devrez soit modifier le service, soit l'envelopper dans un processus d'assistance: à part les problèmes d'accès aux sessions / lecteurs, les mappages de lecteurs persistants ne sont restaurés que lors d'une connexion interactive, ce que les services n'effectuent généralement pas.

L'approche du processus d'assistance peut être assez simple: il suffit de créer un nouveau service qui mappe le lecteur et démarre le «vrai» service. Les seules choses qui ne sont pas entièrement triviales à ce sujet sont:

  • Le service d'assistance devra transmettre toutes les commandes SCM appropriées (démarrage / arrêt, etc.) au service réel. Si le vrai service accepte les commandes SCM personnalisées, n'oubliez pas de les transmettre également (je ne m'attends pas à ce qu'un service qui considère les chemins UNC exotiques utilise de telles commandes, cependant ...)

  • Les choses peuvent devenir un peu délicates au niveau des informations d'identification. Si le service réel s'exécute sous un compte d'utilisateur normal, vous pouvez également exécuter le service d'assistance sous ce compte, et tout devrait être OK tant que le compte dispose d'un accès approprié au partage réseau. Si le vrai service ne fonctionne que lorsqu'il est exécuté en tant que LOCALSYSTEM ou quelque chose du genre, les choses deviennent plus intéressantes, car il ne pourra pas du tout `` voir '' le lecteur réseau ou nécessitera un jonglage d'informations d'identification pour que les choses fonctionnent.

mdb
la source
2
Très informatif ... Ai-je raison de supposer que les scripts d'ouverture de session sont également exécutés uniquement pour les sessions d'ouverture de session interactives et non pour les sessions de service?
VoidPointer
220

Utilisez-le à vos risques et périls. (Je l'ai testé sur XP et Server 2008 x64 R2)

Pour ce hack, vous aurez besoin de SysinternalsSuite de Mark Russinovich :

Étape 1: Ouvrez une invite cmd.exe élevée (Exécuter en tant qu'administrateur)

Deuxième étape: élever à nouveau à la racine à l'aide de PSExec.exe: accédez au dossier contenant SysinternalsSuite et exécutez la commande suivante, psexec -i -s cmd.exe vous êtes maintenant à l'intérieur d'une invite qui est nt authority\systemet vous pouvez le prouver en tapant whoami. Le -iest nécessaire parce que les correspondances d'entraînement doivent interagir avec l'utilisateur

Étape 3: créer le lecteur mappé persistant en tant que compte SYSTEM avec la commande suivante net use z: \\servername\sharedfolder /persistent:yes

C'est si facile!

AVERTISSEMENT : vous ne pouvez supprimer ce mappage que de la même manière que vous l'avez créé, à partir du compte SYSTEM. Si vous devez le supprimer, suivez les étapes 1 et 2 mais remplacez la commande de l'étape 3 par net use z: /delete.

REMARQUE : Le lecteur mappé nouvellement créé apparaîtra maintenant pour TOUS les utilisateurs de ce système, mais ils le verront affiché comme "Lecteur réseau déconnecté (Z :)". Ne laissez pas le nom vous tromper. Il peut prétendre être déconnecté, mais cela fonctionnera pour tout le monde. Voilà comment vous pouvez dire que ce hack n'est pas pris en charge par M $.

ForcePush
la source
3
J'essayais d'utiliser cette solution et suis tombé sur ce problème: le lecteur mappé apparaît comme déconnecté des utilisateurs (même des administrateurs). Aucune suggestion?
Constantin Baciu
7
Après un redémarrage, le lecteur mappé a disparu. Des idées? Le mappage est persistant, mais le statut est "Non disponible" donc il n'apparaît pas
Tommy
4
Je vois également le mappage comme indisponible après un redémarrage.
Dave Patterson
33
Pour le faire fonctionner après un redémarrage, créez un script contenant simplement net use z: \\servername\sharedfolderet configurez-le pour qu'il s'exécute au démarrage de l'ordinateur, par technet.microsoft.com/en-us/library/cc770556.aspx Cela s'exécutera en tant que compte SYSTEM, donc pas besoin de psexec.
TRS-80
2
Je veux ajouter qu'il est important que tout le monde utilise la clause /USER:[remotecomp]\[remoteusername] [password](la commande ne fonctionne pas correctement parfois lorsque le nom d'utilisateur distant n'est pas précédé du nom de l'ordinateur distant et d'une barre oblique inverse. De plus, si le partage est protégé par mot de passe et apparaît pour les autres comme déconnecté lecteur, il n'est PAS accessible à tout le monde. Tout utilisateur de ce système, où SYSTEM monte un partage doit connaître le mot de passe de ce partage. (testé sur XPx64)
Kitet
65

J'ai trouvé une solution similaire à celle avec psexec mais fonctionne sans outils supplémentaires et survit à un redémarrage .

Ajoutez simplement une tâche planifiée, insérez "système" dans le champ "exécuter en tant que" et pointez la tâche vers un fichier de commandes avec la commande simple

net use z: \servername\sharedfolder /persistent:yes

Sélectionnez ensuite "exécuter au démarrage du système" (ou similaire, je n'ai pas de version anglaise) et vous avez terminé.

larry
la source
qu'est-ce qui commence en premier? un service Windows ou cette tâche planifiée? notre service s'éteint au démarrage si le chemin n'est pas disponible. Nous devons reconstruire cela si le service démarre en dernier.
Thomas
1
J'ai essayé cela sur 2008 R2, il crée un lecteur mappé déconnecté et lorsque j'essaye d'ouvrir le même, il dit "z: \ n'est pas accessible. Échec de la connexion: nom d'utilisateur inconnu ou mauvais mot de passe." Mais j'ai réussi à créer un lecteur mappé avec succès en exécutant le même fichier bat manuellement. Ny aperçus?
Gopi
1
@Thomas peu importe qui commence en premier à condition que la tâche ait été exécutée au moins une fois à cause du/persistent:yes
Edd
4
Pourquoi faut-il que ce soit une tâche planifiée? Il est / persistant: oui, n'est-ce pas suffisant pour le garder?
Scott Stafford
2
@ScottStafford Non / persistant: oui ne suffit pas sur Win7 et versions ultérieures. Le mappage est supprimé après le redémarrage, quel que soit ce commutateur.
Eternal21
44

Une meilleure façon serait d'utiliser un lien symbolique à l'aide de mklink.exe. Vous pouvez simplement créer un lien dans le système de fichiers que n'importe quelle application peut utiliser. Voir http://en.wikipedia.org/wiki/NTFS_symbolic_link .

Hal
la source
Si simple et fonctionne bien. Comme il fait partie du système de fichiers, le lien est disponible pour tous les comptes. Assurez-vous simplement que le service s'exécute en tant que compte ayant accès à la ressource réseau (ce qui pourrait ne pas être le cas pour le système, etc.).
Jeremy Frank
1
C'est définitivement la meilleure réponse à la question, merci beaucoup!
Sten Petrov
3
Malheureusement, si le lien sym accède à un partage réseau, vous êtes de retour à la case départ
davidfrancis
23

Il y a une bonne réponse ici: https://superuser.com/a/651015/299678

C'est-à-dire que vous pouvez utiliser un lien symbolique, par exemple

mklink /D C:\myLink \\127.0.0.1\c$
philu
la source
1
Que faire si vous obtenez après une tentative de création d'un répertoire à partir du service une erreur d'autorisation?
tyoc213
Vous devez mettre cela hors ligne dans une salle de discussion, puis donner des détails sur le message d'erreur. Vous devrez probablement exécuter les commandes avec des autorisations élevées.
philu
@ tyoc213 Avez-vous obtenu une réponse?
Lsakurifaisu
9

Vous pouvez nous utiliser la commande 'net use':

var p = System.Diagnostics.Process.Start("net.exe", "use K: \\\\Server\\path");
var isCompleted = p.WaitForExit(5000);

Si cela ne fonctionne pas dans un service, essayez Winapi et PInvoke WNetAddConnection2

Edit: Évidemment, je vous ai mal compris - vous ne pouvez pas changer le code source du service, non? Dans ce cas, je suivrais la suggestion de mdb , mais avec une petite torsion: créez votre propre service (appelons-le service de mappage) qui mappe le lecteur et ajoutez ce service de mappage aux dépendances du premier service (le travail réel). De cette façon, le service de travail ne démarre pas avant le démarrage du service de mappage (et le mappage du lecteur).

Treb
la source
avec cette configuration de service de mappage, je pense que le mappage de lecteur établi par le service de mappage ne serait pas disponible dans le contexte du service d'origine, n'est-ce pas?
VoidPointer
Je pense qu'il <disclaim> devrait </disclaim> - il n'y a qu'un seul environnement pour chaque session winlogon.
Treb
Votre code fonctionne dans un service. Je suis venu ici avec le même problème que le PO mais je suis l'auteur du service. Votre réponse a résolu mon problème.
Joe Gayetty
5

ForcePush,

REMARQUE : Le lecteur mappé nouvellement créé apparaîtra maintenant pour TOUS les utilisateurs de ce système, mais ils le verront affiché comme "Lecteur réseau déconnecté (Z :)". Ne laissez pas le nom vous tromper. Il peut prétendre être déconnecté, mais cela fonctionnera pour tout le monde. Voilà comment vous pouvez dire que ce hack n'est pas pris en charge par M $ ...

Tout dépend des autorisations de partage. Si vous avez Tout le monde dans les autorisations de partage, ce lecteur mappé sera accessible par d'autres utilisateurs. Mais si vous n'avez qu'un utilisateur particulier dont vous avez utilisé les informations d'identification dans votre script de commandes et que ce script de commandes a été ajouté aux scripts de démarrage, seul le compte système aura accès à ce partage, pas même l'administrateur. Ainsi, si vous utilisez, par exemple, un travail ntbackuo planifié, le compte système doit être utilisé dans «Exécuter en tant que». Si «Ouvrir une session en tant que: compte système local» de votre service, cela devrait fonctionner.

Ce que j'ai fait , je n'ai mappé aucune lettre de lecteur dans mon script de démarrage, j'ai simplement utilisé net use \\\server\share ...et utilisé le chemin UNC dans mes travaux planifiés. Ajout d'un script d'ouverture de session (ou tout simplement ajouter un fichier de commandes dans le dossier de démarrage) avec le mappage sur le même partage avec une lettre de lecteur: net use Z: \\\...avec les mêmes informations d'identification. L'utilisateur connecté peut maintenant voir et accéder à ce lecteur mappé. Il y a 2 connexions au même partage. Dans ce cas, l'utilisateur ne voit pas ce "lecteur réseau déconnecté ..." ennuyeux. Mais si vous avez vraiment besoin d'accéder à ce partage par la lettre de lecteur et pas seulement UNC, mappez ce partage avec les différentes lettres de lecteur, par exemple Y pour System et Z pour les utilisateurs.

lk7777
la source
4

Trouvé un moyen d'accorder l'accès du service Windows au lecteur réseau.

Prenez Windows Server 2012 avec NFS Disk par exemple:

Étape 1: écrire un fichier de commandes à monter.

Écrivez un fichier batch, ex: C: \ mount_nfs.bat

echo %time% >> c:\mount_nfs_log.txt
net use Z: \\{your ip}\{netdisk folder}\ >> C:\mount_nfs_log.txt 2>&1

Étape 2: Montez le disque en tant qu'AUTORITÉ / SYSTÈME NT.

Ouvrez le "Planificateur de tâches", créez une nouvelle tâche:

  1. Exécutez en tant que "SYSTEM", à "System Startup".
  2. Créer une action: exécutez "C: \ mount_nfs.bat".

Après ces deux étapes simples, mon service Windows ActiveMQ s'exécute sous le privilège "Système local", fonctionne parfaitement sans connexion.

Val
la source
3

La raison pour laquelle vous pouvez accéder au lecteur lorsque vous exécutez normalement l'exécutable à partir de l'invite de commande est que lorsque vous l'exécutez en tant qu'exe normal, vous exécutez cette application dans le compte utilisateur à partir duquel vous vous êtes connecté. Et cet utilisateur a les privilèges d'accéder au réseau. Mais, lorsque vous installez l'exécutable en tant que service, par défaut si vous voyez dans la tâche gérer il s'exécute sous le compte 'SYSTEM'. Et vous savez peut-être que le «SYSTÈME» n'a pas le droit d'accéder aux ressources réseau.

Il peut y avoir deux solutions à ce problème.

  1. Pour mapper le lecteur aussi persistant que déjà indiqué ci-dessus.

  2. Il existe une autre approche qui peut être suivie. Si vous ouvrez le gestionnaire de services en tapant «services.msc», vous pouvez accéder à votre service et dans les propriétés de votre service, il y a un onglet de connexion où vous pouvez spécifier le compte comme n'importe quel autre compte que «Système», vous pouvez soit démarrer le service à partir de votre propre compte utilisateur connecté ou via «Service réseau». Lorsque vous faites cela .. le service peut accéder à n'importe quel composant réseau et conduire même s'ils ne sont pas persistants également. Pour y parvenir par programme, vous pouvez examiner la fonction «CreateService» à l' adresse http://msdn.microsoft.com/en-us/library/ms682450(v=vs.85).aspx et définir le paramètre «lpServiceStartName» sur «NT AUTHORITY \ NetworkService '. Cela démarrera votre service sous «Service réseau»

  3. Vous pouvez également essayer de rendre le service aussi interactif en spécifiant SERVICE_INTERACTIVE_PROCESS dans l'indicateur de paramètre servicetype de votre fonction CreateService (), mais cela ne sera limité que jusqu'à ce que XP comme Vista et 7 ne prennent pas en charge cette fonctionnalité.

J'espère que les solutions vous aideront. Faites-moi savoir si cela a fonctionné pour vous.

Kushagra
la source
1

Vous ne devez pas changer l'utilisateur sous lequel le service est exécuté à partir de "Système" ou trouver un moyen sournois pour exécuter votre mappage en tant que système.

Ce qui est amusant, c'est que cela est possible en utilisant la commande "at" , il suffit de planifier le mappage de votre lecteur dans une minute dans le futur et il sera exécuté sous le compte système, rendant le lecteur visible pour votre service.

Torbjörn Gyllebring
la source
le service ne s'exécute pas en tant que "Système". Il est configuré pour s'exécuter sous un compte local spécifique. Même si je me connecte avec ce compte, crée un mappage réseau persistant, me déconnecte et redémarre le service, le mappage ne sera pas disponible pour le service.
VoidPointer
1

Au lieu de compter sur un lecteur persistant, vous pouvez définir le script pour mapper / démapper le lecteur chaque fois que vous l'utilisez:

net use Q: \\share.domain.com\share 
forfiles /p Q:\myfolder /s /m *.txt /d -0 /c "cmd /c del @path"
net use Q: /delete

Cela fonctionne pour moi.

Jeff
la source
0

Je ne peux pas encore commenter (travaillant sur la réputation), mais j'ai créé un compte juste pour répondre à @Tech Jerk @ spankmaster79 (joli nom lol) et aux problèmes @NMC qu'ils ont signalés en réponse au message "J'ai trouvé une solution similaire à celle avec psexec mais fonctionne sans outils supplémentaires et survit à un redémarrage. " post @Larry avait fait.

La solution à cela est de simplement parcourir ce dossier à partir du compte connecté, c'est-à-dire:

    \\servername\share  

et laissez-le vous inviter à vous connecter, et entrez les mêmes informations d'identification que vous avez utilisées pour l'UNC dans psexec. Après cela, il commence à fonctionner. Dans mon cas, je pense que c'est parce que le serveur avec le service n'est pas membre du même domaine que le serveur auquel je mappe. Je pense que si l'UNC et la tâche planifiée font référence à l'IP au lieu du nom d'hôte

    \\123.456.789.012\share 

cela peut éviter complètement le problème.

Si jamais j'obtiens suffisamment de points de répétition ici, j'ajouterai cela comme réponse à la place.

CanadaDave
la source