nemesis
Goto Top

Bat Script Probleme bei Sonderzeichen

hi @all,
habe ein bat script geschrieben mit dem ich alle PC's in meinem Netzwerk schnell und bequem das pw änder lasse, doch wenn ich nun pw's mit sonderzeichen (in meinem Fall "&") wird der eintrag an diesem Zeichen ("&") natürlich im bat script in viele fetzen gerissen.
Ergebnis das script schmiert natürlich ab. habt ihr ne Idee?

REM Die Variablen
REM -------------------
set logfile=logfile.txt
set iplist=iplist.txt
set passfile=passwort.bat
REM -------------------
REM Ab hier nichtsmehr ändern!
REM -------------------
@echo off
cls
set /p username=Benutzernamen eingeben:
set /p passwort=Benutzer Kenwort eingeben:
goto 3
:1
cls
echo Leider ist das neue Kennwort nicht identisch!
:3
echo Bitte noch keine Sonderzeichen verwenden.
set /p newpassword=neues Kennwort eingeben:
set /p newpassword2=Bitte wiederholen Sie das neue Kennwort:
IF NOT "%newpassword%"=="%newpassword2%" (
goto 1 ) ELSE ( goto 2 )
:2
echo moechten Sie die PC's danach neustarten herunterfahren oder anlassen?
set /p sys=0 fuer anlassen, 1 fuer Neustart, 2 fuer Herunterfahren:
IF NOT "%sys%"=="0" (
set /p comment=Kommentar fuer den Neustart/Herunterfahren?:
set /p sek=Zeit bis der Neustart/Herunterfahren wirkt in sek.: )
echo alle Variablen sind jetzt komplett, um zu beginnen.
echo Druecken Sie bitte ENTER
echo net user %username% %newpassword% >> c:\%passfile%
echo Scan Ergebnisse vom %date%, %time% >> %logfile%
echo ............................................................... >> %logfile%
echo I >> %logfile%
pause > NUL
FOR /F %%i in (%iplist%) do (
ping -n 1 %%i | find "Antwort" >> nul ) && (
NET USE \\%%i\IPC$ /USER:"%username%" "%passwort%" > NUL
copy c:\%passfile% \\%%i\c$\ > NUL
cmd /c PSEXEC \\%%i -u "%username%" -p "%passwort%" C:\%passfile% > NUL
DEL \\%%i\c$\%passfile% > nul
IF "%sys%"=="0" ( goto 4 )
IF "%sys%"=="1" (
cmd /c SHUTDOWN -m \\%%i -t "%sek%" -c "%comment%" -f -r > NUL
) ELSE (cmd /c SHUTDOWN -m \\%%i -t "%sek%" -c "%comment%" -f -s > NUL)
:4
NET USE \\%%i\IPC$ /D > nul
echo [ %%i ] ERFOLGREICH [ Zumindest sollte es]
echo I [ %%i ] ERFOLGREICH [ Zumindest sollte es] >> %logfile%
echo I [ %%i ] GESCHEITERT -!- [Offline] >> %logfile% )
)
del c:\%passfile%
echo I >> %logfile%
echo ............................................................... >> %logfile%
echo. >> %logfile%
echo. >> %logfile%
echo. >> %logfile%
echo.
echo.
cls
echo Script beendet! %iplist% verarbeitet. Die Logfile: %logfile% liegt zur auswertung bereit.!
pause > nul

Content-ID: 23541

Url: https://administrator.de/forum/bat-script-probleme-bei-sonderzeichen-23541.html

Ausgedruckt am: 28.12.2024 um 15:12 Uhr

Biber
Biber 14.01.2006 um 00:33:12 Uhr
Goto Top
Moin nEmEsIs,

schade, das wollte ich mir alles für mein Batch-Tut IV aufheben, aber egal...

...dann kennen die Syntax in 10 Minuten halt doppelt so viele Leute wie vorher.. *gg

