stefanhans
Goto Top

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

Content-Key: 381383

Url: https://administrator.de/contentid/381383

Printed on: April 18, 2024 at 22:04 o'clock

Member: erikro
erikro Jul 26, 2018 updated at 07:01:32 (UTC)
Goto Top
Moin,

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
Member: stefanhans
stefanhans Jul 26, 2018 updated at 07:23:31 (UTC)
Goto Top
Hallo Erik

Danke für Deine Antwort und Dein Feedback.

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 versuche es aber mal mit Deinen Ansätzen.

Jetzt habe ich gerade noch erfahren, dass wir noch kein PowerShell ausführen können. Wie auch immer, ich muss es mit Batch hinbekommen.

Gruss Stefan
Member: Kraemer
Kraemer Jul 26, 2018 at 07:28:07 (UTC)
Goto Top
Moin,

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.

reg add /?

ist dein Freund.

Gruß
Member: erikro
erikro Jul 26, 2018 at 07:32:47 (UTC)
Goto Top
Moin,


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.

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
Member: stefanhans
stefanhans Jul 26, 2018 updated at 08:17:20 (UTC)
Goto Top
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?

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.

Gruss Stefan
Member: erikro
erikro Jul 26, 2018 at 08:58:58 (UTC)
Goto Top
Moin,

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?

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.

Und? Powershell ist integraler Bestandteil jeder Windows-Installation seit Windows 7 bzw. Server 2008 R2. Das muss nicht verteilt werden.

Liebe Grüße

Erik
Member: colinardo
colinardo Jul 26, 2018 updated at 09:46:17 (UTC)
Goto Top
Auch kein Thema mit Batch wenn du es warum auch immer noch damit umsetzen willst/musst/kannst:
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  
Grüße Uwe
Member: erikro
erikro Jul 26, 2018 at 10:07:04 (UTC)
Goto Top
Moin,


Zitat von @colinardo:

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
Member: colinardo
colinardo Jul 26, 2018 updated at 10:32:22 (UTC)
Goto Top
Zitat von @erikro:
Und das WMI-Objekt? Geht das auch per Batch? Reine Neugier ...
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.
Member: stefanhans
stefanhans Jul 26, 2018 at 10:56:48 (UTC)
Goto Top
Hallo Erik

Also mit PowerShell habe ich es jetzt hinbekommen.

Jetzt muss ich nur noch versuchen, dies in unserer Umgebung hinzubekommen.

Vielen Dank für Deine Hilfe.

Gruss Stefan
Member: stefanhans
stefanhans Jul 26, 2018 at 11:03:48 (UTC)
Goto Top
Hallo Uwe

Super, auch das funktioniert wunderbar.

Kannst Du mir vielleicht auch noch das Beispiel erweitern mit der WMI. Dann bin ich damit auch schon schlauer.

Was meinst Du mit, ob die Klasse schon angelegt ist?

Könnte man das so bauen, dass zuerst die Klasse geprüft und wenn diese nicht existiert, dass man Sie anlegt?

Ich danke Euch allen für Eure Hilfestellungen.

Viele Grüsse Stefean
Member: colinardo
colinardo Jul 26, 2018 updated at 11:26:11 (UTC)
Goto Top
Zitat von @stefanhans:
Was meinst Du mit, ob die Klasse schon angelegt ist?
Naja die Klasse muss ja erst mal existieren, der Namespace Inventory existiert ja auf Kisten nur wenn er schon mal von jemand angelegt wurde
Könnte man das so bauen, dass zuerst die Klasse geprüft und wenn diese nicht existiert, dass man Sie anlegt?
Kannst du

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
# 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()
Ändern des Werts ist alsdann Namespace und Klasse existiert dann mit Set-WMIInstance möglich:
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!!)
Member: erikro
erikro Jul 26, 2018 at 11:46:08 (UTC)
Goto Top
Zitat von @stefanhans:
Vielen Dank für Deine Hilfe.

Gerne
Member: stefanhans
stefanhans Jul 27, 2018 updated at 06:45:00 (UTC)
Goto Top
Guten Morgen zusammen

