Startseite

© Juni 2015 • by dieseyer • all rights reserved • www.dieseyer.de

Du bist hier: dieseyer.de > . . . mehr > CDM
CMD
Batch-Programmierung / CMD-Dateien

Auch unter den Windows-Betriebssystemen der neusten Geneartion ist das verfügbar, was häufig als DOS-Box bezeichnet wird. Richtiger ist die Bezeichnung 'Eingabeaufforderung' oder engl. 'Command-Prompt'. Dieses 'schwarze Fenster' öffnet sich, wenn man z.B. über <Start> - <Ausführen> 'cmd' (oder richtiger cmd.exe) startet.

Der in diesem 'schwarzen Fenster' blinkende Unterstrich ist die Eingabeafforderung. . . . diese Aufforderung richtet sich an den Benutzer - er möge doch bitte etwas eingeben: Jede gedrückte Taste wird ala Tastatureingabe zunächst einmal nur angezeigt.

Ist man fertig mit der Eingabe fertig, wird diese Eingabe mit der [Eingabe]-Taste (bzw. engl. [Return]) abgeschlossen und zur Verarbeitung an die cmd.exe 'gesendet'. Diese erwartet eigentlich Befehle (statt irgendwelcher Zeichen) und versucht entspr. Programme zu finden und zu starten, wobei interne und externe Programme bzw. Befehle unterscheidet.

Interne und externe Befehle der cmd.exe

Die cmd.exe gehört zu jedem Windows-Betriebssystem und kann interne und externe Befhele abarbeiten. Interne Befehle lassen sich NICHT über <Start> - <Ausführen> starten - externe schon.

Externe Befehle sind meistens Programme im C:\Windows\System32 - Verzeichnis mit der Dateiendung .exe oder .cmd. Startet man über <Start> - <Ausführen> 'ping 12345' wird der externe Befehl (bzw. das Programm) 'ping.exe' gestartet und erhält dabei den Parameter '12345'. Beim Start wertet das Programm 'ping.exe' alle Parameter aus (in diesem Fall gibt es nur einen, der aus fünf Zeichen besteht) und versucht über das Netzwerk den PC mit dem Namen '12345' anzu-ping-en - DAS ist die Uafgabe des Programms. Ohne Parameter versucht das Programm dies dreimal (vergeblich), beendet sich dann und schließt das 'mitgebrachte' Fenster.

Interne Befehle lassen sich nicht über <Start> - <Ausführen> starten, zeigen in einer Eingabeaufforderung aber wertvolle Informationen - der Befehl 'dir' soll hier als Beispiel dienen . . . bitte auch mal 'ping 12345' in einer Eingabeaufforderung zum Vergleich starten. Wie oben angedeutet, bedeutet 'starten' in einer Eingabeaufforderung (nach der Eingabe über die Tastatur) die [Eingabe]-Taste zu drücken.

Um mehrerer Befehle nacheinander zu starten, schreibt man jeden Befehl für sich in eine Zeile. Hat man die Datei so umbenannt, dass sie nicht mehr .txt sondern .cmd heißt, kann diese CMD-Datei im Windows-Explorer durch einen Doppelklick gestartet werden. Eigentlich läuft das dann so ab: Durch den Doppelklick auf die CMD-Datei prüft Windows, was mit CMD-Dateien zu tun ist und startet die cmd.exe und übergibt als Parameter den kompletten Pfad zur CMD-Datei. (Mitunter muss im Windows-Explorer die Anzeige der Dateiendungen eingeschlatet werden: Im Windows-Explorer über 'Extras' - 'Ordneroptionen' - Reiter 'Ansicht' der Haken bei 'Erweiterungen bei bekannten Dateitypen ausblenden' entfernen.)

Im folgenden werden einge (zunächst) einfache CMD-Dateien vorgestellt. Jeder umrahmte Block kann markiert und in eine CMD-Datei eingefügft werden und sollte dann 'lauffähig' sein, kann also per Doppelklick im Windows-Explorer gestartet werden.

Ausgaben (im 'schwarzen DOS-Fenster')
@echo off
: alle folgenden Befehlszeilen der CMD werden vor der Ausführung NICHT angezeigt.

