Batch - Betriebssysteminformationen abfragen (auch ohne WSH) - NT, 200x, XP, Vista, ... - Name ink. Typ (Server, Home, etc.), Version, Product Suite (Terminal Server, etc.), Sprache und Windows Service Pack, 32 oder 64 Bit
Der Beitrag, inkl. Quelltext, ist Gemeinfrei (er darf ohne jegliche Einschränkung genutzt werden).
In dieser Anleitung soll eine Batch-Funktion gebaut werden, die gebräuchliche Betriebssysteminformationen ermittelt kann und dabei auch in der Lage ist zu prüfen, ob bestimmte Eigenschaften für das aktuelle System zutreffen (also ob es sich z. B. um einen Terminal Server handelt, ob Service Pack 2 [oder womöglich höher] installiert wurde, ob die deutsche Sprachversion von Windows verwendet wird, etc.).
Die Batch soll ohne .vbs und anderen optionalen Skriptsprachen auskommen. Ziel ist es also, eine Batch-Funktion zu schreiben, die möglichst auf allen Computern ablauffähig ist, auf denen ein Windows-Betriebssysem läuft; also auch auf Computern, auf denen kein Windows Scripting Host (WSH) läuft.
Einschränkung: Da Batch-Funktionen erst seit NT3.51 unterstützt werden, ist der Ablauf unter älteren Betriebssystemen (Win3.x bis Win9x) nicht möglich.
Es wird zunächst gezeigt, wie man mit der Funktion umgeht. Dabei soll ein Überblick geschaffen werden, was sich mit der Funktion machen lässt. Der eigentliche Funktionscode ist recht lang, da er die Besonderheiten zahlreicher Betriebssystemversionen berücksichtigen muss. Der Code befindet sich am Ende des Beitrages.
aufgerufen.
Unter Windows XP könnte das die folgende Ausgabe bewirken:
Zudem ist es möglich, die Ausgabezeile wie folgt einer Variablen (hier _x) zuzuweisen:
Eine Aufschlüsselung der Werte ist dann in folgender Weise denkbar:
oder
Das lässt sich auch auf die hier gezeigte Batch-Funktion anwenden. Die denkbar einfachste Abfrage ist die nach dem verwendeten Betriebssystem-Namen. Sie kann wie folgt erfolgen:
bzw.
Es ist auch möglich, mehrere Anweisungen an die Funktion zu binden
Mögliche Betriebssystem-Namen, die sich hier abfragen lassen, sind z.B.
Grundsätzlich sollte die Funktion auf allen Windows-Versionen laufen, die auf NT basieren, von NT3 bis Vista und Nachfolgende, wobei die Namen nur bis zur maximal gewünschten Übereinstimmung angegeben werden müssen. Also wird hier z. B. „NT“ angegeben, so ist die Bedingung unter NT3 und NT4 erfüllt. Wird stattdessen „3“ angegeben, so passt 2003 und NT3 in das Suchmuster der Funktion.
Auf gleicher Weise lassen sich nicht nur die Betriebssystem-Namen abfragen, sondern auch sämtliche andere Felder, die die Funktion ohne Parameter ausgegeben hat.
Bei einer "Windows XP Home"-Version würde nur die erste Zeile ausgegeben werden. Eine englische Variante von "Windows XP Professional" würden die beiden ersten Ausgaben hervorbringen. Bei einer deutschen Variante von "Windows XP Professional" würden alle vier Ausgabezeilen zu sehen sein. Die Anfrage wurde so formuliert, dass als weitere Bedingung genau das "Service Pack 2" (nicht höher oder niedriger) installiert sein muss, um eine Ausgabe zu erzeugen.
Hinweis: Seit Windows Vista wurde die Länderkennung von German in de geändert. Eine entsprechende Abfrage nach einer deutschen 32-Bit Variante von Windows Vista mit beispielsweise Service Pack 1 muss also wie folgt erfolgen:
Auch Abfragen ohne Angabe des Betriebssystem-Namens sind möglich:
Die folgende Abfrage zeigt, wie man ermitteln kann, ob es sich um Windows 2000 mit Service Pack 2 oder höher handelt. Das schließt Service Pack 3 genauso mit ein, wie neuere Versionen von Windows (2003, 2008, etc.). Das wird erreicht, indem die anderen bekannten Systeme ausgeschlossen werden (hier beispielhaft auch XP und Vista):
Künftige Betriebssystem-Versionen führen in diesem Beispiel ebenfalls zur Abarbeitung des
Bedeutung der Versionsfelder:
| | '-->Änderungen in diesem Bereich zeigen an, dass ein Fehler beseitigt
| | oder eine Optimierung vorgenommen wurde
| '---->Der Parameteraufbau zu einer Option oder der Funktionsumfang hat
| sich verändert (neue Optionen, etc.)
'------->Es wurde eine grundlegende Änderung vorgenommen (allgemeiner
Parameteraufbau, Rückgabewert oder ähnliches)
Version 2.0.1: In der vorherigen Version schlug die Anweisung
leider auch bei z.B. "Windows 2003 E
Version 2.0.0: Der Rückgabewert enthält nun ein zusätzliches Feld, welches angibt, ob es sich um eine 32-Bit- oder eine 64-Bit-Variante von Windows handelt. Die Abfrage kann wie folgt erfolgen:
Version 1.0.3: Windows Vista kennt keine prodspec.ini mehr. Die Länderkennung befindet sich jetzt in der Variablen %LC_LANG%, allerdings als en oder de und nicht als German. Damit muss man wohl leben. Die allgemeine Produktinformation findet sich jetzt in der Registry wieder. Der Code und die Anleitung wurden entsprechend angepaßt. -- NeonZero 29.01.2009
Version 1.0.2: Anders als unter Windows 2000 (und neuer) wird unter NT4 die Information über die Verfügbarkeit eines Terminal Servers nicht unter ProductSuite abgelegt. Vielmehr ist sie Bestandteil der allgemeinen Produktinformation ("Windows NT Server 4.0 Terminal Server Edition"). Zur Vereinheitlichung wurde der Eintrag "Terminal Server Edition" aus diesem (ersten) Feld entfernt und in das (dritte) Feld ProductSuite verschoben. Damit sollte nun auch unter NT4 der Terminal Server wie in der Anleitung beschrieben im dritten Feld abfragbar sein (
Version 1.0.1: Das Auslesen der Registry-Einträge wurde derart angepaßt, dass nun auch NT3, NT4 und Windows 2000 unterstützt werden. Einzige Einschränkung: Eine Auflistung der "ProductSuite" (unter "HKLM\System\CurrentControlSet\Control\ProductOptions") ist mir unter diesen alten Betriebssystemen noch nicht gelungen, da dies ein MULTI_SZ-Eintrag ist. Das bedeutet, dass die Funktion so tut, als ob auf dem System keine ProductSuite installiert wurde. Alle anderen Informationen sind ohne Einschränkung abfragbar. XP, Windows 2003 und neuer sind von dieser EInschränkung nicht betroffen. Wenn jemand eine Idee hat, wie sich unter Windows 2000 mit Standardmethoden (ohne WSH und ohne ein zusätzliches Tool installieren zu müssen) ein MULTI_SZ-Eintrag auswerten läßt, dann wäre ich für einen Hinweis dankbar. -- NeonZero 13.01.2009
Version 1.0.0: Erste Version, die lediglich unter XP, Windows 2003 und neueren Versionen von Windows funktioniert; sie nutzt reg.exe, die von NT3 bis w2k auf einer Standardinstallation noch nicht vorhanden ist (das wird erst ab Version 1.0.1 berücksichtigt - danke an @paulepank für den Hinweis). -- NeonZero 11.01.2009
Tipp: Wird der Inhalt in den Quelltextfenstern chaotisch angezeigt, kann es hilfreich sein dort auf den Link "Quelltext" (oben rechts) zu klicken. Es öffnet sich dann ein separates Fenster, welches in der maximierten Darstellung, je nach Bildschirmauflösung, den unerwünschten Zeilenumbruch unterbindet.
In dieser Anleitung soll eine Batch-Funktion gebaut werden, die gebräuchliche Betriebssysteminformationen ermittelt kann und dabei auch in der Lage ist zu prüfen, ob bestimmte Eigenschaften für das aktuelle System zutreffen (also ob es sich z. B. um einen Terminal Server handelt, ob Service Pack 2 [oder womöglich höher] installiert wurde, ob die deutsche Sprachversion von Windows verwendet wird, etc.).
Die Batch soll ohne .vbs und anderen optionalen Skriptsprachen auskommen. Ziel ist es also, eine Batch-Funktion zu schreiben, die möglichst auf allen Computern ablauffähig ist, auf denen ein Windows-Betriebssysem läuft; also auch auf Computern, auf denen kein Windows Scripting Host (WSH) läuft.
Einschränkung: Da Batch-Funktionen erst seit NT3.51 unterstützt werden, ist der Ablauf unter älteren Betriebssystemen (Win3.x bis Win9x) nicht möglich.
Es wird zunächst gezeigt, wie man mit der Funktion umgeht. Dabei soll ein Überblick geschaffen werden, was sich mit der Funktion machen lässt. Der eigentliche Funktionscode ist recht lang, da er die Besonderheiten zahlreicher Betriebssystemversionen berücksichtigen muss. Der Code befindet sich am Ende des Beitrages.
Inhaltsverzeichnis
Aufruf der Funktion
Die Funktion wird im Folgenden „FncWinVer“ genannt und percall :FncWinVer [Parameter]
aufgerufen.
Betriebssysteminformationen ermitteln
Sobald die Funktion ohne Parameter aufgerufen wird, werden die Betriebssysteminformationen ein einem Format ausgegeben, das sich gut für die Verarbeitung in einer for-Schleife eignet:@echo off
call :FncWinVer
goto :EOF
<an dieser Stelle muss noch die Funktion FncWinVer hineinkopiert werden, deren Sourcecode weiter unten zu finden ist>
Windows XP Professional:5.1 Build 2600:NonSuite:German:SP2:32 bit
Zudem ist es möglich, die Ausgabezeile wie folgt einer Variablen (hier _x) zuzuweisen:
call :FncWinVer -s _x
Eine Aufschlüsselung der Werte ist dann in folgender Weise denkbar:
@echo off
call :FncWinVer -s _x
for /F "tokens=1-6 delims=:" %%a in ("%_x%") do (
echo Operating System... %%a &rem e.g. "Windows XP Professional"
echo Version............ %%b &rem e.g. "5.1 Build 2600"
echo Product Suite...... %%c &rem e.g. "Terminal Server, ..."
echo Localization....... %%d &rem e.g. "German"
echo Service Pack....... %%e &rem e.g. "SP2"
echo Architecture....... %%f &rem e.g. "32 bit"
)
goto :EOF
<an dieser Stelle muss noch die Funktion FncWinVer hineinkopiert werden, deren Sourcecode weiter unten zu finden ist>
Betriebssysteminformationen abfragen
Für eine Abfrage, ob etwas zutrifft, oder nicht, bieten Batch-Funktionen ganz allgemein einen Rückgabewert an, der sich mit<call :Batch-Funktion>
&& echo Die Bedingung ist erfülltoder
Das lässt sich auch auf die hier gezeigte Batch-Funktion anwenden. Die denkbar einfachste Abfrage ist die nach dem verwendeten Betriebssystem-Namen. Sie kann wie folgt erfolgen:
call :FncWinVer -e "NT4" "XP" && echo Das Betriebssystem ist entweder NT4 oder XP
bzw.
Es ist auch möglich, mehrere Anweisungen an die Funktion zu binden
call :FncWinVer -e "2000" "2008" "XP" && (
echo Das Betriebssystem ist entweder Windows 2000, 2008 oder XP
echo ... hier eine zweite echo-Anweisung
)
Mögliche Betriebssystem-Namen, die sich hier abfragen lassen, sind z.B.
"NT3", "NT4", "2000", "2003", "2008", "XP", "Vista", ...
Grundsätzlich sollte die Funktion auf allen Windows-Versionen laufen, die auf NT basieren, von NT3 bis Vista und Nachfolgende, wobei die Namen nur bis zur maximal gewünschten Übereinstimmung angegeben werden müssen. Also wird hier z. B. „NT“ angegeben, so ist die Bedingung unter NT3 und NT4 erfüllt. Wird stattdessen „3“ angegeben, so passt 2003 und NT3 in das Suchmuster der Funktion.
Auf gleicher Weise lassen sich nicht nur die Betriebssystem-Namen abfragen, sondern auch sämtliche andere Felder, die die Funktion ohne Parameter ausgegeben hat.
call :FncWinVer -e "XP::::SP2" && echo Das ist Windows XP mit Service Pack 2
call :FncWinVer -e "XP Professional::::SP2" && echo Das ist Windows XP Profssional mit SP2
call :FncWinVer -e "XP Professional:::German:SP2" && echo Das ist ein deutsches WinXP Prof mit SP2
call :FncWinVer -e "XP Pro:::Ger:SP2" && echo Das ist ein deutsches WinXP Prof mit SP2
Hinweis: Seit Windows Vista wurde die Länderkennung von German in de geändert. Eine entsprechende Abfrage nach einer deutschen 32-Bit Variante von Windows Vista mit beispielsweise Service Pack 1 muss also wie folgt erfolgen:
call :FncWinVer -e "Vista:::de:SP1:32" && echo Das ist ein deutsches Windows Vista, 32-Bit, mit Service Pack 1
Auch Abfragen ohne Angabe des Betriebssystem-Namens sind möglich:
call :FncWinVer -e "::Terminal Server:::" && echo Das Betriebssystem arbeitet als Terminal Server
call :FncWinVer -e ":::::64" && echo Das ist eine 64-Bit-Variante des Betriebssystems
call :FncWinVer -e ":5.1::::" && echo Das Betriebssystem hat die Version 5.1
call :FncWinVer -e ":Build 2600::::" && echo Das Betriebsystem hat das Build 2600
call :FncWinVer -e ":5.1 Build 2600::::" && echo Das Betriebssystem hat die Version 5.1 Build 2600
call :FncWinVer -e ":5.1 Build 2600" && echo Das Betriebssystem hat die Version 5.1 Build 2600
Die folgende Abfrage zeigt, wie man ermitteln kann, ob es sich um Windows 2000 mit Service Pack 2 oder höher handelt. Das schließt Service Pack 3 genauso mit ein, wie neuere Versionen von Windows (2003, 2008, etc.). Das wird erreicht, indem die anderen bekannten Systeme ausgeschlossen werden (hier beispielhaft auch XP und Vista):
@echo off
call :FncWinVer -e "NT" "XP" "Vista" "2000::::SP0" "2000::::SP1" || (
echo Das ist Windows 2000 mit SP2 oder höher.
echo Neben Windows 2000 mit SP3 könnte es also auch z.B. Windows 2003, 2008 oder höher sein.
)
goto :EOF
<an dieser Stelle muss noch die Funktion FncWinVer hineinkopiert werden, deren Sourcecode weiter unten zu finden ist>
()
-Blocks, da sie ja nicht explizit ausgeschlossen wurden.Der Funktionscode
Um den Funktionscode zu kopieren, klicke auf "in den Speicher kopieren". Wenn nur ein Teil des Codes kopiert werden soll, klicke auf "Quelltext" und maximiere das sich dann öffnende Fenster, um den unerwünschten Zeilenumbruch zu unterbinden. Dort lassen sich die Zeilen wie gewohnt markieren und kopieren.:FncWinVer ::Version 2.0.1
::Parameters: [-e | -s] [...]
::Options: -e <Name> [Name2] When the Operating System is one of the name, function returns true (0)
:: Name can be "NT3", "NT4", "2000", "2003", "2008", "XP", "Vista"
:: For Detail-Information use e.g. "XP Professional:::German:SP2" (see Example)
:: -s <VarNameToReturnOSString>
::Example: if "%OS%" == "" echo The OS is DOS, Win3.x or Win9x & goto :EOF (you can not use batch-functions)
:: call :FncWinVer (print OS-Version, e.g. "Windows XP Professional:5.1 Build 2600:NonSuite:German:SP2:32 bit")
:: call :FncWinVer -s _x (set _x=OS-Version)
:: for /F "tokens=1-6 delims=:" %%a in ("%_x%") do (
:: echo Operating System... %%a &rem e.g. "Windows XP Professional"
:: echo Version............ %%b &rem e.g. "5.1 Build 2600"
:: echo Product Suite...... %%c &rem e.g. "Terminal Server, ..."
:: echo Localization....... %%d &rem e.g. "German"
:: echo Service Pack....... %%e &rem e.g. "SP2"
:: echo Architecture....... %%f &rem e.g. "32 bit"
:: )
:: call :FncWinVer -e "NT" "XP" && (
:: echo The Operating System is Windows NT3 or NT4 or XP
:: call :FncWinVer -e "XP::::SP2" && echo The OS is Windows XP with Service Pack 2
:: call :FncWinVer -e "XP Professional:::SP2" && echo The OS is Windows XP Profssional with SP2
:: call :FncWinVer -e "XP Professional::German:SP2" && echo The OS is German Windows XP Prof with SP2
:: call :FncWinVer -e "XP Pro::Ger:SP2" && echo The OS is German Windows XP Prof with SP2
:: )
:: call :FncWinVer -e "NT4" "XP" || echo The OS is not Windows NT4 or XP (&&=is true; ||=is not true)
:: call :FncWinVer -e "NT" "XP" "Vista" "2000" "2003::::SP0" "2003::::SP1" || (
:: echo This is Windows 2003 with SP2 or higher - also can be Windows 2008, etc.
:: )
:: call :FncWinVer -e "::Terminal Server::" && echo This is a Terminal Server
:: call :FncWinVer -e ":5.1:::" && echo This is Version 5.1
:: call :FncWinVer -e ":Build 2600:::" && echo This is Build 2600
:: call :FncWinVer -e ":5.1 Build 2600:::" && echo This is Version 5.1 Build 2600
:: call :FncWinVer -e ":5.1 Build 2600" && echo This is Version 5.1 Build 2600
::Return: 0=Operating System found; 1=Operating System not found; 2=syntax error
setlocal EnableDelayedExpansion & set "_#SP=SP0" & set "_#OSEX1=NonSuite" & set "_#TMP=" & set "_#EL=0" & set "_#Prd=unknown system"
if exist "%systemroot%\system32\prodspec.ini" ( ::Name und Sprache ermitteln; NT3 bis Windows 2008
for /F "tokens=1* delims==" %%a in ('type "%systemroot%\system32\prodspec.ini"') do (
if /i "%%a" == "Product" set _#Prd=%%b
if /i "%%a" == "Localization" set _#Lang=%%b
)
) else ( ::ab Vista
set _#Lang=%LC_LANG%
set _#TmpPrdFile=%TMP:"=%\%~n0_Prd%RANDOM%.tmp &::Da der ProductName, z.B. "Vista (TM)", auch Klammern enthalten kann...
for /f "tokens=2,* delims= " %%a in ('%SYSTEMROOT%\system32\reg.exe query
"HKLM\Software\Microsoft\Windows NT\CurrentVersion"
/v "ProductName" 2^>NUL ^| find /i "ProductName"') do (echo."%%b") > "!_#TmpPrdFile!"
set /p "_#Prd=" < "!_#TmpPrdFile!" &::... wird die Variablen-Zuweisung ueber diesen Umweg vorgenommen.
set "_#Prd=!_#Prd:(=!" & set "_#Prd=!_#Prd:)=!" & set "_#Prd=!_#Prd:"=!"
del "!_#TmpPrdFile!"
)
if exist "%windir%\SysWOW64" ( set "_#Bit=64 bit" ) else ( set "_#Bit=32 bit" )
set "_#Prd=%_#Prd:NT Workstation 4.=NT4 Workstation 4.%" & set "_#Prd=%_#Prd:NT Server 4.=NT4 Server 4.%"
set "_#Prd=%_#Prd:NT Workstation 3.=NT3 Workstation 3.%" & set "_#Prd=%_#Prd:NT Server 3.=NT3 Server 3.%"
if not exist "%SYSTEMROOT%\system32\reg.exe" ( ::NT3, NT4 und w2k kennen keine reg.exe, daher...
set _#TmpRegFile=%TMP:"=%\%~n0_RegExport%RANDOM%.tmp
%SYSTEMROOT%\regedit.exe /E "!_#TmpRegFile!" "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion"
type "!_#TmpRegFile!" > "!_#TmpRegFile!_ANSI-Format"
rem Von den ca. 60.000 rekursiv exportierten Registry-Zeilen die ersten 100 Zeilen extrahieren...
(for /L %%i in (1,1,100) do set /p "_x=" & echo.!_x!) <"!_#TmpRegFile!_ANSI-Format" >"!_#TmpRegFile!"
rem ...damit die nun folgende for-Schleife wesentlich schneller abgearbeitet werden kann:
for /f "tokens=1,2,4 delims== " %%a in ('type "!_#TmpRegFile!"') do (
if /i %%a == "CSDVersion" set _#SP=SP%%c
if /i %%a == "CurrentVersion" set _#Ver=%%b
if /i %%a == "CurrentBuildNumber" set _#Build=%%b
)
del "!_#TmpRegFile!" "!_#TmpRegFile!_ANSI-Format"
set _#OSEX1=NT3_NT4_or_2000=Product Suite can not be identified
) else ( ::Windows XP, 2003 oder hoeher... (reg.exe ist schneller und kann MULTI_SZ "ProductSuite" auslesen)
for /f "tokens=1,3,5 delims= " %%a in ('%SYSTEMROOT%\system32\reg.exe query
"HKLM\Software\Microsoft\Windows NT\CurrentVersion" 2^>NUL') do (
if /i "%%a" == "CSDVersion" set _#SP=SP%%c
if /i "%%a" == "CurrentVersion" set _#Ver=%%b
if /i "%%a" == "CurrentBuildNumber" set _#Build=%%b
)
for /f "tokens=2,* delims= " %%a in ('%SYSTEMROOT%\system32\reg.exe query
"HKLM\System\CurrentControlSet\Control\ProductOptions"
/v "ProductSuite" 2^>NUL ^| find /i "ProductSuite"') do set _#TMP=%%b
if defined _#TMP set _#TMP=!_#TMP:\0\0=!
if defined _#TMP set _#TMP=!_#TMP:\0=, !
if defined _#TMP if not "!_#TMP!" == ", " set _#OSEX1=!_#TMP!
)
set _#TMP=%_#Prd:*Terminal Server Edition=Found_%
if "%_#TMP:~0,6%" == "Found_" ( ::zur Vereinheitlichung: unter NT4 den Prd-TS-Eintrag nach ProductSuite verschieben
set _#Prd=%_#Prd: Terminal Server Edition=%
set _#OSEX1=Terminal Server Edition, %_#OSEX1%
)
set "_#OS_Info=%_#Prd%:%_#Ver% Build %_#Build%:%_#OSEX1%:%_#Lang%:%_#SP%:%_#Bit%" & set "_#OS_Info=!_#OS_Info:"=!"
if "%~1" == "" (
echo %_#OS_Info%
goto :LEB_FncWinVer_END
) else if "%~1" == "-s" (
endlocal & set "%~2=%_#OS_Info%" & exit /b %_#EL%
) else if not "%~1" == "-e" (
set _#EL=2 & goto :LEB_FncWinVer_END
)
set _#EL=1
:LOOP_FncWinVer_NextOS ::Option -e gefunden (es soll gestestet werden, ob das aktuelle Betriebssystem bestimmte Bedingungen erfuellt)
shift
set "_#InfoLST=%_#OS_Info%:#END#" & set "_#ParLST=%~1:#END#"
:LOOP_FncWinVer_NextDetail
set "_#InfoITM=%_#InfoLST%" &rem die OS-Info-Liste (z.B. "Windows XP Professional:5.1 Build 2600:...") auseinandernehmen...
set "_#InfoLST=%_#InfoLST:*:=%" &rem "*:=" loescht alles bis zum Aufkommen des ersten ":"-Zeichens; uebrig bleibt der rechte Teilstring
if not "%_#InfoITM%" == "%_#InfoLST%" (
set "_#InfoITM=!_#InfoITM::%_#InfoLST%=!" &rem InfoITM=erster Eintrag (entspricht urspruengliche Liste abzueglich rechtem Teilstring)
)
set "_#ParITM=%_#ParLST%" &rem Den Suchstring (z.B. "XP:::SP2:#END#") auseinandernehmen...
set "_#ParLST=%_#ParLST:*:=%" &rem "*:=" loescht alles bis zum Aufkommen des ersten ":"-Zeichens; uebrig bleibt der rechte Teilstring
if not "%_#ParITM%" == "%_#ParLST%" (
set "_#ParITM=!_#ParITM::%_#ParLST%=!" &rem ParITM=erster Eintrag (entspricht urspruengliche Liste abzueglich rechtem Teilstring)
)
if defined _#InfoITM if defined _#ParITM if not "%_#ParITM%" == "#END#" (
set "_#TMP=!_#InfoITM:*%_#ParITM%=Found_!" &rem das ist _wesentlich_ schneller als find.exe, ignoriert aber Gross-/Kleinschreibung
if "!_#TMP:~0,6!" == "Found_" ( ::gefunden; nun muss die Ueberpruefung noch einmal case-sensitiv durchgefueht werden...
echo "!_#InfoITM!" | find "!_#ParITM!" >NUL && set "_#EL=0" && rem "ParITM kommt in InfoITM vor" ist fuer dieses Item erfuellt
) else ( ::die erste Unstimmigkeit des Parameters wurde im aktuellen Item entdeckt
set "_#EL=1"
set "_#ParITM=#END#" &rem Weitersuchen nicht erforderlich; auf zum naechsten Parameter
)
)
if not "%_#ParITM%" == "#END#" if not "%_#InfoITM%" == "#END#" goto :LOOP_FncWinVer_NextDetail
if not "%~2" == "" if not "%_#EL%" == "0" goto LOOP_FncWinVer_NextOS
:LEB_FncWinVer_END
endlocal & exit /b %_#EL%
Bedeutung der Versionsfelder:
x.x.x
| | '-->Änderungen in diesem Bereich zeigen an, dass ein Fehler beseitigt
| | oder eine Optimierung vorgenommen wurde
| '---->Der Parameteraufbau zu einer Option oder der Funktionsumfang hat
| sich verändert (neue Optionen, etc.)
'------->Es wurde eine grundlegende Änderung vorgenommen (allgemeiner
Parameteraufbau, Rückgabewert oder ähnliches)
Version 2.0.1: In der vorherigen Version schlug die Anweisung
call :FncWinVer -e "NT" && echo Es wurde Windows NT gefunden.
leider auch bei z.B. "Windows 2003 E
nt
erprise Edition" an. Der Fehler wurde behoben. Hintergrund: Die verwendete Suchmethode arbeitete nicht case-sensitive. -- NeonZero 22.07.2009Version 2.0.0: Der Rückgabewert enthält nun ein zusätzliches Feld, welches angibt, ob es sich um eine 32-Bit- oder eine 64-Bit-Variante von Windows handelt. Die Abfrage kann wie folgt erfolgen:
call :FncWinVer -e ":::::32" && echo Es handelt sich um eine 32 Bit Variante von Windows
call :FncWinVer -e ":::::64" && echo Es handelt sich um eine 64 Bit Variante von Windows
Version 1.0.3: Windows Vista kennt keine prodspec.ini mehr. Die Länderkennung befindet sich jetzt in der Variablen %LC_LANG%, allerdings als en oder de und nicht als German. Damit muss man wohl leben. Die allgemeine Produktinformation findet sich jetzt in der Registry wieder. Der Code und die Anleitung wurden entsprechend angepaßt. -- NeonZero 29.01.2009
Version 1.0.2: Anders als unter Windows 2000 (und neuer) wird unter NT4 die Information über die Verfügbarkeit eines Terminal Servers nicht unter ProductSuite abgelegt. Vielmehr ist sie Bestandteil der allgemeinen Produktinformation ("Windows NT Server 4.0 Terminal Server Edition"). Zur Vereinheitlichung wurde der Eintrag "Terminal Server Edition" aus diesem (ersten) Feld entfernt und in das (dritte) Feld ProductSuite verschoben. Damit sollte nun auch unter NT4 der Terminal Server wie in der Anleitung beschrieben im dritten Feld abfragbar sein (
call :FncWinVer -e "NT4::Terminal Server::" && echo Das Betriebssystem arbeitet als Terminal Server
). Zusätzlich wurde die NT-Produktinformation (Feld1) für eine bessere Abfragemöglichkeit vereinheitlicht (eine Suche nach "NT3", "NT4" oder auch "NT4 Server", etc. ist nun möglich). -- NeonZero 13.01.2009Version 1.0.1: Das Auslesen der Registry-Einträge wurde derart angepaßt, dass nun auch NT3, NT4 und Windows 2000 unterstützt werden. Einzige Einschränkung: Eine Auflistung der "ProductSuite" (unter "HKLM\System\CurrentControlSet\Control\ProductOptions") ist mir unter diesen alten Betriebssystemen noch nicht gelungen, da dies ein MULTI_SZ-Eintrag ist. Das bedeutet, dass die Funktion so tut, als ob auf dem System keine ProductSuite installiert wurde. Alle anderen Informationen sind ohne Einschränkung abfragbar. XP, Windows 2003 und neuer sind von dieser EInschränkung nicht betroffen. Wenn jemand eine Idee hat, wie sich unter Windows 2000 mit Standardmethoden (ohne WSH und ohne ein zusätzliches Tool installieren zu müssen) ein MULTI_SZ-Eintrag auswerten läßt, dann wäre ich für einen Hinweis dankbar. -- NeonZero 13.01.2009
Version 1.0.0: Erste Version, die lediglich unter XP, Windows 2003 und neueren Versionen von Windows funktioniert; sie nutzt reg.exe, die von NT3 bis w2k auf einer Standardinstallation noch nicht vorhanden ist (das wird erst ab Version 1.0.1 berücksichtigt - danke an @paulepank für den Hinweis). -- NeonZero 11.01.2009
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 105641
Url: https://administrator.de/contentid/105641
Ausgedruckt am: 21.11.2024 um 22:11 Uhr
16 Kommentare
Neuester Kommentar
Moin TuXHunt3R,
Batchdateien sind wirklich nicht selbstdokumentierend und erzwingen syntaktisch nicht unbedingt eine strukturierte Herangehensweise.
Gerade deshalb finde ich NeonZeros Tutorial - mit sauberer Herleitung, Struktur und Dokumentation - im Bereich "Batch & Shell" sehr gelungen.
Und die von NeonZero formulierte Ausgangssituation "Wie kann ich verlässliche Ergebnisse erzielen, wenn ich als Werkzeuge nur ein Stück Bindfaden und zwei Streichhölzer zur Verfügung habe?" finde ich bezogen auf Windows-Standard-Client-Installationen durchaus begründet.
Natürlich geht es mit einem prall gefüllten Powershell-Werkzeugkasten eventuell "besser". aber ...
... ein C#-oder .NET-Coder würde auch sagen:
"Hey, da brat ich Dir in 10 Minuten was Besseres zusammen."
Von mir jedenfalls großes Lob für das mit Bindfaden und Streichhölzern erstellte Ergebnis.
Grüße
Biber
Batchcode ist meiner Meinung nach zu unleserlich und zu kryptisch für solch komplexe Scripts.
Genau diese Ansicht ist ja die große Herausforderung beim Erstellen von Batchscripts und erst recht von Tutorials zum Thema "Batchlösungen für komplexere Probleme".Batchdateien sind wirklich nicht selbstdokumentierend und erzwingen syntaktisch nicht unbedingt eine strukturierte Herangehensweise.
Gerade deshalb finde ich NeonZeros Tutorial - mit sauberer Herleitung, Struktur und Dokumentation - im Bereich "Batch & Shell" sehr gelungen.
Und die von NeonZero formulierte Ausgangssituation "Wie kann ich verlässliche Ergebnisse erzielen, wenn ich als Werkzeuge nur ein Stück Bindfaden und zwei Streichhölzer zur Verfügung habe?" finde ich bezogen auf Windows-Standard-Client-Installationen durchaus begründet.
Natürlich geht es mit einem prall gefüllten Powershell-Werkzeugkasten eventuell "besser". aber ...
... ein C#-oder .NET-Coder würde auch sagen:
"Hey, da brat ich Dir in 10 Minuten was Besseres zusammen."
Von mir jedenfalls großes Lob für das mit Bindfaden und Streichhölzern erstellte Ergebnis.
Grüße
Biber
Hallo hier,
@Biber
@NeonZero
Am Beispiel vom Windows 2000 - hier gibt es keine reg.exe.
Diese muß per Hand aus dem Supporttool entweder in den System32-Ordner kopiert werden.
Dann wäre der Aufruf %SYSTEMROOT%\system32\reg.exe doppelt gemoppelt.
oder die Supporttools werden installiert. Dann liegt reg.exe im Ordner %ProgramFiles%\Supporttools.
Dann ist der Aufruf %SYSTEMROOT%\system32\reg.exe sogar falsch.
Fazit:
Da %ProgramFiles%\Supporttools zur PATH-Variablen hinzugefügt wird genügt auf jeden Fall als Aufruf reg.exe query ....
Der Anspruch "ohne weiteres Zutun" kann durch Verwenden von reg.exe nicht erfüllt werden.
cu paulepank
@Biber
...für das mit Bindfaden und Streichhölzern erstellte Ergebnis
naja, etwas Zauberpulver war auch dabei, weil ...@NeonZero
...dass der Code ohne weiteres Zutun auf jedem...
Das stimmt so nicht.Am Beispiel vom Windows 2000 - hier gibt es keine reg.exe.
Diese muß per Hand aus dem Supporttool entweder in den System32-Ordner kopiert werden.
Dann wäre der Aufruf %SYSTEMROOT%\system32\reg.exe doppelt gemoppelt.
oder die Supporttools werden installiert. Dann liegt reg.exe im Ordner %ProgramFiles%\Supporttools.
Dann ist der Aufruf %SYSTEMROOT%\system32\reg.exe sogar falsch.
Fazit:
Da %ProgramFiles%\Supporttools zur PATH-Variablen hinzugefügt wird genügt auf jeden Fall als Aufruf reg.exe query ....
Der Anspruch "ohne weiteres Zutun" kann durch Verwenden von reg.exe nicht erfüllt werden.
cu paulepank
@ Biber:
Bei Servern gehört die PowerShell ab 2008 standardmässig dazu, bei den Clientsystemen ab Windows 7. Das .NET Framework 2.0 ist seit Vista auch überall standardmässig drauf (ausser der Core-Installation von 2008 Server) und den WSH gibt es seit Windows 2000 auch überall standardmässig dazu. Aber ich verstehe deine Argumentation...
Und die von NeonZero formulierte Ausgangssituation "Wie kann ich verlässliche Ergebnisse erzielen, wenn ich als Werkzeuge nur ein Stück Bindfaden und zwei Streichhölzer zur Verfügung habe?" finde ich bezogen auf Windows-Standard-Client-Installationen durchaus begründet.
Bei Servern gehört die PowerShell ab 2008 standardmässig dazu, bei den Clientsystemen ab Windows 7. Das .NET Framework 2.0 ist seit Vista auch überall standardmässig drauf (ausser der Core-Installation von 2008 Server) und den WSH gibt es seit Windows 2000 auch überall standardmässig dazu. Aber ich verstehe deine Argumentation...
Am Beispiel vom Windows 2000 - hier gibt es keine reg.exe.
Richtig. Es gibt auch noch andere Dinge, die bei Windows 2000 anders sind, z.B. die Abfrage des Errorlevels (%errorlevel%).
Windows 2000:
Windows Vista:
(Aus dem Kopf, nicht getestet)
Des weiteren ändert bei den verschiedenen zusätzlichen Commandline-Tools (z.B. Resource Kit) manchmal die Syntax. Ich glaube, RMTSHARE ist so ein Beispiel. Bin mir allerdings nicht sicher.
ping -n 1 192.168.1.1 | find /i "TTL" >nul
if "%errorlevel%"=="0" (
echo Erreichbar
) else (
echo Nicht erreichbar
)
Windows Vista:
ping -n 1 192.168.1.1 | find /i "TTL" >nul
if %errorlevel%==0 (
echo Erreichbar
) else (
echo Nicht erreichbar
)
Des weiteren ändert bei den verschiedenen zusätzlichen Commandline-Tools (z.B. Resource Kit) manchmal die Syntax. Ich glaube, RMTSHARE ist so ein Beispiel. Bin mir allerdings nicht sicher.
Hallo NeonZero,
Erstmal Respekt. Wirklich Klasse gemacht.
Dazu noch eine Frage:
Kann man hier auch die Abfrage ob 32- oder 64-bit-System ebenfalls mit einbauen?
gruß
onegasee59
Erstmal Respekt. Wirklich Klasse gemacht.
Dazu noch eine Frage:
Kann man hier auch die Abfrage ob 32- oder 64-bit-System ebenfalls mit einbauen?
gruß
onegasee59
Hallo NeonZero,
erstmal Danke für Deinen Antwort.
Ich habe inzwischen auch mal recherchiert.
Zu Punkt 4.
Ich frage das gleiche Verzeichnis "%windir%\SysWOW64" in meinem Tool XPandWMP-PermReset-Fix , damit es nicht auf 64bit-Systemen angewendet werden kann. Vor einigen Tagen erhielt ich Rückmeldung das bei einem User mein Tool das weiterarbeiten verweigert und ihm 64bit meldet, er aber angeblich nur ein 32bit-System hat.
Habe dann mal weiter recherchiert und jetzt die Abfrage über Systemvariable eingebaut:
if %PROCESSOR_ARCHITECTURE%==x86 (set osbit=32bit) else (set osbit=64bit)
Vielleicht ist das auch für Dich gegeignet.
Gruß
onegasee59
erstmal Danke für Deinen Antwort.
Ich habe inzwischen auch mal recherchiert.
Zu Punkt 4.
Ich frage das gleiche Verzeichnis "%windir%\SysWOW64" in meinem Tool XPandWMP-PermReset-Fix , damit es nicht auf 64bit-Systemen angewendet werden kann. Vor einigen Tagen erhielt ich Rückmeldung das bei einem User mein Tool das weiterarbeiten verweigert und ihm 64bit meldet, er aber angeblich nur ein 32bit-System hat.
Habe dann mal weiter recherchiert und jetzt die Abfrage über Systemvariable eingebaut:
if %PROCESSOR_ARCHITECTURE%==x86 (set osbit=32bit) else (set osbit=64bit)
Vielleicht ist das auch für Dich gegeignet.
Gruß
onegasee59
Hallo NeonZero,
Ist Batch-to-EXE, d.h. nur als *.exe verpackt.
Klar könnte ich machen, aber dann müsste sich jeder Interressent den ganzen Kram runterladen.
Wollte ich vermeiden, weil wenn man die *.zip entpackt und die *.exe startet, findet man den gesamten Inhalt der *.exe im Ordner Temp.
"C:\Dokumente und Einstellungen\..username..\Lokale Einstellungen\Temp"
Gerne, muss ich aber hoffen das von Ihm noch eine Reaktion auf mein Antwort an Ihn kommt.
Er hatte in der Newsgroup geantwortet und ist dabei über das Webinterface von MS gegangen, also keinen replayfähigen Emailaccount benutzt.
Thread "Installation fehlgeschlagen" in NG microsoft.public.de.inetexplorer.ie7
Gruß
onegasee59
Hallo Matthias. Danke für Deinen Tipp. In einer .exe sollte die Abfrage kein Problem sein. Du kannst leicht auf eine entsprechende API
zugreifen, die Dir u.a. die 32 oder 64-Bit-Variante zurückgibt (siehe msdn-Suche).
zugreifen, die Dir u.a. die 32 oder 64-Bit-Variante zurückgibt (siehe msdn-Suche).
Ist Batch-to-EXE, d.h. nur als *.exe verpackt.
<ot>Sympathisch finde ich, dass Du Deine Tools als Freeware zur Verfügung stellst. Perfekt wäre es, wenn auch die
Sourcen enthalten wären. Gibt es einen speziellen Grund dafür, sie nicht in die .zip zu packen?</ot>
Sourcen enthalten wären. Gibt es einen speziellen Grund dafür, sie nicht in die .zip zu packen?</ot>
Klar könnte ich machen, aber dann müsste sich jeder Interressent den ganzen Kram runterladen.
Wollte ich vermeiden, weil wenn man die *.zip entpackt und die *.exe startet, findet man den gesamten Inhalt der *.exe im Ordner Temp.
"C:\Dokumente und Einstellungen\..username..\Lokale Einstellungen\Temp"
Ich würde mich gerne selbst davon überzeugen, ob auf der fraglichen 32-Bit-Version tatsächlich dieses Verzeichnis
existiert. Dabei ist es wichtig zu wissen, was genau unter „Systemsteuerung / System / Allgemein“ des betroffenen PCs
ausgegeben wird. Kannst Du die Angaben des Anwenders bitte hier posten?
existiert. Dabei ist es wichtig zu wissen, was genau unter „Systemsteuerung / System / Allgemein“ des betroffenen PCs
ausgegeben wird. Kannst Du die Angaben des Anwenders bitte hier posten?
Gerne, muss ich aber hoffen das von Ihm noch eine Reaktion auf mein Antwort an Ihn kommt.
Er hatte in der Newsgroup geantwortet und ist dabei über das Webinterface von MS gegangen, also keinen replayfähigen Emailaccount benutzt.
Thread "Installation fehlgeschlagen" in NG microsoft.public.de.inetexplorer.ie7
Gruß
onegasee59
Hallo Leute,
bin neu hier und bin schon durch einige Threads hier im Unterforum "Batch & Shell" inspiriert worden, komme aber momentan nicht weiter.
Habe mal vor längerer Zeit angefangen, das Betriebssystem bei Win2000 zu ermitteln, dann ist WinXP dazugekommen und mittlerweile bin ich bei Win7 / 64bit angekommen. Auf der Suche nach einer allgemeingültigen Abfrage bin ich auf diesen Thread gestoßen.
Super Sache, allerdings sind mir 2 Sachen aufgefallen.
Bei Windows 7 wird folgendes Ergebnis ausgespuckt:
Ergebnisse von "ServicePack" und "Architecture" rutschen ein Feld nach oben. Nach dem ich unter die Zeile 42
noch folgende Zeile eingefügt habe
klappt es mit der Abfrage. Ich denke, da Win7 mehrsprachig ist, wird auch keine direkte Sprache hinterlegt sein. Ist aber nur eine Vermutung von mir und es funktioniert.
Da, wo ich nicht weiterkomme, ist bei Windows 2000:
Wie man sieht, wird bei "Architecture" noch ein Rest vom nachfolgenden Befehl mit angehängt. Ich habe schon ein bisschen probiert, da ich aber, sagen wir mal, fortgeschrittener Anfänger bin, komme ich mit meinem Latein nicht weiter.
Hat jemand von Euch eine Idee, wo der Fehler in diesem Skript liegt ?
Ach ja, noch eine kleiner Schönheitsfehler meinerseits: Wollte bei "Architecture" folgende Ausgabe: "64bit (x64)" bzw. "32bit (x86)"
Bei den Klammern innerhalb des "SET"-Befehls für die Variablen-Deklaration "_#Bit" kommt das Skript ins Straucheln. Habe es mit dem Maskierungszeichen ^ versucht, klappt aber auch nicht. Wie gesagt nur ein kleiner Schönheitsfehler, sollte aber jemand eine Lösung dafür haben, immer her damit.
So das war es fürs erste Mal.
Gruß
Batchler
Nachtrag:
Habe es gerade nochmals probiert mit der "Architecture"-Ausgabe: "64bit (x64)" bzw. "32bit (x86)" und dem Maskieren von der Klammer.
wenn ich mir per ECHO die Variable direkt anzeigen lasse
habe ich folgende Ausgabe
wenn ich aber die Ausgabe wieder in einer Variable hinterlege
und danach per ECHO aufrufe
habe ich folgende Ausgabe
also alles wieder im Lot.
bin neu hier und bin schon durch einige Threads hier im Unterforum "Batch & Shell" inspiriert worden, komme aber momentan nicht weiter.
Habe mal vor längerer Zeit angefangen, das Betriebssystem bei Win2000 zu ermitteln, dann ist WinXP dazugekommen und mittlerweile bin ich bei Win7 / 64bit angekommen. Auf der Suche nach einer allgemeingültigen Abfrage bin ich auf diesen Thread gestoßen.
Super Sache, allerdings sind mir 2 Sachen aufgefallen.
Bei Windows 7 wird folgendes Ergebnis ausgespuckt:
Operating System... Windows 7 Professional
Version............ 6.1 Build 7600
Product Suite...... Terminal Server
Localization....... SP0
Service Pack....... 64 bit
Architecture.......
Ergebnisse von "ServicePack" und "Architecture" rutschen ein Feld nach oben. Nach dem ich unter die Zeile 42
set _#Lang=%LC_LANG%
noch folgende Zeile eingefügt habe
IF "%_#Lang%" == "" SET _#Lang=No Localization
klappt es mit der Abfrage. Ich denke, da Win7 mehrsprachig ist, wird auch keine direkte Sprache hinterlegt sein. Ist aber nur eine Vermutung von mir und es funktioniert.
Da, wo ich nicht weiterkomme, ist bei Windows 2000:
Operating System... Windows 2000 Professional
Version............ "5.0" Build "2195"
Product Suite...... NT3_NT4_or_2000=Product Suite can not be identified
Localization....... German
Service Pack....... SP4"
Architecture....... 32 bit" & set "_#OS_Info "=
Wie man sieht, wird bei "Architecture" noch ein Rest vom nachfolgenden Befehl mit angehängt. Ich habe schon ein bisschen probiert, da ich aber, sagen wir mal, fortgeschrittener Anfänger bin, komme ich mit meinem Latein nicht weiter.
Hat jemand von Euch eine Idee, wo der Fehler in diesem Skript liegt ?
Ach ja, noch eine kleiner Schönheitsfehler meinerseits: Wollte bei "Architecture" folgende Ausgabe: "64bit (x64)" bzw. "32bit (x86)"
Bei den Klammern innerhalb des "SET"-Befehls für die Variablen-Deklaration "_#Bit" kommt das Skript ins Straucheln. Habe es mit dem Maskierungszeichen ^ versucht, klappt aber auch nicht. Wie gesagt nur ein kleiner Schönheitsfehler, sollte aber jemand eine Lösung dafür haben, immer her damit.
So das war es fürs erste Mal.
Gruß
Batchler
Nachtrag:
Habe es gerade nochmals probiert mit der "Architecture"-Ausgabe: "64bit (x64)" bzw. "32bit (x86)" und dem Maskieren von der Klammer.
wenn ich mir per ECHO die Variable direkt anzeigen lasse
echo Architecture....... %%f
habe ich folgende Ausgabe
Architecture....... 32bit ^(x86^)
wenn ich aber die Ausgabe wieder in einer Variable hinterlege
SET Architecture=%%f
und danach per ECHO aufrufe
ECHO Architecture....... %Architecture%
habe ich folgende Ausgabe
Architecture....... 32bit (x86)
also alles wieder im Lot.
Ich hätte da einen 5-Zeiler im Angebot, bei dem die wesentlichen Informationen das Systemprogramm systeminfo.exe, dabei ab Windows XP ermittelt und eine Batchzeile für die Ausgabe sorgt:
Funktioniert ab XP bis Win7 32/64 auf Workstations, Server habe ich nicht, kann es also nicht testen, sollte aber eigentlich ebenfalls funktionieren. Evtl. muss der Zähler von 15 auf einen etwas höheren Wert gesetzt werden.
@echo off & setlocal enabledelayedexpansion
set /a line=0
for /f "tokens=1,2* delims=:" %%a in ('systeminfo') do @echo %%a %%b & set /a line+=1 & if !line! gtr 15 goto :raus
:raus
set /p blubb=fertig.
Funktioniert ab XP bis Win7 32/64 auf Workstations, Server habe ich nicht, kann es also nicht testen, sollte aber eigentlich ebenfalls funktionieren. Evtl. muss der Zähler von 15 auf einen etwas höheren Wert gesetzt werden.