Powershell gci - Variableneinsatz - Bedingung schlägt fehl

VoodooMax

Lieutenant
Registriert
Feb. 2010
Beiträge
686
Servus an alle Powershell-Gurus ;)

Ich scheitere gerade daran, in einem Verzeichnis eine Datei zu finden in deren Namen eine bestimmte Zeichenkette ist, die ich vorher in eine Variable gelesen habe. Genauer lese ich die Firmware/Softwareversion eines TPM-Moduls aus.

PowerShell:
# ManufacturerVersion auslesen
$TPMVER = get-tpm | Select-Object ManufacturerVersion
# überflüssige Teile entfernen
$TPMVER = $TPMVER.ManufacturerVersion

Anschließend suche ich in einem festgelegten Verzeichnis, ob eine Datei vorhanden ist, die den Inhalt von $TPMVER im Namen trägt:

PowerShell:
$Dateiname = get-ChildItem -filter *.bin | Where-Object { $_.Name -match $TPMVER }

Jetzt kommt das was mich fuchsig macht:
Die Variable $TPMVER erhält z.B. den Wert 7.63.3353.0
Im Script bleibt $Dateiname aber -eq $NULL.

Lösche ich $TPMVER und weise den Wert direkt zu
PowerShell:
clear-variable TPMVER
$TPMVER = "7.63.3353.0"
erhalte ich wie gewünscht den Dateinamen... Was mache ich hier falsch? Testweise habe ich bereits $TPMVER als String definiert, Anführungszeichen verwendet, den Wert in eine neue Variable überführt (alles erfolglos oder mit anderen dadurch erzeugten Fehlern), mit $Variablennamen.GetType().FullName festgestellt, dass $TPMVER immer ein System String ist und ich mit meinem Scripting-KungFu am Ende bin...

Siehe Screenshot:
1653454177538.png

Hier sieht man dass der Wert 7.85.4555.0 ausgelesen bzw. selektiert wird und der Typ der Variable ein System.String ist.
Der gci-Befehl macht aber keine Ausgabe, also wird die Bedingen $_:Name -match $check nicht erfüllt.
Nach Löschen der Variable und Neuzuweisung des oben ausgelesenen Wertes ist die Variable immer noch ein System.String und die Bedingung wird offensichtlich erfüllt, da die Ausgabe der gefundenen Dateien wie erwartet erfolgt...
 
Lösung
Ich hab das gerade Mal auf meinem Rechner ausprobiert..
PowerShell:
PS C:\Windows\system32> $TPMVER.ManufacturerVersion
1.258.0.0
PS C:\Windows\system32> $TPMVER.ManufacturerVersion.Equals("1.258.0.0")
False

ToCharArray spuckt was interessantes aus, offenbar ist der String 32 Zeichen lang und mit 0x0 aufgefüllt:
PowerShell:
PS C:\Windows\system32> $TPMVER.ManufacturerVersion.ToCharArray()
1
.
2
5
8
.
0
.
0























PS C:\Windows\system32>

Heureka, die NUL Bytes am Ende entfernen, und schon klappt's:

PowerShell:
PS C:\Windows\system32> $TPMVER.ManufacturerVersion.Trim([char]0).Equals("1.258.0.0")
True
PS C:\Windows\system32>
Ich hab das gerade Mal auf meinem Rechner ausprobiert..
PowerShell:
PS C:\Windows\system32> $TPMVER.ManufacturerVersion
1.258.0.0
PS C:\Windows\system32> $TPMVER.ManufacturerVersion.Equals("1.258.0.0")
False

ToCharArray spuckt was interessantes aus, offenbar ist der String 32 Zeichen lang und mit 0x0 aufgefüllt:
PowerShell:
PS C:\Windows\system32> $TPMVER.ManufacturerVersion.ToCharArray()
1
.
2
5
8
.
0
.
0























PS C:\Windows\system32>

Heureka, die NUL Bytes am Ende entfernen, und schon klappt's:

PowerShell:
PS C:\Windows\system32> $TPMVER.ManufacturerVersion.Trim([char]0).Equals("1.258.0.0")
True
PS C:\Windows\system32>
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: NotNerdNotDau, quaaaak und Der Lord
@schalli110 Danke fürs Testen. Ist jetzt mal ein neuer Ansatz - Jetzt muss ich nur noch rauskrieben wie ich den "Müll" aus der Variable rauskriege...

Wenn da noch jemand einen Tipp für mich hat, Dr. Google sieht mich schon entnervt an :D
 
@VoodoMax, hab meinen Beitrag ein paar Mal editiert, die Lösung, wie man den "Müll" entfernt steht auch drin. Hast du vielleicht übersehen:

$TPMVER.ManufacturerVersion.Trim([char]0).Equals("1.258.0.0")
 
  • Gefällt mir
Reaktionen: VoodooMax
Super - und vielmals Danke.
Manchmal sieht man einfach den Wald vor lauter Bäumen nicht mehr. Und wenn man dann - so wie ich - noch nicht alle Kräuter kennt ;)
Die ToCharArray-Funktion und die Trim-Funktion waren mir bisher noch unbekannt, also wieder was gelernt. 👍
 
Nur als Hinweis:
Select-object kennt -Expandproperty.

-match erwartet einen regulären Ausdruck. Das geht schief, sobald der übergebene Wert “Sonderzeichen” im Sinne von Regex beinhaltet. Schau nach -like.

Und ja, für Systeminfos aller Art empfiehlt sich immer ein trim().
Aber bedenken, daß $null.irgendeineMethode() immer eine Ausnahme werfen wird. Also vorher .Length angucken.

PS. Typ “version” könnte evtl implizit funktionieren, auch mit dem Null am Ende des Strings. Kann ich allerdings grad nicht testen.
 
Danke für Eure Vorschläge, das Problem war hier wohl wirklich die Länge der Daten in $TPMVER.
Die Code-Vereinfachungen (die ich teils bereits getestet hatte, aber ohne die Daten zu "trimmen") sehen gut aus.
Für dieses Script ist "schön" aber nicht zwingend erforderlich, unsere Techniker sollen halt einfach auf den Notebooks die zur Neuinstallation kommen eine Aktualisierung des TPM durchführen, ohne vorher alle Voraussetzungen manuell zu überprüfen bzw. herzustellen. Es scheiterte hier einfach an meinem Unvermögen die Variable auf ihren tatsächlichen Inhalt zu untersuchen und zu bereinigen, da logischerweise so die Datei nicht gefunden wurde...

Tatsächlich war das mein erster Gehversuch in der Powershell. Dafür hat´s ganz gut hingehauen, sonst habe ich bisher alles mit der CMD machen können. Für die Abfrage der TPM-Daten und ein paar andere Sachen war die CMD aber nicht mehr tauglich.

Und ich muss sagen - Powershell ist anders, aber geil :D
 
Hmm... ich bekomme immer nur $Null raus, egal was ich mache. 🤔

PowerShell:
PS ~> echo "#".$var."#";
PS ~> (echo "#".$var."#") -eq $null
True
PS ~>

Was mache ich falsch? Ich hab auch bisher immer Write-Debug genommen.
 
Zurück
Oben