映射服务要使用的网络驱动器


213

假设某些Windows服务使用的代码需要映射的网络驱动器且没有UNC路径。启动服务后,如何使驱动器映射可用于该服务的会话?以服务用户身份登录并创建持久映射将不会在实际服务的上下文中建立映射。


6
参见ForcePush的答案,他的解决方法起作用。
Ubikuity,2011年

Answers:


44

您要么需要修改服务,要么将其包装在帮助程序中:除了会话/驱动器访问问题之外,持久驱动器映射仅在交互式登录时才能恢复,而服务通常不会执行。

辅助过程的方法可能非常简单:只需创建一个新的服务即可映射驱动器并启动“真实”服务。唯一不完全无关紧要的事情是:

  • 辅助服务将需要将所有适当的SCM命令(启动/停止等)传递给真实服务。如果真实的服务接受自定义的SCM命令,请记住也要传递这些命令(尽管如此,我不希望将UNC路径视为异类的服务使用此类命令)。

  • 事情可能在证书方面有点棘手。如果真实服务在普通用户帐户下运行,则您也可以在该帐户下运行帮助程序服务,只要该帐户具有对网络共享的适当访问权限,一切都应正常。如果真正的服务仅在以LOCALSYSTEM或类似的方式运行时才起作用,那么事情将变得更加有趣,因为它要么根本无法“看到”网络驱动器,要么需要某种凭证处理才能使事情起作用。


2
非常有用……我是否正确假设登录脚本也仅针对交互式登录会话而不是服务会话运行?
VoidPointer

220

使用此方法后果自负。(我已经在XP和Server 2008 x64 R2上对其进行了测试)

对于这种黑客,您将需要Mark Russinovich的SysinternalsSuite

第一步: 打开提升的cmd.exe提示符(以管理员身份运行)

第二步: 使用PSExec.exe再次提升到根目录:导航到包含SysinternalsSuite的文件夹,并执行以下命令, psexec -i -s cmd.exe 您现在位于提示符下,nt authority\system可以通过键入进行证明whoami-i之所以需要,是因为驱动器映射需要与用户互动

第三步: 使用以下命令将永久映射的驱动器创建为SYSTEM帐户 net use z: \\servername\sharedfolder /persistent:yes

就这么简单!

警告:您只能以与创建它相同的方式从SYSTEM帐户中删除此映射。如果需要将其删除,请按照步骤1和2进行操作,但是将步骤3的命令更改为net use z: /delete

注意:现在,该系统的所有用户都将出现新创建的映射驱动器,但他们将看到它显示为“断开的网络驱动器(Z :)”。不要让这个名字愚弄你。它可能声称已断开连接,但适用于所有人。这样您就可以知道M $不支持这种黑客攻击。


3
我试图使用此解决方案并遇到此问题:映射的驱动器显示为与用户(甚至管理员)断开连接。有什么建议?
康斯坦丁·巴丘

7
重新启动后,映射的驱动器不见了。有任何想法吗?映射会保留下来,但状态为“不可用”,因此不会显示
Tommy

4
重新启动后,我也看到该映射不可用。
戴夫·帕特森

33
要使其在重新启动后能够正常工作,请创建一个脚本,仅包含该脚本net use z: \\servername\sharedfolder并将其设置为在计算机启动时运行,每个technet.microsoft.com/en-us/library/cc770556.aspx该脚本将作为SYSTEM帐户运行,因此无需psexec。
TRS-80

