Fast alles über eine Konsole von vielen

An unordered list with the default layout

An unordered list with inline layout

div.inline-list ul {
	padding: 3px 0;
	margin-left: 0;
	border-bottom: 1px solid #778;
}
div.inline-list ul li {
	display: inline;
	list-style: none;
	border: 1px solid #f66;
	border-bottom: none;
	margin: 0;
	margin-right: 5px;
	padding: 3px;
}

cmd.exe als Shell

Seit Windows 2000 oder vielleicht auch schon seit Windows NT gibt es im Kommandozeilen-Interpreter cmd.exe die Möglichkeit die Codepage vom dem DOS-typischen Standard 850 auf Windows ANSI 1252 umzustellen.
Wichtig ist dabei aber auch, dass als Font nicht die Rasterschriftart sondern der alternative True-Type Font Lucida Console verwendet wird, sonst werden die deutschen Umlaute trotzdem nicht korrekt dargestellt.
Hilfreich ist das vor allen Dingen bei den klassischen Commandline Tools aus der Unix-Welt, also vi, perl oder auch die Datenbank-Terminals mysql, psql und sqlplus. Dagegen werden aber die Hilfetexte zu internen Kommandos der Shell oder was sonst noch alles so auf deutsch vorhanden ist, falsch ausgegeben. Denn die sind ja auf die cp850 Codierung ausgelegt.

Den Befehl, den man sich dafür merken muss, heißt "Change Codepage" chcp 1252 und man lässt ihn am besten gleich beim Start der Command-Shell direkt ausführen.

cmd.exe /k chcp 1252

Manchmal reichen vier Stellen auch nicht mehr aus für die Angabe einer Code-Page, etwa wenn es Unicode UTF-8 sein soll. Dann braucht es:

cmd.exe /k chcp 65001
EingabeaufforderungX
Aktive Codepage: 1252.

C:> route PRINT
===========================================================================
Schnittstellenliste
0x1 ........................... MS TCP Loopback interface
0x2 ...00 e0 7d 9f 35 2b ...... NDIS 4.0 driver

===========================================================================
===========================================================================
Aktive Routen:
Netzwerk  Ziel             Netzmaske        Gateway       Schnittst. Metrik
          0.0.0.0          0.0.0.0     192.168.1.91    192.168.1.15       1
        127.0.0.0        255.0.0.0        127.0.0.1       127.0.0.1       1
      192.168.1.0    255.255.255.0     192.168.1.15    192.168.1.15       1
     192.168.1.15  255.255.255.255        127.0.0.1       127.0.0.1       1
    192.168.1.255  255.255.255.255     192.168.1.15    192.168.1.15       1
        224.0.0.0        224.0.0.0     192.168.1.15    192.168.1.15       1
  255.255.255.255  255.255.255.255     192.168.1.15    192.168.1.15       1
===========================================================================

Sowas hätte man dann auch gerne in einer Verknüpfung zum Schnellstart einer Kommandozeile mit den entsprechenden Optionen. Dass man dann %ComSpec% statt cmd.exe verwendet, liegt ja noch nahe, weil genau diese Form auch in der von Windows angelegten Verknüpfung für die "Eingabeaufforderung" genutzt wird. Nur will man halt manchmal vielleicht auch noch eine Environment-Variable setzen, und dann ist lustiges Ausprobieren angesagt:

cmd.exe /k chcp 1252; set LANG=de_DE

meldet sich erst mal mit folgender Fehlermeldung "Parameterformat falsch - 1252;" Den Strichpunkt durch ein Space von der Codepage abzusetzen, hilft auch nicht weiter. Also setzt man das ganze nach dem /k in Quotes. Das hilft aber auch nichts. Oder vielleicht kann man die k-Option auch mehrfach verwenden? Nein, nix geht. Letztendlich erfolgreich ist:

cmd.exe /k "chcp 1252 && set LANG=de_DE"

Manchmal sollte man eben doch die Hilfe durchlesen, anstatt nach einem schnellen

dir *.txt ; attrib *.exe

