mc-doubleyou
Goto Top

New-ADUser (optional Parameter)

Hallo zusammen,

mittels New-ADUser möchten wir mehrere Userkonten anlegen.
Allerdings haben nicht alle Benutzer eine E-Mail Adresse, bei diesen ist dann das Feld in der CSV leer.

Gibt es eine Möglichkeit bestimmte Parameter als optional zu kennzeichnen, damit der Befehl nicht abgebrochen wird wegen einem Fehler?
Also eigentlich ein wenn Parameter Variable leer dann nicht nutzen.

Ich hätte schon im Internet gesucht, aber konnte nur Anleitungen finden wie man es realisert wenn man sich selbst eine Funktion schreiben würde.

Danke!

LG mcdy

Content-ID: 322304

Url: https://administrator.de/contentid/322304

Ausgedruckt am: 22.11.2024 um 04:11 Uhr

Dani
Lösung Dani 28.11.2016 aktualisiert um 12:49:35 Uhr
Goto Top
Moin,
Gibt es eine Möglichkeit bestimmte Parameter als optional zu kennzeichnen, damit der Befehl nicht abgebrochen wir wegen einem Fehler?
leg doch mit New-ADUser den Benutzer zuerst mit allen Pflichtwerten an. Anschließend über Modifizierung die optionalen Wert/Parameter.


Gruß,
Dani
mc-doubleyou
mc-doubleyou 28.11.2016 um 12:55:51 Uhr
Goto Top
Hallo Dani,

gute Idee und da dann also immer erst Prüfung ob Variable leer und wenn nicht dann Set-ADUser -Parameter

Fehler unterdrücken könnte zwar auch helfen sehe ich aber nicht als unbedingt sinnvoll an.
Eine richtige Option dafür ist dir also auch nicht bekannt?
Danke mal für den Ansatz, mal sehen ob noch wer eine Idee mit weniger Zeilen hat ^^

LG mcdy
131381
Lösung 131381 28.11.2016 aktualisiert um 15:29:04 Uhr
Goto Top
Zitat von @mc-doubleyou:

gute Idee und da dann also immer erst Prüfung ob Variable leer und wenn nicht dann Set-ADUser -Parameter
Ja das musst du, denn mit Set-AdUser musst du wenn du ein Feld auf Null setzt statt -Replace den Parameter -Clear benutzen weil -replace keine leeren Werte erlaubt!
Das lässt sich kompakter schreiben indem man die Felder der CSV filtert welche einen leeren Wert haben und welche nicht. D.h. Mit Get-Member alle Spaltennamen holen und dann per Schleife über die Namen prüfen ob Feld leer oder nicht.

Bsp.
$csv = Import-CSV ................
$fields = $csv | gm -Membertype NoteProperty | ?{$_.Name -ne 'SamAccountName'} | Select -Expand Name  
foreach ($line in $csv){
    $user = Get-AdUser $line.SamAccountName -EA Ignore
    If ($user){
        $empty = @(); $notempty = @{}
        $fields | %{
            If ($line.$_ -ne ""){  
                $notempty.$_ = $line.$_
            }else{
                $empty += $_
            }
        }
       Set-Aduser $_.SamAccountName -replace $notempty -clear $empty
    }
}
So fackelt man die Änderung mit einem einzigen Set-Aduser ab und spart sich so mehrere Aufrufe, was Ressourcen einspart und das Script schneller macht.

Gruß
mc-doubleyou
mc-doubleyou 28.11.2016 aktualisiert um 15:11:57 Uhr
Goto Top
Hallo mikrotik,

also da komm ich jetzt nicht ganz mit was du meinst Oo

Ich habe eine CSV und diese wird importiert, folgende Felder sind nicht immer definiert und würden daher einen Fehler liefern weil der Parameter keinen Wert hat:

  • E-Mail
  • Fax
  • Handy

Fax und Handy ist eine 0 also nicht so schlimm, E-Mail wäre aber wirklich leer.