Du musst dieses Sonderzeichen "&" ja im Batch maskieren, weil es für die CMD.exe auch ein Steuerzeichen ist.
Maskieren geht mit "^" vor dem Zeichen - so weit würde man/frau ja auch mit M$-Hilfe kommen.
Wenn dieser String mit Steuerzeichen allerdings noch mehrfach "weitergereicht" (noch mal in einer %Variable% verpackt und aufgelöst) wird, dann:
...muss auch die Maskierung maskiert werden (nein, ich habe keinen an der Waffel, ich zeigs mal).
Ich turn es mal am CMD-Prompt vor:
$cmd$ set /P pass1="Bitte Passwort eingeben: "
Bitte Passwort eingeben: Dies&Das

D:\temp>
$cmd$ set pass1
pass1=Dies&Das
...
Wenn dieser String in der Variablen %pass1% möglicherweise ein Ampersand ("&") enthalten können darf, dann maskieren:
$cmd$set xpass1=%pass1:&=^^^&%
(-----> übersetzt in etwa: "Ersetze das Zeichen "&" durch ein "^&". Da aber "^" auch ein Steuerzeichen ist, muss ich das maskieren.)

D:\temp>
$cmd$ set xpass1
xpass1=Dies^&Das
$cmd$ echo net use username %xpass1%
net use username Dies&Das

Ich denke, das reicht Dir, um das umzusetzen - Dein Batchschnipsel hat ja schon gewisse Reife...

Gruß Biber
nEmEsIs
nEmEsIs 14.01.2006 um 15:58:29 Uhr
Goto Top
entschuldige bitte Biber, dass ich dir da was vorgenommen habe, werde das skript jetzt mit deiner lösung noch verfolständigen und danach ein Link hierher posten wo mann sich dann alles runterladen kann.

nEmEsIs aka draner
P.S.: kennst jemand alle zeichen wie & die von der cmd dann umgesetzt würden?
P.P.S.: wie kann ich einen variable danach überprüfen ob sie nur aus zahlen besteht!?
Biber
Biber 14.01.2006 um 16:41:45 Uhr
Goto Top
Moin nEmEsIs,

soooo schlimm war es nun auch nicht mit dem vorgezogenen Tutorial-Absatz - so war es wenigstens (hoffentlich) für jemand von Nutzen.

Zu Deiner Frage "kennst jemand alle zeichen wie & die von der cmd dann umgesetzt würden?":

Ich fürchte, das wirst Du nur durch probieren herausfinden können, aber das ist ja relativ einfach.
Du kannst alle theoretisch erlaubten Sonderzeichen für Passworte ja per "SET" in Variable packen und wieder ausgeben lassen, wie in dem obigen Schnipsel von mir.

Umlaute oder Zeichen, die nicht auf allen Codepages vorhanden sind, musst Du ohnehin weglassen - so viel bleibt also nicht über.

Zu den Zeichen, die unter dem CMD "maskiert" werden müssen, gehören sicher: Runde und spitze Klammern, arithmetische Operatoren, die logischen Operatoren für UND und ODER, das Prozentzeichen, das Gleichheitszeichen sowie das Komma.

Gruß Biber
P.S. Wenn Du keine Einwände hast, verschieben wir Deinen Beitrag mal von "Betriebssysteme" nach "Batch & Shell".
nEmEsIs
nEmEsIs 14.01.2006 um 21:13:28 Uhr
Goto Top
also dein Tip hat schonmal wunderbar funktionier leuft wie geschmiert, aber es tut sich wie immer das nächste Problem gleich auf!
Wenn das bat script auf dem Client ausgeführt wird setzt er das & wieder falsch um:

net user testuser 1&2&3&4

C:\>net user testuser 1 & 2 & 3 & 4
Der Befehl wurde erfolgreich ausgeführt.

Der Befehl "s" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.
Der Befehl "e96" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.
Der Befehl "n99" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.

C:\>

hast dafür noch ne idee?

P.S.: gegen das verschieben habe ich natürlich keine einwende!
Biber
Biber 15.01.2006 um 04:19:09 Uhr
Goto Top
Moin nEmEsIs,
hast dafür noch ne idee?
Na, frag doch mal hier im Forum rum, ob mir schon mal die Ideen ausgegangen sind ..face-wink

Ich hatte je das Beispiel mit der "maskierten Maskierung am CMD-Prompt durchgespielt.
Wenn der "Net use" von einem Batch aufgerufen wird, ist es noch eine Maskierungsebene mehr.

Denn in der erzeugten Batch-Datei muss ja drinstehen
net user testuser 1^&^2^&3^&4
..damit tatsächlich ausgeführt wird, was Du meinst, nämlich...
net user testuser 1&2&3&4 
Andernfalls tritt der von Dir beschreibene Effekt auf: das "&"-Zeichen wird als "logisches UND" interpretiert.. also führe den Befehl "Net use testuser 1" aus UND den Befehl "1" UND den Befehl "2" UND den Befehl "3" UND...
C:\>net user testuser 1 & 2 & 3 & 4 <i>...wie Du geschrieben hast, oder, in anderer Schreibweise wäre das:</i>
(net user testuser 1) & (2)  & (3) & (4) <i>... so versteht es der/die CMD.exe.</i>
Also zurück..von hinten aufgerollt. Du willst als Net-Use-Aufruf mit Parameter haben:
:: Step 0) 
net user testuser 1&2&3&4
:: 
:: Dann musst Du in der erzeugten *.Bat stehen haben:
:: Step -1) 
net user testuser 1^&2^&3^&4
:: 
:: Dann muss der echo-Befehl im Batch davor schreiben:
:: Step -2) 
echo net user testuser 1^^^&2^^^&3^^^&4
::
:: Also muss Deine Ersetze-Mir-Jedes-&-Zeichen ungefähr so aussehen:
var=1&2&3&4
set xvar=%var:&=^^^^^^^&%
$cmd$set xv
xvar=1^^^&2^^^&3^^^&4
... 
Na ja, so weit die Skizze... ich hab es (das Prinzip) zwar eben am CMD-Prompt an-, aber nicht zu Ende getestet.
Die Zeilen von "var=...." bis " ..." sind aber schon vom Bildschirm kopiert.

