我需要使用批处理文件映射网络驱动器,但不想指定驱动器号。
批处理文件用作部署过程的一部分;我从CruiseControl.Net
调用批处理文件,批处理文件需要映射需要凭据进行身份验证的UNC路径。然后批处理文件调用RoboCopy
将网站从输出目录部署到目标(并排除某些文件和文件夹)。最后,批处理删除网络驱动器。
问题是这不可扩展,只有少数几个项目就可以了,但我们现在有20个项目使用这种方法并且用尽了驱动器号来映射。我不想重复使用驱动器字母,因为它们可能会发生碰撞 - 这会很糟糕。
这是批处理文件的示例:
@echo off
net use x: \\192.168.0.1\Share\wwwroot\MyProject /user:mydomain\myuser MyP455w0rd
robocopy.exe "W:\wwwroot\MyProject" x:\ *.* /E /XO /XD "App_Data/Search" "*.svn" /XF "sitefinity.log" "Thumbs.db" /NDL /NC /NP
net use x: /delete
并格式化以便于阅读:
@echo off
net use x: \\192.168.0.1\Share\wwwroot\MyProject
/user:mydomain\myuser MyP455w0rd
robocopy.exe "W:\wwwroot\MyProject" x:\ *.* /E /XO /XD
"App_Data/Search" "*.svn" /XF "sitefinity.log" "Thumbs.db" /NDL /NC /NP
net use x: /delete
答案 0 :(得分:31)
如果您没有同时连接多个网络共享,则可以net use *
为您分配一个免费的驱动器号。之后,您可以使用robocopy
通过其UNC路径访问共享,并使用net use * /delete
释放所有已连接的共享。
这样的事情:
@echo off
net use * \\192.168.0.1\Share\wwwroot\MyProject /user:mydomain\myuser MyP455w0rd
robocopy.exe "W:\wwwroot\MyProject" "\\192.168.0.1\Share\wwwroot\MyProject" *.* /E /XO /XD "App_Data/Search" "*.svn" /XF "sitefinity.log" "Thumbs.db" /NDL /NC /NP
net use * /delete /yes
修改强>
正如我从一些研究中了解到的那样,您可以简单地映射共享而无需分配驱动器号。然后通过其远程UNC路径匿名映射。这样,您也可以通过仅指定其远程名称来删除映射。
这应该有效:
@echo off
net use \\192.168.0.1\Share\wwwroot\MyProject /user:mydomain\myuser MyP455w0rd
robocopy.exe "W:\wwwroot\MyProject" "\\192.168.0.1\Share\wwwroot\MyProject" *.* /E /XO /XD "App_Data/Search" "*.svn" /XF "sitefinity.log" "Thumbs.db" /NDL /NC /NP
net use \\192.168.0.1\Share\wwwroot\MyProject /delete
答案 1 :(得分:11)
我使用它来让NET选择一个免费的驱动器号,然后使用NET找出它分配的字母:
net use * \\server\share
for /f "tokens=2" %%i in ('net use ^| find "\\server\share"') do set netdrive=%%i
echo %netdrive% has been mapped
答案 2 :(得分:5)
有些人可能会发现以下批处理文件很有用。
它不依赖于外部程序。
批处理文件包含一个函数:freedrive
,它找到一个空闲的驱动器号并将其返回到变量中。它还可以正确检测没有媒体占用驱动器号的光驱。
@echo off
setlocal
call :freedrive mydriveletter && goto :cont
echo ERROR: No free drive letter found.
goto :exit
:cont
echo Found drive letter: %mydriveletter%
goto :exit
rem Finds a free drive letter.
rem
rem Parameters:
rem %1 = Output variable name.
rem
rem Example:
rem call :freedrive mydriveletter && goto :cont
rem echo ERROR: No free drive letter found.
rem goto :EOF
rem :cont
rem echo Found drive letter: %mydriveletter%
:freedrive
setlocal EnableDelayedExpansion
set exitcode=0
set "output_var=%~1"
for %%i in (A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z) do (
set "drive=%%i:"
rem If 'subst' fails, the drive letter is already in use.
rem This way we can even detect optical drives that have a drive
rem letter but no media in them, a case that goes undetected when
rem using 'if exist'.
subst !drive! %SystemDrive%\ >nul
if !errorlevel! == 0 (
subst !drive! /d >nul
goto :freedrive0
)
)
set exitcode=1
set drive=
:freedrive0
endlocal & set "%output_var%=%drive%" & exit /b %exitcode%
:exit
pause
答案 3 :(得分:2)
好的......这可能并不富有魅力,但这就是我现在这样做的方式;基本的尝试捕获方法。尝试映射驱动器,如果它正在使用,则转到下一步。我只用了2次尝试来说明这一点,但要将它扩展到4个,10个或更多的驱动器号并不难。
是的,它冒犯了我的编程敏感度,我不喜欢代码的重复。不幸的是我不知道如何将路径和凭证传递到批处理文件中,因为我自己不称它,CruiseControl.net不带参数调用它。
@echo off
:START
net use z: \\192.168.0.1\Share\wwwroot\MyProject /user:mydomain\myuser MyP455w0rd
if %ERRORLEVEL% ==2 goto Y
ROBOCOPY HERE
net use z: /delete
exit
:Y
net use y: \\192.168.0.1\Share\wwwroot\MyProject /user:mydomain\myuser MyP455w0rd
if %ERRORLEVEL% ==2 goto W
ROBOCOPY HERE
net use y: /delete
exit
:W
sleep 20
goto START
答案 4 :(得分:1)
一种可能的解决方案是将pushd
command应用于肯定存在的UNC路径,以便创建指向该路径的临时驱动器号。可以确定当前目录(即临时驱动器的根目录)以获取驱动器号。最后,必须使用popd
命令删除临时驱动器号:
pushd "\\%COMPUTERNAME%\ADMIN$"
rem /* Do stuff here with the root of the temporarily created drive
rem used as the current working directory... */
rem // Store the current drive in variable `DRIVE` for later use:
for /F "delims=:" %%D in ("%CD%") do set "DRIVE=%%D:"
popd
echo The next free drive letter is `%DRIVE%`.
变量COMPUTERNAME
和共享\\%COMPUTERNAME%\ADMIN$
应该存在于所有现代(基于NT的)Windows系统上。
如果您不希望当前环境暂时变为“污染”状态,那么#34;通过pushd
尝试获得免费驱动器号,您可能希望使用以下方法:
for /F "delims=:" %%D in ('
pushd "\\%COMPUTERNAME%\ADMIN$" ^& ^
for %%Z in ^(.^) do popd
') do set "DRIVE=%%D:"
echo The next free drive letter is `%DRIVE%`.
答案 5 :(得分:0)
最简单的方法:
pushd "\\server\share\wwwroot\My Project"
robocopy . x:\ *.* /E ...etc
popd
Pushd会自动将网络驱动器映射到可用的字母,popd会将其删除。它们是内部CMD命令;使用UNC路径需要启用扩展。批处理示例:
@echo off
pushd %1
echo. --- Processing %1 as "%cd%"
echo. ...
rem do thing here
echo. Done.
popd
注意:在使用命令行参数的此实现中,必须引用命令行上的路径。
示例会话:
E:\temp>.\demo-pushd.bat "\\server\share\wwwroot\My Project"
--- Processing "\\server\share\wwwroot\My Project" as "X:\wwwroot\My Project"
...
Done.
E:\temp> net use X:
The network connection could not be found.
More help is available by typing NET HELPMSG 2250.
E:\temp>
答案 6 :(得分:0)
@longneck,我使用这样的东西:
for /f "tokens=2" %%i in ('net use * \\server\share') do (
if defined netdrive goto :cont
set netdrive=%%i
)
:cont
echo.%netdrive% has been mapped
pause
net use %netdrive% /d /y
pause
这样就可以避免第二次通过find来调用net。
您也可以对此进行扩展,以便不是直接调用set netdrive,而是在子例程中执行此操作。这允许您进行更多错误检查或处理。
for /f "tokens=2" %%i in ('net use * \\server\share') do (
if defined netdrive goto :cont
call :parse %%i
)
:parse
if ~%1==%1~ goto :eof
if Z:==%1 (
set netdrive=%1
)
goto :eof
:cont
echo.%netdrive% has been mapped
pause
net use %netdrive% /d /y
pause
这里的解析子程序不是非常有用,只是说明了这个概念。