Powershell Script zum ändern von bestimmten Strings funktioniert nicht richtig
Guten Tag,
ich arbeite momentan an einem Powershell Script das bestimmte Strings in einer Textdatei sucht und durch einen anderen definierten String ersetzen soll.
Dies funktioniert leider nur teilweise, da plötzlich manche Strings doppelt vorhanden sind. Einmal der abgeänderte String und einmal der vorherige String.
Das Script soll bewirken, dass die Namen des Strings ersetzt werden und nicht mehr durch ein Leerzeichen getrennt sind, damit diese korrekt in eine Excel Tabelle eingefügt werden können.
Über Hilfe wäre ich sehr dankbar!
ich arbeite momentan an einem Powershell Script das bestimmte Strings in einer Textdatei sucht und durch einen anderen definierten String ersetzen soll.
Dies funktioniert leider nur teilweise, da plötzlich manche Strings doppelt vorhanden sind. Einmal der abgeänderte String und einmal der vorherige String.
Das Script soll bewirken, dass die Namen des Strings ersetzt werden und nicht mehr durch ein Leerzeichen getrennt sind, damit diese korrekt in eine Excel Tabelle eingefügt werden können.
Über Hilfe wäre ich sehr dankbar!
$lookupTable = @{
'Windows Server© 2008 Standard ohne Hyper-V' = 'WindowsServer©2008StandardohneHyper-V'
'Windows Server© 2008 Standard' = 'WindowsServer©2008Standard'
'Windows Server 2008 R2 Datacenter' = 'WindowsServer2008R2Datacenter'
'Windows Server 2003' = 'WindowsServer2003'
'Windows XP Professional' = 'WindowsXPProfessional'
'Windows 2000 Professional' = 'Windows2000Professional'
'Windows Server 2008 R2 Standard' = 'WindowsServer2008R2Standard'
'Windows NT' = 'WindowsNT'
'EMC Celerra File Server' = 'EMCCelerraFileServer'
'Windows VistaT Business' = 'WindowsVistaTBusiness'
'Windows Server 2008 R2 Enterprise' = 'WindowsServer2008R2Enterprise'
'Windows Server© 2008 Enterprise' = 'WindowsServer©2008Enterprise'
'Windows Server 2012 R2 Standard' = 'WindowsServer2012R2Standard'
'Windows Server 2012 R2 Datacenter' = 'WindowsServer2012R2Datacenter'
'macmon appliance' = 'macmonappliance'
'Windows 8.1 Enterprise' = 'Windows8.1Enterprise'
'Windows 7 Ultimate' = 'Windows7Ultimate'
'Windows 7 Professional' = 'Windows7Professional'
'Windows 2000 Server' = 'Windows2000Server'
'Windows 8 Pro' = 'Windows8Pro'
'Windows 7 Enterprise N' = 'Windows7EnterpriseN'
'Windows 7 Professional N' = 'Windows7ProfessionalN'
}
$original_file = 'N:\SAM\Serverliste\compneu.txt'
$destination_file = 'N:\SAM\Serverliste\compneu1.txt'
Get-Content -Path $original_file | ForEach-Object {
$line = $_
$lookupTable.GetEnumerator() | ForEach-Object {
if ($line -match $_.Key)
{
$line -replace $_.Key, $_.Value
}
}
} | Set-Content -Path $destination_file
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 315118
Url: https://administrator.de/contentid/315118
Ausgedruckt am: 25.11.2024 um 14:11 Uhr
16 Kommentare
Neuester Kommentar
Hallo Mars123,
ein Grund ist das -replace Regular Expressions verwendet, d.h. also das Sonderzeichen wie Punkte Dollarzeichen etc. besondere Bedeutung haben. Außerdem gibst du die geänderten Zeilen überhaupt nicht aus. und das einzelne durchlaufen der Zeilen ist ebenfalls nicht nötig und überflüssig das Replace mit Arrays umgehen kann.
Optimiert lässt sich das folgendermaßen machen. (Das Aufführen der Replacement-Strings ohne Leerzeichen ist hier nicht nötig, das das hier mit einem Regex-Iterator-Object automatisch gemacht wird:
Grüße Uwe
ein Grund ist das -replace Regular Expressions verwendet, d.h. also das Sonderzeichen wie Punkte Dollarzeichen etc. besondere Bedeutung haben. Außerdem gibst du die geänderten Zeilen überhaupt nicht aus. und das einzelne durchlaufen der Zeilen ist ebenfalls nicht nötig und überflüssig das Replace mit Arrays umgehen kann.
Optimiert lässt sich das folgendermaßen machen. (Das Aufführen der Replacement-Strings ohne Leerzeichen ist hier nicht nötig, das das hier mit einem Regex-Iterator-Object automatisch gemacht wird:
$lookupTable = @(
'Windows Server© 2008 Standard ohne Hyper-V'
'Windows Server© 2008 Standard'
'Windows Server 2008 R2 Datacenter'
'Windows Server 2003'
'Windows XP Professional'
'Windows 2000 Professional'
'Windows Server 2008 R2 Standard'
'Windows NT'
'EMC Celerra File Server'
'Windows VistaT Business'
'Windows Server 2008 R2 Enterprise'
'Windows Server© 2008 Enterprise'
'Windows Server 2012 R2 Standard'
'Windows Server 2012 R2 Datacenter'
'macmon appliance'
'Windows 8.1 Enterprise'
'Windows 7 Ultimate'
'Windows 7 Professional N'
'Windows 7 Professional'
'Windows 2000 Server'
'Windows 8 Pro'
'Windows 7 Enterprise N'
)
$original_file = 'N:\SAM\Serverliste\compneu.txt'
$destination_file = 'N:\SAM\Serverliste\compneu1.txt'
# make regex 'or' expression
$lookuptable = ($lookupTable | %{[regex]::Escape($_)}) -join '|'
# replace with regex iterator
[regex]::replace((gc -Path $original_file | out-string),$lookupTable,{param($m) $m.Value -replace '\s',''}) | set-content $destination_file
Zitat von @Mars123:
Jedoch werden bei den im Array aufgeführten Strings nicht alle Leerzeilen entfernt.
Beispiel: Aus 'Windows 7 Professional N' wird 'Windows7Professional N'
Glaube das war soweit auch der einzige String den ich bisher gefunden habe.
Wenn das noch klappen würde, wäre ich überaus zufrieden!
Ist oben angepasst, lag in dem Fall an der Reihenfolge.Jedoch werden bei den im Array aufgeführten Strings nicht alle Leerzeilen entfernt.
Beispiel: Aus 'Windows 7 Professional N' wird 'Windows7Professional N'
Glaube das war soweit auch der einzige String den ich bisher gefunden habe.
Wenn das noch klappen würde, wäre ich überaus zufrieden!
Hier noch eine mögliche Variante , die für dich vielleicht leichter verständlich ist:
$lookupTable = @(
'Windows Server© 2008 Standard ohne Hyper-V'
'Windows Server© 2008 Standard'
'Windows Server 2008 R2 Datacenter'
'Windows Server 2003'
'Windows XP Professional'
'Windows 2000 Professional'
'Windows Server 2008 R2 Standard'
'Windows NT'
'EMC Celerra File Server'
'Windows VistaT Business'
'Windows Server 2008 R2 Enterprise'
'Windows Server© 2008 Enterprise'
'Windows Server 2012 R2 Standard'
'Windows Server 2012 R2 Datacenter'
'macmon appliance'
'Windows 8.1 Enterprise'
'Windows 7 Ultimate'
'Windows 7 Professional N'
'Windows 7 Professional'
'Windows 2000 Server'
'Windows 8 Pro'
'Windows 7 Enterprise N'
)
$original_file = 'N:\SAM\Serverliste\compneu.txt'
$destination_file = 'N:\SAM\Serverliste\compneu1.txt'
$content = gc $original_file
$lookupTable | %{
$content = $content -replace [regex]::Escape($_),($_ -replace '\s','')
}
$content | set-content $destination_file
Zitat von @Mars123:
Nun stehe ich wiederum vor dem Problem, dass ich in der Textdatei für jeden Server einen distiguished Name habe, in dem sich auch wieder Leerzeichen befinden und ich die CNs und OUs nicht ordnungsgemäß trennen kann. Hast dafür ne Idee?
Erkläre doch mal genau was du willst machen (extrahieren/ersetzen) willst. Mit einer passenden Regular Expression ist das im Handumdrehen erledigt.Nun stehe ich wiederum vor dem Problem, dass ich in der Textdatei für jeden Server einen distiguished Name habe, in dem sich auch wieder Leerzeichen befinden und ich die CNs und OUs nicht ordnungsgemäß trennen kann. Hast dafür ne Idee?
aber schaffe es nicht nur einen bestimmten Bereich einzugrenzen, in dem die Leerzeichen gelöscht werden sollen.
Wenn ich wüsste was du wo ersetzen willst alles kein Problem,Du musst mir schon sagen ob im CN oder OU Bereich Leerzeichen ersetzt werden sollen etc.
Ein Replacement Pattern für einen CN könnte z.B. so aussehen:
CN=(.*?)(?=,(CN|OU|DC))
Das ganze dann wie oben mit einem Replacement iterator mit Eliminierung der Spaces abgefackelt, fertig.
By the way, was ist der Sinn und Zweck der Ersetzung der Leerzeichen? Nur für eine Excel-Aufbereitung? Dafür gibt es wesentlich bessere Methoden wenn man auf andere Delimiter setzt, das Leerzeichen ist da alles andere als optimal wie du gerade feststellst . In Powershell gibt es diverse Methoden um ein File Excel freundlich umzubauen, vielleicht kann ich dir dein Vorhaben ja etwas optimieren und du kennst vielleicht einige dieser Tricks noch nicht.
[OT] Ich habe ja normalerweise keine Probleme damit, aber das Ausschweifen mit Fragen in einem Thread der von etwas anderem handelt sehen wir hier eigentlich nicht so gerne, zumal das für die Leute die hier vorbei schauen mehr als verwirrend ist.
Melde dich doch via PM mit deinen weiteren Fragen und markiere den Thread hier als gelöst. Merci.
[/OT]
Dann war dieses Tool aber nicht besonders toll, mit Leerzeichen trennen?? welcher Depp macht den sowas ??
Das AD kannst du doch bequem mit der Powershell selbst mit den AD-CMDlets (Get-ADComputer) oder per LDAP auslesen.
Damit kann man das gleich schön als CSV formatiert ausgeben.
Also absolut unverständlich sich jetzt die Mühe zu machen das wieder auseinander zu pflücken was zudem Fehleranfällig sein ist.
Eine Zeile in der Testdatei sieht wie folgt aus:
M-DC-02 Windows Server© 2008 Standard 6.0 (6002) CN=M-DC-02,OU=Domain Controllers,DC=geno,DC=intern
OK.
Mit Get-ADComputer kommst du zudem an alle Infos von oben, dann mit select die gewünschten Felder selektieren und du dann das ergebnis direkt an Export-CSV pipen.
Das AD kannst du doch bequem mit der Powershell selbst mit den AD-CMDlets (Get-ADComputer) oder per LDAP auslesen.
Damit kann man das gleich schön als CSV formatiert ausgeben.
Also absolut unverständlich sich jetzt die Mühe zu machen das wieder auseinander zu pflücken was zudem Fehleranfällig sein ist.
Eine Zeile in der Testdatei sieht wie folgt aus:
M-DC-02 Windows Server© 2008 Standard 6.0 (6002) CN=M-DC-02,OU=Domain Controllers,DC=geno,DC=intern
Die Felder sind halt durch keinen Feldtrenner so getrennt,
Das zum Thema Tool Wenn es da einen Trick gibt oder eine Methode die ich noch nicht kenne, wäre ich sehr froh darüber, wenn du sie mir verraten könntest.
Wenn deine Felder bestimmte Muster aufweisen z.B. manche Felder nur Zahlen oder anderes lässt sich das in einen Pattern pressen, ich würde aber definitiv den Weg gehen das vernünftig via Ldap/ AD-CMDLets aufzuziehen und es direkt vernünftig auszugeben.Mit Get-ADComputer kommst du zudem an alle Infos von oben, dann mit select die gewünschten Felder selektieren und du dann das ergebnis direkt an Export-CSV pipen.
Bist du sicher das das keine Tabs sind ?
Hiermit benutzt du dann bei mindestens 2 aufeinander folgenden Spaces als Trenner, in $columns sind dann die einzelnen Daten der aktuellen Zeile der Schleife als Array enthalten.
Zitat von @Mars123:
Gibt es denn die Möglichkeit, eine variable Anzahl von Leerzeichen durch z.B. ein # zu ersetzen? Bzw. sobald mehr als ein Whitespace aufeinanderfolgend auftritt? An solch einer Lösung wäre ich auf jeden Fall auch für die Zukunft interessiert.
Ja klar du kannst per regex 'splitten'Gibt es denn die Möglichkeit, eine variable Anzahl von Leerzeichen durch z.B. ein # zu ersetzen? Bzw. sobald mehr als ein Whitespace aufeinanderfolgend auftritt? An solch einer Lösung wäre ich auf jeden Fall auch für die Zukunft interessiert.
Hiermit benutzt du dann bei mindestens 2 aufeinander folgenden Spaces als Trenner, in $columns sind dann die einzelnen Daten der aktuellen Zeile der Schleife als Array enthalten.
gc file.txt | %{
$columns = $_ -split '\ {2,}'
}
Zitat von @Mars123:
Das würde natürlich super funktionieren, nur bräuchte ich als Feldtrenner zwischen den Strings ein anderes Zeichen als das Leerzeichen,
Wieso ?? Du hast CNs bei denen du mehr als zwei direkt aufeinanderfolgende Leerzeichen haben? Das wäre sehr sehr ungewöhnlich und würde auf ein sehr unsauber geführtes AD hinweisen.Das würde natürlich super funktionieren, nur bräuchte ich als Feldtrenner zwischen den Strings ein anderes Zeichen als das Leerzeichen,
Wir drehen und im Kreis, lese die Daten direkt per Get-ADComputer aus und du bist in 5 Minuten fertig, ich sehe hier absolut keine Probleme, sorry. Das ist lächerliches Anfängerskripting.
Wenn du mir sagst welche Computer und welche Felder du auslesen willst, schreibe ich dir das schnell zusammen, du wirfst das Script auf einem DC oder einer WS mit RSAT an und feddich.
Wieso jetzt wieder durch ein anderes ersetzen nur um dann hinterher wieder zu splitten?
Ich würde da direkt eine vernünftige CSV draus machen, die sich sofort mit Excel öffnen lässt.
Die weiteren Spalten solltest du jetzt im Object ergänzen können.
Viele Grüße und ebenso eine schöne Woche
Uwe
Ich würde da direkt eine vernünftige CSV draus machen, die sich sofort mit Excel öffnen lässt.
gc N:\SAM\Serverliste\compneu.txt | %{
$columns = $_ -split '\ {2,}'
[pscustomobject] @{Name=$columns;OS=$columns[1]}
} | export-CSV 'c:\export.csv' -delim ";" -NoType -Encoding UTF8
Viele Grüße und ebenso eine schöne Woche
Uwe