Alternativen:
- die Benutzung von "&" in diesen Passworten verbieten
- oder eine andere Form der Passworterfassung - Suche mal in Beiträgen von fpschultze hier im Forum.
Der hat bei einem Beitrag "Batch: Passwort verdeckt eingeben" eine pragmatischere Lösung.

BTW...willst Du jetzt ein
- "Net use"/Laufwerke mappen machen oder
- "Net user" / neue Benutzerpassworte setzen?

Oben stehen beide Varianten, deshalb die Rückfrage.

Grüße Biber

P.S. Für diese IsNumeric-Funktion mach bitte einen neuen Beitrag auf in "Batch und Shell".
Da gibt es keine Standard-Funktion, da müssen eine Handvoll Zeilen *.bat geschrieben werden und ist auch ein anderes Thema.
nEmEsIs
nEmEsIs 15.01.2006 um 13:15:58 Uhr
Goto Top
Also dein vorschlag werde ich mal einbauen und schaun ob das dann so (hoffentlich funzed)
unten ist schonmal die überarbeitete version wo dann auch mal die logfile und alles richtig funktioniert
P.S.: ich will das Benutzerpasswort setzen!

REM Die Variablen
REM -------------------
set logfile=logfile.txt
set iplist=iplist.txt
set passfile=passwort
REM -------------------
REM Ab hier nichtsmehr ändern!
REM -------------------
@echo off
cls
goto first
:wrongip
echo Sie haben keine gueltige Option gewaehlt versuchen Sie es nochmal!
goto first
{{comment_single_line_double_colon:1}}
echo es existiert noch keine IP File!
{{comment_single_line_double_colon{{comment_single_line_double_colon:6}}}}
IF NOT EXIST %iplist% ( goto create 
	       ) ELSE ( echo moechten Sie eine neue IP Liste erstellen oder die Aktuell Liste verwenden?
			set /p createip=1 = erstellen / 2 = Aktuelle verwenden:
		      )