vorschnell anzunehmen, dass die cmd.exe den Strichpunkt als Kommandotrenner unterstützt und man auf dieses geliebte Feature der Bash nicht verzichten muss. Mit einer kleinen Umstellung der obigen Befehlssequenz hätte man das auch ohne Doku rausgefunden.

attrib *.exe ; dir *.txt

Command Prompt here

Seit Windows 95 gibt es ja die netten Powertoys, die unter anderem auch ein Registry-Skript mitbrachten, um das Kontextmenüs eines Ordners so zu erweitern, dass man durch einen rechten Mausklick auf den Ordner eine Konsole öffnen konnte, die eben diesen Ordner als aktuelles Arbeitsverzeichnis hatte. Nach 2 oder 3 Monaten Einarbeitungszeit hat dieses Feature bei mir aber ein bisschen seinen Mehrwert verloren, weil ich eben doch meistens nur eine Konsole geöffnet hatte und, wenn ich dann in ein bestimmtes Verzeichnis wollte, in der Konsole cd und ein Leerzeichen tippte und dann das Verzeichnis aus dem Explorer per Drag'n'Drop in die Konsole fallen ließ. (Seit UAC, also seit Vista und 7, funktioniert das leider nicht mehr, wenn die Konsole mit anderen Benutzerrechten läuft.)
Ein anderes Problem waren Ordner auf Remote-Systemen. Auf denen hat das nämlich auch nicht funktioniert. Windows 7 braucht für das Command-Prompt Feature keine Powertoys mehr, sondern hat diese Funktionalität gleich mit eingebaut. Allerdings versteckt, denn den entsprechenden Kontextmenüeintrag sieht man nur, wenn man während des Mausklicks die Shift-Taste gedrückt hält. Natürlich gibt es im Netz schon Tipps, wie man den Eintrag auch, ohne die Shift Taste bemühen zu müssen, zu sehen bekommt. Es gibt aber keinen Grund, den Powertoys nach zu trauern, denn die interne Funktionalität ist besser umgesetzt. Ein Blick in den Registrierungsschlüssel HKEY_CLASSES_ROOT\Directory\shell verrät das. Da wird jetzt

cmd.exe /s /k pushd "%V"

statt

cmd.exe /k cd "%1"

verwendet. Die Option /s oder %V als Parameter regen dazu an, sich nochmal mit help cmd die Hilfe zu cmd.exe anzuschauen (was durchaus aufschlussreich ist). Entscheidend ist aber die Verwendung von pushd statt cd. pushd kann nämlich mit UNC Pfaden umgehen (übrigens schon seit Windows 2000), wenn die Befehlserweiterungen aktiviert sind (was in allen neueren Windowsversionen so ist). Die folgende Kommando-Sequenz verdeutlicht das sehr eindrücklich. Und wenn dabei der Explorer im Hintergrund sichtbar ist, lässt sich auch gut sehen, dass beim pushd ein neues Netzlaufwerk Z: angelegt wird und bei popd wieder verschwindet.

C:\Windows\system32\cmd.exeX
C:\Temp> cd \\iova\shared\anything
"\\iova\shared\anything"
CMD unterstützt keine UNC-Pfade als aktuelles Verzeichnis.

C:\Temp> pushd \\iova\shared\anything

Z:\anything> popd

C:\Temp> help pushd

Sichert das aktuelle Verzeichnis für die Verwendung des Befehls POPD, und
wechselt dann zum angegebenen Verzeichnis.

PUSHD [Pfad | ..]

  Pfad     Gibt das Verzeichnis an, zu dem gewechselt werden soll.

Wenn die Befehlserweiterungen aktiviert sind, akzeptiert der PUSHD-Befehl
neben dem normalen Laufwerkbuchstaben und -pfad auch Netzwerkpfade als
Parameter. Wenn ein Netzwerkpfad angegeben ist, legt PUSHD einen temporären
Laufwerkbuchstaben fest, der auf die angegebene Netzwerkressource zeigt.
Das aktuelle Laufwerk und Verzeichnis wird dann unter Verwendung des neu
definierten Laufwerkbuchstaben gewechselt. Temporäre Laufwerkbuchstaben
werden von Z: abwärts zugeordnet, angefangen beim ersten noch nicht
verwendeten Buchstaben.