@echo on
: alle folgenden Befehlszeilen der CMD werden vor der Ausführung immer angezeigt.

echo Feine Sache das!
: die Befehlszeile beginnt mit 'echo' - 'echo' ist der (interne) Befehl, der 'Feine Sache das!' ausgibt.
: ist aktuell 'echo off' wird nur die Ausgabe 'Feine Sache das!' angezeigt
: ist aktuell 'echo on' wird vor der Ausgabe von 'Feine Sache das!' noch 'echo ... das!' ausgegeben.

@echo Feine Sache das!
: durch das @ vor 'echo' wird die Befehlszeile vor der Ausführung nicht angezeigt,
: auch wenn aktuell 'echo on' gesetzt ist.

@eco %0
: zeigt den den komplette Pfad zur CMD-Datei.

@type %0
: zeigt den Inhalt der CMD-Datei an.

@echo.
: zeigt eine Leerzeile.

@rem Kommentar / Erklärung
: wird nicht angezeigt; für Kommentare

An dieser Stelle (mal wieder) die Aufforderung, so oft wie möglich in Programmen und Skripten Kommentaren und Hinweisen einzufügen! Spätestens, wenn man eigenen Code wieder verwenden will, freut man sich über diese Infos! Die Übertreibung 'so oft wie möglich' führt vielleicht dazu, dass wenigstens gelegentlich Kommentare eingefügt werden. Denn: Wer mit Skripten arbeitet ist zu faul alles selber zu machen und deligiert deshalb seine Arbeit an diese Helferlein. Und wer faul ist, schreibt auch wenige Kommentare . . . leider.

Tastatureingabe (muss mit [Enter] abgeschlossen werden)
@echo off
@echo.
Set /p PCName==Bitte einen PCNamen eingeben:
@echo.
@echo Eingegebener PCName: '%PCName%'
@echo.
@echo.
@pause&&@pause

LogDatei mit aktuellem Datum im Dateinamen
Entscheidend ist hierbei, dass es ein 'deutsches Datum' ist 20.12.2012, weil die Zeichen ausgezählt werden.
Set LogDatei="%~dpn0%date:~-4%-%date:~-7,2%-%date:~-10,2%.log"
: %~dpn0 ergibt den Pfad zur aktuell aufgerufenen CMD OHNE Dateiendung (also ohne .cmd)
: %date:~-4% ergibt die letzten (rechten) 4 Zeichen des aktuellen Datums (also 2011 vom 03.05.2010)
: %date:~-7,2% ergibt die ersten (linken) 2 Zeichen der letzten (rechten) 7 Zeichen des aktuellen Datums (also 05 vom 03.05.2010)
: %date:~-10,2% ergibt die ersten (linken) 2 Zeichen der letzten (rechten) 10 Zeichen des aktuellen Datums (also 03 vom 03.05.2010)

Set LogDatei="%~dpn0%date:~6%-%date:~3,2%-%date:~0,2%.log"
: %~dpn0 ergibt den Pfad zur aktuell aufgerufenen CMD OHNE Dateiendung (also ohne .cmd)
: %date:~6% ergibt alle Zeichen nach dem 6. Zeichen des aktuellen Datums (also 2011 vom 03.05.2010)
: %date:~3,2% ergibt die ersten 2 Zeichen nach dem 3. Zeichen des aktuellen Datums (also 05 vom 03.05.2010)
: %date:~0,2% ergibt die ersten 2 Zeichen der letzten 0. Zeichen des aktuellen Datums (also 03 vom 03.05.2010)

Set LogDatei="%~dpn0%date:~-4%-%date:~-7,2%-%date:~-10,2%.log"

LogDatei mit fortlaufender Nummer im Dateinamen; 'Dateiname hochzählen'
Set Ziel=%~dp0%COMPUTERNAME%_
for /L %%N IN (10, 1, 99) DO If not Exist "%Ziel%_%%N.Txt" Set Ziel="%Ziel%_%%N.Txt"&& Goto :FreieDatei
:FreieDatei
@echo Ziel ==%ZIEL%==

: %~dp0 ergibt den Pfad zur aktuell aufgerufenen CMD (OHNE Dateiname)
: for /L %%N IN (10, 1, 99) zählt von 10 in einer Schritten bis 99; ab 10, damit die Zahlen immer zweistellig sind

