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

问题描述 投票:201回答:12

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

windows windows-services unc system-administration mapped-drive
12个回答
39
投票

您需要修改服务,或将其包装在帮助程序进程中:除会话/驱动器访问问题外,永久性驱动器映射仅在交互式登录时恢复,这些服务通常不会执行。

辅助进程方法可以非常简单:只需创建一个映射驱动器并启动“真实”服务的新服务。唯一不完全是微不足道的事情是:

  • 帮助程序服务需要将所有适当的SCM命令(启动/停止等)传递给实际服务。如果真实服务接受自定义SCM命令,请记住也要传递它们(我不认为考虑UNC路径异常的服务使用此类命令,但是......)
  • 事情可能会有点棘手的凭证。如果真实服务在普通用户帐户下运行,您也可以在该帐户下运行帮助程序服务,只要该帐户具有对网络共享的适当访问权限,所有服务都应该正常。如果实际服务仅在以LOCALSYSTEM或其他类似的方式运行时才会起作用,事情变得更有趣,因为它要么根本不能“看到”网络驱动器,要么需要一些凭证来完成工作。

1
投票

您不想更改服务在“系统”下运行的用户,或者找一个偷偷摸摸的方式将您的映射作为系统运行。

有趣的是,通过使用"at"命令可以实现这一点,只需将驱动器映射安排到未来一分钟,它将在系统帐户下运行,使驱动器对您的服务可见。


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(漂亮的名字lol)和@NMC问题,他们在回复“我发现了一个类似于psexec,但没有额外的工具,并在重新启动后幸存。“发布@Larry已经发了。

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

    \\servername\share  

并让它提示登录,并输入您在psexec中用于UNC的相同凭据。之后它开始工作。在我的情况下,我认为这是因为具有该服务的服务器不是与我映射到的服务器相同的域的成员。我在想UNC和计划任务是否都引用IP而不是主机名

    \\123.456.789.012\share 

它可以完全避免这个问题。

如果我在这里获得足够的重复点,我会将其添加为回复。


210
投票

使用此风险需要您自担风险。 (我在XP和Server 2008 x64 R2上测试过它)

对于这个黑客你需要SysinternalsSuite by Mark Russinovich

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

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

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

就这么简单!

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

注意:现在将为该系统的所有用户显示新创建的映射驱动器,但它们将看到它显示为“断开网络驱动器(Z :)”。不要让这个名字欺骗你。它可能声称已断开连接,但它适用于所有人。这就是M $不支持这个hack的方法。


56
投票

我发现了一个与psexec类似的解决方案,但无需额外工具即可工作,并且可以在重新启动后继续使用。

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

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

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


38
投票

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


17
投票

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

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

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

9
投票

你可以使用'net use'命令:

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

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

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


5
投票

ForcePush,

注意:现在将为该系统的所有用户显示新创建的映射驱动器,但它们将看到它显示为“断开网络驱动器(Z :)”。不要让这个名字欺骗你。它可能声称已断开连接,但它适用于所有人。这就是你怎么能告诉M $不支持这个hack ...

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

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


4
投票

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

以Windows Server 2012和NFS磁盘为例:

第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. 在“系统启动”中以“SYSTEM”运行。
  2. 创建操作:运行“C:\ mount_nfs.bat”。

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


3
投票

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

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

  1. 将驱动器映射为上面已经指出的持久性。
  2. 还有一种方法可以遵循。如果您通过键入'services.msc'打开服务管理器,您可以转到您的服务,并在服务的属性中有一个logOn选项卡,您可以在其中指定帐户,除了'System'之外的任何其他帐户从您自己登录的用户帐户或“网络服务”开始服务。当你这样做..服务可以访问任何网络组件和驱动器,即使它们也不是持久的。要以编程方式实现此目的,您可以在http://msdn.microsoft.com/en-us/library/ms682450(v=vs.85).aspx查看“CreateService”函数,并可以将参数“lpServiceStartName”设置为“NT AUTHORITY \ NetworkService”。这将在“网络服务”帐户下启动您的服务,然后您就完成了。
  3. 您还可以尝试通过在CreateService()函数的servicetype参数标志中指定SERVICE_INTERACTIVE_PROCESS使服务成为交互式,但这仅限于XP,因为Vista和7不支持此功能。

希望这些解决方案可以帮助您..如果这对您有用,请告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.