none
PowerShell AD Abfrage nach deaktivierten User mit verschiebung LoNo .nsf Dateien RRS feed

  • Frage

  • Hallo alle zusammen,

    ich bin ein PowerShell Neuling, der bis jetzt immer nur die Google-Akademie genutzt hat wenn es um PowerShell ging.

    Doch in diesem Fall finde ich einfach nicht die richte Verknüpfung für die einzelnen Abfragen.

    Ich habe folgendes anliegen:

    Ich habe auf mehreren LoNo (Lotus Notes von IBM) Servern .nsf Dateien liegen, die auf einen Archiv Server verschoben werden sollen wenn der Nutzer im AD deaktiviert wird. Die .nsf Dateien haben den selben Namen wie der SamAccountName.

    Wie ich die einzelnen Abfragen formuliere weiß...

    Für die Ad Abfrage

    Import-Module ActiveDirectory

    $off-user = Serch-ADAccount -AccountDisablen | Select-Object SamAccountName

    wie Vergleiche ich das jetzt mit den .nsf Dateien die auf \\MailServer1\data bis \\MailServer30\data liegen und wenn eine Übereinstimmung da ist soll die .nsf Datei auf \\ArchivServer\LoNo verschoben werden?

    Für einen PowerShell Profi ist das bestimmt eine einfache Sache.

    Ich danke schon mal allen für die Hilfe

    Grüß

    Dimatrix


    • Bearbeitet Dimatrix Donnerstag, 2. April 2015 05:07
    Donnerstag, 2. April 2015 05:06

Antworten

  • Müsste ungefähr so gehen, Ungetestet:

    # Eine Hashtabe enthält dDaten al Liste von Name = Wert Paare (Key = Value)
    # Der Name des Wertes (Value) wird auch Schlüssel (Key) genannt, weil er in der Hashtable eindeutig sein muss
    # Über den Schlüsselnamen, kann man auf den Wert zugreifen.
    
    # Eine leere Hashtable erstellen, diese soll die Liste mit den .nfs Dateien enthalten soll
    $NfsFiles = @{}
    
    # von 1 bis 30 Zählen und für jede Zahl etwas ausführen
    for ($i = 1; $i -le 30 ; $i++)
    {     
        # Der Pfad zum mailserver wird mit der Lauf-Variable $i zusammengebaut und
        # alle .nfs Dateinen werden vom Share geholt
        # Für jede Date (ForEach) wird ein Code {} ausgeführt
        Get-ChildItem -Path "\\MailServer$i\data" -filter *.nsf | ForEach-Object {
          
          # Das Aktuell Verarbeitete Objekt liegt in der automatisch generierten Variable mit dem Namen $_
          # Die Variable $_ existiert nur innerhalb der geschweiften {} Klammern des aktuellen Scriptblockes {}
          # $_ enthält hier innerherhalb des ForEach-Object {} Scriptblockes ein .nfs Datei-Objekt!
          
          
          # Testen ob die Hashtable schon einen Schlüsselwert mit dem Dateinamen enthält
          # dadurch werden doppelte Dateinamen erkannt
          If($NfsFiles.Keys -notcontains $_.Basename) {
            
            # Der Dateiname wird als Schlüssel zu Hashtable zugefügt
            # der Wert für den Schlüssel ist der volle Pfad zur Datei
            $NfsFiles.($_.Basename) = $_.Fullname
          } Else {
            Write-Warning "$($_.Basename) kommt doppelt auf den Exchange Server MailServer$i vor!`n$($_.Fullname)`n$($NfsFiles.($_.Basename))"
          }
        } 
    }
    
    # nun haben wir eine Hash-Liste mit allen .nfs Dateien auf allen Servern
    # Anzeigen der Liste am Bildschirm
    $NfsFiles
    
    
    
    Search-ADAccount -AccountDisabled -UsersOnly | ForEach-Object {
      
      # Das Aktuell Verarbeitete Objekt liegt in der automatisch generierten Variable mit dem Namen $_
      # Die Variable $_ existiert nur innerhalb der geschweiften {} Klammern des aktuellen Scriptblockes {}
      # $_ enthält hier innerherhalb des ForEach-Object {} Scriptblockes ein User-Objekt!
    
      # Testen ob die hashtabel mit den .nfs Dateien eine Datei mit dem SamAccountName enthält
      If($NfsFiles.($_.SamAccountName)) {
        # .nfs Datei mit SamAccountName existiert
        # Der volle Pfad zu Datei wird angezeigt
        $NfsFiles.($_.SamAccountName)
        
        # mach was mit der .nfs Datei hier ....
    
      } Else {
        Write-Verbose "SamAccountName $($_.SamAccountName) ist keine .nfs Datei zugeordnet" -verbose
      }
    
    }


    PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
    auf der deutschsprachigen PowerShell Community

    Mein 21 Teiliger PowerShell Video Grundlehrgang
    Deutsche PowerShell Videos auf Youtube
    Folge mir auf:
    Twitter | Facebook | Google+

    Donnerstag, 2. April 2015 06:47

