2010-09-15 27 views
13

Potrzebuję zmapować dysk sieciowy za pomocą pliku wsadowego, ale nie chcę podawać litery dysku.Mapowanie dysku sieciowego bez kodowania dysku twardego w pliku wsadowym

Plik wsadowy jest używany jako część procesu wdrażania; Wezwę plik wsadowy z CruiseControl.Net, plik wsadowy musi zmapować ścieżkę UNC, która wymaga poświadczeń do uwierzytelnienia. Następnie plik wsadowy wywołuje RoboCopy, aby wdrożyć witrynę z katalogu wyjściowego do miejsca docelowego (i wyklucza niektóre pliki i foldery). Wreszcie partia usuwa dysk sieciowy.

Problem polega na tym, że nie jest to skalowalne, jest w porządku, gdy jest tylko kilka projektów, ale mamy teraz 20 projektów wykorzystujących to podejście i brakuje nam liter dysku do mapowania. Nie chcę ponownie używać liter dysków, ponieważ mogłyby się zderzyć - co byłoby złe.

To jest przykład pliku wsadowego:

@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 

i sformatowany dla czytelności:

@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 

Odpowiedz

28

Jeśli nie masz wiele akcji sieciowe podłączone simultaniously, można dokonać net use * przypisać bezpłatna litera dysku dla Ciebie. Następnie można użyć numeru robocopy, aby uzyskać dostęp do udziału za pośrednictwem jego ścieżki UNC i zwolnić połączony udział za pomocą net use * /delete.

coś takiego:

@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 

EDIT:

Jak dowiedziałem się od niektórych badań, można po prostu mapować udział bez przypisywania litery dysku. Następnie jest mapowany anonimowo, tylko przez jego zdalną ścieżkę UNC. W ten sposób możesz również usunąć mapowanie, określając tylko jego nazwę zdalną.

To powinno działać:

@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 
+0

Nie jest szansą na jednoczesne połączenie wielu udziałów sieciowych, w przeciwnym razie zawsze mógłbym przypisać Z: lub zakodowaną na stałe literę na projekt. użycie net */delete spowoduje również uwolnienie WSZYSTKICH połączonych udziałów, a to byłby problem na serwerze –

+0

@Simon Martin: zobacz moją zaktualizowaną odpowiedź. –

+0

to o wiele ładniejsze niż moje rozwiązanie :) –

2

Ok ... to może nie być tak uroczo, ale to jak robię to teraz; podstawowe podejście do chwytania prób. Spróbuj zmapować dysk i jeśli jest on używany, przejdź do następnego kroku. Zilustrowałem to zaledwie 2 próbami, ale nie jest trudno rozszerzyć go na 4, 10 lub więcej liter dysków.

Tak, to obraża moje wrażenia programistyczne, nie podoba mi się powtórzenie kodu. Niestety nie wiem, jak mogę przekazać ścieżkę i poświadczenia do pliku wsadowego, ponieważ nie nazywam go sobą, CruiseControl.net nazywa to bez parametrów.

@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 
10

używam to pozwolić NET odebrać wolną literę dysku, a następnie net use, aby dowiedzieć się, co to litera przypisana:

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

Niektórzy mogą znaleźć następujące plik wsadowy pożytecznego.

Nie polega na programach zewnętrznych.

Plik wsadowy zawiera funkcję :freedrive, która znajduje wolną literę dysku i zwraca ją w zmiennej. To również poprawnie wykrywa dyski optyczne, które nie mają nośnika jako zajmującego literę dysku.

@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 
+0

Podoba mi się to podejście; nie "sprawdź, co jest dostępne i go używaj", ale raczej "użyj go i sprawdź, czy zadziałało". – Ben

0

Najprostsza metoda:

pushd "\\server\share\wwwroot\My Project" 
robocopy . x:\ *.* /E ...etc 
popd 

Pushd automatycznie mapować dysk sieciowy z dostępną literę i popd będzie go usunąć. Są to wewnętrzne polecenia CMD; używanie ścieżek UNC wymaga włączenia rozszerzeń. Przykładem partii:

@echo off 
pushd %1 
    echo. --- Processing %1 as "%cd%" 
    echo. ... 
    rem do thing here 
    echo. Done. 
popd 

Uwaga: w tej implementacji przy użyciu wiersza poleceń argumentu, musi być cytowany ścieżka na linii poleceń.

sesja Próbka:

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> 
+0

Nie ma możliwości zdefiniowania poświadczeń wymaganych przez OP. –

+0

@thomas: tylko 2 z 6 odpowiedzi tutaj dzisiaj ilustrują korzystanie z poświadczeń, ale to jest jedyna odpowiedź, która zasługuje na awans? Używanie funkcji pushd zamiast pętli For jest o wiele bardziej bezpośrednie i proste, dla części problemu, do której się odnosi. –

+1

Pozostałe odpowiedzi używają polecenia 'net'. Chociaż nie ilustrują sposobu korzystania z poświadczeń, jest to przynajmniej możliwe. –

0

@longneck używam coś takiego:

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 

ten sposób unika się drugi nabór do NET rurami dzięki znalezisku.

Możesz także rozwinąć tę opcję, aby zamiast wywoływać zestaw netdrive bezpośrednio, robiłeś to w podprogramie. Pozwala to na dalsze sprawdzanie lub przetwarzanie błędów.

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 

Podprogram parsowania tutaj nie jest bardzo przydatny i tylko ilustruje koncepcję.

1

Możliwym rozwiązaniem jest zastosowanie pushd command do ścieżki UNC, która istnieje na pewno, więc tymczasowy litera dysku jest tworzony, że punkty na tej ścieżce. Bieżący katalog, a mianowicie katalog główny dysku tymczasowego, może zostać określony w celu uzyskania litery dysku. Wreszcie, komenda popd należy zastosować, aby usunąć tymczasowe literę:

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

Zmienna COMPUTERNAME a udział \\%COMPUTERNAME%\ADMIN$ powinny istnieć na wszystkich nowoczesnych (NT) w systemach Windows.


Jeśli nie chcesz bieżące środowisko stać nawet tymczasowo „zanieczyszczone” przez próbę pushd celu uzyskania wolnego literę dysku, może chcesz używać następujące podejście:

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