Ich kann mit PowerShell nun die Datei auslesen
$arr_text = get-content "c:\temp\version.txt"  
foreach($line in $arr_text) {
$arr_version = $line.split(":")  

In die Registry schreiben (inkl. Prüfung ob Key vorhanden ist
if(-not $(test-path "HKLM:\Software\Inventory\Thunderbolt Host Controller\")) {  
new-item -Path "HKLM:\Software\Inventory" -Force  
new-item -Path "HKLM:\Software\Inventory\Thunderbolt Host Controller" -Force  
}
new-ItemProperty -Type String -Path "HKLM:\Software\Inventory\Thunderbolt Host Controller" -Name "Firmware Version" -value $arr_version[1] -Force  
} 

Dann kann ich in der WMI einen Namespace sowie eine Klasse und die Properties erstellen
$newClass = New-Object System.Management.ManagementClass ("root\cimv2\Inventory", [String]::Empty, $null);   
$newClass["__CLASS"] = "ThunderboltHostController";   
$newClass.Properties.Add("FirmwareVersion", [System.Management.CimType]::String, $false)  
$newClass.Put() 

Aber die Instanz und den Wert ($arr_version[1] ) bringe ich einfach nicht in die WMI

Diese Code habe ich probiert:
Set-WmiInstance -Namespace root\cimv2\Inventory -Class ThunderboltHostController -Arguments @{FirmwareVersion = '$arr_version[1]'}  
und diesen
Set-WmiInstance -Namespace root\cimv2\Inventory -Class ThunderboltHostControllers -Arguments $arr_version[1]

Diese Infos bekomme ich zurück:
Set-WmiInstance : Cannot bind parameter 'Arguments'. Cannot convert the " 20.2.5.5.1" value of type "System.String" to type "System.Collections.Hashtable".  
At line:1 char:110
+ ...  -Class ThunderboltHostControllers -Arguments $arr_version[1]
+                                                           ~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Set-WmiInstance], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.SetWmiInstance

Was mache ich falsch bzw. wo könnte der Fehler sein?

Danke für die Hilfe.

LG Stefan
Member: colinardo
colinardo Jul 27, 2018 updated at 06:49:08 (UTC)
Goto Top
Was mache ich falsch bzw. wo könnte der Fehler sein?
Hochkommata weg lassen, in diesen werden keine Variablen geparst.
Set-WmiInstance -Namespace root\cimv2\Inventory -Class ThunderboltHostController -Arguments @{FirmwareVersion = $arr_version[1]}
Member: stefanhans
stefanhans Jul 27, 2018 updated at 07:07:29 (UTC)
Goto Top
Danke colinardo

Jetzt funktioniert das auch.

Habe nur noch eine kleine Unschönheit. Der Doppelpunkt als Seperator ist gut un recht, aber nach dem Doppelpunkt hat es ein Leerzeichen und das nimmt er jetzt mit in die WMI. Also anstatt "20.2.5.5.1" steht nun " 20.2.5.5.1" drin. Wie bringe ich das Leerzeichen nach dem Doppelpunkt bzw. vor der 2 noch weg?

Und leider noch was weiteres: Wenn ich das Script weitere Male ausführe, erhalte ich die Meldung: "Set-WmiInstance : Object or property already exists". Der soll das doch einfach überschreiben bzw. aktualisieren.
Member: colinardo
colinardo Jul 27, 2018 updated at 07:10:27 (UTC)
Goto Top
Einfach mal in die Doku schauen, hätte auch dich erleuchtet:
$arr_version[1].Trim()
Und leider noch was weiteres: Wenn ich das Script weitere Male ausführe, erhalte ich die Meldung:
Hätte ich dich oben schon drauf hingewiesen!
Member: stefanhans
stefanhans Jul 27, 2018 at 07:22:32 (UTC)
Goto Top
Habe es nun so hinbekommen:

$arr_text = get-content "c:\temp\version.txt"  
foreach($line in $arr_text) {
$arr_version = $line.split(":")  
if(-not $(test-path "HKLM:\Software\Inventory\Thunderbolt Host Controller\")) {  
new-item -Path "HKLM:\Software\Inventory" -Force  
new-item -Path "HKLM:\Software\Inventory\Thunderbolt Host Controller" -Force  
}
new-ItemProperty -Type String -Path "HKLM:\Software\Inventory\Thunderbolt Host Controller" -Name "Firmware Version" -value $arr_version[1].Trim() -Force  
} 
Remove-WmiObject -Class "ThunderboltHostController" -Namespace "root\cimv2\Inventory"  
$Class = New-Object wmiclass ("root\cimv2\Inventory", [String]::Empty, $null);   
$Class["__CLASS"] = "ThunderboltHostController";   
$Class.Properties.Add("FirmwareVersion", $arr_version[1], [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()}

Vermutlich könnte man noch etwas Kosmetik betreiben, aber ich denke, dass es so gut ist. Seht Ihr das auch so?

Würdet Ihr den Punkt
Remove-WmiObject -Class "ThunderboltHostController" -Namespace "root\cimv2\Inventory"  

auch so umsetzen oder anders (ist evtl. etwas extrem)?
Member: colinardo
colinardo Jul 27, 2018 updated at 07:30:01 (UTC)
Goto Top
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.
Member: stefanhans
stefanhans Jul 27, 2018 at 07:49:03 (UTC)
Goto Top
Die Property "Static" habe ich schon gesehen und auch getestet. Hat aber bisher nicht funktioniert.

Meldung: Set-WmiInstance : Object or property already exists

Auch mit $Class.Properties.Remove('FirmwareVersion') funktioniert es nicht. Daher mein Weg mit dem Remove-WmiObject.
Member: colinardo
colinardo Jul 27, 2018 at 08:03:34 (UTC)
Goto Top
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.
Member: erikro
erikro Jul 27, 2018 at 08:07:26 (UTC)
Goto Top
Moin,

Zitat von @stefanhans:
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
Member: stefanhans
stefanhans Jul 27, 2018 at 08:20:17 (UTC)
Goto Top
Aktuellster Code:

$arr_text = get-content "c:\temp\version.txt"  
#$arr_text = get-content "C:\Windows\Helsana\Logs\Scripts\Intel\Thunderbolt Host Controller\version.txt" 
foreach($line in $arr_text) {
$arr_version = $line.split(":")  

if(-not $(test-path "HKLM:\Software\Intel\")) {  
new-item -Path "HKLM:\Software\Intel" -Force  
}
if(-not $(test-path "HKLM:\Software\Intel\Thunderbolt Host Controller\")) {  
new-item -Path "HKLM:\Software\Intel\Thunderbolt Host Controller" -Force  
}
new-ItemProperty -Type String -Path "HKLM:\Software\Intel\Thunderbolt Host Controller" -Name "Firmware Version" -value $arr_version[1].Trim() -Force  
}

Remove-WmiObject -Class "ThunderboltHostController" -Namespace "root\cimv2\Inventory"  

$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()} 

Wie und wo würde er also die Klasse und das Objekt prüfen?

Bzw. wie würdet Ihr es umbauen, dass kein Remove-WmiObject benötigt wird und das Script immer ausgeführt werden kann und dabei die Firmware Version bei jeder Ausführung aktualisiert wird (auch wenn der wert unverändert ist, also nicht aktualisiert worden ist)?

Wäre froh um ein Beispiel. Danke.
Member: erikro
erikro Jul 27, 2018 updated at 09:18:48 (UTC)
Goto Top
Moin,

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
Member: colinardo
Solution colinardo Jul 27, 2018 updated at 10:28:14 (UTC)
Goto Top
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.

screenshot

[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
}
Member: stefanhans
stefanhans Jul 27, 2018 at 09:33:33 (UTC)
Goto Top
Hallo Erik

Dann erhalte ich ab dem zweiten Mal ausführen diese Meldung, wenn sich der Wert $arr_version[1] nicht ändert:

Set-WmiInstance : Object or property already exists
At line:26 char:1

Line 26:
Set-WmiInstance -Namespace root\cimv2\Inventory -Class ThunderboltHostController -Arguments @{FirmwareVersion = $arr_version[1].Trim()} 


Wenn sich der Wert $arr_version[1] ändert, dann läuft es durch, aber in der WMI sind dann zwei Instancen vorhanden. Das sollte auch nicht sein.
Member: stefanhans
stefanhans Jul 27, 2018 at 09:39:19 (UTC)
Goto Top
habe es getestet, die version wird aber weder in der regsitry noch in der wmi eingetragen


Zitat von @colinardo:

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.

screenshot

> [string]$version = [regex]::match(@(gc "$env:windir\temp\version.txt" -raw -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}
> }
> 
Member: colinardo
colinardo Jul 27, 2018 updated at 09:45:02 (UTC)
Goto Top
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.
Member: stefanhans
stefanhans Jul 27, 2018 at 09:45:17 (UTC)
Goto Top
So sieht es bei mir in der Registry aus:


So habe ich es ausgeführt:
capture
capture1
Member: colinardo
colinardo Jul 27, 2018 updated at 09:51:08 (UTC)
Goto Top
PS Version? (Wie gesagt >=PS3.0). Und wie sieht die Textdatei bzw. Version nun exakt aus? Pfadangabe gecheckt? Ich gehe davon aus das die Version nur DIgits und Punkte enthält oder enthält sie bei dir noch andere Zeichen?
Member: stefanhans
stefanhans Jul 27, 2018 at 09:58:44 (UTC)
Goto Top
Der Dateiinhalt sieht so aus:


Die datei liegt unter C:\temp\ und heisst version.txt

Und nun hab eich auch den Fehler gefunden:

In Deinem Code steht: "$env:windir\temp\version.txt" -> das entspircht c:\windows\temp\version.txt

Ich habe die Datei aber und c:\temp\

Verschiebe ich die Datei oder passe den Code an, dann funktioniert es.

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?
capture2
Member: colinardo
colinardo Jul 27, 2018 updated at 10:21:14 (UTC)
Goto Top
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 face-wink.
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  
Da kann man sich austoben wie man möchte face-smile.
Bassis-Wissen über vorausgesetzt kann dann der Text beliebig komplex werden und du kannst es trotzdem noch mit einem Ausdruck erfassen:
Regular Expressions Tutorial
Member: stefanhans
stefanhans Jul 27, 2018 at 10:21:21 (UTC)
Goto Top
Super vielen herzlichen Dank.

Ich habe nun noch einen abschliessenden Test durchgeführt und dabei in Registry und den WMI Eintrag gelöscht. Dann erhalte ich die Meldung

New-CimInstance : One or more parameter values passed to the method were invalid.
At line:27 char:5

Sobald ich es ein zweites Mal starte, dann läuft es ohne Meldung durch.
Member: colinardo
colinardo Jul 27, 2018 updated at 10:29:42 (UTC)
Goto Top
Kann ich nicht bestätigen.

screenshot

Ich bin jetzt draußen, das Handwerkszeug hast du nun.

Viel Erfolg.
Grüße Uwe
Member: stefanhans
stefanhans Jul 27, 2018 at 10:46:10 (UTC)
Goto Top
Vielen Dank Uwe