IF {{comment_strings{{comment_single_line_double_colon:7}}3827493737}} EQU {{comment_strings:1226097885}} ( goto create ) 
IF {{comment_strings{{comment_single_line_double_colon{{comment_single_line_double_colon:7}}}}2255219522}} EQU "2" ( goto ipnow   
	      	 ) ELSE ( goto wrongip )
{{comment_single_line_double_colon{{comment_single_line_double_colon{{comment_single_line_double_colon:7}}}}}}
IF NOT EXIST %iplist% ( goto ipfirst )
set /p username=Benutzernamen eingeben:
set username=%username:&=^^^&%
set /p passwort=Benutzer Kenwort eingeben:
set passwort=%passwort:&=^^^&%
goto 3
:1
cls
echo Leider ist das neue Kennwort nicht identisch!
{{comment_single_line_double_colon{{comment_single_line_double_colon:7}}}}
set /p newpassword=neues Kennwort eingeben:
set newpassword=%newpassword:&=^^^&%
set /p newpassword2=Bitte wiederholen Sie das neue Kennwort:
set newpassword2=%newpassword2:&=^^^&%
IF NOT "%newpassword%"=="%newpassword2%" (  
   goto 1 ) ELSE ( goto 2 )
{{comment_single_line_double_colon:6}}
goto 7
{{comment_single_line_double_colon:7}}
echo Sie haben keine gueltige Zahl eingegeben!
:7
echo moechten Sie die PC's danach neustarten herunterfahren oder anlassen?  
set /p sys=0 fuer anlassen, 1 fuer Neustart, 2 fuer Herunterfahren:
IF /I "%sys%" EQU "0" ( goto 6 )  
IF /I {{comment_strings{{comment_single_line_double_colon{{comment_single_line_double_colon:7}}}}572100347}} EQU {{comment_strings:73259758631}} ( goto 6 ) 
IF /I {{comment_strings:6728670173}} EQU {{comment_strings:13383179147}} ( goto 6 ) 
goto 5
:6
IF NOT "%sys%"=={{comment_strings:7230705724}} (   
      set /p comment=Kommentar fuer den Neustart/Herunterfahren?:
      set comment=%comment:&=^^^&% 
      set /p sek=Zeit bis der Neustart/Herunterfahren wirkt in sek.: 
      set sek=%sek:&=^^^&%)
