Batch File auslesen und in Registry oder WMI schreiben
Hallo zusammen
Ich habe ein Problem. Mein Arbeitskollege fällt wegen einem schweren Unfall länger aus und ich darf dringende Arbeiten für Ihn ausführen. Da ich noch in Ausbildung bin, ist es für mich schwierig gewisse Arbeiten ohne Hilfe selbständig auszuführen. Daher hoffe ich, dass mir jemand von Euch weiterhelfen kann.
Ich muss unser Inventar erweitern. Von einem Hersteller haben wir ein Programm erhalten, dass die in Windows verbauten Controller Firmware Version ausliest und in eine TXT-Datei in c:\windows\temp mit dem Namen version.txt schreibt.
In dieser version.txt Datei steht in einer einzigen Zeile folgendes:
Thunderbolt Host Controller - Firmware Version: 20.2.5.5.1
Oder auch irgendeine andere Version (zum Beispiel 16.4.3.6.1.12341.1 oder 12.9.2), wobei der Anfang bis zum Doppelpunkt immer gleich ist, nur die Nummer ändert sich.
Damit unser Inventar, diese Infos einsammeln und wir zentral auswerten können, muss diese Info in die Registry oder in die WMI geschrieben werden. Dies am besten mit einer Batch-Datei.
In der Registry, muss / sollte die Infos wie folgt geschrieben werden:
"HKLM\Software\Inventory\Thunderbolt Host Controller"
Zeichenfolge: "Firmware Version"
Wert: "20.2.5.5.1"
In der WMI, muss / sollte es wie folgt geschrieben werden:
Namespace: Root\cimv2\Inventory
Class: "Thunderbolt Host Controller"
Instance: "Thunderbolt Host Controller"
Properties: "Firmware Version"
Wert: "20.2.5.5.1"
Der Wert sollte alles nach dem Doppelpunkt beinhalten.
Ich habe div. schon ausprobiert, mit tail , type und for. Leider einfach immer ohne Erfolg. Da es für uns hohe Prio hat, erhoffe ich mir hier bei Euch Hilfe. Ich hoffe, dass ich diese bekomme.
Viele Dank für die Hilfe und Unterstützung.
Viele Grüsse Stefan
Ich habe ein Problem. Mein Arbeitskollege fällt wegen einem schweren Unfall länger aus und ich darf dringende Arbeiten für Ihn ausführen. Da ich noch in Ausbildung bin, ist es für mich schwierig gewisse Arbeiten ohne Hilfe selbständig auszuführen. Daher hoffe ich, dass mir jemand von Euch weiterhelfen kann.
Ich muss unser Inventar erweitern. Von einem Hersteller haben wir ein Programm erhalten, dass die in Windows verbauten Controller Firmware Version ausliest und in eine TXT-Datei in c:\windows\temp mit dem Namen version.txt schreibt.
In dieser version.txt Datei steht in einer einzigen Zeile folgendes:
Thunderbolt Host Controller - Firmware Version: 20.2.5.5.1
Oder auch irgendeine andere Version (zum Beispiel 16.4.3.6.1.12341.1 oder 12.9.2), wobei der Anfang bis zum Doppelpunkt immer gleich ist, nur die Nummer ändert sich.
Damit unser Inventar, diese Infos einsammeln und wir zentral auswerten können, muss diese Info in die Registry oder in die WMI geschrieben werden. Dies am besten mit einer Batch-Datei.
In der Registry, muss / sollte die Infos wie folgt geschrieben werden:
"HKLM\Software\Inventory\Thunderbolt Host Controller"
Zeichenfolge: "Firmware Version"
Wert: "20.2.5.5.1"
In der WMI, muss / sollte es wie folgt geschrieben werden:
Namespace: Root\cimv2\Inventory
Class: "Thunderbolt Host Controller"
Instance: "Thunderbolt Host Controller"
Properties: "Firmware Version"
Wert: "20.2.5.5.1"
Der Wert sollte alles nach dem Doppelpunkt beinhalten.
Ich habe div. schon ausprobiert, mit tail , type und for. Leider einfach immer ohne Erfolg. Da es für uns hohe Prio hat, erhoffe ich mir hier bei Euch Hilfe. Ich hoffe, dass ich diese bekomme.
Viele Dank für die Hilfe und Unterstützung.
Viele Grüsse Stefan
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 381383
Url: https://administrator.de/forum/batch-file-auslesen-und-in-registry-oder-wmi-schreiben-381383.html
Ausgedruckt am: 22.03.2025 um 03:03 Uhr
35 Kommentare
Neuester Kommentar
Moin,
Powershell heißt Dein Freund. Hier hast Du direkten Zugriff auf die Registry. Gib mal (als Admin ausführen)
auf der Shell ein. ;) Und auch die WMI-Objekte sind damit kein Problem.
Vom Prinzip sieht das dann so aus:
Mit
kannst Du die Datei auslesen. Dann durchläufst Du die Zeilen mit einer Foreach-Schleife und schreibst das, was Du gerne hättest direkt in die Registry und (ziemlich) direkt in das WMI-Objekt.
Die Befehle für die Registry:
für die WMI-Objekte guckst Du hier: https://powershellpraxis.de/index.php/grundlagen/automation-interfaces/w ...
Hier noch die Dokumentation: https://docs.microsoft.com/de-de/powershell/
<edit>Hier noch ein Link, wie das mit dem Manipulieren der WMI-Objekte geht: https://blogs.technet.microsoft.com/systemcentervnext/2011/05/25/powersh ... </edit>
hth
Erik
Powershell heißt Dein Freund. Hier hast Du direkten Zugriff auf die Registry. Gib mal (als Admin ausführen)
cd HKLM:\
auf der Shell ein. ;) Und auch die WMI-Objekte sind damit kein Problem.
Vom Prinzip sieht das dann so aus:
Mit
get-content file.txt
kannst Du die Datei auslesen. Dann durchläufst Du die Zeilen mit einer Foreach-Schleife und schreibst das, was Du gerne hättest direkt in die Registry und (ziemlich) direkt in das WMI-Objekt.
Die Befehle für die Registry:
new-item
new-itemProperty
für die WMI-Objekte guckst Du hier: https://powershellpraxis.de/index.php/grundlagen/automation-interfaces/w ...
Hier noch die Dokumentation: https://docs.microsoft.com/de-de/powershell/
<edit>Hier noch ein Link, wie das mit dem Manipulieren der WMI-Objekte geht: https://blogs.technet.microsoft.com/systemcentervnext/2011/05/25/powersh ... </edit>
hth
Erik
Moin,
ist dein Freund.
Gruß
Zitat von @stefanhans:
Jetzt habe ich gerade noch erfahren, dass wir noch kein PowerShell ausführen können. Wie auch immer, ich muss es mit Batch hinbekommen.
Jetzt habe ich gerade noch erfahren, dass wir noch kein PowerShell ausführen können. Wie auch immer, ich muss es mit Batch hinbekommen.
reg add /?
ist dein Freund.
Gruß
Moin,
So ist das, wenn man in der Ausbildung ist. ;)
Ich versuche es aber mal mit Deinen Ansätzen.
Nur Mut. So schwer ist es auch nicht. Versuche es. Wenn es nicht klappt, dann weißt Du ja, wo Du fragen kannst.
Jetzt habe ich gerade noch erfahren, dass wir noch kein PowerShell ausführen können. Wie auch immer, ich muss es mit Batch hinbekommen.
Wieso könnt Ihr keine Powershell ausführen? Ist Euer System so alt? Oder liegt es an der Execution Policy? Die kann man als Admin umgehen. Guck mal unter
Das mit einem Batch zu lösen wird erheblich schwerer.
Liebe Grüße
Erik
Zitat von @stefanhans:
Ich habe mich mit PowerShell erst ein klein wenig auseinander gesetzt. Sieht mächtig aus, aber da bin ich noch überhaupt nicht soweit, um das zu verstehen.
Ich habe mich mit PowerShell erst ein klein wenig auseinander gesetzt. Sieht mächtig aus, aber da bin ich noch überhaupt nicht soweit, um das zu verstehen.
So ist das, wenn man in der Ausbildung ist. ;)
Ich versuche es aber mal mit Deinen Ansätzen.
Nur Mut. So schwer ist es auch nicht. Versuche es. Wenn es nicht klappt, dann weißt Du ja, wo Du fragen kannst.
Jetzt habe ich gerade noch erfahren, dass wir noch kein PowerShell ausführen können. Wie auch immer, ich muss es mit Batch hinbekommen.
Wieso könnt Ihr keine Powershell ausführen? Ist Euer System so alt? Oder liegt es an der Execution Policy? Die kann man als Admin umgehen. Guck mal unter
Get-ExecutionPolicy
Set-ExecutionPolicy
Das mit einem Batch zu lösen wird erheblich schwerer.
Liebe Grüße
Erik
Moin,
Das sieht so aus:
Auf die Schnelle hingeschrieben, ohne es zu testen. Das mit dem WMI-Objekt findest Du selbst raus. ;)
Und? Powershell ist integraler Bestandteil jeder Windows-Installation seit Windows 7 bzw. Server 2008 R2. Das muss nicht verteilt werden.
Liebe Grüße
Erik
Zitat von @stefanhans:
Hallo Erik
Also einzelne Steps kann ich mittlerweile mit PowerShell ausführen. Mit dem "verknüpfen" haperts es aber noch sehr.
Vor allem das mit dem foreach klappt überhaupt nicht. Wie kann ich den Text teilen (Doppelpunkt) mit vorne und hinten und das danach weiter geben?
Hallo Erik
Also einzelne Steps kann ich mittlerweile mit PowerShell ausführen. Mit dem "verknüpfen" haperts es aber noch sehr.
Vor allem das mit dem foreach klappt überhaupt nicht. Wie kann ich den Text teilen (Doppelpunkt) mit vorne und hinten und das danach weiter geben?
Das sieht so aus:
# Textdatei in ein Array einlesen
$arr_text = get-content deinedatei.txt
# In dem Array stehen jetzt die einzelnen Zeilen des Textes
foreach($line in $arr_text) {
# Text am Doppelpunkt trennen.
$arr_version = $line.split(":")
# Jetzt hast Du ein Array, in dem steht im ersten Element der Text und im zweiten die Nummer.
# Erstmal gucken, ob der Schlüssel schon existiert. Ansonsten anlegen. Eventuell solltest Du auch prüfen,
# ob denn Inventory schon existiert.
if(-not $(test-path "HKLM:\Software\Inventory\Thunderbolt Host Controller\")) {
new-item "HKLM:\Software\Inventory\Thunderbolt Host Controller"
}
New-ItemProperty -Type String -Path "HKLM:\Software\Inventory\Thunderbolt Host Controller" -Name "Firmware Version" -value $arr_version
}
Auf die Schnelle hingeschrieben, ohne es zu testen. Das mit dem WMI-Objekt findest Du selbst raus. ;)
Kannst Du mir nicht ein kleines Bespiel erstellen? Das wäre es nett.
PowerShell kann unsere Software-Verteilung noch nicht. Da soll es bis Ende Jahr eine neue Lösung oder Version geben.
PowerShell kann unsere Software-Verteilung noch nicht. Da soll es bis Ende Jahr eine neue Lösung oder Version geben.
Und? Powershell ist integraler Bestandteil jeder Windows-Installation seit Windows 7 bzw. Server 2008 R2. Das muss nicht verteilt werden.
Liebe Grüße
Erik
Auch kein Thema mit Batch wenn du es warum auch immer noch damit umsetzen willst/musst/kannst:
Grüße Uwe
set /p content=<"c:\windows\temp\version.txt"
for /f "tokens=2 delims=:" %%a in ("%content%") do for /f %%b in ("%%a") do set "version=%%b"
reg add "HKLM\Software\Inventory\Thunderbolt Host Controller" /v "Firmware Version" /d "%version%" /f
Moin,
...
Und das WMI-Objekt? Geht das auch per Batch? Reine Neugier ...
Liebe Grüße
Erik
Zitat von @colinardo:
Auch kein Thema mit Batch wenn du es warum auch immer noch damit umsetzen willst/musst/kannst:
Auch kein Thema mit Batch wenn du es warum auch immer noch damit umsetzen willst/musst/kannst:
...
Und das WMI-Objekt? Geht das auch per Batch? Reine Neugier ...
Liebe Grüße
Erik
Das ginge auch etwas aufwendiger mit mofcomp je nachdem ob die Klasse schon angelegt wurde oder eben nicht, da er das aber nur als "Option" aufgeführt hat wollte ich ihm den Wust erst mal ersparen. Aber auch per Batch lässt sich ja mit Set-WMIInstance und PS Aufruf arbeiten.
Naja die Klasse muss ja erst mal existieren, der Namespace Inventory existiert ja auf Kisten nur wenn er schon mal von jemand angelegt wurde
Ich poste dir das hier mal als Powershell Schnippsel (also wie du Namespace und eine generische Klasse anlegst, welche weiteren Eigenschaften diese haben soll und muss wissen wir ja nicht deswegen hier nur mal ein Beispiel mit einer Eigenschaft der FirmwareVersion):
Batch wäre mit Erstellung einer Description-Datei für den Namespace und die Klasse verbunden ist ungleich aufwendiger als mit der PS
Ändern des Werts ist alsdann Namespace und Klasse existiert dann mit Set-WMIInstance möglich:
Abfragen ob Namespace oder Klasse exisitiert machst du dann z.B. mit Get-CimInstance und bei Exception ben entsprechend Namespace/Klasse anlegen.(Achtung Admin-Rechte erforderlich!!)
Könnte man das so bauen, dass zuerst die Klasse geprüft und wenn diese nicht existiert, dass man Sie anlegt?
Kannst duIch poste dir das hier mal als Powershell Schnippsel (also wie du Namespace und eine generische Klasse anlegst, welche weiteren Eigenschaften diese haben soll und muss wissen wir ja nicht deswegen hier nur mal ein Beispiel mit einer Eigenschaft der FirmwareVersion):
Batch wäre mit Erstellung einer Description-Datei für den Namespace und die Klasse verbunden ist ungleich aufwendiger als mit der PS
# Create WMI Namespace
$ns = [wmiclass]'root\cimv2:__namespace'
$c = $ns.CreateInstance()
$c.Name = "Inventory"
$c.Put()
# Create new wmi management class
$class = new-object wmiclass('root\Cimv2\Inventory',[string]::Empty,$null)
$class['__CLASS'] = 'ThunderboltHostController'
$class.Qualifiers.Add("Static",$true)
$class.Properties.Add("FirmwareVersion","IRGENDEIN initialer WERT",[System.Management.CimType]::String)
$class.Properties['FirmwareVersion'].Qualifiers.Add("Key",$true)
$class.Put()
Set-WmiInstance -Namespace root\cimv2\Inventory -Class ThunderboltHostController -Arguments @{FirmwareVersion = '99.99.99'}
Abfragen ob Namespace oder Klasse exisitiert machst du dann z.B. mit Get-CimInstance und bei Exception ben entsprechend Namespace/Klasse anlegen.(Achtung Admin-Rechte erforderlich!!)
Gerne
Hättest du dir meinen Code noch mal genau angesehen, dann hättest du die Property "Static" bemerkt und das so übernommen hättest du auch kein Problem mit dem Überschreiben, und müsstest die Klasse auch nur einmal erstellen und nicht jedes mal neu!
Die Version hätte ich pers. Per Regex direkt ausgelesen, aber jeder wie er kann und seinem Wissensstand entspricht.
Dann noch Haken dran und fertig. Merci.
Die Version hätte ich pers. Per Regex direkt ausgelesen, aber jeder wie er kann und seinem Wissensstand entspricht.
Dann noch Haken dran und fertig. Merci.
Zitat von @stefanhans:
Die Property "Static" habe ich schon gesehen und auch getestet. Hat aber bisher nicht funktioniert.
Meldung: Set-WmiInstance : Object or property already exists
Klar, weil du ja nicht prüfst ob es die Klasse schon gibt, da ist es klar das er dir diesen Fehler wirft.Die Property "Static" habe ich schon gesehen und auch getestet. Hat aber bisher nicht funktioniert.
Meldung: Set-WmiInstance : Object or property already exists
Moin,
Nein, ich würde prüfen, ob das Objekt schon exisitiert.
Liebe Grüße
Erik
Zitat von @stefanhans:
Würdet Ihr den Punkt
auch so umsetzen oder anders (ist evtl. etwas extrem)?
Würdet Ihr den Punkt
Remove-WmiObject -Class "ThunderboltHostController" -Namespace "root\cimv2\Inventory"
auch so umsetzen oder anders (ist evtl. etwas extrem)?
Nein, ich würde prüfen, ob das Objekt schon exisitiert.
Liebe Grüße
Erik
Moin,
genauso wie beim Testen, ob der Pfad in der Registry existiert:
Liebe Grüße
Erik
genauso wie beim Testen, ob der Pfad in der Registry existiert:
# Remove-WmiObject -Class "ThunderboltHostController" -Namespace "root\cimv2\Inventory" Weg damit. ;)
# Testen, ob die Klasse existiert.
if(-not $(get-wmiObject ThunderboltHostController -list)) {
# Und falls nicht, dann Klasse anlegen.
$Class = New-Object wmiclass ("root\cimv2\Inventory", [String]::Empty, $null);
$Class["__CLASS"] = "ThunderboltHostController";
$Class.Qualifiers.Add("Static",$true)
$Class.Properties.Add("FirmwareVersion", $arr_version[1].Trim(), [System.Management.CimType]::String)
$Class.Properties['FirmwareVersion'].Qualifiers.Add("Key",$true)
$Class.Put()
}
Set-WmiInstance -Namespace root\cimv2\Inventory -Class ThunderboltHostController -Arguments @{FirmwareVersion = $arr_version[1].Trim()}
Liebe Grüße
Erik
Damit das hier mal endet, (vorher lösche die Klasse bitte einmalig, da diese hier als Key eine andere Property bekommt, der spielt hier nämlich eine wichtige Rolle.)
Ich empfehle dir mal das Tool wbemtest. Damit kannst du per GUI im WMI hantieren und auch schneller debuggen.
Ich empfehle dir mal das Tool wbemtest. Damit kannst du per GUI im WMI hantieren und auch schneller debuggen.
[string]$version = [regex]::match(@(gc "$env:windir\temp\version.txt" -TotalCount 1 -ea 0),'[\d\.]+').Value
new-Item -Path "HKLM:\Software\Intel\Thunderbolt Host Controller" -Force | out-null
New-ItemProperty -Path "HKLM:\Software\Intel\Thunderbolt Host Controller" -Name "Firmware Version" -Value $version -PropertyType String -Force | out-null
try{
$ns = [wmiclass]'root\cimv2\Inventory'
}catch{
# Create WMI Namespace
write-host "Namespace does not exist, creating now..." -F Green
$ns = [wmiclass]'root\cimv2:__namespace'
$c = $ns.CreateInstance()
$c.Name = "Inventory"
$c.Put() | out-null
}
write-host "Updating Firmware-Version in WMI." -F Green
try{
gcim -Query "SELECT * FROM ThunderboltHostController WHERE Index=1" -Namespace root\cimv2\Inventory -EA Stop | Set-CimInstance -Property @{FirmwareVersion=$version} -EA Stop
}catch{
write-host "Creating WMI-Class..." -F Green
$c = new-object wmiclass('root\Cimv2\Inventory',[string]::Empty,$null)
$c['__CLASS'] = 'ThunderboltHostController'
$c.Properties.Add("FirmwareVersion","",[System.Management.CimType]::String)
$c.Properties.Add("Index",0,[System.Management.CimType]::UInt32)
$c.Properties['Index'].Qualifiers.Add("Key",$true)
$c.Put() | out-null
New-CimInstance -ClassName ThunderboltHostController -Namespace root\cimv2\Inventory -Property @{FirmwareVersion=$version;Index=[uint32]1} | out-null
}
Doch alles getestet! Wenn du das natürlich nicht "elevated als Admin" ausführst ist es klar, denn weder in die Registry kann ein normaler User in HKLM schreiben noch Klassen oder WMI Objekte erstellen ....
Eine aktuelle Powershell >= 3.0 ist Voraussetzung, da in diesem Beispiel die CImInstance CMDLets zum Einsatz kommen.
Eine aktuelle Powershell >= 3.0 ist Voraussetzung, da in diesem Beispiel die CImInstance CMDLets zum Einsatz kommen.
Zitat von @stefanhans:
Die datei liegt unter C:\temp\ und heisst version.txt
In Deinem Code steht: "$env:windir\temp\version.txt" -> das entspircht c:\windows\temp\version.txt
Naja das Stand ja als Pfad in deinem Ursprungspost und hätte erwartet das du das anpasst Die datei liegt unter C:\temp\ und heisst version.txt
In Deinem Code steht: "$env:windir\temp\version.txt" -> das entspircht c:\windows\temp\version.txt
Noch eine ergänzende Frage: Sollte sich in der Versionsnummer einen Buchstaben befinden (was bei gewissen Herstellern leider ab und zu der Fall ist), funktioniert es dann auch?
Nein, das passt du mit dem Regex in der ersten Zeile an: '[\d\.]+'. Da kannst du es definieren was drin sein darf.Universeller kannst du es so schreiben, dann kann nach dem Doppelpunkt und 1 oder keinem Leerzeichen alles stehen und es wird davon alles außer weitere Leerzeichen übernommen.
[string]$version = [regex]::match(@(gc "$env:windir\temp\version.txt" -TotalCount 1 -ea 0),'(?<=:\s*)[^\s]+').Value
Bassis-Wissen über vorausgesetzt kann dann der Text beliebig komplex werden und du kannst es trotzdem noch mit einem Ausdruck erfassen:
Regular Expressions Tutorial