wake-up-neo.net

Zuordnen eines Netzlaufwerks, ohne einen Laufwerkbuchstaben in einer Stapeldatei festzukodieren

Ich muss ein Netzlaufwerk mit einer Batchdatei zuordnen, möchte aber nicht den Laufwerksbuchstaben angeben.

Die Batchdatei wird als Teil eines Bereitstellungsprozesses verwendet. Wenn ich die Batchdatei von CruiseControl.Net aus aufrufe, muss die Batchdatei einen UNC-Pfad zuordnen, für den zur Authentifizierung Anmeldeinformationen erforderlich sind. Dann ruft die Batchdatei RoboCopy auf, um die Website vom Ausgabeverzeichnis zum Ziel bereitzustellen (und schließt einige Dateien und Ordner aus). Schließlich löscht der Stapel das Netzlaufwerk.

Das Problem ist, dass dies nicht skalierbar ist. Es ist in Ordnung, wenn es nur wenige Projekte gibt, aber jetzt haben wir 20 Projekte, die diesen Ansatz verwenden, und die Laufwerksbuchstaben sind knapp. Ich möchte keine Laufwerksbuchstaben wiederverwenden, da sie kollidieren könnten - was schlecht wäre.

Dies ist ein Beispiel für die Batchdatei:

@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

und zur besseren Lesbarkeit formatiert:

@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
14
Simon Martin

Wenn Sie nicht mehrere Netzwerkfreigaben gleichzeitig angeschlossen haben, können Sie Net Use * einen freien Laufwerksbuchstaben zuweisen. Anschließend können Sie robocopy verwenden, um über den UNC-Pfad auf die Freigabe zuzugreifen und die mit Net Use * /delete verbundene Freigabe freizugeben.

Etwas wie das:

@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

BEARBEITEN:

Wie ich aus einigen Recherchen gelernt habe, können Sie die Freigabe einfach zuordnen, ohne einen Laufwerksbuchstaben zuzuweisen. Es wird dann anonym nur durch seinen Remote-UNC-Pfad abgebildet. Auf diese Weise können Sie die Zuordnung auch entfernen, indem Sie nur ihren entfernten Namen angeben.

Das sollte funktionieren:

@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
31
Frank Bollack

ich benutze dies, um NET einen freien Laufwerksbuchstaben auswählen zu lassen, und dann mit NET herauszufinden, welchen Buchstaben er zugewiesen hat:

Net Use * \\server\share
for /f "tokens=2" %%i in ('Net Use ^| find "\\server\share"') do set netdrive=%%i
echo %netdrive% has been mapped
11
longneck

Einige finden die folgende Batchdatei für nützlich.

Es ist nicht auf externe Programme angewiesen.

Die Batchdatei enthält eine Funktion :freedrive, die einen freien Laufwerksbuchstaben findet und ihn in einer Variablen zurückgibt. Es erkennt auch, dass optische Laufwerke, die über keine Medien verfügen, einen Laufwerksbuchstaben belegen.

@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
5
Jelle Geerts

Ok ... das ist vielleicht nicht glamourös, aber so mache ich das jetzt; ein grundlegender try catch-Ansatz. Versuchen Sie, ein Laufwerk zuzuordnen, und wenn es verwendet wird, fahren Sie mit dem nächsten Schritt fort. Ich habe dies mit nur zwei Versuchen veranschaulicht, aber es ist nicht schwer, es auf 4, 10 oder mehr Laufwerksbuchstaben auszudehnen.

Ja, es beleidigt meine Programmierfähigkeiten, ich mag die Wiederholung von Code nicht. Leider weiß ich nicht, wie ich den Pfad und die Anmeldeinformationen in die Batchdatei eingeben könnte, da ich sie selbst nicht benenne. CruiseControl.net ruft sie ohne Parameter auf.

@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
2
Simon Martin

Eine mögliche Lösung besteht darin, den pushd-Befehl auf einen UNC-Pfad anzuwenden, der sicher existiert, sodass ein temporärer Laufwerksbuchstabe erstellt wird, der auf diesen Pfad zeigt. Das aktuelle Verzeichnis, nämlich das Stammverzeichnis des temporären Laufwerks, kann ermittelt werden, um den Laufwerksbuchstaben zu erhalten. Schließlich muss der Befehl popd verwendet werden, um den temporären Laufwerksbuchstaben zu löschen:

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

Die Variable COMPUTERNAME und die Freigabe \\%COMPUTERNAME%\ADMIN$ sollten auf allen modernen (NT-basierten) Windows-Systemen vorhanden sein.


Wenn Sie nicht möchten, dass die aktuelle Umgebung durch den Versuch von pushd, einen freien Laufwerksbuchstaben abzuleiten, vorübergehend "verschmutzt" wird, möchten Sie möglicherweise den folgenden Ansatz verwenden:

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

Einfachste Methode:

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

Pushd ordnet ein Netzlaufwerk automatisch einem verfügbaren Buchstaben zu und popd entfernt es. Sie sind interne CMD-Befehle. Für die Verwendung von UNC-Pfaden müssen Erweiterungen aktiviert sein. Batch-Beispiel:

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

Hinweis: In dieser Implementierung muss ein Pfad in der Befehlszeile angegeben werden, der ein Befehlszeilenargument verwendet.

Beispielsitzung:

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
matt wilkie

@longneck, ich benutze so etwas:

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

Dies vermeidet den zweiten Aufruf, um durch find weiterzuleiten.

Sie können dies auch erweitern, damit Sie set netdrive nicht direkt aufrufen, sondern in einer Subroutine. Auf diese Weise können Sie mehr Fehler prüfen oder bearbeiten.

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

Das Unterprogramm parse ist hier nicht besonders nützlich und illustriert nur das Konzept.

0
Ryan Beesley