echo alle Variablen sind jetzt komplett, um zu beginnen.
echo Druecken Sie bitte ENTER
IF EXIST c:\%passfile%.bat ( del c:\%passfile%.bat )
echo net user %username% %newpassword% >> c:\%passfile%.bat
IF EXIST %logfile% ( del %logfile% )
echo Scan Ergebnisse vom %date%, %time% >> %logfile%
IF EXIST c:\%date%temp.txt ( del c:\%date%temp.txt )
IF EXIST c:\%date%cont.txt ( del c:\%date%cont.txt )
echo ............................................................... >> %logfile%
echo I >> %logfile%
pause > NUL
FOR /F %%i in (%iplist%) do (ping -n 1 %%i | find "Antwort" >> NUL  
			    ) && ( echo [ {{comment_strings{{comment_single_line_double_colon{{comment_single_line_double_colon:7}}}}2422836230}} ] ERFOLGREICH     [ Client ist Aktiv] 
				   echo %%i >> c:/%date%temp.txt
		       	    ) || ( echo [ {{comment_strings:63530944984}} ] GESCHEITERT -!- [ Offline] 
			           echo I [ "%%i" ] GESCHEITERT -!- [ Offline] >> %logfile%  
)
FOR /F %%i in (c:\%date%temp.txt) do (NET USE \\%%i\IPC$ /USER:%username% %passwort% | find {{comment_strings{{comment_single_line_double_colon{{comment_single_line_double_colon:7}}}}2489665979}} >> NUL 
		       ) && (
			     IF EXIST \\%%i\c$\%passfile%.bat ( del c:\%passfile%.bat) > NULL
			     copy {{comment_strings{{comment_single_line_double_colon{{comment_single_line_double_colon:7}}}}1522817078}} \\%%i\c$\ > NUL 
			     cmd /c PSEXEC \\%%i -u %username% -p %passwort% C:\%passfile%.bat > NUL
			     DEL \\%%i\c$\%passfile%.bat > NUL
			     NET USE \\%%i\IPC$ /D > nul
			     IF {{comment_strings{{comment_single_line_double_colon:7}}1160825127}}=={{comment_strings{{comment_single_line_double_colon:6}}2012269980}} ( cmd /c SHUTDOWN -m \\%%i -t "%sek%" -c %comment% -f -r > NUL )  
			     IF {{comment_strings{{comment_single_line_double_colon:7}}3920499296}}=="2" ( cmd /c SHUTDOWN -m \\%%i -t "%sek%" -c %comment% -f -s > NUL )  
			     echo %%i >> c:/%date%cont.txt
			     echo [ {{comment_strings{{comment_single_line_double_colon{{comment_single_line_double_colon:7}}}}1113670509}} ] ERFOLGREICH     [ Kennwort geaendert] 
			     echo I [ {{comment_strings:62382368797}} ] ERFOLGREICH     [ Kennwort geaendert] >> %logfile% 
		       ) || (echo [ {{comment_strings{{comment_single_line_double_colon{{comment_single_line_double_colon:7}}}}1769547681}} ] GESCHEITERT -!- [ Kennwort konnte nicht geaendert werden] 
			     echo I [ "%%i" ] GESCHEITERT -!- [ Kennwort konnte nicht geaendert werden] >> %logfile%  
)
FOR /F %%i in (c:\%date%cont.txt) do (NET USE \\%%i\IPC$ /USER:%username% %newpassword% | find {{comment_strings:62859448579}} >> NUL 
		       ) && (
			     echo [ {{comment_strings:7608689171}} ] ERFOLGREICH     [ Neues Kennwort geprueft] 
		       ) || (
			     echo [ {{comment_strings{{comment_single_line_double_colon:6}}2987594027}} ] GESCHEITERT -!- [ Neues Kennwort nicht korrekt gesetzt] 
			     echo I [ "%%i" ] GESCHEITERT -!- [ Neues Kennwort nicht korrekt gesetzt] >> %logfile%  
)
del c:\%passfile%.bat
del c:\%date%temp.txt
del c:\%date%cont.txt
echo I >> %logfile%
echo ............................................................... >> %logfile%
echo. >> %logfile%
echo. >> %logfile%
echo. >> %logfile%
echo.
echo.
cls
echo Script beendet! %iplist% verarbeitet. Die Logfile: %logfile% liegt zur auswertung bereit.!
pause > nul
exit

:create
IF EXIST %iplist% ( del %iplist% )
goto ipsetupabfrage
:ipsetupwrong
echo Sie haben keine gueltige Optinon gewaehlt versuchen Sie es nochmal:
:ipsetupabfrage
echo IP Setup - moechten Sie eine Liste erstellen oder einzelne IP's eintragen?  
set /p ipsetup=1 - Liste / 2 - Einzel IP's / 0 - Script starten:  
IF {{comment_strings:7134923917}} EQU {{comment_strings{{comment_single_line_double_colon:6}}3114520965}} ( goto ipnow ) 
IF {{comment_strings:12278668581}} EQU "1" ( goto ipliststart )  
IF {{comment_strings:1638703784}} EQU {{comment_strings{{comment_single_line_double_colon:6}}168302051}} ( goto ipipsetup ) 
goto ipsetupwrong

