none
Bestimmten Teil einer Zeile in mehreren .txt vergleichen RRS feed

  • Frage

  • Hallo,

    Bei meinem ersten Powershell-Script hapert es an allen Ecken und Enden. Ziel soll sein, die zugeordneten Netzlaufwerke von zwei Rechnern miteinander zu vergleichen und so automatisch Rechner #2 (Win7) die noch fehlenden Netzlaufwerke von Rechner #1 (WinXP) zuzuordnen. Die Abfrage habe ich auf beiden Rechnern mit net use in eine .txt umgeleitet, welche ungefähr so aussieht:

    Neue Verbindungen werden gespeichert. Status Lokal Remote ----------------------------------------- I: \\domäne\freigabe$ K: \\server\freigabe$ Nicht verfgb M: \\Rechnername\Freigabe$ V: \\domäne\freigabe Nicht verfgb X: \\domäne\C$

    Der Befehl wurde erfolgreich ausgeführt.

    Mit der Formatierung bin ich nicht zufrieden, aber mit select-string bekomme ich nur die Zeilen mit "\\" angezeigt.

    Mit

    ...-replace "nicht verfgb", ""


    und

    ...-replace "  ",""


    sind nur noch die Laufwerksbuchstaben und Pfade ohne Einrückung zu sehen.

    Wenn ich nun die beiden .txts mit compare-object vergleiche wird mir natürlich angezeigt, dass keine Zeile gleich ist (auch weil die Laufwerksbuchstaben trotz gleichen Pfads sich unterscheiden können).

    Hat jemand eine Idee, wie ich nur die Freigabepfade vergleiche und mir die, die exklusiv auf Rechner #1 zu finden sind, anzeigen lasse so dass ich diese Ausgabe weiter verarbeiten kann.

    Ich hoffe ich konnte

    mich verständlich machen und bedanke mich schonmal.

    EDIT:

    Mit Dank an NBC2009:

    Der erste Teil der Aufgabe ist gelöst:

    $liste = @{}
    foreach ($zeile in $datei) {
     $splitzeile = $zeile -split "="
     $liste[$splitzeile[0]] = $splitzeile[1]
     write-host $splitzeile[1]
    }

    Bleibt noch die Ausgabe von doppelten Namen zu verhindern.


    IT Berater

    Mit

    -split ":"

    konnte ich Laufwerksbuchstaben und Pfad trennen. Der Vergleich dürfte jetzt auch kein Problem mehr sein.

    • Bearbeitet Bori5 Donnerstag, 7. März 2013 11:57
    Donnerstag, 7. März 2013 11:10

Antworten

  • Du kannst mit WMI und dem Get-WMIObject cmdlet auch Rechner abfragen die keine PowerShell installiert haben!
    PowerShell nutzt bei WMI meistens den normalen WMI remote Procedure Call (RPC).
    Hier können Fehlerquellen sein:
    - Firewall verhindert den RPC Aufruf (RPC verhandelt die Ports dynamisch) siehe: http://msdn.microsoft.com/de-de/library/bb979501.aspx#ID0ECG

    - Dein Account den du benutzt muss meistens auf dem Zielrechner Administrator sein!

    Siehe auch hier: http://www.windowspro.de/wolfgang-sommergut/remote-zugriff-fuer-wmi-konfigurieren-testen

    Dann hast du auch glaube ich einen Denkfehler in deiner Logik!
    Die Kommandos zeigen immer die Laufwerke von dem Account an, mit dem sie ausgeführt werden.

    Siehe hier: http://support.microsoft.com/kb/180362

    Umgeleitete Laufwerke unter Microsoft Windows XP (und später)
    Unter Windows XP und Microsoft Windows Server 2003 werden jeder Anmeldesitzung eigene Laufwerkbuchstaben von A-Z zugeteilt. Daher können umgeleitete Laufwerke nicht von Prozessen gemeinsam verwendet werden, die unter verschiedenen Benutzerkonten ausgeführt werden. Außerdem kann ein Dienst (oder ein Prozess, der in einer eigenen Anmeldesitzung ausgeführt wird) nicht auf Laufwerkbuchstaben zugreifen, die in einer anderen Anmeldesitzung erstellt wurden. Laufwerkbuchstaben, die von einem Dienst zugeordnet wurden, der unter dem lokalen Systemkonto ausgeführt wird, sind hingegen in allen Anmeldesitzungen sichtbar.

    Das heißt der User der die Laufwerke verbunden hat muss dies ausführen!
    Das geht am besten über das User Logonscript!
    Hier musst du dann eventuell wieder mit Texdateien Arbeiten.
    Normalerweise werden Netzlaufwerke für den User auch mit dem Logonscript verbunden. Diese Funktionieren unter XP und Win7!

    Du kannst die fest verbundenen Laufwerke anhand der User-SID aus der Registry lesen siehe hier, dann brauchst du nicht den User belästigen ;-):
    http://serverfault.com/questions/81797/script-to-list-current-users-mapped-network-drives
    http://winadminnotes.wordpress.com/2010/06/23/how-to-list-users-mapped-drives/
    http://community.spiceworks.com/scripts/show/576-current-user-mapped-drives



    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!


    • Bearbeitet Peter Kriegel Freitag, 8. März 2013 07:15
    • Als Antwort markiert Bori5 Freitag, 8. März 2013 11:15
    Donnerstag, 7. März 2013 15:16