Wenn ich nun, wie Dani meinte, mit New-ADUser alle definiere die sicher nicht leer sind und dann diese drei mit
if (!(!$email)) { Set-AdUser -EmailAddress $email }
if (!(!$fax)) { Set-AdUser -Fax $fax }
if (!(!$handy)) { Set-AdUser -MobilePhone $handy }
dann ist mir die Lösung klar.

Mit deinem Ansatz würde ich doch nur ein bereits volles AD Feld wieder löschen, oder?

Danke!

LG mcdy
131381
131381 28.11.2016 aktualisiert um 15:27:56 Uhr
Goto Top
Zitat von @mc-doubleyou:

Hallo mikrotik,

also da komm ich jetzt nicht ganz mit was du meinst Oo

Ich habe eine CSV und diese wird importiert, folgende Felder sind nicht immer definiert und würden daher einen Fehler liefern weil der Parameter keinen Wert hat:

  • E-Mail
  • Fax
  • Handy
Ja.
Fax und Handy ist eine 0 also nicht so schlimm, E-Mail wäre aber wirklich leer.
Ok
Wenn ich nun, wie Dani meinte, mit New-ADUser alle definiere die sicher nicht leer sind und dann diese drei mit
> if (!(!$email)) { Set-AdUser -EmailAddress $email }
> if (!(!$fax)) { Set-AdUser -Fax $fax }
> if (!(!$handy)) { Set-AdUser -MobilePhone $handy }
> 
dann ist mir die Lösung klar.

Mit deinem Ansatz würde ich doch nur ein bereits volles AD Feld wieder löschen, oder?
Wenn in deiner CSV nicht immer die vollständig gewünschten Daten drin stehen dann ja, ich ging davon aus das in der CSV alle Daten des Users drin stehen, d.h. wenn dort ein Feld leer ist dann soll es auch im AD leer gemacht werden.
Aber das kannst du oben ganz einfach anpassen indem du das -Clear Flag weglässt face-smile

Kommt halt drauf an wie euer Workflow ist.
Mit obigem sparst du dir halt sämtliche einzelnen Set-ADUser Schreibzugriffe und reduzierst das auf einen einzigen.

Du kannst auch das $user Objekt selber verändern und am Schluss an Set-AdUser pipen dann braucht man auch nicht mehrfach mit seit-Aduser hantieren, denn das kostet einfach zu viele Resourcen wenn man für ein und den selben User 10mal Set-Aduser aufruft.

Es gibt 1000 Wege nach Rom face-smile

Das obige Script macht nichts anderes als gefüllte Felder in eine Hashtable zu schreiben die dann an Set-Aduser -Replace gefüttert wird. Wenn du leere Felder in der CSV nicht am AD Objekt ändern willst lässt du im Set-Aduser Befehl einfach das -Clear Flag und das Array der leeren Spalten weg.
mc-doubleyou
mc-doubleyou 28.11.2016 um 16:12:45 Uhr
Goto Top
Hallo und Danke mikrotik,

mehrfach Set-ADUser ist sicher nicht optimal da bin ich bei dir, leider verstehe ich deinen Aufbau aber so gar nicht.

Damit würde ich auch mehrfaches Set-ADUser verhindern

$Land = "AT"  
$vara = "user@domain.eu"  
$varb = "05123456789"  
$varc = "09123456789"  

if (!(!$vara)) { $Mail = @{mail=$vara} }
if (!(!$varb)) { $Fax = @{facsimileTelephoneNumber=$varb} }
if (!(!$varc)) { $Handy = @{mobile=$varc} }

if ($Land -eq "AT") { $Additional = @{c="AT";co="Austria";countrycode=40} }  

if (!(!$Mail)) { $Additional += $Mail }
if (!(!$Fax)) { $Additional += $Fax }
if (!(!$Handy)) { $Additional += $Handy }

bezüglich der Sinnhaftigkeit bin ich aber nicht sicher ;)

Eventuell kannst mir deinen Ansatz um $empty erleichtern und kurz erklären.

Danke!

LG mcdy
131381
131381 28.11.2016 aktualisiert um 17:50:38 Uhr
Goto Top
Wohl noch nicht so lange dabei was face-wink

