映射一个网络驱动器供服务使用

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

429270 次浏览

您既不想从“System”更改服务运行的用户,也不想找到一种狡猾的方式将映射运行为System。

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

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

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

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

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

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

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

  • helper服务需要将所有适当的SCM命令(启动/停止等)传递给真正的服务。如果真正的服务接受自定义SCM命令,记住也要传递这些命令(不过,我不期望一个认为UNC路径是外来的服务使用这样的命令……)

  • 事情可能会变得有点棘手。如果真正的服务在普通用户帐户下运行,那么您也可以在该帐户下运行helper服务,只要该帐户具有对网络共享的适当访问权限,那么一切都应该没问题。如果真正的服务只能在以LOCALSYSTEM或类似的方式运行时才能工作,那么事情就会变得更有趣,因为它要么根本无法“看到”网络驱动器,要么需要一些凭据才能工作。

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

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

  1. 将驱动器映射为上面已经指出的持久驱动器。

  2. 还有一种方法可以遵循。如果您通过键入“services.”打开服务管理器。你可以进入你的服务,在你的服务的属性中有一个登录选项卡,在这里你可以指定帐户为任何其他帐户,而不是“系统”,你可以从你自己的登录用户帐户或通过“网络服务”启动服务。当你这样做的时候…该服务可以访问任何网络组件和驱动器,即使它们也不是持久的。 要以编程方式实现这一点,您可以查看'CreateService'函数 http://msdn.microsoft.com/en-us/library/ms682450 (v = vs.85) . aspx,可以将参数“lpServiceStartName”设置为“NT AUTHORITY\NetworkService”。这将在“网络服务”帐户下启动您的服务,然后您就完成了。李< / p > < / >
  3. 你也可以尝试通过在CreateService()函数的servicetype参数标志中指定SERVICE_INTERACTIVE_PROCESS来使服务具有交互性,但这将仅限于XP as Vista和7不支持此功能。

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

使用此信息的风险自负。(我已经在XP和Server 2008 x64 R2上进行了测试)

对于这个hack,你需要SysinternalsSuite由Mark Russinovich设计:

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

.exe

< >强第二步: 使用PSExec.exe再次提升到根目录: 导航到包含SysinternalsSuite的文件夹并执行以下命令 psexec -i -s cmd.exe 你现在在一个nt authority\system的提示符中,你可以通过输入whoami来证明这一点。-i是必需的,因为驱动器映射需要与用户

交互

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

就是这么简单!

警告:你只能像创建它一样从SYSTEM帐户中删除这个映射。如果你需要移除它,遵循步骤1和2,但将步骤3中的命令更改为net use z: /delete

请注意:新创建的映射驱动器现在将出现在此系统的所有用户中,但他们将看到它显示为“断开连接的网络驱动器(Z:)”。别被名字骗了。它可能声称是断开连接的,但它对每个人都适用。这就是为什么你可以告诉这个黑客是不支持的M$。

我找到了一个解决方案,类似于psexec,但工作不需要额外的工具,并在重新启动后存活

只需添加一个计划任务,在“作为运行”字段中插入“system”,并使用简单的命令将任务指向一个批处理文件

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

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

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

ForcePush,

请注意:新创建的映射驱动器现在将出现在此系统的所有用户中,但他们将看到它显示为“断开连接的网络驱动器(Z:)”。别被名字骗了。它可能声称是断开连接的,但它对每个人都适用。这就是为什么你可以告诉这个黑客是不支持M$…

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

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

找到一种方法授予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。

打开“Task Scheduler”,创建一个新任务:

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

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

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

例如,你可以使用符号链接。

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

我还不能评论(在声誉方面),但创建了一个帐户,只是为了回答@Tech Jerk @spankmaster79(好名字lol)和@NMC问题,他们在回复“我发现了一个解决方案,与psexec类似,但不需要额外的工具,并在重启后幸存。”

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

    \\servername\share

并让它提示登录,并输入您在psexec中用于UNC的相同凭据。之后就开始工作了。在我的例子中,我认为这是因为提供服务的服务器与我要映射到的服务器不属于同一个域。我在想,如果UNC和计划任务都是指IP而不是主机名

    \\123.456.789.012\share

它可能会完全避免这个问题。

如果我曾经得到足够的代表点在这里,我会把这作为一个回复。

而不是依赖于一个持久驱动器,你可以设置脚本映射/取消映射驱动器每次你使用它:

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

这对我很有用。

我发现了一个非常简单的方法:使用命令“New-SmbGlobalMapping"powershell,它将挂载全局驱动器:

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