241

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.

1

14 Answers 14

242

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$.

17
  • 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? Commented Feb 14, 2011 at 16:04
  • 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
    Commented Oct 17, 2011 at 9:48
  • 4
    I also see the mapping as unavailable after a reboot. Commented Oct 20, 2011 at 11:19
  • 40
    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 technet.microsoft.com/en-us/library/cc770556.aspx This will run as the SYSTEM account, so no need for psexec.
    – TRS-80
    Commented Apr 20, 2012 at 2:06
  • 4
    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
    Commented Jan 18, 2016 at 10:14
81

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.

9
  • 1
    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
    Commented Dec 20, 2011 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
    Commented Jul 18, 2013 at 7: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
    Commented Sep 25, 2013 at 10:41
  • 5
    Why does it need to be a scheduled task? It is /persistent:yes, isn't that enough to keep it around? Commented Feb 5, 2015 at 18:49
  • 5
    @ScottStafford No /persistent:yes is not enough on Win7 and later. The mapping gets removed after reboot regardless of that switch.
    – Eternal21
    Commented Oct 10, 2017 at 15:11
50

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.

1
  • 2
    Very informative... Am I correct in assuming that logon scripts are also run only for interactive logon sessions and not for service sessions? Commented Oct 8, 2008 at 13:55
48

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.

5
  • 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.). Commented Feb 23, 2012 at 21:51
  • 1
    This is DEFINITELY the better answer to the question, thank you much! Commented Jun 6, 2014 at 14:32
  • 8
    Unfortunately if the sym link accesses a network share then you're back to square one Commented Sep 4, 2017 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
    Commented Jul 17, 2020 at 12:11
  • Could you guys describe in more details what exactly you did ?
    – dBlaze
    Commented Apr 24, 2021 at 22:16
29

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$
2
  • 1
    What if you get after try to create a directory from within the service a permission error?
    – tyoc213
    Commented Dec 8, 2016 at 23:43
  • You should take this off-line into a chat room, and then give details of the error message. You probably need to run the commands with elevated permissions.
    – philu
    Commented Jan 2, 2017 at 1:26
11

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).

3
  • 1
    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? Commented Oct 10, 2008 at 8:51
  • 1
    I think it <disclaim>should</disclaim> - there is only one environment for each winlogon session.
    – Treb
    Commented Oct 10, 2008 at 15:45
  • 1
    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. Commented Mar 6, 2017 at 21:00
7

I find a very simple method: using command "New-SmbGlobalMapping" of powershell, which will mount drive globally:

$User = "usernmae"
$PWord = ConvertTo-SecureString -String "password" -AsPlainText -Force
$creds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $PWord
New-SmbGlobalMapping -RemotePath \\192.168.88.11\shares -Credential $creds -LocalPath S:
6
  • Thanks for New-SmbGlobalMapping :)
    – boomdrak
    Commented May 12, 2022 at 10:24
  • This answer (and i'll spare you the details) helped me out so much - thanks!
    – sommmen
    Commented Sep 8, 2022 at 11:23
  • Can anyone explain how to do this exactly? I don't have any experience with powershell. Is this something you run one time and that's it or does it need to be run every time I reboot?
    – DanCue
    Commented Oct 18, 2022 at 13:08
  • 1
    I figured it out. This worked beautifully. I can't comment for other people/scenarios but this would be my choice for best answer. Simple and effective. One note for others who may use this. In my case the user name required the format COMPUTERNAME\USERNAME.
    – DanCue
    Commented Oct 18, 2022 at 14:48
  • fyi, win server ≤ 2016 missing SmbGlobalMapping support reddit.com/r/PowerShell/comments/w2vhvm/comment/igu18mo/… Commented Dec 1, 2022 at 9:06
6

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.

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.

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 .

1

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.

1
  • 3
    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. Commented Oct 8, 2008 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.

0

I would like to add something to the most accepted answer. In my case I was mounting azure file share, Where i need to provide the credentials to connect. Below is the script I used in a bat file

@echo off
net use z: \\sampleblobstorage.file.core.windows.net\logs /u:sampleblobstorage <storage-account-key> /persistent:yes

Run this .bat file from Task Manager using the run as account SYSTEM

-2

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.

1
  • 3
    This is a REALLY bad example. It's using "del" to delete all files, anyone copy-pasting this might end up having a bad time. Let's try to use non-destructive examples, please.
    – DARKGuy
    Commented Mar 30, 2022 at 3:22

Not the answer you're looking for? Browse other questions tagged or ask your own question.