Na dann hier der obige Code nochmal mit Kommentaren
# CSV importieren ...
$csv = Import-CSV ................
# Überschriften der CSV ermitteln und SamAccountName Spalte excluden (wollen wir ja nicht ändern :-))
$fields = $csv | gm -Membertype NoteProperty | ?{$_.Name -ne 'SamAccountName'} | Select -Expand Name  
# Für jede Zeile der CSV:
foreach ($line in $csv){
    #userobject holen
    $user = Get-AdUser $line.SamAccountName -EA Ignore
    If ($user){
        # ein Array das die Spalten enthalten soll dievLeer sind, und eine Hashtable die hinterher die nicht leeren Felder mit deren Werten enthält
        $empty = @(); $notempty = @{}
        # Array der Spaltennamen durchlaufen
        $fields | %{
            # wenn Spalte der aktuellen Zeile nicht leer ist
            If ($line.$_ -ne ""){  
                # füge sie zur Hashtabke hinzu
                $notempty.$_ = $line.$_
            }else{
                #Spalte ist leer also füge den Namen zum Array $empty hinzu
                $empty += $_
            }
        }
       # setze die Informationen im Account per replace Parameter und clear parameter (steht ja in der Doku was diese machen!)
       Set-Aduser $_.SamAccountName -replace $notempty -clear $empty
    }
}
Statt jede Spalte der CSV manuell zu prüfen macht das der obige Code über eine zusätzliche Schleife über die CSV-Spaltennamen, und das spart Zeilen wenn es um eine Menge Spalten geht.
Das ganze spart halt das andauernde Variablen erstellen und prüfen jeder einzelnen Spalte separat und reduziert somit den Codeaufwand, und das war ja wie du geschrieben hast dein primäres Ziel.
mc-doubleyou
mc-doubleyou 28.11.2016 um 17:29:30 Uhr
Goto Top
Hallo mikrotik,

Wohl noch nicht so lange dabei was face-wink

Noch nicht sehr lange, war bisher nur Batcher und da kein besonders guter ;)

Hab eben dein Script versucht und verstehe jetzt wie es funktioniert, es baut einfach darauf auf, dass der Titel der Spalte dem AD Attribut entspricht.
Ist aber bei mir nicht der Fall weil die Namen der AD Attribute nicht jeder verstehen würde, auch ich tue mir da zugegebenermaßen auch noch etwas schwer.

Somit wird es vorerst bei einem größeren Codeaufwand, wie oben geschrieben bleiben, immerhin mach ich dann nur einmal

  • New-ADUser
  • Add-ADGroupMember
  • Set-ADUser

Wobei ich Set-ADUser ohnehin schon für Manager und Land gebraucht habe.

Für den Lerneffekt habe ich aber trotzdem noch paar kurze Fragen.

?{$_.Name -ne 'SamAccountName'}  
wird da durch das ?{} exkludiert?

-EA Ignore
ist das um Fehler zu unterdrücken?