cmd.exe auf 64 bit Windows Systemen mit einem 32 bit Subsystem

Auf einem 64 bit Windows System sind zwei Command Interpreter vorhanden, einer für das 32 bit Subsystem (im Task-Manager an dem *32 beim Prozessname zu erkennen) und einer für den nativen 64 bit Modus. Windows Task Manager showing 64 and 32 bit cmd.exe

Der Filesystem Redirection Mechanismus für 32 bit Anwendungen, der dafür sorgt, dass Programme denken, dass sie im System32 Systemverzeichnis sind, tatsächlich aber die Dateien aus dem SysWOW64 Verzeichnis untergeschoben bekommen, führt da mitunter zu skurrilen Situationen.
In dem dargestellten Fall wird in einem 64-bit Command-Interpreter in das System32 Verzeichnis gewechselt und dort die shell32.dll Systemdatei ausgelesen. Soweit scheint das alles zu funktionieren, allerdings ergibt sich für die Datei ein anderer MD5 Hashwert, wenn der mit dem Powershell Skript ermittelt wird. Ein Bug im Skript? Was stimmt da nicht?

C:\Windows\System32\cmd.exeX
C:\>cd \windows\System32

C:\Windows\System32>dir shell32.dll

 Verzeichnis von C:\Windows\System32
06.08.2015  19:04        14.176.768 shell32.dll

C:\Windows\System32>md5sum shell32.dll
f811b932e3dba308014f8c870f752f16 *shell32.dll

C:\Windows\System32>powershell -File C:\tools\md5sum.ps1 -FileName shell32.dll
885b08e5ec912d2680f533094b87770d

C:\Windows\System32>md5sum ../System32/shell32.dll
f811b932e3dba308014f8c870f752f16 *../System32/shell32.dll

C:\Windows\System32>dir ..\System32\shell32.dll

 Verzeichnis von C:\Windows\System32
06.08.2015  19:04        14.176.768 shell32.dll

C:\Windows\System32>powershell -File C:\tools\md5sum.ps1 -FileName ..\System32\shell32.dll
885b08e5ec912d2680f533094b87770d

C:\Windows\System32>powershell -File C:\tools\md5sum.ps1 -FileName ..\SysWOW64\shell32.dll
f811b932e3dba308014f8c870f752f16

C:\Windows\System32>md5sum ..\SysWOW64\shell32.dll
md5sum: ..\SysWOW64\shell32.dll: No such file or directory

C:\Windows\System32>dir ..\SysWOW64\shell32.dll

 Verzeichnis von C:\Windows\SysWOW64
06.08.2015  18:44        12.875.776 shell32.dll

Der entscheidende Punkt ist, dass das Programm zum Berechnen des MD5 Hashs md5sum ein 32 bit Programm ist. Obwohl das aktuelle Verzeichnis das System32 ist, sieht es dessen Dateien nicht, sondern die aus SysWOW64 und für die berechnet es den Hash. Der f8811... Hash-Wert ist also nicht von der shell32.dll Datei aus System32 sondern aus SysWOW64. In letzter Konsequenz bedeutet das, dass 32 bit Programme die tatsächlichen, echten Dateien im System32 nie zu sehen bekommen und damit auch keine Programme ausführen können, die es nur in einer 64 bit Variante, nur im realen System32 gibt.

Ein anderes Bild ergibt sich, wenn von Beginn an ein 32 bit Command-Interpreter gestartet wird und damit alles, was im schwarzen Block der Konsole läuft, in die 32 bit Quarantäne eingekesselt ist.

C:\Windows\SysWOW64\cmd.exeX
C:\Windows\System32>md5sum shell32.dll
f811b932e3dba308014f8c870f752f16 *shell32.dll

C:\Windows\System32>powershell -File C:\tools\md5sum.ps1 shell32.dll
f811b932e3dba308014f8c870f752f16

C:\Windows\System32>md5sum ../System32/shell32.dll
f811b932e3dba308014f8c870f752f16 *../System32/shell32.dll

C:\Windows\System32>>powershell -File c:\tools\md5sum.ps1 ..\System32\shell32.dll
f811b932e3dba308014f8c870f752f16