2
我想补充一点,每个人都使用该子句很重要/USER:[remotecomp]\[remoteusername] [password](当远程用户名前面没有远程计算机名和反斜杠时,命令有时无法正常工作。此外,如果共享受密码保护,并且对其他人显示为断开连接驱动器,它不是每个人都可以访问的,该系统上任何安装了共享的用户都必须知道该共享的密码(在XPx64上进行了测试)
Kitet 2016年

65

我找到了一种与psexec类似的解决方案,但无需其他工具即可工作,并且在重启后仍然可以幸免

只需添加一个计划任务,在“运行方式”字段中插入“系统”,然后使用简单命令将任务指向批处理文件

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

然后选择“在系统启动时运行”(或类似的程序,我没有英文版本),您就完成了。


什么先开始?Windows服务或此计划任务?如果路径不可用,我们的服务将在启动时终止。如果服务最后启动,我们将不得不重新构建它。
托马斯

1
我在2008 R2上尝试过此操作,它创建了一个断开的映射驱动器,当我尝试打开它时,它说“ z:\无法访问。登录失败:未知的用户名或密码错误”。但是我能够通过手动运行相同的bat文件成功创建映射的驱动器。Ny见解?
Gopi

1
@Thomas它并不重要的开始首先提供任务已至少因为一旦被运行/persistent:yes
埃德

4
为什么它需要排定的任务?是/ persistent:是的,不足以保持它吗?
斯科特·斯塔福德

2
@ScottStafford否/ persistent:是的,在Win7及更高版本上还不够。重新启动后,无论该开关如何,映射都会被删除。
Eternal21 '10 -10-10

44

更好的方法是使用mklink.exe使用符号链接。您可以在任何应用程序都可以使用的文件系统中创建链接。请参阅http://en.wikipedia.org/wiki/NTFS_symbolic_link


非常简单,效果很好。由于它是文件系统的一部分,因此该链接可用于所有帐户。只需确保该服务以可访问网络资源的帐户身份运行(System可能不是这种情况)。
杰里米·弗兰克

1
绝对是这个问题的最佳答案,非常感谢!
Sten Petrov 2014年

3
不幸的是,如果sym链接访问网络共享,那么您将回到第一个位置
davidfrancis

23

这里有一个很好的答案:https : //superuser.com/a/651015/299678

即,您可以使用符号链接,例如

mklink /D C:\myLink \\127.0.0.1\c$

1
如果尝试从服务内部创建目录后出现权限错误怎么办?
tyoc213

您应该将此脱机进入聊天室,然后提供错误消息的详细信息。您可能需要以提升的权限运行命令。
菲乌

@ tyoc213你得到答案了吗?
Lsakurifaisu

9

您可以使用“ net use”命令:

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

如果在服务中不起作用,请尝试Winapi和PInvoke WNetAddConnection2

编辑:显然我误解了您-您无法更改服务的源代码,对吗?在这种情况下,我会遵循mdb的建议,但要稍作改动:创建自己的服务(将其称为映射服务),以对驱动器进行映射,并将此映射服务添加到第一个(实际工作)服务的依赖项中。这样,在映射服务启动(并映射驱动器)之前,工作服务将不会启动。


通过此映射服务设置,我认为由映射服务建立的驱动器映射在原始服务的上下文中将不可用,对吗?
VoidPointer

我认为<disclaim>应该</ disclaim>-每个winlogon会话只有一个环境。
Treb

您的代码在服务中起作用。我来到这里时遇到的问题与OP相同,但我是该服务的作者。您的回答解决了我的问题。
Joe Gayetty

5

ForcePush,

注意:现在将为该系统的所有用户显示新创建的映射驱动器,但他们将看到它显示为“断开的网络驱动器(Z :)”。不要让这个名字愚弄你。它可能声称已断开连接,但适用于所有人。这样您就可以知道M $不支持此黑客...

这完全取决于共享权限。如果您在共享中具有“所有人”权限,则其他用户将可以访问此映射的驱动器。但是,如果您只有某个特定用户,该用户在批处理脚本中使用了其凭据,并且此批处理脚本已添加到启动脚本中,则只有系统帐户将有权访问该共享,甚至管理员也不能。因此,例如,如果您使用计划的ntbackuo作业,则必须在“运行方式”中使用系统帐户。如果您服务的“以以下身份登录:本地系统帐户”,它应该可以工作。

我做了什么,我没有在启动脚本中映射任何驱动器号,只是net use \\\server\share ...在计划的作业中使用和使用了UNC路径。添加了登录脚本(或仅将批处理文件添加到启动文件夹),并映射到具有某些驱动器号的相同共享:net use Z: \\\...具有相同的凭据。现在,已登录的用户可以查看和访问该映射的驱动器。同一共享有2个连接。在这种情况下,用户不会看到烦人的“ Disconnected network drive ...”。但是,如果确实需要通过驱动器号(而不只是UNC)访问该共享,请使用不同的驱动器号映射该共享,例如,“ Y”表示“系统”,“ Z”表示“用户”。


4

找到一种授予Windows服务对网络驱动器访问权限的方法。

以带有NFS磁盘的Windows Server 2012为例:

步骤1:写入要挂载的批处理文件。

编写一个批处理文件,例如: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

步骤2:将磁盘挂载为NT AUTHORITY / SYSTEM。

打开“任务计划程序”,创建一个新任务:

  1. 在“系统启动”中以“系统”运行。
  2. 创建操作:运行“ C:\ mount_nfs.bat”。

经过这两个简单的步骤,我的Windows ActiveMQ服务在“本地系统”权限下运行,无需登录即可完美运行。


3

当您从命令提示符处正常运行可执行文件时,能够访问驱动器的原因是,当您以普通exe身份执行该可执行文件时,您正在从中登录的用户帐户中运行该应用程序。该用户具有访问网络的特权。但是,当您将可执行文件作为服务安装时,默认情况下,如果您在任务管理中看到它在“ SYSTEM”帐户下运行。您可能已经知道'SYSTEM'没有访问网络资源的权限。

这个问题可以有两种解决方案。

  1. 将驱动器映射为如上所述的持久驱动器。

  2. 还有另一种方法可以遵循。如果通过键入“ services.msc”打开服务管理器,则可以转到服务,并且在服务的属性中有一个“登录”选项卡,您可以在其中将帐户指定为“系统”以外的任何其他帐户。从您自己的登录用户帐户或通过“网络服务”启动服务。当您这样做时..服务也可以访问任何网络组件和驱动器,即使它们也不是持久性的。若要以编程方式实现此目的,可以在http://msdn.microsoft.com/zh-cn/library/ms682450(v=vs.85).aspx中查看“ CreateService”功能, 并将参数“ lpServiceStartName”设置为“ NT” AUTHORITY \ NetworkService”。这将在“网络服务”下启动您的服务

  3. 您也可以通过在CreateService()函数的servicetype参数标志中指定SERVICE_INTERACTIVE_PROCESS来使该服务具有交互性,但是只有在XP(由于Vista和7不支持此功能)之前,此服务才受到限制。

希望解决方案对您有所帮助。让我知道这是否对您有用。


1

您既不能从“系统”中更改服务在其下运行的用户,也不会找到一种偷偷摸摸的方式来将您的映射作为系统运行。

有趣的是,通过使用“ at”命令,可以实现此目的,只需将驱动器映射计划在未来一分钟,它将在系统帐户下运行,使驱动器对您的服务可见。


该服务不能作为“系统”运行。它被设置为在特定的本地帐户下运行。即使我使用该帐户登录,创建持久网络映射,注销并重新启动服务,该映射也将无法用于该服务。
VoidPointer

1

您可以将脚本设置为在每次使用时映射/取消映射该驱动器,而不是依赖持久性驱动器:

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

这对我有用。


0

我还无法发表评论(致力于提高声誉),但创建了一个帐户来回答@Tech Jerk @ spankmaster79(好听的名字大声笑)和@NMC问题,他们回答了“我发现了一个与psexec,但无需其他工具即可工作,并且在重启后仍然可以生存。” @拉里发的帖子。

解决方案是只从登录帐户中浏览到该文件夹​​,即:

    \\servername\share  

并提示其登录,然后在psexec中输入用于UNC的相同凭据。之后,它开始工作。就我而言,这是因为具有该服务的服务器与我要映射的服务器不在同一域中。我在想UNC和计划任务是否都引用IP而不是主机名

    \\123.456.789.012\share 

可以完全避免该问题。

如果我在这里获得了足够的代表积分,则将其添加为回复。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.