$fields | %{ 
was bewirkt das %{}

If ($line.$_ -ne "")  
müsste dann das selbe sein wie
if (!line.$_)


$empty += $_
meintest du nicht eher: Spalte ist leer also füge den Namen zum Array $empty hinzu

Danke!

LG mcdy
131381
Lösung 131381 28.11.2016 aktualisiert um 17:57:59 Uhr
Goto Top
Zitat von @mc-doubleyou:
Hab eben dein Script versucht und verstehe jetzt wie es funktioniert, es baut einfach darauf auf, dass der Titel der Spalte dem AD Attribut entspricht.
Ist aber bei mir nicht der Fall weil die Namen der AD Attribute nicht jeder verstehen würde, auch ich tue mir da zugegebenermaßen auch noch etwas schwer.
Das zu implementieren wäre aber ein leichtes. Dazu würde man einfach eine weitere Mapping-Tabelle mit einer Hashtable erstellen die die tatsächlichen AD-Attribute auf die in der CSV genutzen umsetzt und nutzt dann diese in der Schleife.
Somit wird es vorerst bei einem größeren Codeaufwand, wie oben geschrieben bleiben, immerhin mach ich dann nur einmal
Eigentlich nicht, s.o.
Für den Lerneffekt habe ich aber trotzdem noch paar kurze Fragen.

?{$_.Name -ne 'SamAccountName'}  
wird da durch das ?{} exkludiert?
Nein das ist eine Abkürzung für das CMDLet where-object, es werden also nur Objekte in der Pipeline übernommen dessen Eigenschaft nicht gleich "SamAccountName" ist.
-EA Ignore
ist das um Fehler zu unterdrücken?
Ja. Abkürzung für -ErrorAction
$fields | %{ 
was bewirkt das %{}
Das ist eine Abkürzung für eine For-Schleife in der Pipeline.
If ($line.$_ -ne "")  
müsste dann das selbe sein wie
if (!line.$_)
Kannst du auch.

$empty += $_
meintest du nicht eher: Spalte ist leer also füge den Namen zum Array $empty hinzu
Ja Tippfehler face-smile ist oben korrigiert.

Gruß
mc-doubleyou
mc-doubleyou 28.11.2016 um 20:27:51 Uhr
Goto Top
Hallo mikrotik,

solltest du es noch sehen.

Ich muss wohl nochmal das Skript überarbeiten weil paar Parameter viel Rot liefern.
Darum würde mich interessieren wie das mit der Hashtable Übersetzung funktionieren könnte.

Danke!

LG mcdy
131381
131381 28.11.2016 aktualisiert um 23:53:00 Uhr
Goto Top
Zitat von @mc-doubleyou:
Ich muss wohl nochmal das Skript überarbeiten weil paar Parameter viel Rot liefern.
Darum würde mich interessieren wie das mit der Hashtable Übersetzung funktionieren könnte.
# CSV importieren ...
$csv = Import-CSV ................
# Zuordnungstabelle von Spalten der CSV zu Active Directory Attributen
$map = @{
    'deinecsvspalte1' = 'activedirectoryattribut1'  
    'deinecsvspalte2' = 'activedirectoryattribut2'  
}
# Überschriften der CSV ermitteln und SamAccountName Spalte excluden (wollen wir ja nicht ändern :-), wenn die Spalte in deiner CSV anders heißt natürlich anpassen)
$fields = $csv | gm -Membertype NoteProperty | ?{$_.Name -ne 'SamAccountName'} | Select -Expand Name  
# Für jede Zeile der CSV:
foreach ($line in $csv){
    #userobject holen
    $user = Get-AdUser $line.SamAccountName -EA Ignore
    If ($user){
        # ein Array das die Spalten enthalten soll dievLeer sind, und eine Hashtable die hinterher die nicht leeren Felder mit deren Werten enthält
        $empty = @(); $notempty = @{}
        # Array der Spaltennamen durchlaufen
        $fields | %{
            # wenn Spalte der aktuellen Zeile nicht leer ist
            If ($line.$_ -ne ""){  
                # füge sie zur Hashtable hinzu (inkl. Umwandlung durch Attributmapping)
                $notempty.($map[$_]) = $line.$_
            }else{
                # Spalte ist leer also füge den Namen zum Array $empty hinzu
                $empty += $_
            }
        }
       # setze die Informationen im Account per replace Parameter und clear parameter (steht ja in der Doku was diese machen!)
       Set-Aduser $_.SamAccountName -replace $notempty -clear $empty
    }
}
mc-doubleyou
mc-doubleyou 29.11.2016 um 13:24:49 Uhr
Goto Top
Hallo mikrotik,

danke!

Werde mal sehen wann und wie ich umbaue, wie sich herausgestellt hat, wird es nicht zwangsweise rot.
Habe heute nur mal eine Firma importiert und das hat hervorragend funktioniert, es liegt dann also eher an der Formatierung der CSV bzw. am Aufbau der Namen. Vermutlich passen ihm á é usw. nicht, nachdem was ich bisher gelesen habe.

Wenn ich aber doch mal eine Finale Version für Import der User baue, nach Initialimport werde ich mit deinem Script arbeiten.

Nochmal danke und LG
mcdy
131381
131381 29.11.2016 um 13:33:38 Uhr
Goto Top
wird es nicht zwangsweise rot.
Ich werd auch gleich rot face-big-smile