224

Suppose some Windows service uses code that wants mapped network drives and no UNC paths. How can I make the drive mapping available to the service's session when the service is started? Logging in as the service user and creating a persistent mapping will not establish the mapping in the context of the actual service.

bluish
  • 23,093
  • 23
  • 110
  • 171
VoidPointer
  • 16,811
  • 14
  • 51
  • 58

12 Answers12

227

Use this at your own risk. (I have tested it on XP and Server 2008 x64 R2)

For this hack you will need SysinternalsSuite by Mark Russinovich:

Step one: Open an elevated cmd.exe prompt (Run as administrator)

Step two: Elevate again to root using PSExec.exe: Navigate to the folder containing SysinternalsSuite and execute the following command psexec -i -s cmd.exe you are now inside of a prompt that is nt authority\system and you can prove this by typing whoami. The -i is needed because drive mappings need to interact with the user

Step Three: Create the persistent mapped drive as the SYSTEM account with the following command net use z: \\servername\sharedfolder /persistent:yes

It's that easy!

WARNING: You can only remove this mapping the same way you created it, from the SYSTEM account. If you need to remove it, follow steps 1 and 2 but change the command on step 3 to net use z: /delete.

NOTE: The newly created mapped drive will now appear for ALL users of this system but they will see it displayed as "Disconnected Network Drive (Z:)". Do not let the name fool you. It may claim to be disconnected but it will work for everyone. That's how you can tell this hack is not supported by M$.

bluish
  • 23,093
  • 23
  • 110
  • 171
