none
Active Directory leere Felder in CSV RRS feed

  • Frage

  • Hallo,

    Ich habe folgendes Problem, in meiner CSV Datei sind nicht bei jedem Benutzer alle Felder gefüllt. Bei einigen fehlt z.B. die Telefonnummer. Wenn die fehlt  in der Liste bearbeitet er den ganzen Benutzer nicht mehr d.h. der Benutzer wurde nicht bearbeitet, dies möchte ich nicht. Ich möchte, dass der Benutzer vollständig bearbeitet wird egal ob ein Feld nicht gefüllt werden kann.

    $Pfad = Read-Host "Bitte Pfad zur .CSV Datei angeben"
    Import-Csv -Delimiter ";" -Encoding utf8 -Path $Pfad | 
    %{
    Set-ADUser -Identity $_.SamAccountName -GivenName $_.Vorname -Surname $_.Nachname -Company $_.Firma -Department $_.Organisationseinheit -EmailAddress $_.EMail -OfficePhone $_.telefon
    }
    

    Montag, 16. Juni 2014 07:18

Antworten

  • Hallo!

    Du könntest es wie folgt lösen:

    - Jeden Eintrag in der CSV-Datei durchlaufen

    - Für jeden Eintrag durch die entsprechenden Attribute durchlaufen

    - Wenn das Attribut nicht leer ist und nicht dem Benutzernamen entspricht, das entsprechende Set-ADUser-Kommando zusammenbasteln

    - Das zusammengebastelte Kommando mittels Invoke-Expression aufrufen

    Das sieht dann ungefähr so aus:

    #AD-Module importieren
    Import-Module ac*
    
    #CSV-Datei importieren
    $DatenSaetze = Import-Csv Test.csv -UseCulture 
    
    #Jeden Datensatz der CSV-Datei durchlaufen
    ForEach ($DatenSatz in $DatenSaetze){
    
    # Set-AdUser-Aufruf mit dem SamAccountName des derzeitigen CSV-Eintrags initieren.
    $Kommando = "Set-AdUser $($Datensatz.samAccountName)"
    	
    # Für jeden CSV-Eintrag die entsprechenden Attribute durchlaufen
    ForEach ($Attribut in (Get-Member -InputObject $DatenSatz -MemberType NoteProperty)){
    	
    $Wert = $DatenSatz.($Attribut.Name)
    		
    
    #Überprüfen, ob Wert nicht leer ist und nicht den SamAccountName enthält
    if ($Wert -and ($Wert.Name -ne 'samAccountName')){
    		
    # Zuvor initierten Aufruf von Set-AdUser um entsprechende Werte erweitern
    $Kommando+= " -$($Attribut.Name) '$Wert'"
    		
    }
    	
    }
    
    #Inhalt von $Kommando mittels Invoke-Expression ausführen
    Invoke-Expression $Kommando
    
    
    }

    Deine CSV-Datei sollte in diesem Fall als Spaltenüberschriften die entsprechenden Bezeichnungen enthalten, die Set-AdUser erwartet. Also Company anstatt Firma, Department anstatt Organisation, usw.

    Viele Grüße

    MichaMS

    • Als Antwort markiert Moobo Montag, 16. Juni 2014 12:17
    Montag, 16. Juni 2014 09:48

