Mit Powershell in einer Datei eine Zeile auslesen
Hallo zusammen,
wie bekomme ich es hin, das ich einen Bestimmt wert aus einer Zeil auslesen kann?
Ich hab einen Job erstellt der die Registry 32 und 64 Bit in eine Datei einliest, jetzt suche ich in der Datei nach einem Bestimmt Eintrag um damit weiter zu arbeiten.
Die C:\temp\PS-INI\INSTALL.INI sieht so aus:
32
WinSCP 5.9.2
C:\TEMP\winscp592\Protokolle\SYS-1P16010-1-PS.log
Das Skipt:
#Einlesen der Datei INSTALL.INI, in der das zu überprüfende Programm genannt ist
$var = get-content 'C:\temp\PS-INI\INSTALL.INI' # Datei wird vom SW-Paket erstellt.
$LOG = $var[2]
Remove-Item $LOG
write "----------------- START Powershell ------------------">>$LOG
write "Varieabeln zuseisung: ">>$LOG
$TX0 = "var "+$var
$TX1 = "var[1] "+$var[1]
$TX2 = "var[2] "+$var[2]
$TX3 = "var[3] "+$var[3]
$TX4 = "var[4] "+$var[4]
$TX5 = "var[5] "+$var[5]
$TX6 = "var[6] "+$var[6]
Write-Output $TX0 >>$LOG
Write-Output $TX1 >>$LOG
Write-Output $TX2 >>$LOG
Write-Output $TX3 >>$LOG
Write-Output $TX4 >>$LOG
Write-Output $TX5 >>$LOG
Write-Output $TX6 >>$LOG
$BIT = $var # BIT
$REG = $var[1] # DISPLAYNAME
$LOG = $var[2] # C:\temp\[ParketName]\Protokolle\SYS-xxxxxxx-PS.log
$var11 = $var[3] # Bezeichung die gefunden wird
$unstall1 = 'C:\temp\PS-INI\unstall1.txt' # Registry ausgabe Datei (32 und 64 BIT)
$unstall2 = 'C:\temp\PS-INI\unstall2.txt' # Ausgabe der unstall1.txt auf eine Zeile gebracht
$TX1 = "BIT Version ="+$BIT
$TX2 = "DISPLAYNAME ="+$REG
$TX3 = "LOG-File ="+$LOG
$TX4 = "INSTALL Datei1 ="+$unstall1
$TX5 = "INSTALL Datei2 ="+$unstall2
$TX6 = "Dieser Eintrag wird gesucht ="+$var[3]
Write-Output $TX1 >>$LOG
Write-Output $TX2 >>$LOG
Write-Output $TX3 >>$LOG
Write-Output $TX4 >>$LOG
Write-Output $TX5 >>$LOG
Write-Output $TX6 >>$LOG
write "------------------------------------------------------">>$LOG
write " ">>$LOG
$TX = "Das Programm "+$REG+" wird in der Registry gesucht. Bei 64 Bit Systemen, wird die ganze Registry druch sucht. Bei 32 Bit Systemen nur die der Teil der für 32 Bit."
Write-Output $TX3 >>$LOG
write " ">>$LOG
$TX = "Gesucht wird: "+$REG
Write $TX >>$LOG
$TX = "Ausgabe in "+$unstall1
write $TX >>$LOG
#Wenn 64 Bit System, dann auch die Wow6432Node mit auslesen
if($BIT -eq '64')
{
wie bekomme ich es hin, das ich einen Bestimmt wert aus einer Zeil auslesen kann?
Ich hab einen Job erstellt der die Registry 32 und 64 Bit in eine Datei einliest, jetzt suche ich in der Datei nach einem Bestimmt Eintrag um damit weiter zu arbeiten.
Die C:\temp\PS-INI\INSTALL.INI sieht so aus:
32
WinSCP 5.9.2
C:\TEMP\winscp592\Protokolle\SYS-1P16010-1-PS.log
Das Skipt:
#Einlesen der Datei INSTALL.INI, in der das zu überprüfende Programm genannt ist
$var = get-content 'C:\temp\PS-INI\INSTALL.INI' # Datei wird vom SW-Paket erstellt.
$LOG = $var[2]
Remove-Item $LOG
write "----------------- START Powershell ------------------">>$LOG
write "Varieabeln zuseisung: ">>$LOG
$TX0 = "var "+$var
$TX1 = "var[1] "+$var[1]
$TX2 = "var[2] "+$var[2]
$TX3 = "var[3] "+$var[3]
$TX4 = "var[4] "+$var[4]
$TX5 = "var[5] "+$var[5]
$TX6 = "var[6] "+$var[6]
Write-Output $TX0 >>$LOG
Write-Output $TX1 >>$LOG
Write-Output $TX2 >>$LOG
Write-Output $TX3 >>$LOG
Write-Output $TX4 >>$LOG
Write-Output $TX5 >>$LOG
Write-Output $TX6 >>$LOG
$BIT = $var # BIT
$REG = $var[1] # DISPLAYNAME
$LOG = $var[2] # C:\temp\[ParketName]\Protokolle\SYS-xxxxxxx-PS.log
$var11 = $var[3] # Bezeichung die gefunden wird
$unstall1 = 'C:\temp\PS-INI\unstall1.txt' # Registry ausgabe Datei (32 und 64 BIT)
$unstall2 = 'C:\temp\PS-INI\unstall2.txt' # Ausgabe der unstall1.txt auf eine Zeile gebracht
$TX1 = "BIT Version ="+$BIT
$TX2 = "DISPLAYNAME ="+$REG
$TX3 = "LOG-File ="+$LOG
$TX4 = "INSTALL Datei1 ="+$unstall1
$TX5 = "INSTALL Datei2 ="+$unstall2
$TX6 = "Dieser Eintrag wird gesucht ="+$var[3]
Write-Output $TX1 >>$LOG
Write-Output $TX2 >>$LOG
Write-Output $TX3 >>$LOG
Write-Output $TX4 >>$LOG
Write-Output $TX5 >>$LOG
Write-Output $TX6 >>$LOG
write "------------------------------------------------------">>$LOG
write " ">>$LOG
$TX = "Das Programm "+$REG+" wird in der Registry gesucht. Bei 64 Bit Systemen, wird die ganze Registry druch sucht. Bei 32 Bit Systemen nur die der Teil der für 32 Bit."
Write-Output $TX3 >>$LOG
write " ">>$LOG
$TX = "Gesucht wird: "+$REG
Write $TX >>$LOG
$TX = "Ausgabe in "+$unstall1
write $TX >>$LOG
#Wenn 64 Bit System, dann auch die Wow6432Node mit auslesen
if($BIT -eq '64')
{
- Reg Auswertung für 64 Bit
- Reg Auswertung für 32 Bit
write "hklm:\software\Wow6432Node\microsoft\windows\currentversion\uninstall einlesen">>$LOG
$LIST = Get-ChildItem hklm:\software\Wow6432Node\microsoft\windows\currentversion\uninstall | ForEach-Object {Get-ItemProperty $_.pspath|select -property DisplayName}
write $LIST >$unstall1
}
write " ">>$LOG
write "hklm:\software\microsoft\windows\currentversion\uninstall einlesen">>$LOG
$LIST1 = Get-ChildItem hklm:\software\microsoft\windows\currentversion\uninstall | ForEach-Object {Get-ItemProperty $_.pspath|select -property DisplayName}
write $LIST1 >>$unstall1
$LIST2 = Select-String -path $unstall1 -SimpleMatch $REG
write $LIST2 >>$unstall2
$LIST3 = Get-Content $unstall2 -totalcount 2 | Select-Object -Skip 1
$TX = "Ausgabe in "+$LIST3
write $TX >>$LOG >>>>>>> Ausgabe sieht so aus: "C:\temp\PS-INI\unstall1.txt:24:WinSCP 5.9.2"
ich brauch aber z.B. nur "WinSCP 5.9.2"
Meine Frage ist jetzt, wie komme ich nur an den Wert "WinSCP 5.9.2" oder noch besser wie bekomme ich es nicht, das "C:\temp\PS-INI\unstall1.txt:24:" erst gar nicht mit angeführt wird?
VG
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 315928
Url: https://administrator.de/contentid/315928
Ausgedruckt am: 22.11.2024 um 09:11 Uhr
6 Kommentare
Neuester Kommentar
Hallo Bommi,
was soll die ganze "Textschreiberei" Das ist vielleicht noch zu Batchzeiten eine genutzte Methode, aber mit Powershell ist das absolut nicht mehr nötig jeden Schritt in eine Textdatei zu schreiben.
So wie ich das sehe liest du die installierten Programme über die Registry aus und möchtest ein bestimmtes Programm herausfiltern.
Ich würde daher folgendes vorschlagen, was auch die Registry eines Remote-Computers abfragen kann (wenn der Remote-Registry-Dienst läuft) wenn es nötig werden sollte (Ich weiß es geht auch über gci und get-itemproperty die jedoch nicht für remote computer geeignet sind):
Nun zu deinem Code:
Ausgabe
Die reine Zeile erhältst du dann wie immer so
Hoffe ich konnte dich in dieser Hinsicht aufklären .
Viel Erfolg weiterhin beim Lernen von Powershell..., und gewöhne dir das zwischenspeichern und Ausgeben in Textdateien ab, das ist eine blöde Angewohnheit aus ganz frühen Batchzeiten. In Powershell schreibt man meist alles erst in eine Variable und dann das Log ganz zum Schluss auf einen Rutsch.
Grüße Uwe
was soll die ganze "Textschreiberei" Das ist vielleicht noch zu Batchzeiten eine genutzte Methode, aber mit Powershell ist das absolut nicht mehr nötig jeden Schritt in eine Textdatei zu schreiben.
So wie ich das sehe liest du die installierten Programme über die Registry aus und möchtest ein bestimmtes Programm herausfiltern.
Ich würde daher folgendes vorschlagen, was auch die Registry eines Remote-Computers abfragen kann (wenn der Remote-Registry-Dienst läuft) wenn es nötig werden sollte (Ich weiß es geht auch über gci und get-itemproperty die jedoch nicht für remote computer geeignet sind):
function Get-InstalledSoftware(){
param(
[parameter(mandatory=$true)][ValidateNotNullOrEmpty()][string]$Computer
)
$all = @()
$key = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
$key64 = "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
try{
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Computer)
$root = $reg.OpenSubKey($key)
$all += $root.GetSubKeyNames() | %{$root.OpenSubKey($_).GetValue("DisplayName")}
$root.Close() | out-null
if ((gwmi Win32_OperatingSystem -Computer $computer).OSArchitecture -eq '64-Bit'){
$root = $reg.OpenSubKey($key64)
$all += $root.GetSubKeyNames() | %{$root.OpenSubKey($_).GetValue("DisplayName")}
$root.Close() | out-null
}
}catch{
throw $_.Exception.Message
}finally{
if($reg){$reg.Close | out-null}
}
return ($all | sort | select -Unique)
}
# Liest auf dem aktuellen System installierte Programme aus und filtert nach "WinSCP"
Get-InstalledSoftware -Computer $env:COMPUTERNAME | ?{$_ -like 'WinSCP*'}
Nun zu deinem Code:
Ausgabe sieht so aus: "C:\temp\PS-INI\unstall1.txt:24:WinSCP 5.9.2"
Das ist die Default-Ausgabeformatierung von Select-String. Wenn du dir mal die Eigenschaften eines Select-String Ergebnisses ansiehst wirst du feststellen das der pure String in der Eigenschaft Line des resultierenden Objekts enthalten ist:Select-String -path $unstall1 -SimpleMatch $REG | fl *
IgnoreCase : True
LineNumber : 750
Line : WinSCP 5.9.2
Filename : InputStream
Path : InputStream
Pattern : Windows
Context :
Matches : {}
Die reine Zeile erhältst du dann wie immer so
Select-String -path $unstall1 -SimpleMatch $REG | select -Expand Line
# bzw. so
(Select-String -path $unstall1 -SimpleMatch $REG).Line
Hoffe ich konnte dich in dieser Hinsicht aufklären .
Viel Erfolg weiterhin beim Lernen von Powershell..., und gewöhne dir das zwischenspeichern und Ausgeben in Textdateien ab, das ist eine blöde Angewohnheit aus ganz frühen Batchzeiten. In Powershell schreibt man meist alles erst in eine Variable und dann das Log ganz zum Schluss auf einen Rutsch.
Grüße Uwe
Hallo Thilo,
den Computer gibst du in der letzten Zeile mit:
an.
Bitte beachte das in diesem Fall der aktuelle Account mit dem das Script ausgeführt wird über Admin-Rechte am Remote-Rechner verfügen muss, du kannst die Credentials auch im Windows Tresor hinterlegen.
Zusätzlich muss der Dienst Remoteregistrierung auf dem Remote-Rechner laufen, das ist per Default nicht der Fall. Zum Abschluss muss natürlich auch die Firewall des Remotesystems die "Remoteverwaltung" durchlassen damit der Zugriff klappt.
Hast du keine Domäne und UAC ist aktiviert muss ebenfalls in der Registry noch der LocalAccountTokenfilterPolicy Eintrag gesetzt sein.
Grüße Uwe
den Computer gibst du in der letzten Zeile mit:
Get-InstalledSoftware -Computer 'COMPUTERNAME' | ?{$_ -like 'WinSCP*'}
Bitte beachte das in diesem Fall der aktuelle Account mit dem das Script ausgeführt wird über Admin-Rechte am Remote-Rechner verfügen muss, du kannst die Credentials auch im Windows Tresor hinterlegen.
Zusätzlich muss der Dienst Remoteregistrierung auf dem Remote-Rechner laufen, das ist per Default nicht der Fall. Zum Abschluss muss natürlich auch die Firewall des Remotesystems die "Remoteverwaltung" durchlassen damit der Zugriff klappt.
Hast du keine Domäne und UAC ist aktiviert muss ebenfalls in der Registry noch der LocalAccountTokenfilterPolicy Eintrag gesetzt sein.
Grüße Uwe