:ipipsetup
echo Geben Sie eine IP ein
:ipipreplay
set /p ip=IP:
echo %ip% >> %iplist%
goto ipipip
:ipipwrong
Echo Sie haben keine gueltige Optinon gewaehlt versuchen Sie es nochmal:
:ipipip
echo Moechten Sie weitere IP's eintragen?  
set /p ipreplayq=1 - Ja / 2 - Nein:
IF {{comment_strings:74209159547}}=={{comment_strings:12894107787}} ( goto ipipreplay ) 
IF {{comment_strings{{comment_single_line_double_colon{{comment_single_line_double_colon:7}}}}3595991584}}=={{comment_strings{{comment_single_line_double_colon:7}}1526813775}} ( goto ipsetupabfrage ) 
goto ipipwrong

goto ipliststart
:iplisterror
echo Sie haben keinem gueltige Bereich gewaehlt versuchen Sie es nochmal:
:ipliststart
echo geben Sie die range an BSP.: 192.168.1
set /p range=RANGE:
set /p ipstart=erste IP Adresse:
set /p ipstop=letzte IP Adresse:
IF {{comment_strings{{comment_single_line_double_colon:6}}1404601293}} GTR {{comment_strings:12671244235}} ( goto iplisterror ) 
IF {{comment_strings{{comment_single_line_double_colon:7}}671653361}} GTR {{comment_strings:12054461110}} ( goto iplisterror ) 
IF {{comment_strings{{comment_single_line_double_colon{{comment_single_line_double_colon:7}}}}2504656005}} LSS {{comment_strings{{comment_single_line_double_colon:6}}1188808047}} ( goto iplistklein ) 
IF {{comment_strings:6646786308}} GTR {{comment_strings{{comment_single_line_double_colon{{comment_single_line_double_colon:7}}}}735027032}} ( goto iplistbig ) 
:iplistklein
FOR /L %%i IN (%ipstart%,1,%ipstop%) do (
					echo %range%.%%i >> %iplist%
				     )
:iplistbig
FOR /L %%i IN (%ipstop%,1,%ipstart%) do (
					echo %range%.%%i >> %iplist%
				     )
goto ipsetupabfrage
Biber
Biber 15.01.2006 um 19:13:05 Uhr
Goto Top
Jau, nEmEsIs,

ich denke schon, dass dieser Beitrag in "Batch und Shell" besser reinpasst als in "Betriebssysteme".

a) Einen formalen Tipp noch zur Lesbarkeit:

Statt:
IF NOT EXIST %iplist% ( goto create
) ELSE ( echo moechten Sie eine neue IP Liste erstellen oder die Aktuell Liste verwenden?
set /p createip=1 = erstellen / 2 = Aktuelle verwenden:
)
IF "%createip%" EQU "1" ( goto create )
IF "%createip%" EQU "2" ( goto ipnow
) ELSE ( goto wrongip )

besser:
IF NOT EXIST %iplist% goto create
echo moechten Sie eine neue IP Liste erstellen oder die Aktuell Liste verwenden?
set /p createip=1 = erstellen / 2 = Aktuelle verwenden:

IF "%createip%" EQU "1" goto create
IF "%createip%" EQU "2" goto ipnow
goto wrongip

.. ist kürzer und weniger tippfehlerträchtig IMO.

b) und der Fairness halber (so gerne ich Bätchelchen zusammenbrate)
Es gibt auch CMD-Line-Tools zum ändern des User-Passworts. Die natürlich dann "pwchange.exe" oder "changepw.exe" heißen.
Sollten über Suchmaschinen zu finden sein.
Eventuell kannst Du mit so einem Utility diesen Aufruf:
"cmd /c PSEXEC \\%%i -u %username% -p %passwort% C:\%passfile%.bat > NUL"
durch einen direkteren Aufruf (ohne Zwischenbatch) ersetzen.

Bzw. ginge das an dieser Stelle nicht ohnehin ohne Temp-Batch??
PSEXEC \\%%i -u %username% -p %passwort% net user %username% %newpasswort% > NUL
Laut PsExec-Syntax kannst Du Parameter einfach mitgeben. Evtl noch den (Server-)Pfad vor die Net.exe.
Oder übersehe ich etwas?

Grübelnd
Biber