Alle Antworten

  • Müsste ungefähr so gehen, Ungetestet:

    # Eine Hashtabe enthält dDaten al Liste von Name = Wert Paare (Key = Value)
    # Der Name des Wertes (Value) wird auch Schlüssel (Key) genannt, weil er in der Hashtable eindeutig sein muss
    # Über den Schlüsselnamen, kann man auf den Wert zugreifen.
    
    # Eine leere Hashtable erstellen, diese soll die Liste mit den .nfs Dateien enthalten soll
    $NfsFiles = @{}
    
    # von 1 bis 30 Zählen und für jede Zahl etwas ausführen
    for ($i = 1; $i -le 30 ; $i++)
    {     
        # Der Pfad zum mailserver wird mit der Lauf-Variable $i zusammengebaut und
        # alle .nfs Dateinen werden vom Share geholt
        # Für jede Date (ForEach) wird ein Code {} ausgeführt
        Get-ChildItem -Path "\\MailServer$i\data" -filter *.nsf | ForEach-Object {
          
          # Das Aktuell Verarbeitete Objekt liegt in der automatisch generierten Variable mit dem Namen $_
          # Die Variable $_ existiert nur innerhalb der geschweiften {} Klammern des aktuellen Scriptblockes {}
          # $_ enthält hier innerherhalb des ForEach-Object {} Scriptblockes ein .nfs Datei-Objekt!
          
          
          # Testen ob die Hashtable schon einen Schlüsselwert mit dem Dateinamen enthält
          # dadurch werden doppelte Dateinamen erkannt
          If($NfsFiles.Keys -notcontains $_.Basename) {
            
            # Der Dateiname wird als Schlüssel zu Hashtable zugefügt
            # der Wert für den Schlüssel ist der volle Pfad zur Datei
            $NfsFiles.($_.Basename) = $_.Fullname
          } Else {
            Write-Warning "$($_.Basename) kommt doppelt auf den Exchange Server MailServer$i vor!`n$($_.Fullname)`n$($NfsFiles.($_.Basename))"
          }
        } 
    }
    
    # nun haben wir eine Hash-Liste mit allen .nfs Dateien auf allen Servern
    # Anzeigen der Liste am Bildschirm
    $NfsFiles
    
    
    
    Search-ADAccount -AccountDisabled -UsersOnly | ForEach-Object {
      
      # Das Aktuell Verarbeitete Objekt liegt in der automatisch generierten Variable mit dem Namen $_
      # Die Variable $_ existiert nur innerhalb der geschweiften {} Klammern des aktuellen Scriptblockes {}
      # $_ enthält hier innerherhalb des ForEach-Object {} Scriptblockes ein User-Objekt!
    
      # Testen ob die hashtabel mit den .nfs Dateien eine Datei mit dem SamAccountName enthält
      If($NfsFiles.($_.SamAccountName)) {
        # .nfs Datei mit SamAccountName existiert
        # Der volle Pfad zu Datei wird angezeigt
        $NfsFiles.($_.SamAccountName)
        
        # mach was mit der .nfs Datei hier ....
    
      } Else {
        Write-Verbose "SamAccountName $($_.SamAccountName) ist keine .nfs Datei zugeordnet" -verbose
      }
    
    }


    PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
    auf der deutschsprachigen PowerShell Community

    Mein 21 Teiliger PowerShell Video Grundlehrgang
    Deutsche PowerShell Videos auf Youtube
    Folge mir auf:
    Twitter | Facebook | Google+

    Donnerstag, 2. April 2015 06:47
  • Moin,

    danke für die schnelle Antwort. Aber ich versteh nicht ganz wie die letzte IF schleife funktioniert den ob wohl ich extra eine Gast.nsf erstellt habe sagt mir das Script es gibt keine Übereinstimmung :(

    Mich interessieren ja nur die deaktivierten Accounts und nur die sollen angezeigt werden und dann verschoben.

    • Als Antwort markiert Dimatrix Donnerstag, 2. April 2015 12:40
    • Tag als Antwort aufgehoben Dimatrix Donnerstag, 2. April 2015 12:40
    Donnerstag, 2. April 2015 12:01
  • Oder liegt es daran dass ich erst mal NUR einen Server direkt abgefragt habe.

    NfsFiles = Get-ChildItem -Path "\\MailServer$i\data" -filter *.nsf | % {$_.BaseName}

    und dann

    If($NfsFiles.($_.SamAccountName)) { $NfsFiles.($_.SamAccountName) # mach was mit der .nfs Datei hier .... } Else { Write-Verbose "SamAccountName $($_.SamAccountName) ist keine .nfs Datei zugeordnet" -verbose } }

    • Bearbeitet Dimatrix Donnerstag, 2. April 2015 12:22
    Donnerstag, 2. April 2015 12:21
  • Dein Code kann schon in der 1 Zeile nicht Funktionieren.

    Weil bei  dir die Variable $i nicht gefüllt wird und weil du keine Hashtable hast und weil die nicht vorhanden Hashtable bei dir nicht Ordnungsgemäss gefüllt wird und weil du nur den Basename ausgeben lässt.

    Du brauchst den Basename UND den Fullpath! Nur über den follen Pad (Fullpath) erreichst du die Datei wieder!

    Bitte benutze meinen Code so wie er ist.

    Funktioniert mein Code wenn du nur den oberen Teil ausführst?

    # Eine Hashtabe enthält dDaten al Liste von Name = Wert Paare (Key = Value)
    # Der Name des Wertes (Value) wird auch Schlüssel (Key) genannt, weil er in der Hashtable eindeutig sein muss
    # Über den Schlüsselnamen, kann man auf den Wert zugreifen.

    # Eine leere Hashtable erstellen, diese soll die Liste mit den .nfs Dateien enthalten soll
    $NfsFiles = @{}

    # von 1 bis 30 Zählen und für jede Zahl etwas ausführen
    for ($i = 1; $i -le 30 ; $i++)
    {     
        Write-Verbose "Ich frage nun folgendes Share ab: \\MailServer$i\data" -verbose
        
        # Der Pfad zum mailserver wird mit der Lauf-Variable $i zusammengebaut und
        # alle .nfs Dateinen werden vom Share geholt
        # Für jede Date (ForEach) wird ein Code {} ausgeführt
        Get-ChildItem -Path "\\MailServer$i\data" -filter *.nsf | ForEach-Object {
          
          # Das Aktuell Verarbeitete Objekt liegt in der automatisch generierten Variable mit dem Namen $_
          # Die Variable $_ existiert nur innerhalb der geschweiften {} Klammern des aktuellen Scriptblockes {}
          # $_ enthält hier innerherhalb des ForEach-Object {} Scriptblockes ein .nfs Datei-Objekt!
          
          
          # Testen ob die Hashtable schon einen Schlüsselwert mit dem Dateinamen enthält
          # dadurch werden doppelte Dateinamen erkannt
          If($NfsFiles.Keys -notcontains $_.Basename) {
            
            Write-Verbose "Ich füge $($_.Basename) zu hashtable hinzu" -verbose

            # Der Dateiname wird als Schlüssel zu Hashtable zugefügt
            # der Wert für den Schlüssel ist der volle Pfad zur Datei
            $NfsFiles.($_.Basename) = $_.Fullname
          } Else {
            Write-Warning "$($_.Basename) kommt doppelt auf den Exchange Server MailServer$i vor!`n$($_.Fullname)`n$($NfsFiles.($_.Basename))"
          }
        }
    }

    # nun haben wir eine Hash-Liste mit allen .nfs Dateien auf allen Servern
    # Anzeigen der Liste am Bildschirm
    $NfsFiles


    PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
    auf der deutschsprachigen PowerShell Community

    Mein 21 Teiliger PowerShell Video Grundlehrgang
    Deutsche PowerShell Videos auf Youtube
    Folge mir auf:
    Twitter | Facebook | Google+

    Donnerstag, 2. April 2015 12:51
  • Nein Leider nicht, es kommt die folgende Fehlermeldung

    Get-ChildItem : Es wurde kein Positionsparameter gefunden, der das Argument "1" akzeptiert.
    Bei Zeile:14 Zeichen:18
    +     Get-ChildItem <<<<  -Path "\\Server" $i "mail\d$\Lotus\Domino\data\mail\user" -filter *.nsf | ForEach-Object {
        + CategoryInfo          : InvalidArgument: (:) [Get-ChildItem], ParameterBindingException
        + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

    Meine Server sind aber nicht chronologisch gestaffelt sprich es gibt keinen Server1mail sondern es geht erst mit Server003Mail los und dann 006, 011, 065 u.s.w.

    Donnerstag, 2. April 2015 13:19
  • Hallo Diamatrix!Aus der Fehlermeldung entnehme ich, dass du den Code wieder verädert hast.
    In der Fehlermeldung steht

    Get-ChildItem -Path "\\Server" $i "mail\d$\Lotus\Domino\data\mail\user" -filter *.nsf | ForEach-Object {..... usw...

    So Funktioniert das nicht!

    Doppelte und einfache Anführungszeichen in der PowerShell

    Bei Textverarbeitung in der Windows PowerShell sollte man sich unbedingt mit den Regeln zur Verwendung einzelner und doppelter Anführungszeichen in Windows PowerShell vertraut machen.

    Doppelte und einfache Anführungszeichen verhalten sich unterschiedlich in der PowerShell.

    In PowerShell ist das Dollarzeichen $ ein Sonderzeichen!!!!

    Bei Zeichenfolgen zwischen doppelten Anführungszeichen (auch bei Here-Strings), werden Variablennamen nach einem Dollarzeichen $ durch den Wert der Variablen ersetzt (expandiert), bevor die Zeichenfolge zur Verarbeitung an den Befehl übergeben wird.

    Beispiel:
    $World = 'Welt'
    "Hallo $World!"

    Ergibt als Ergebnis:

    Hallo Welt!

    Da die Windows PowerShell ein Administrationstool ist, werden auch häufig Pfadangaben die ein Dollarzeichen enthalten verwendet. Wie z.B. die  Administrativen Pfade
    \\Rechnername\C$\Windows
    oder
    \\Rechnername\D$

    Damit nicht aus Versehen C$ oder D$ als Variable interpretiert wird, sollte man es sich Grundsätzlich angewöhnen in der PowerShell die einfachen Anführungszeichen zu benutzen. (Best Practice)
    Solche Fehler sind schwer zu finden!
    Nur wenn man wirklich eine Variable oder eine Sub-Expression benutzt, sollte man den Text in doppelte Anführungszeichen setzten.

    Get-ChildItem -Path "\\Rechnername\C$\Windows" # Falsch! Fehler!
    Get-ChildItem -Path '\\Rechnername\C$\Windows' # Richtig!

    Maskierungszeichen

    Wenn man in einem String die eine Variable expandieren möchte und gleichzeitig ein Dollarzeichen im Text benötigt das keine Variable darstellt, kann man das Dollarzeichen mit dem mit dem Escape-Zeichen 'Maskieren' oder entwerten.
     z.B. man muss eine Variable Expandieren UND muss einen Pfad mit einem Dollarzeichen benutzen.

    Maskierungszeichen oder Fluchtsymbol, (Englisch: ‚escape character‘ kurz auch nur ‚escape‘ genannt), ist ein bestimmtes Zeichen, das verhindert, dass das nachfolgende Zeichen als ein Funktionszeichen erkannt wird.
    In der Windows PowerShell ist das Graviszeichen (Englisch 'Backtick')  ` das Escape-Zeichen.

    Wenn ein Dollarzeichen $ in einem Text mit doppelten Anführungszeichen steht, wird dies wie gesagt als eine Variable interpretiert. Möchte man dies verhindern so kann man die Sonderfunktion des Dollarzeichens mit dem Backtick aufheben (maskieren) `$.

    Beispiel:
    "Keine `$Variable hier"

    Ergebnis:
    Keine $Variable hier

    Beispiel:
    "\\$Server1\C`$\Windows"

    Ergebnis:
    \\ServerName\C$\Windows


    Hierzu sollte man sich unbedingt die PowerShell Hilfe zu den Regel der Anführungszeichen durchlesen.

    Wenn die PowerShell Hilfe Installiert ist:
    Get-Help about_Quoting_Rules # (Möglicherweise in Englischer Sprache)
    Oder wenn die Hilfe nicht Installiert ist die Hilfe Online abrufen
    Get-Help about_Quoting_Rules -Online # (Möglicherweise in Englischer Sprache)

    Das i$ Muss einfach in die doppelten Anführungstriche!

    Meine Server sind aber nicht chronologisch gestaffelt sprich es gibt keinen Server1mail sondern es geht erst mit Server003Mail los und dann 006, 011, 065 u.s.w.

    Deine Zielvorgaben sind nicht sehr Präzise!
    Das Kostet uns Zeit und Ärger. Bitte drücke dich Präzise aus!

    Ich hoffe die Share-Pfade sind wenigstens alle gleich auf den Servern!?

    # Eine Hashtabe enthält dDaten al Liste von Name = Wert Paare (Key = Value)
    # Der Name des Wertes (Value) wird auch Schlüssel (Key) genannt, weil er in der Hashtable eindeutig sein muss
    # Über den Schlüsselnamen, kann man auf den Wert zugreifen.
    
    # Eine leere Hashtable erstellen, diese soll die Liste mit den .nfs Dateien enthalten soll
    $NfsFiles = @{}
    
    
    # liste (Array) mit Servern füllen
    $Servers = @('Server003Mail', 'Server006Mail', 'Server011Mail', 'Server065Mail')
    
    
    # Für jeden Server aus dem Array (ForEach) einen Codeblock {} ausführen 
    ForEach($Server in Servers) {     
        Write-Verbose "Ich frage nun folgendes Share ab: \\$Server\mail\d`$\Lotus\Domino\data\mail\user" -verbose
        
        # Der Pfad zum mailserver wird mit der Lauf-Variable $i zusammengebaut und
        # alle .nfs Dateinen werden vom Share geholt
        # Für jede Date (ForEach) wird ein Code {} ausgeführt
        Get-ChildItem -Path "\\$Server\d`$\Lotus\Domino\data\mail\user" -filter *.nsf | ForEach-Object {
          
          # Das Aktuell Verarbeitete Objekt liegt in der automatisch generierten Variable mit dem Namen $_
          # Die Variable $_ existiert nur innerhalb der geschweiften {} Klammern des aktuellen Scriptblockes {}
          # $_ enthält hier innerherhalb des ForEach-Object {} Scriptblockes ein .nfs Datei-Objekt!
          
          
          # Testen ob die Hashtable schon einen Schlüsselwert mit dem Dateinamen enthält
          # dadurch werden doppelte Dateinamen erkannt
          If($NfsFiles.Keys -notcontains $_.Basename) {
            
            Write-Verbose "Ich füge $($_.Basename) zu hashtable hinzu" -verbose
    
            # Der Dateiname wird als Schlüssel zu Hashtable zugefügt
            # der Wert für den Schlüssel ist der volle Pfad zur Datei
            $NfsFiles.($_.Basename) = $_.Fullname
          } Else {
            Write-Warning "$($_.Basename) kommt doppelt auf den Exchange Server $Server vor!`n$($_.Fullname)`n$($NfsFiles.($_.Basename))"
          }
        } 
    }
    
    # nun haben wir eine Hash-Liste mit allen .nfs Dateien auf allen Servern
    # Anzeigen der Liste am Bildschirm
    $NfsFiles


    PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
    auf der deutschsprachigen PowerShell Community

    Mein 21 Teiliger PowerShell Video Grundlehrgang
    Deutsche PowerShell Videos auf Youtube
    Folge mir auf:
    Twitter | Facebook | Google+

    Dienstag, 7. April 2015 08:46