Nur weil es das gleiche Kommando ist, bedeutet das nicht, dass das Powershell Skript md5sum.ps1 immer die "64 bit Version" veranschaulicht. Die Powershell gibt es genauso wie die traditionelle Shell cmd.exe in einer 64 bit und einer 32 bit Version. Wenn die Powershell von einem SysWOW64 Command-Interpreter gestartet wurde, ist es immer auch eine Powershell im 32 bit Modus und eben keine 64 bit Powershell. Und damit ist sie genauso an die Redirection-Scheinwelt gebunden, wie alle anderen 32 bit Programme auch.

Aus der Hilfe zu Windows 2000 oder "nur zur Suche"

Regedit.exe ist im Lieferumfang von Windows 2000 hauptsächlich aufgrund der Sucheigenschaften enthalten. Sie können Regedit.exe verwenden, um in der Registrierung Änderungen durchzuführen, jedoch können nicht alle Funktionen oder Datentypen ordnungsgemäß angezeigt oder bearbeitet werden. Regedit.exe stellt die folgenden Funktionen oder Leistungsmerkmale nicht zur Verfügung:

Microsoft empfiehlt die Verwendung von Regedit.exe nur zum Suchen und den Einsatz von Regedt32.exe für die Bearbeitung der Registrierung.

xcopy und die /exclude Option

help xcopy in der deutschen Version sagt:
  /EXCLUDE:Datei1[+Datei2][+Datei3]...
            Gibt eine Liste von Zeichenfolgen an. Wenn eine der
            Zeichenfolgen Teil des absoluten Verzeichnispfads
            der zu kopierenden Datei ist, wird diese Datei vom
            Kopiervorgang ausgeschlossen. Beispiel: Bei der
            Zeichenfolge \obj\ oder .obj werden alle Dateien
            unterhalb des Verzeichnisses OBJ bzw. alle Dateien mit
            der Erweiterung .obj vom Kopiervorgang ausgeschlossen.

Aber das naheliegende /EXCLUDE:.obj funktioniert nicht. Beim zweiten Blick auf die Option fällt auf, dass da nicht .ext1 steht sondern Datei1. Und in der Tat muss da eine Datei angeben werden, die diese beschriebenen Zeichenfolgen enthält. Und zwar immer ein Pattern pro Zeile.

forfiles als Ersatz für GNU find

forfiles /S /M *.aspx /C "%COMSPEC% /c echo @fsize @relpath @file"
1130 ".\www\WebForms\Demo\DataProviders.aspx" "DataProviders.aspx"
5002 ".\www\WebForms\Demo\DataControls.aspx" "DataControls.aspx"
3239 ".\www\WebForms\Demo\Default.aspx" "Default.aspx"
4191 ".\www\WebForms\Demo\Download.aspx" "Download.aspx"
353 ".\www\WebForms\Demo\DownloadProgress.aspx" "DownloadProgress.aspx"
703 ".\www\OracleAccess\OracleAccess\Default.aspx" "Default.aspx"

forfiles hat noch weitere Optionen, die man sich mit forfiles /? ausgeben lassen kann. Das oben angeführte Beispiel macht nun wenig mehr als ein simples "dir /s *.aspx". Allerdings ist die Ausgabe dank der Platzhalter-Variablen flexibler anzupassen.

Commands for the daily life of an administrator

The basic idea is to keep the desktop and the GUI for the currently logged in non-privileged user and start a console with Administrator privileges. WinXP and Vista came up with concepts like switching users, but to my understanding this is a waste of resources because it simply hides the current user and overlays it with the new user. Think of having two desktops (or even more if you did switch more than once) but only one of them is visible.

If you are familiar how to start the most common system utilities from the command line you won't need this bloated concept and can simply use the Windows counterpart to the UNIX su: runas. This is available for all Windows versions since Windows 2000 (and basically the reason that made me switch from NT to 2000). It is integrated into some Startmenu shortcuts that ask you if you want to run the program with a different user identity, but it is most useful to start the command shell with administrator rights and in a second step start any system tools that you might need from that privileged console.

There is one caveat and this is the registry hive for the current user. Most applications and also the system tools store their settings there, but what is the current user for this administrator console? The answer is: this can be specified by command line parameters of the runas command. Typically you start the privileged console with:

%SystemRoot%\system32\runas.exe /user:administrator "%ComSpec% /k"

This throws you into the environment of the default user, which is somehow no man's land. You can verify this if you output the environment with set and look for the user related variables like HOMEPATH, TEMP, USERNAME or USERPROFILE:

 ...
SystemRoot=C:\WINNT
TEMP=C:\WINNT\TEMP
TMP=C:\WINNT\TEMP
USERPROFILE=C:\home\Default User

HOMEPATH and USERNAME are not set at all. This makes it difficult for the OS to load the user's registry hive and consequently any user specific changes will be lost when you start the same application the next time. The prefered way is mostly to work in the environment of the user that you specify after /user:. Add the command line switch /profile:

%SystemRoot%\system32\runas.exe /profile /user:administrator "%ComSpec% /k"
 ...
SystemRoot=C:\WINNT
TEMP=C:\home\ADMINI~1\LOKALE~1\Temp
TMP=C:\home\ADMINI~1\LOKALE~1\Temp
USERDOMAIN=GRAPPA
USERNAME=Administrator
USERPROFILE=C:\home\Administrator

With another switch /env you can stay in the environment of the currently logged in user

%SystemRoot%\system32\runas.exe /env /user:administrator "%ComSpec% /k"

But though you are in the environment of this user you can't use his network shares because the credentials are different. In other words something like start \\remote-server\company.doc won't work. You can check this with net use in the privileged console that will give you an empty list.

 ...
SystemRoot=C:\WINNT
TEMP=C:\home\theuser\LOKALE~1\Temp
TMP=C:\home\theuser\LOKALE~1\Temp
USERDOMAIN=GRAPPA
USERNAME=theuser
USERPROFILE=C:\home\theuser

To Start .cpl files from the command line with control.exe you need to know their file name:

 appwiz.cpl     Software Installation
 desk.cpl       Graphik and Desktop Configuration
 jpicpl32.cpl   Java Plugin
 main.cpl       Mouse Configuration (less important as it seems to be)
 mmsys.cpl      Multimedia
 odbccp32.cpl   ODBC Configuration
 timedate.cpl   Time and Date
 sysdm.cpl      System Configuration (Environment, Profiles, ..)
 sticcpl.cpl    Scanner and Cameras
 ------- since Windows 7 ----------
 Firewall.cpl   Windows Firewall   Both are not very helpful when started
 ncpa.cpl       Network adapters   with control from a cmd.exe window
                                   with admin privileges because they open
                                   a Explorer window and fallback to the
                                   privilege of the currently active user.
                                   (Hence the runas can't help)

Start the management console with mmc

certmgr.msc
ciadv.msc
compmgmt.msc    Contains everything (marked with * in this list
devmgmt.msc(*)  Device Manager
dfrg.msc        
diskmgmt.msc(*) View disks, partitions and their filesystems
eventvwr.msc(*) Event viewer
faxserv.msc
fsmgmt.msc(*)   SMB shares
gpedit.msc
ias.msc
lusrmgr.msc     User and Groups (not active in the Windows HOME editions)
ntmsmgr.msc
ntmsoprq.msc
perfmon.msc     Performance-Monitor
secpol.msc
services.msc(*) Start, stop and configure services
WF.msc          Windows Firewall (since Windows 7)
wmimgmt.msc(*)  WMI

More information can be found at commandwindows.com

Use of cacls:

echo j| cacls cool.ini /E /G Benutzer:C

echo j is to directly confirm the change

/E
Nearly always needed otherwise you will delete the existing rights for all other users

Or you use the extended version for cacls from the Microsoft resource kit: XcAcls.exe

The following command edits the ACL of a file or a directory, but its effect on a directory is different. The ACL added to the directory is also an inherit ACL for new files created in this directory.

In this example, the command gives TestUser read, write, run, and delete rights on all new files created in this directory, but only read and write permissions on the directory itself.

xcacls *.* /G TestUser:RWED;RW /E /Y

The /Y works as the analogous parameters for move or copy. In contrary to the standard cacls command, xcacls allows to skip the confirmation prompting with this option.