ForcePush
  • 2,279
  • 2
  • 12
  • 2
  • 3
    I was trying to use this solution and ran into this problem: the mapped drive appears as disconnected to the users (even admins). Any suggestions? – Constantin Baciu Feb 14 '11 at 16:04
  • 1
    Works like a charm! Thanks! Been struggling with this for a while – Tommy Aug 04 '11 at 13:42
  • I have the same problem as Constantin - any ideas how to share for both system and users? – Nik Oct 04 '11 at 13:43
  • 7
    After a reboot the mapped drive is gone. Any ideas?The mapping is persisted, but the status is "Unavailable" so it doesn't show up – Tommy Oct 17 '11 at 09:48
  • 4
    I also see the mapping as unavailable after a reboot. – Dave Patterson Oct 20 '11 at 11:19
  • 36
    To get it working after a reboot, create a script just containing `net use z: \\servername\sharedfolder` and set it to run on computer startup, per http://technet.microsoft.com/en-us/library/cc770556.aspx This will run as the SYSTEM account, so no need for psexec. – TRS-80 Apr 20 '12 at 02:06
  • 1
    Why does ForcePush's solution not work for IIS? On IIS, I mapped /VirtualDirectory to Z: which maps to another machine. But when I tried to browse website/VirtualDirectory, I can't get to the map. If I use command line or explorer, I can see Z: and copy files there. – chuacw Mar 06 '13 at 10:13
  • @TRS-80 Startup scripts run before user login's, to create a mapped drive you have to be logged in. I tried your solution but the mapped drive is unavailable after a reboot. Am i missing something? – Shrage Smilowitz Apr 03 '13 at 03:00
  • 1
    You should update your answer to address this in newer windows hosts (server 2008+). You need to add `/user:username` or it refuses to mount the drive as the system account – dlamotte Jul 10 '13 at 14:58
  • On Windows 7, `/persistent:yes` has apparently no effect and the drive isn't available after reboot. I ended up including `net use z: /delete` and `net use z: \\servername\sharedfolder /user:username password` directly in the batch script. – Calimo Sep 24 '13 at 14:05
  • You can also run this script you created as a part of startup group policy for your computer, http://technet.microsoft.com/en-us/library/cc770556.aspx. This will set the drive up for any user on the system every time the computer starts. – James Eby Jan 12 '15 at 19:51
  • 3
    I want to add that it is important that everyone uses the clause `/USER:[remotecomp]\[remoteusername] [password]` (command does not work properly sometimes when remote user name is not preceeded with remote computer name and a backslash. Also, if the share is password protected, and appears for others as disconnected drive, it is **NOT** accessible for everyone. Any user on that system, where SYSTEM mounts a share must know the password to that share. (tested on XPx64) – Kitet Jan 18 '16 at 10:14
  • This works, I would reccomend using /savecred also so that it will save credentials. This worked great for me mapping NAS drives to an apache server. – mberna Nov 17 '16 at 23:18
  • How can I remove the credentials for this or specify different credentials if I specified savecred the first time? The system credentials do not appear in the control keymgr.dll – mberna Nov 18 '16 at 00:27
  • 1
    For reasons I'm not sure of this has NOT worked for me. It has instead screwed up my boot up and shutdown process to the point I could not log in any more. It took me quiet some effort to undo what is suggested here, because the suggested tool doesn't work in safe mode. Luckily I could apply the revert changes without using the tool (psexec). – AudioDroid Nov 30 '16 at 10:58
  • Do you know the technical reason of why mapped drive is visible to all users? Or it's just a bug? – iPath ツ Feb 14 '17 at 15:57
  • 1
    /persistent:yes has no effect on Windows 10 neither – Tomasz Plonka Mar 20 '19 at 09:48
71

I found a solution that is similar to the one with psexec but works without additional tools and survives a reboot.

Just add a sheduled task, insert "system" in the "run as" field and point the task to a batch file with the simple command

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

Then select "run at system startup" (or similar, I do not have an English version) and you are done.

bluish
  • 23,093
  • 23
  • 110
  • 171
larry
  • 719
  • 5
  • 2
  • what starts first? a windows service or this scheduled task? our service dies at start if the path is unavailable. We'd have to rebuild this if the service starts last. – Thomas Dec 20 '11 at 14:26
  • 2
    I tried this on 2008 R2, it creates a Disconnected Mapped Drive and when I try to open the same it says "z:\ is not accessible. Logon Failure:unknown user name or bad password." But I was able to create mapped drive successfully by running the same bat file manually. Ny insights? – Gopi Jul 18 '13 at 07:32
  • 1
    @Thomas it doesn't matter which starts first providing the task has been run at least once because of the `/persistent:yes` – Edd Sep 25 '13 at 10:41
  • This the only method that worked for me on Windows 8.1. I had to do it to back up my NAS to Crashplan, and the trigger was set to happen when any user logged in. – Jim Hunziker Oct 27 '13 at 01:19
  • @TechJerk did you solve your problem? I'm having the same trouble and can't get it to work – spankmaster79 Jun 20 '14 at 14:31
  • 4
    Why does it need to be a scheduled task? It is /persistent:yes, isn't that enough to keep it around? – Scott Stafford Feb 05 '15 at 18:49
  • @TechJerk Did you ever find a fix for the logon failure ? – NMC May 01 '16 at 22:52
  • This worked well on a Windows laptop running a Windows VM. The Vm maps a drive onto some of the host's disk space, and also wishes to use symbolic link on the VM's C: drive to point to the shared drive and therefore point to the correct place on the host's disk space. The VM needs to access this disk space from a Windows service so I needed this workaround with a scheduled job running as System. Thanks – davidfrancis Sep 04 '17 at 13:35
  • 4
    @ScottStafford No /persistent:yes is not enough on Win7 and later. The mapping gets removed after reboot regardless of that switch. – Eternal21 Oct 10 '17 at 15:11
47

You'll either need to modify the service, or wrap it inside a helper process: apart from session/drive access issues, persistent drive mappings are only restored on an interactive logon, which services typically don't perform.

The helper process approach can be pretty simple: just create a new service that maps the drive and starts the 'real' service. The only things that are not entirely trivial about this are:

  • The helper service will need to pass on all appropriate SCM commands (start/stop, etc.) to the real service. If the real service accepts custom SCM commands, remember to pass those on as well (I don't expect a service that considers UNC paths exotic to use such commands, though...)

  • Things may get a bit tricky credential-wise. If the real service runs under a normal user account, you can run the helper service under that account as well, and all should be OK as long as the account has appropriate access to the network share. If the real service will only work when run as LOCALSYSTEM or somesuch, things get more interesting, as it either won't be able to 'see' the network drive at all, or require some credential juggling to get things to work.

mdb
  • 49,388
  • 10
  • 62
  • 62
  • 2
    Very informative... Am I correct in assuming that logon scripts are also run only for interactive logon sessions and not for service sessions? – VoidPointer Oct 08 '08 at 13:55
46

A better way would be to use a symbolic link using mklink.exe. You can just create a link in the file system that any app can use. See http://en.wikipedia.org/wiki/NTFS_symbolic_link.

Hal
  • 477
  • 4
  • 2
  • So simple and works well. Since it is part of the filesystem, the link is available to all accounts. Just make sure the service is running as an account that has access to the network resource (which might not be the case for System etc.). – Jeremy Frank Feb 23 '12 at 21:51
  • 1
    This is DEFINITELY the better answer to the question, thank you much! – Sten Petrov Jun 06 '14 at 14:32
  • 5
    Unfortunately if the sym link accesses a network share then you're back to square one – davidfrancis Sep 04 '17 at 14:33
  • This is the solution I choose, the symlink being a netwerk share. I had to take care that the service starts using a (network) user that is permitted to follow the symlinks. Once that is covered, this is an ideal solution. – ruud Jul 17 '20 at 12:11
  • Could you guys describe in more details what exactly you did ? – dBlaze Apr 24 '21 at 22:16
26

There is a good answer here: https://superuser.com/a/651015/299678

I.e. You can use a symbolic link, e.g.

mklink /D C:\myLink \\127.0.0.1\c$
Community
  • 1
  • 1
philu
  • 684
  • 1
  • 7
  • 16
9

You could us the 'net use' command:

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

If that does not work in a service, try the Winapi and PInvoke WNetAddConnection2

Edit: Obviously I misunderstood you - you can not change the sourcecode of the service, right? In that case I would follow the suggestion by mdb, but with a little twist: Create your own service (lets call it mapping service) that maps the drive and add this mapping service to the dependencies for the first (the actual working) service. That way the working service will not start before the mapping service has started (and mapped the drive).

Community
  • 1
  • 1
Treb
  • 19,065
  • 6
  • 50
  • 83
  • with this mapping service setup, I think that the drive mapping established by the mapping service wouldn't be available in the context of the original service, would it? – VoidPointer Oct 10 '08 at 08:51
  • I think it should - there is only one environment for each winlogon session. – Treb Oct 10 '08 at 15:45
  • Your code DOES work in a service. I came here with the same issue as the OP but I am the author of the Service. Your answer solved my problem. – Joe Gayetty Mar 06 '17 at 21:00
5

ForcePush,

NOTE: The newly created mapped drive will now appear for ALL users of this system but they will see it displayed as "Disconnected Network Drive (Z:)". Do not let the name fool you. It may claim to be disconnected but it will work for everyone. That's how you can tell this hack is not supported by M$...

It all depends on the share permissions. If you have Everyone in the share permissions, this mapped drive will be accessible by other users. But if you have only some particular user whose credentials you used in your batch script and this batch script was added to the Startup scripts, only System account will have access to that share not even Administrator. So if you use, for example, a scheduled ntbackuo job, System account must be used in 'Run as'. If your service's 'Log on as: Local System account' it should work.

What I did, I didn't map any drive letter in my startup script, just used net use \\\server\share ... and used UNC path in my scheduled jobs. Added a logon script (or just add a batch file to the startup folder) with the mapping to the same share with some drive letter: net use Z: \\\... with the same credentials. Now the logged user can see and access that mapped drive. There are 2 connections to the same share. In this case the user doesn't see that annoying "Disconnected network drive ...". But if you really need access to that share by the drive letter not just UNC, map that share with the different drive letters, e.g. Y for System and Z for users.

bluish
  • 23,093
  • 23
  • 110
  • 171
lk7777
  • 183
  • 3
  • 10
4

Found a way to grant Windows Service access to Network Drive.

Take Windows Server 2012 with NFS Disk for example:

Step 1: Write a Batch File to Mount.

Write a batch file, 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

Step 2: Mount Disk as NT AUTHORITY/SYSTEM.

Open "Task Scheduler", create a new task:

  1. Run as "SYSTEM", at "System Startup".
  2. Create action: Run "C:\mount_nfs.bat".

After these two simple steps, my Windows ActiveMQ Service run under "Local System" priviledge, perform perfectly without login.

Val
  • 17,555
  • 7
  • 57
  • 78
3

The reason why you are able to access the drive in when you normally run the executable from command prompt is that when u are executing it as normal exe you are running that application in the User account from which you have logged on . And that user has the privileges to access the network. But , when you install the executable as a service , by default if you see in the task manage it runs under 'SYSTEM' account . And you might be knowing that the 'SYSTEM' doesn't have rights to access network resources.

There can be two solutions to this problem.

  1. To map the drive as persistent as already pointed above.

  2. There is one more approach that can be followed. If you open the service manager by typing in the 'services.msc'you can go to your service and in the properties of your service there is a logOn tab where you can specify the account as any other account than 'System' you can either start service from your own logged on user account or through 'Network Service'. When you do this .. the service can access any network component and drive even if they are not persistent also. To achieve this programmatically you can look into 'CreateService' function at http://msdn.microsoft.com/en-us/library/ms682450(v=vs.85).aspx and can set the parameter 'lpServiceStartName ' to 'NT AUTHORITY\NetworkService'. This will start your service under 'Network Service' account and then you are done.

  3. You can also try by making the service as interactive by specifying SERVICE_INTERACTIVE_PROCESS in the servicetype parameter flag of your CreateService() function but this will be limited only till XP as Vista and 7 donot support this feature.

Hope the solutions help you.. Let me know if this worked for you .

Andro Selva
  • 51,960
  • 51
  • 189
  • 237
Kushagra
  • 31
  • 1
1

Instead of relying on a persistent drive, you could set the script to map/unmap the drive each time you use it:

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

This works for me.

mwfearnley
  • 2,377
  • 1
  • 27
  • 29
jeff
  • 11
  • 1
0

You wan't to either change the user that the Service runs under from "System" or find a sneaky way to run your mapping as System.

The funny thing is that this is possible by using the "at" command, simply schedule your drive mapping one minute into the future and it will be run under the System account making the drive visible to your service.

Torbjörn Gyllebring
  • 16,878
  • 2
  • 27
  • 22
  • 1
    the service does not run as "System". It is set up to run under a specific local account. Even I log in with that account, create a persistent network mapping, log out and restart the service, the mapping will not be available to the service. – VoidPointer Oct 08 '08 at 13:47
0

I can't comment yet (working on reputation) but created an account just to answer @Tech Jerk @spankmaster79 (nice name lol) and @NMC issues they reported in reply to the "I found a solution that is similar to the one with psexec but works without additional tools and survives a reboot." post @Larry had made.

The solution to this is to just browse to that folder from within the logged in account, ie:

    \\servername\share  

and let it prompt to login, and enter the same credentials you used for the UNC in psexec. After that it starts working. In my case, I think this is because the server with the service isn't a member of the same domain as the server I'm mapping to. I'm thinking if the UNC and the scheduled task both refer to the IP instead of hostname

    \\123.456.789.012\share 

it may avoid the problem altogether.

If I ever get enough rep points on here i'll add this as a reply instead.