Alle Antworten

  • Du benutzt Net Use das ist der Fehler !
    Net Use ist ein DOS Befehl PowerShell ist kein DOS!
    DOS Befehle liefern als Ergebnis Text! PowerShell Verarbeitet Objekte!
    Du kannst in der PowerShell viele Techniken nutzen die auch Objekte erzeugen. Dazu gehört auch WMI.

    Zum Auflisten von schon vorhandenen Netzlaufwerken gibt es zwei WMI Klassen die man dazu benutzen kann. "Win32_LogicalDisk"
    Get-WmiObject -Class Win32_LogicalDisk

    Alternative kann man die WMI Klasse “Win32_MappedLogicalDisk” nehmen.

    Get-WmiObject -Class Win32_MappedLogicalDisk

    Bei Objekten kann man (fast) alle Daten Punktgenau auslesen, das geht bei Text nun mal nicht!
    Genau aus diesem Grund verarbeitet PowerShell Objekte und keinen Text!

    Jetzt musst du nur noch sagen was du vergleichen willst!
    Wie man an den Ausgaben von beiden obigen Befehlen erkennen konnte ist der String des Netzwerkpfades den wir suchen, in dem Property “ProviderName” !

    Also lesen wir nur diesen mit Select-Object aus:

    Get-WmiObject Win32_MappedLogicalDisk | Select-Object ProviderName

    Nun kannst du diese Liste in eine Textdatei packen und diese mit Compare-Object vergleichen.
    Aber halt dann hätten wir ja wieder Text den wir miteinander vergleichen wollen!

    PowerShell kann CSV und XML Textdateien wieder in Objekte zurückverwandeln!
    Nehmen wir doch diese!

    Datei erzeugen für den Windows 7 Rechner:

    Get-WmiObject Win32_MappedLogicalDisk | Select-Object ProviderName | Export-CSV C:\temp\MappedDriveWin7.csv -NoTypeInformation

    Datei erzeugen für den Windows XP Rechner:

    Get-WmiObject Win32_MappedLogicalDisk | Select-Object ProviderName | Export-CSV C:\temp\MappedDriveXP.csv -NoTypeInformation

    Beide Dateien Vergleichen:

    Compare-Object -ReferenceObject (Import-CSV C:\temp\MappedDriveWin7.csv)  -DifferenceObject (Import-CSV C:\temp\MappedDriveXP.csv)

    Du kannst den Inhalt der CSV Dateien mit einem Texteditor ansehen oder mit Excel öffnen! ;-)

    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!

    Donnerstag, 7. März 2013 12:10
  • Danke für die Antwort.

    Ich erkläre kurz worum es eigentlich geht:

    Ich möchte ein Script erstellen, welches mir die Benutzerumstellung von WinXP auf Windows 7 erleichtert. Neue Rechner werden per automatischer Softwareverteilung mit Windows 7 versorgt, einige Einstellungen müssen aber noch von Hand gemacht werden.  Es gibt sicherlich Tools dafür, der Lernfaktor (Azubi) ist aber um einiges höher wenn ich mich etwas genauer mithilfe der Scripterstellung damit beschäftige. Zwei Fliegen mit einer Klappe!

    Mit

    gwmi win32_mappedlogicaldisk -computername <Name> -credential <benutzer>

    hatte ich leider auf dem XP-Rechner keinen Erfolg, das wäre natürlich die komfortablere Variante. Das ganze soll remote passieren und auf der XP-Maschine ist Powershell nicht installiert. Daher erschien mir die Lösung mit net use>>c:\NetzLW.txt am einfachsten. Der Befehl wird mittel psexec auf der XP-Maschine ausgeführt.

    Verglichen werden soll am Ende, welche Netzlaufwerke auf dem Win7-PC schon über die Softwareverteilung zugeteilt wurden und welche es auf dem WinXP-Rechner gab. Die LW, die noch nicht auf dem Win7-PC existieren sollen dann per Skript nachgeschoben werden.



    • Bearbeitet Bori5 Donnerstag, 7. März 2013 13:46
    Donnerstag, 7. März 2013 12:48
  • Du kannst mit WMI und dem Get-WMIObject cmdlet auch Rechner abfragen die keine PowerShell installiert haben!
    PowerShell nutzt bei WMI meistens den normalen WMI remote Procedure Call (RPC).
    Hier können Fehlerquellen sein:
    - Firewall verhindert den RPC Aufruf (RPC verhandelt die Ports dynamisch) siehe: http://msdn.microsoft.com/de-de/library/bb979501.aspx#ID0ECG

    - Dein Account den du benutzt muss meistens auf dem Zielrechner Administrator sein!

    Siehe auch hier: http://www.windowspro.de/wolfgang-sommergut/remote-zugriff-fuer-wmi-konfigurieren-testen

    Dann hast du auch glaube ich einen Denkfehler in deiner Logik!
    Die Kommandos zeigen immer die Laufwerke von dem Account an, mit dem sie ausgeführt werden.

    Siehe hier: http://support.microsoft.com/kb/180362

    Umgeleitete Laufwerke unter Microsoft Windows XP (und später)
    Unter Windows XP und Microsoft Windows Server 2003 werden jeder Anmeldesitzung eigene Laufwerkbuchstaben von A-Z zugeteilt. Daher können umgeleitete Laufwerke nicht von Prozessen gemeinsam verwendet werden, die unter verschiedenen Benutzerkonten ausgeführt werden. Außerdem kann ein Dienst (oder ein Prozess, der in einer eigenen Anmeldesitzung ausgeführt wird) nicht auf Laufwerkbuchstaben zugreifen, die in einer anderen Anmeldesitzung erstellt wurden. Laufwerkbuchstaben, die von einem Dienst zugeordnet wurden, der unter dem lokalen Systemkonto ausgeführt wird, sind hingegen in allen Anmeldesitzungen sichtbar.

    Das heißt der User der die Laufwerke verbunden hat muss dies ausführen!
    Das geht am besten über das User Logonscript!
    Hier musst du dann eventuell wieder mit Texdateien Arbeiten.
    Normalerweise werden Netzlaufwerke für den User auch mit dem Logonscript verbunden. Diese Funktionieren unter XP und Win7!

    Du kannst die fest verbundenen Laufwerke anhand der User-SID aus der Registry lesen siehe hier, dann brauchst du nicht den User belästigen ;-):
    http://serverfault.com/questions/81797/script-to-list-current-users-mapped-network-drives
    http://winadminnotes.wordpress.com/2010/06/23/how-to-list-users-mapped-drives/
    http://community.spiceworks.com/scripts/show/576-current-user-mapped-drives



    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!


    • Bearbeitet Peter Kriegel Freitag, 8. März 2013 07:15
    • Als Antwort markiert Bori5 Freitag, 8. März 2013 11:15
    Donnerstag, 7. März 2013 15:16

  • Die Kommandos zeigen immer die Laufwerke von dem Account an, mit dem sie ausgeführt werden.


    Da liegt (glaube ich) das Problem mit gwmi win32_mapped...... ich muss die Powershell als Admin ausführen und den Befehl auch mit -credential Admin übergeben da der Benutzer, um den es eigentlich geht die erforderlichen Rechte nicht hat. So werden mir nur die Netzlaufwerke des Admins angezeigt.

    Die Registry-Lösuzng schaue ich mir mal an.

    Danke!

    Freitag, 8. März 2013 11:15