Datei zeilenweise abarbeiten
Zunächst wird einen Datei mit PCNamen gefüllt, bevor jede Zeile der Datei als Parameter an eine Prozedur übergeben und von dieser angezeigt wird.
@echo off
Set PCDatei="%~dpn0.pcs"
Set PCDatei=%~dpn0.pcs
: Der Inhalt der Variable 'PCDatei' ist identisch mit dem Namen
: der CMD - nur die Endung ist .pcs statt .cmd

@echo Name der 'PCDatei': %PCDatei%
@echo.
@echo PC01 >> %PCDatei%
: durch die (doppelte) spitze Klammer wird die echo-Ausgabe
: in eine Datei umgeleitet, statt angezeigt.

@echo PC01 > %PCDatei%
: durch die (einzelne) spitze Klammer wird die echo-Ausgabe
: in eine neue Datei umgeleitet, statt angezeigt.

@echo %PCName% >> %PCDatei%
@echo PC02 >> %PCDatei%
@echo PC-Mein >> %PCDatei%
@echo PC-RADIO >> %PCDatei%
wait.vbs 1
@echo.
@echo Inhalt der 'PCDatei': %PCDatei% . . .
type %PCDatei%
: 'type' gibt den Inhalt einer Datei (auf den Bildschirm) aus

@echo.
@echo Zeilenweise abarbeiten . . . (Datei OHNE Gleichheitszeichen '='; OHNE einstellige Zahlen!)
@echo ACHTUNG: OHNE Gleichheitszeichen '='
@echo ACHTUNG: OHNE (einstellige?) Zahlen
FOR /F "tokens=*" %%i in (%PCDatei%) do call :EinzelPC %%i x-x
: für jede Zeile der Datei wird die Prozedur 'EinzelPC' aufgerufen;
: als erster Parameter wird der Zeileninhalt und als zweiter 'x-x'
: an die Prozedur übergeben.

@echo Zeilenweise Abarbeitung beendet.
@pause&&@pause&&goto :EOF


: Die Prozedur wird mit 'goto :EOF' beendet (EOF = 'End Of File')
:EinzelPC
    @echo Start der Prozedur ===%0===
    @echo Parameter 1: ===%1===
    @echo Parameter 2: ===%2===
    @echo Parameter 3: ===%3===
    @echo Ende der Prozedur ===%0===
goto :EOF

Ausgaben auswerten
Nachdem wir nun eine Datei mit PCNamen zeilenweise an eine Prozedur übergeben haben, soll die Prozedur die Zeilen nicht nur anzeigen, sondern prüfen, ob die PCs per ping.exe erreichbar (also eingeschaltet) sind - die CMD wird dazu nur in der Prozedur geändert:
:EinzelPC
    @echo Start der Prozedur ===%0===
    @echo Parameter 1: ===%1===
    @echo Parameter 2: ===%2===
    @echo Parameter 3: ===%3===
    Set Tst=
    : Umgebunsvariable leeren / löschen

    for /F "tokens=*" %%i in ('ping %1 -w 500 -n 2^|find /I "ttL"') do set Tst=%%i
    : -w 500   wenn der Ziel PC nicht antwortet, nach 500ms nicht weiter warten
    : -n 2     wenn der Ziel PC nicht antwortet, nach 500ms nicht weiter warten
    : 'find /i "ttL"' filtert die Ausgaben des Ping-Befehls und
    : lässt nur die Durch, die die Zeichenkette 'TTL' enthalten
    : Mit '/i' missachtet die find.exe Groß-/Kleinschreibung.

    If not "%Tst%"=="" @echo Gott sei Dank, der PC ==%1== ist erreichbar . . .

    @echo Ende der Prozedur ===%0===
goto :EOF


Registrei bearbeiten
REG.EXE gibt %errorlevel%=0 für erfolgreich' oder %errorlevel%=1 für Fehlgeschlagen zurück.

REG QUERY HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
: listet alle Unterschlüssel und alle Werte - Werte mit Daten)
: Im Schlüssel (Key) 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run'
: gibt es den Wert (Value) 'Adobe Reader Speed Launcher' - die Daten (Data)
: sind im Typ (Type) 'REG_SZ' enthalten:
: '"C:\Program Files\Adobe\Reader 9.0\Reader\Reader_sl.exe"'

REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" /v NachDerAnmeldung /t REG_SZ /d "notepad" /f
: Es wir der Wert (/v; Value) 'NachDerAnmeldung' mit dem Typ (Type) 'REG_SZ' angelegt
: und der Wert mit den Daten (/d; Date) "notepad" gefüllt. Gibt es den Wert, wird er
: ohne Rückfrage forciert (/f; force) überschrieben.

REG DELETE "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" /v "NachDerAnmeldung" /f
: Ohne Rückfrage den Wert (/v, Value) löschen.


Set HKLMKey="HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
Set Wert=NachDerAnmeldung
REG QUERY %HKLMKey% /v "%Wert%" | find /i "%Wert%" >"%~dpn0.temp"
: Schreibt nur ' NachDerAnmeldung REG_SZ notepad' in die .TEMP-Datei

Set /P Tst=<"%~dpn0.temp"

: Schreibt den Inhalt der .TEMP-Datei in die Umgebungsvariable %Tst%

Set Tst=%Tst:~28%
: (Über-) schreibt ab dem Zeichen 28 alle Zeichen in die Umgebungsvariable %Tst% -
: es bleibt 'notepad' in der Umgebungsvariable %Tst%

Set Tst=%Tst% """C:\1 x 1.txt"""
: Erweitert die Umgebungsvariable %Tst% auf 'notepad """C:\1 x 1.txt"""'

REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" /v NachDerAnmeldung /t REG_SZ /d "%Tst%" /f
: Es wir der Wert (/v; Value) 'NachDerAnmeldung' mit dem Typ (Type) 'REG_SZ' angelegt / überschrieben
: und der Wert mit den Daten (/d; Date) 'notepad "C:\1.txt"' gefüllt.


WindowsInstaller (MSIExec.exe) neu registrieren:

%sys%\MSIEXEC.EXE /UNREGISTER
%sys%\MSIEXEC.EXE /REGSERVER

: Unter x64-Windows gibt es die MSIExec.exe zwei mal:
: %systemroot%\SysWOW64\msiexec.exe (C:\Windows\SysWOW64\msiexec.exe; für 32Bit-WinInstaller)
: %systemroot%\System32\msiexec.exe (C:\Windows\System32\msiexec.exe; für 64Bit-WinInstaller)
Set Tst="%systemroot%\System32\MSIEXEC.EXE"
If exist %Tst% %Tst% /UNREGISTER && %Tst% /REGSERVER
Set Tst="%systemroot%\SysWOW64\MSIEXEC.EXE"
If exist %Tst% %Tst% /UNREGISTER && %Tst% /REGSERVER


MSIEXEC /i "AnwendungXXX.msi" REBOOT=ReallySuppress /qb-! /l*v "AnwendungXXX.log" ROOTDRIVE=%Systemdrive%\
: "%systemroot%\SysWOW64\MSIExec" /i "AnwendungXXX.msi" REBOOT=ReallySuppress /li+ "%LogVerz%AnwendungXXX.msi.log"



Einige NET.EXE Befehlszeilen:

NET USER /ADD dieseyer 1xGanzGeheim! /PASSWORDCHG:NO /EXPIRES:NEVER /COMMENT:"an dieseyer"
: Legt einen lokalen User 'dieseyer' mit dem Passwort '1xGanzGeheim!' an -
: Uset darf Passwort nicht ändern und Passwort läuft nicht ab.

NET LOCALGROUP "Administratoren" dieseyer /ADD
: Fügt den User 'dieseyer' zu den 'Lokalen Administratoren' hinzu.
: Achtung: Auf einem Engl. System heisst es "Administrators"



Häufig benutzte Befehlszeilen mit etwas Erklärungen:

Set ZielVerz=C:\xcopy.tst\unsinn
XCopy /Y/S/E/V/D/C/H/R "%~dp0daten.tst\*.*" "%ZielVerz%\"
: kopiert alle neuen Dateien (auch versteckte) und Verzeichnisse (auch leere)
: aus den Verzeichnis 'daten.tst' im aktuellen Verzeichnis.
: Fehlt etwas vom Zielervzeichnis, wird es erstellt.
: /Y   Überschreiben vorhandener Zieldateien ohne Rückfrage (Yes).
: /S   Kopiert Verzeichnisse und Unterverzeichnisse, die nicht leer sind.
: /E   Kopiert alle Unterverzeichnisse (leer oder nicht leer).
: /V   Überprüft jede neue Datei auf Korrektheit (Verify).
: /D   Nur neuere Dateien kopieren (Date).
:      /D:[Datum] Nur neuere Dateien nach [Datum] kopieren.
: /C   Setzt das Kopieren fort, auch wenn Fehler auftreten.
: /H   Kopiert auch Dateien mit den Attributen 'Versteckt' und 'System'.
: /R   Überschreibt schreibgeschützte Dateien.


SCHTASKS /S %COMPUTERNAME% /Create /RU %COMPUTERNAME%\Administrator /RP DasAdminPwd /SC TÄGLICH /ST 23:00:00 /TN "Backup des Admins" /TR "C:\backup\Backup.cmd"
: /S   ZielPC-Name; ist auch lokal erforderlich, wenn ein User mit Passwort hinterlegt wird
: /Create   'Geplanten Tasks' erstellen
: /RU   Username (Remote User)
: /RP   Userpasswort (Remote Password)
: /SC   Zeitplan (DAILY auf engl. System)
: /ST   Zeitplan-Uhrzeit
: /TN   Taskname
: /TR   Auszuführender Tasks / auszuführende Befehlszeile


@ver | find /i "WINDOWS XP"
if %errorlevel%==0 @echo shutdown -f -r -t 600 -c "%~nx0 löst einen Reboot aus." -m \\%COMPUTERNAME%
@ver | find /i "[Version 5.2.3790]"
if %errorlevel%==0 @echo shutdown -f -r -t 600 -c "%~nx0 löst einen Reboot aus." /d P:2:4 -m \\%COMPUTERNAME%
@echo %Tst%
: Bei Win-Betriebssystem höher WinXP (auch WinXP x64) muss für 'schutdown.exe' ein 'erweiterter'
: Grund mit übergeben werden. (Damit die Zeilen 'wirken', muss das '@echo' entfernt werden.)



Gelegentlich benutzte Befehlszeilen mit etwas Erklärungen:

netsh firewall add portopening protocol=TCP port=4711 name="CMD_Ports (port=4711)" scope=CUSTOM addresses=LocalSubnet profile = ALL
netsh firewall add allowedprogram program = "C:\WINDOWS\system32\ProGramm.exe" Name = "CMD_Progr ProGramm.exe" profile = ALL
netsh firewall show state
netsh firewall show config
netsh firewall reset

Die 'Autologon.exe' von BB963905 setzt das lokale AutoLogon, ohne dass das Passwort im Klartext in der Registry steht:
Autologon.exe UserName Dom Pwd

Ruhezustand (Hibernation, Supend to Disk) ausschalten (WinXP und Win7):
powercfg -H OFF

Standby ausschalten; bei Batteriebetrieb (dc) bzw. Netz-/Wechslestrombetrieb (ac) (nicht WinXP):
powercfg /X /standby-timeout-ac 0
powercfg /X /standby-timeout-dc 0



Austausch von Zeichen bzw. 'Suchen und Ersetzen' (Replace) z.T. aus 'An A-Z Index of the Windows CMD command line'

Die Aufgabe: An eine CMD wird ein Verzeichnis übergeben und die entspr. Log-Datei soll im Log-Datei-Namen
den Verzeichnisnamen widerspiegeln. Deshalb wird der \ (Backslash) gegen ³ (hoch 3) getauscht. Und ggf.
umgebende " (Anführungszeichen) werden vom Parameter %1 entfernt und für die Log-Datei hinzu gefügt.
Set Tst=%1
Set Tst=%Tst:\=ü%
@echo %Tst%
Set Tst=%Tst:"=%
@echo %Tst%

Set LogVerz=%~dp0Logs\
If not Exist %LogVerz% md %LogVerz%
Set LogDatei="%LogVerz%_%Tst%.log"
@echo %LogDatei%



↑ Zum Seitenanfang ↑