Сопоставление сетевого диска без жесткого кодирования буквы диска в командном файле - PullRequest
14 голосов
/ 15 сентября 2010

Мне нужно сопоставить сетевой диск с командным файлом, но я не хочу указывать букву диска.

Пакетный файл используется как часть процесса развертывания;Я вызываю пакетный файл с 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

Ответы [ 7 ]

31 голосов
/ 15 сентября 2010

Если у вас нет нескольких сетевых ресурсов, подключенных одновременно, вы можете 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
11 голосов
/ 25 января 2012

Я использую это, чтобы позволить 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
5 голосов
/ 18 декабря 2013

Некоторые могут найти следующий пакетный файл полезным.

Не зависит от внешних программ.

Пакетный файл содержит функцию :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
2 голосов
/ 15 сентября 2010

Хорошо ... это не может быть гламурно, но именно так я сейчас и делаю; базовый подход попытки поймать. Попробуйте подключить диск и, если он используется, перейдите к следующему шагу. Я проиллюстрировал это всего двумя попытками, но нетрудно расширить его до 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
1 голос
/ 31 января 2017

Возможное решение - применить команду pushd к 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.


Если вы не хотите, чтобы текущая среда даже временно «загрязнялась» при попытке 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%`.
0 голосов
/ 27 июня 2015

@ 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

Это позволяет избежать второго вызова net по каналу через find.

Вы также можете расширить это, чтобы вместо вызова 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

Подпрограмма разбора здесь не очень полезна и только иллюстрирует концепцию.

0 голосов
/ 02 апреля 2015

Самый простой способ:

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