Alle Antworten

  • Hallo!

    Du könntest es wie folgt lösen:

    - Jeden Eintrag in der CSV-Datei durchlaufen

    - Für jeden Eintrag durch die entsprechenden Attribute durchlaufen

    - Wenn das Attribut nicht leer ist und nicht dem Benutzernamen entspricht, das entsprechende Set-ADUser-Kommando zusammenbasteln

    - Das zusammengebastelte Kommando mittels Invoke-Expression aufrufen

    Das sieht dann ungefähr so aus:

    #AD-Module importieren
    Import-Module ac*
    
    #CSV-Datei importieren
    $DatenSaetze = Import-Csv Test.csv -UseCulture 
    
    #Jeden Datensatz der CSV-Datei durchlaufen
    ForEach ($DatenSatz in $DatenSaetze){
    
    # Set-AdUser-Aufruf mit dem SamAccountName des derzeitigen CSV-Eintrags initieren.
    $Kommando = "Set-AdUser $($Datensatz.samAccountName)"
    	
    # Für jeden CSV-Eintrag die entsprechenden Attribute durchlaufen
    ForEach ($Attribut in (Get-Member -InputObject $DatenSatz -MemberType NoteProperty)){
    	
    $Wert = $DatenSatz.($Attribut.Name)
    		
    
    #Überprüfen, ob Wert nicht leer ist und nicht den SamAccountName enthält
    if ($Wert -and ($Wert.Name -ne 'samAccountName')){
    		
    # Zuvor initierten Aufruf von Set-AdUser um entsprechende Werte erweitern
    $Kommando+= " -$($Attribut.Name) '$Wert'"
    		
    }
    	
    }
    
    #Inhalt von $Kommando mittels Invoke-Expression ausführen
    Invoke-Expression $Kommando
    
    
    }

    Deine CSV-Datei sollte in diesem Fall als Spaltenüberschriften die entsprechenden Bezeichnungen enthalten, die Set-AdUser erwartet. Also Company anstatt Firma, Department anstatt Organisation, usw.

    Viele Grüße

    MichaMS

    • Als Antwort markiert Moobo Montag, 16. Juni 2014 12:17
    Montag, 16. Juni 2014 09:48
  • leider bekomme ich fehlermeldungen:

    #AD-Module importieren
    Import-Module ActiveDirectory
    
    #CSV-Datei importieren
    $DatenSaetze = Import-Csv C:\Users\Administrator\Desktop\Powershell\export_cherwell.csv -UseCulture 
    
    #Jeden Datensatz der CSV-Datei durchlaufen
    ForEach ($DatenSatz in $DatenSaetze){
    
    # Set-AdUser-Aufruf mit dem SamAccountName des derzeitigen CSV-Eintrags initieren.
    $Kommando = "Set-AdUser $($Datensatz.samAccountName)"
    	
    # Für jeden CSV-Eintrag die entsprechenden Attribute durchlaufen
    ForEach ($Attribut in (Get-Member -InputObject $DatenSatz -MemberType NoteProperty)){
    	
    $Wert = $DatenSatz.($Attribut.Name)
    		
    
    #Überprüfen, ob Wert nicht leer ist und nicht den SamAccountName enthält
    if ($Wert -and ($Wert.Name -ne 'samAccountName')){
    		
    # Zuvor initierten Aufruf von Set-AdUser um entsprechende Werte erweitern
    $Kommando+= " -$($Attribut.Name) '$Wert'"
    		
    }
    	
    }
    
    #Inhalt von $Kommando mittels Invoke-Expression ausführen
    Invoke-Expression $Kommando
    
    
    }

    Invoke-Expression : In Zeile:1 Zeichen:69
    + Set-AdUser  -Company 'HHLA Intermodal Polska sp.zo.o.' -Emailaddress,SamAccountN ...
    +                                                                     ~
    Argument in der Parameterliste fehlt.
    In Zeile:30 Zeichen:1
    + Invoke-Expression $Kommando
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : ParserError: (:) [Invoke-Expression], ParseException
        + FullyQualifiedErrorId : MissingArgument,Microsoft.PowerShell.Commands.InvokeExpressionCommand

    Montag, 16. Juni 2014 10:01
  • Moin!

    Da scheint in der CSV-Datei noch etwas nicht zu passen. Kleiner Tipp: Kommentier das Invoke-Expression aus und lass dir den Befehl mittels Write-Host $Kommando ausgeben. Dann kannst du sehen an welchen Datensätzen es hakt, bzw. wie sich der Befehl zusammensetzt.

    Grüße

    MichaMS

    Montag, 16. Juni 2014 10:41
  • Moin,

    sofern es um einen einmaligen Import oder eine gelegentliche Aktion geht, empfehle ich in solchen Situationen gern Excel als Skriptgenerator.

    [Excel: Admins unbekannter Liebling | faq-o-matic.net]
    http://www.faq-o-matic.net/2008/01/19/excel-admins-unbekannter-liebling/

    Gruß, Nils


    Nils Kaczenski
    MVP Hyper-V
    Hannover, Germany


    Montag, 16. Juni 2014 13:52
  • Hallo,

    ich bekomme bei meinem Script folgende Meldung:

    Cmdlet Set-ADUser an der Befehlspiplinepostion 1
    Geben Sie Werte für die folgenden Parameter an: 
    Identity:

    Script:

    # startet das Skript im STA-Mode neu, wenn dies erforderlich sein sollte.
    If ($host.Runspace.ApartmentState -ne 'STA') { 
    	write-host "Script is not running in STA mode. Switching "
    	$Script = $MyInvocation.MyCommand.Definition
    	Start-Process powershell.exe -ArgumentList "-sta $Script"
    	Exit
    }
    
    # Grundform
    
    Function Form {
        [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
        [Reflection.Assembly]::LoadWithPartialName("System.Drawing") | Out-Null
    	[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms.VisualStyles") | Out-Null
    	
    	
        $ProgressForm = New-Object System.Windows.Forms.Form
        $ProgressForm.Text = 'Bitte warten...'
        $ProgressForm.Width = 350
        $ProgressForm.Height = 144
        $ProgressForm.MaximizeBox = $False
        $ProgressForm.MinimizeBox = $False
        $ProgressForm.ControlBox = $False
        $ProgressForm.ShowIcon = $False
        $ProgressForm.StartPosition = 1
        $ProgressForm.Visible = $False
        $ProgressForm.FormBorderStyle = "FixedDialog"
        #$ProgressForm.WindowState = "Normal"
        
        $InText = New-Object System.Windows.Forms.Label
        $InText.Text = 'Die Anfrage wird bearbeitet...'
        $InText.Location = '18,26'
        $InText.Size = New-Object System.Drawing.Size(330,18)
    
        $progressBar1 = New-Object System.Windows.Forms.ProgressBar
        $ProgressBar1.Name = 'LoadingBar'
        $ProgressBar1.Style = "Marquee"
        $ProgressBar1.Location = "17,61"
        $ProgressBar1.Size = "300,18"
        $ProgressBar1.MarqueeAnimationSpeed = 40
    
        $ProgressForm.Controls.Add($InText)
        $ProgressForm.Controls.Add($ProgressBar1)
    
        $sharedData.Form = $ProgressForm # Speichern der Form in die Hashtable
        
    	[System.Windows.Forms.Application]::EnableVisualStyles()
    	[System.Windows.Forms.Application]::Run($ProgressForm)
    	#[System.Windows.Forms.Application]::DoEvents()
        }
       
    # Hashtable für Datenaustausch zwischen den Threads
    $sharedData = [HashTable]::Synchronized(@{})
    $sharedData.Form = $Null
       
    # Thread eigener Runspace mit der Hashtable
    $newRunspace = [RunSpaceFactory]::CreateRunspace()
    $newRunspace.ApartmentState = "STA"
    $newRunspace.ThreadOptions = "ReuseThread"
    $newRunspace.Open()
    $newRunspace.SessionStateProxy.setVariable("sharedData", $sharedData)
       
    # Thread eigene asynchrone Powershell
    $PS = [PowerShell]::Create()
    $PS.Runspace = $newRunspace
    $PS.AddScript($Function:Form)
    $AsyncResult = $PS.BeginInvoke()
    # --------------------------------------------------------
    
    # Eigentliches Script
    #AD-Module importieren
    Import-Module ActiveDirectory
    
    [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
    $dialog = New-Object System.Windows.Forms.OpenFileDialog
    $dialog = New-Object System.Windows.Forms.OpenFileDialog
    $dialog.DefaultExt = '.csv'
    $dialog.Filter = 'CSV Datei|*.csv|All Files|*.*'
    $dialog.FilterIndex = 0
    $dialog.InitialDirectory = $home
    $dialog.Multiselect = $false
    $dialog.RestoreDirectory = $true
    $dialog.Title = "Select a csv file"
    $dialog.ValidateNames = $true
    $dialog.ShowDialog()
    $dialog.FileName
    
    $script:ErrorActionPreference = "silentlyContinue"
    
    #Eingabeaufforderung
    #$Pfad = Read-Host "Bitte Pfad zur .CSV Datei angeben
    #Beispiel: C:\users\Administrator\desktop\powershell\Export_cherwell_bearbeitet.csv"
    
    #CSV-Datei importieren
    $DatenSaetze = Import-Csv $dialog.FileName -UseCulture -Encoding UTF8
    
    #Jeden Datensatz der CSV-Datei durchlaufen
    ForEach ($DatenSatz in $DatenSaetze){
    
    # Set-AdUser-Aufruf mit dem SamAccountName des derzeitigen CSV-Eintrags initieren.
    $Kommando = "Set-AdUser $($Datensatz.samAccountName)"
    	
    # Für jeden CSV-Eintrag die entsprechenden Attribute durchlaufen
    ForEach ($Attribut in (Get-Member -InputObject $DatenSatz -MemberType NoteProperty)){
    	
    $Wert = $DatenSatz.($Attribut.Name)
    		
    
    #Überprüfen, ob Wert nicht leer ist und nicht den SamAccountName enthält
    if ($Wert -and ($Wert.Name -ne 'samAccountName')){
    		
    # Zuvor initierten Aufruf von Set-AdUser um entsprechende Werte erweitern
    $Kommando+= " -$($Attribut.Name) '$Wert'"
    		
    }
    	
    }
    
    #Inhalt von $Kommando mittels Invoke-Expression ausführen
    Invoke-Expression $Kommando
    } 
    
    # --------------------------------------------------------   
    # Form schließen
    If($sharedData.Form) {
        $sharedData.Form.close()
    }
       
    # neue Powershell beenden und Objekt entfernen
    $PS.Endinvoke($AsyncResult)
    $PS.dispose()

    .CSV Datei

    givenname;department;surname;officephone;samaccountname
    Frank;AU;Mustermann;+49 40 ***;Mustermann-F
    Claus;MaWI / extern / PPS;Lustig;+49 ** ;Wilkens-PPS
    Hans;BR;Muster - Betriebsrat;+49 40**;BR-Muster
    Peter;BR;Mann - Betriebsrat;+49 40 ***;BR-Mann
    Christian;BR;Meier - Betriebsrat;+49 40 ***;BR-Meier

    Die * bei der Telefonnummer sind nur Lückenfüller.

    Freitag, 20. Juni 2014 08:19