coreknabe
Goto Top

Powershell: Zwei Bedingungen in einer if-Anweisung

Moin,

ich versuche mich aktuell gerade wieder einmal an einem Powershell-Skript.

Benötigt wird eine doppelte if-Bedingung, es müssen beide Bedingungen erfüllt sein, damit ein Befehl ausgelöst wird.

Ablauf: Künftige AD-User werden aus einer CSV-Datei ausgelesen, dort ist auch eine private Emailadresse hinterlegt, an die ein Text verschickt wird. Da ich ein äußerst höflicher Mensch bin, soll über das Attribut "weiblich / männlich" aus der CSV die Anrede in der Mail generiert werden: Sehr geehrte Frau / sehr geehrter Herr... Ich weiß, das ist nicht divers face-wink

Die CSV ist nach folgendem Muster aufgebaut:
MatrNr;Name;Vorname;Geschlecht;EMail;DisplayName

Entscheide ich die Mailanrede nur unter der Bedingung, dass die Spalte "Geschlecht" ausgewertet wird, klappt das alles super. Ich möchte aber verhindern, dass versehentlich doppelt Mails an einzelne Personen verschickt werden. Da ich die User mit demselben Skript anlege, habe ich also noch eine Kontrolle hinterlegt, ob es den User nicht bereits gibt.

$Benutzer = $(try {Get-ADUser $user.MatrNr} catch {$Null})

Die Bedingungen möchte ich nun wie folgt auswerten:
if (($($user.Geschlecht) -eq "weiblich") -and $Benutzer -eq $Null)  

Klappt aber nicht, es werden keine Mails verschickt. Ich vermute mal einen Fehler in meiner Syntax?
Das hier allein funktioniert, nimmt aber eben keine Rücksicht darauf, ob der User bereits existiert:
if ($($user.Geschlecht) -eq "weiblich")  

Und noch eine zweite Frage, muss ich eine if-Bedingung zwingend mit einer else-Bedingung beenden (bräuchte ich in diesem Fall nicht), oder ist das davon unabhängig?

Grüße!

Content-ID: 1605044400

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

Ausgedruckt am: 24.11.2024 um 19:11 Uhr

jsysde
jsysde 10.12.2021 um 10:09:24 Uhr
Goto Top
Moin.

Versuch mal so:
if ($($user.Geschlecht) -eq "weiblich" -And $Benutzer -eq $Null))  
S. hier:
https://www.computerperformance.co.uk/powershell/if-and/

[...]Und noch eine zweite Frage, muss ich eine if-Bedingung zwingend mit einer else-Bedingung beenden
Nein.

Cheers,
jsysde
148656
148656 10.12.2021 um 10:14:48 Uhr
Goto Top
Moin,

Deine "-and"-Abfrage ist fehlerhaft. Aber das kann die jede x-beliebige Suchmaschine erklären.

Und was passiert, wenn das Userlein keine private Email-Adresse besitzt oder Sie nicht angeben will?
Darf es dann nicht bei euch arbeiten? Auch wenn es das Wundertier der Firma wäre?


Gruß
C.C.
149569
149569 10.12.2021 aktualisiert um 10:29:15 Uhr
Goto Top
$Benutzer -eq $Null
Ah ja, du willst also Mails schicken wenn es den User im AD nicht gibt? Du meintest wohl eher ein -ne

Kaffee rüberschieb face-smile

Und noch eine zweite Frage, muss ich eine if-Bedingung zwingend mit einer else-Bedingung beenden (bräuchte ich in diesem Fall nicht), oder ist das davon unabhängig?
Das sollte man eigentlich selbst wissen, ist die Bedingung nicht erfüllt ist entweder der User nicht weiblich oder es gibt den User nicht. Die erste Prüfung sollte ja sein ob es den User gibt und erst dann sollte eine Verzweigung kommen ob dieser männlich oder weiblich ist.
Coreknabe
Coreknabe 10.12.2021 um 11:13:41 Uhr
Goto Top
Zitat von @jsysde:

Moin.

Versuch mal so:
> if ($($user.Geschlecht) -eq "weiblich" -And $Benutzer -eq $Null))  
> 
S. hier:
https://www.computerperformance.co.uk/powershell/if-and/

Klappt leider nicht, weil eine schließende Klammer zuviel... Für meine Begriffe müsste das doch so richtig sein:
if ($($user.Geschlecht) -eq "weiblich" -and $Benutzer -eq $Null)  


Zitat von @148656:

Moin,

Deine "-and"-Abfrage ist fehlerhaft. Aber das kann die jede x-beliebige Suchmaschine erklären.

Aha, danke für den Tip. Und die korrekte Syntax finde ich wie? Ich glaube, dass da noch etwas besonderes rein muss, wegen der Besonderheit "CSV-Datei" als eine der Bedingungen.


Zitat von @149569:

$Benutzer -eq $Null
Ah ja, du willst also Mails schicken wenn es den User im AD nicht gibt? Du meintest wohl eher ein -ne

Kaffee rüberschieb face-smile

Nene, danke für den Kaffee, aber ich hatte schon face-wink Ganz genau, ich will nur eine Mail schicken, wenn es den User im AD nicht gibt. Dafür habe ich ja die private Emailadresse aus der CSV.

Und noch eine zweite Frage, muss ich eine if-Bedingung zwingend mit einer else-Bedingung beenden (bräuchte ich in diesem Fall nicht), oder ist das davon unabhängig?
Das sollte man eigentlich selbst wissen, ist die Bedingung nicht erfüllt ist entweder der User nicht weiblich oder es gibt den User nicht. Die erste Prüfung sollte ja sein ob es den User gibt und erst dann sollte eine Verzweigung kommen ob dieser männlich oder weiblich ist.

Die Reihenfolge der Prüfung sollte doch egal sein, ob jetzt zuerst das Geschlecht geprüft wird oder das Vorhandensein im AD. Erst die geforderte Summe beider soll ja eine Aktion (Mailversand) auslösen.
jsysde
jsysde 10.12.2021 um 11:38:11 Uhr
Goto Top
Moin.

Zitat von @Coreknabe:
[...]Klappt leider nicht, weil eine schließende Klammer zuviel...
Mea culpa - Copy&Paste-Typo. face-wink

Cheers,
jsysde
ptr2brain
Lösung ptr2brain 10.12.2021 aktualisiert um 11:46:21 Uhr
Goto Top
Zitat von @Coreknabe:

Die Bedingungen möchte ich nun wie folgt auswerten:
> if (($($user.Geschlecht) -eq "weiblich") -and $Benutzer -eq $Null)  

$user.Geschlecht ist bereits genug. Ich würde auch nicht -eq bei Strings verwenden sondern entweder match oder like. Hatte bisher schräge Erfahrung mit -eq.

Mein Vorschlag:
if($null -eq $Benutzer){
    if($user.Geschlecht -like "weiblich"){  
       #sendmail mit Anrede "sehr geehrte Frau" 
    }
    if($user.Geschlecht -like "männlich"){  
       #sendmail mit Andrede "sehr geehrter Herr" 
    }
}

Zur Anmerkung: Encoding der CSV und Einlesen mit entsprechenden Encoding (bsp. "UTF8") immer kontrollieren, sonst wird das nix mit dem Matching!

Bei
$Benutzer = $(try {Get-ADUser $user.MatrNr} catch {$Null})

Der Vollständigkeithalber:
Aufpassen, dass die Matrikelnummer auch in einem (!) dieser Felder eingetragen ist:
  • A distinguished name
  • A SAM account name (sAMAccountName)
(siehe Get-ADUser - Microsoft Docs)

Zitat von @149569:
Ah ja, du willst also Mails schicken wenn es den User im AD nicht gibt? Du meintest wohl eher ein -ne

Nö, sein Script legt auch gleichzeitig die User an. OP hat geschrieben, dass er User anlegen will und wenn dies erfolgt ist, möchte er an die neuen User eine Mail versenden. Daher die Überprüfung, ob der User nicht eh bereits existiert.

---
Edit:
Wenn schon einen Einzeiler, dann jede Bedingung in Klammer, denn "who knows". 🤷‍♂️
if(($user.Geschlecht -like "weiblich") -and ($null -eq Benutzer))  
Coreknabe
Coreknabe 10.12.2021 um 11:49:08 Uhr
Goto Top
Zitat von @ptr2brain:

Zitat von @Coreknabe:

Die Bedingungen möchte ich nun wie folgt auswerten:
>> if (($($user.Geschlecht) -eq "weiblich") -and $Benutzer -eq $Null)  
> 

$user.Geschlecht ist bereits genug. Ich würde auch nicht -eq bei Strings verwenden sondern entweder match oder like. Hatte bisher schräge Erfahrung mit -eq.

Mein Vorschlag:
> if($null -eq $Benutzer){
>     if($user.Geschlecht -like "weiblich"){  
>        #sendmail mit Anrede "sehr geehrte Frau" 
>     }
>     if($user.Geschlecht -like "männlich"){  
>        #sendmail mit Andrede "sehr geehrter Herr" 
>     }
> }
> 

Nein, das Geschlecht reicht nicht, weil damit nicht verhindert würde, dass die Mail versehentlich erneut verschickt wird, wenn jemand die CSV noch einmal einliest. Habe einmal "-like" statt "-eq" probiert, ändert auch nichts.

Zur Anmerkung: Encoding der CSV und Einlesen mit entsprechenden Encoding (bsp. "UTF8") immer kontrollieren, sonst wird das nix mit dem Matching!

Selbstredend.

Bei
$Benutzer = $(try {Get-ADUser $user.MatrNr} catch {$Null})

Der Vollständigkeithalber:
Aufpassen, dass die Matrikelnummer auch in einem (!) dieser Felder eingetragen ist:
  • A distinguished name
  • A SAM account name (sAMAccountName)
(siehe Get-ADUser - Microsoft Docs)

Das funktioniert alles, das ist kein Problem. Es geht einzig und allein um diese eine Abfrage.

Zitat von @149569:
Ah ja, du willst also Mails schicken wenn es den User im AD nicht gibt? Du meintest wohl eher ein -ne

Nö, sein Script legt auch gleichzeitig die User an. OP hat geschrieben, dass er User anlegen will und wenn dies erfolgt ist, möchte er an die neuen User eine Mail versenden. Daher die Überprüfung, ob der User nicht eh bereits existiert.
Jehova.
Coreknabe
Coreknabe 10.12.2021 um 13:18:07 Uhr
Goto Top
@ptr2brain

Ups, Dein Edit gerade erst gesehen. Eine doppelte Umklammerung bringt's auch nicht...
Ich mache mich nächste Woche einmal daran, mein Skript auf Minimalgröße runterzudampfen, dann kann ich leichter testen. Das die Syntax für if falsch ist, vermute ich aber mal in erster Linie.
149569
Lösung 149569 11.12.2021 aktualisiert um 13:15:32 Uhr
Goto Top
Zitat von @Coreknabe:

@ptr2brain

Ups, Dein Edit gerade erst gesehen. Eine doppelte Umklammerung bringt's auch nicht...
Ich mache mich nächste Woche einmal daran, mein Skript auf Minimalgröße runterzudampfen, dann kann ich leichter testen. Das die Syntax für if falsch ist, vermute ich aber mal in erster Linie.

Das sind viele überflüssige Subexpressions in deinen Zeilen drin aber die Syntax ist OK, ohne kompletten Kontext deines Skripts kann man nur raten, deshalb hier mal ein Beispiel, so läuft das hier problemlos

$users = @'  
MatrNr;Name;Vorname;Geschlecht;EMail;DisplayName
1234;Muster;Max;männlich;user@domain.tld;Max Muster
'@ | ConvertFrom-CSV -Delimiter ";"  


foreach($user in $users){
    $anrede = "Sehr geehrter Herr $($user.Name)"  
    $aduser = Get-ADUser -Filter "SamAccountname -eq '$($user.MatrNr)'"  
    if (!$aduser){
        if ($user.Geschlecht.trim() -eq 'weiblich'){  
            $anrede = "Sehr geehrte Frau $($user.Name)"  
        }
        write-host "Sende mail an '$($user.Email)' ..."  
        # send-mailmessage or whatever comes here
    }else{
        write-host "User '$($user.DisplayName)' existiert bereits."  
    }
}

Tipp: Wenn du bei Get-ADUser einen "Filter" statt dem InputObject benutzt ist das Try-Catch Konstrukt übrigens überflüssig, denn dann schlägt die Abfrage nicht fehl sondern das Ergebnis der Variablen ist automatisch $null ohne getriggerten Fehler.
Coreknabe
Coreknabe 14.12.2021 um 10:00:29 Uhr
Goto Top
Hm, also bei mir funktioniert das so nicht, weil hier schon die if-Anweisung fehlt:

if (!$aduser){
        if ($user.Geschlecht.trim() -eq 'weiblich'){  
            $anrede = "Sehr geehrte Frau $($user.Name)"  
        }

Ich habe mein Skript jetzt einmal eingedampft, um das besser nachvollziehen zu können, berücksichtigt wird lediglich der Part "User vorhanden / Geschlechtsabfrage".

$users = import-csv D:\User-Import\TEST.csv -delimiter ";"  

foreach ($user in $users)
{
$aduser = Get-ADUser -Filter {SamAccountname -eq $user.MatrNr}

if (!$aduser)
    {
    write-host "DIE FRAU MUSS ANGELEGT WERDEN!"  
    }

    elseif ($($user.Geschlecht) -eq "weiblich")  
    {
    write-host "ES IST EIN MÄDCHEN!"  
    }

if (!$aduser)
    {
    write-host "DER MANN MUSS ANGELEGT WERDEN!"  
    }

    elseif ($($user.Geschlecht) -eq "maennlich")  
    {
    write-host "ES IST EIN JUNGE!"  
    }
}

Hier bekomme ich das:

Get-ADUser : Eigenschaft "MatrNr" wurde im Objekt vom Typ "System.Management.Automation.PSCustomObject" nicht gefunden.  
In D:\Stud-Import\test.ps1:5 Zeichen:11
+ $aduser = Get-ADUser -Filter {SamAccountname -eq $user.MatrNr}
+           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-ADUser], ArgumentException
    + FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.ArgumentException,Microsoft.ActiveDirectory.Management.Commands.GetADUser
 
DIE FRAU MUSS ANGELEGT WERDEN!
DER MANN MUSS ANGELEGT WERDEN!
Get-ADUser : Eigenschaft "MatrNr" wurde im Objekt vom Typ "System.Management.Automation.PSCustomObject" nicht gefunden.  
In D:\Stud-Import\test.ps1:5 Zeichen:11
+ $aduser = Get-ADUser -Filter {SamAccountname -eq $user.MatrNr}
+           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-ADUser], ArgumentException
    + FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.ArgumentException,Microsoft.ActiveDirectory.Management.Commands.GetADUser
 
DIE FRAU MUSS ANGELEGT WERDEN!
DER MANN MUSS ANGELEGT WERDEN!
149569
149569 14.12.2021 aktualisiert um 10:06:09 Uhr
Goto Top
Zitat von @Coreknabe:

Hm, also bei mir funktioniert das so nicht, weil hier schon die if-Anweisung fehlt:
Nö tut sie nicht, du hast da nur einen gewaltigen Denkfehler 😉.

Die Fehlermeldung verrät dir schon wo dein Problem liegt, du übergibt statt einem String ein custom object als SamAccountName.
Ergo ist deine CSV falsch formatiert bzw verwendet den falschen delimiter.

Hier funktioniert mein Skript ja einwandfrei 😉.
ptr2brain
ptr2brain 14.12.2021 um 11:09:18 Uhr
Goto Top
Zitat von @Coreknabe:

> $users = import-csv D:\User-Import\TEST.csv -delimiter ";"  
> 
  • Encoding überprüft?
  • Delimiter?

> if (!$aduser)
>     {
>     write-host "DIE FRAU MUSS ANGELEGT WERDEN!"  
>     }
> 
>     elseif ($($user.Geschlecht) -eq "weiblich")  
>     {
>     write-host "ES IST EIN MÄDCHEN!"  
>     }
> 
> if (!$aduser)
>     {
>     write-host "DER MANN MUSS ANGELEGT WERDEN!"  
>     }
> 
>     elseif ($($user.Geschlecht) -eq "maennlich")  
>     {
>     write-host "ES IST EIN JUNGE!"  
>     }
> }
> 
Okay, es scheint als ob du noch nicht genau weißt, wie eine IF-Anweisung hier funktioniert. Erstens hast du dieselbe IF-Bedingung gesetzt, was zwar möglich, aber nur doppelt gemoppelt ist. Denn (!$aduser) als Bedingung reicht 1x völlig. Du unterscheidest ja dann weiter die Fälle, ob weiblich oder männlich und das macht man NICHT mit ELSEIF sondern nur mit IF. ELSEIF ist nur in komplexeren Ausnahmen interessant.
Auch wenn ich mich wiederhole, schau das du die Abfragen zusammenfasst:
if(!aduser){
   Write-Host "User $user.DisplayName wird neu angelegt"  
   if($user.Geschlecht -like "weiblich"){  
       #sendmail mit Anrede "sehr geehrte Frau" 
    }
    if($user.Geschlecht -like "männlich"){  
       #sendmail mit Andrede "sehr geehrter Herr" 
    }
}
else{
   Write-Host "User $user.DisplayName wurde nicht gefunden"  
}

Get-ADUser : Eigenschaft "MatrNr" wurde im Objekt vom Typ "System.Management.Automation.PSCustomObject" nicht gefunden.
In D:\Stud-Import\test.ps1:5 Zeichen:11

back-to-top$aduser = Get-ADUser -Filter {SamAccountname -eq $user.MatrNr}

back-to-top~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+ CategoryInfo : InvalidArgument: (face-smile [Get-ADUser], ArgumentException
+ FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.ArgumentException,Microsoft.ActiveDirectory.Management.Commands.GetADUser

DIE FRAU MUSS ANGELEGT WERDEN!
DER MANN MUSS ANGELEGT WERDEN!

Fehlermeldung sagt eindeutig: In "MatrNr" ist kein Wert enthalten und aufgrund des Filter-Arguments, das keinen $null Wert erlaubt, hat er ein Problem. Das heißt, sei dir zuerst 100% sicher, dass dein CustomObject aus deiner CSV auch wirklich Daten enthält! Ansonsten musst du zuerst dein Input kontrollieren, bevor du damit weiterarbeiten kannst.
Coreknabe
Coreknabe 14.12.2021 um 15:21:17 Uhr
Goto Top
Zitat von @149569:

Zitat von @Coreknabe:

Hm, also bei mir funktioniert das so nicht, weil hier schon die if-Anweisung fehlt:
Nö tut sie nicht, du hast da nur einen gewaltigen Denkfehler 😉.

Die Fehlermeldung verrät dir schon wo dein Problem liegt, du übergibt statt einem String ein custom object als SamAccountName.
Ergo ist deine CSV falsch formatiert bzw verwendet den falschen delimiter.

Hier funktioniert mein Skript ja einwandfrei 😉.

Ich gebe absolut zu, dass ich einiges nicht verstehe, ich neige auch zu fortwährender Selbstverwirrung, wenn ich länger drüber nachdenke face-wink

Aber selbst, wenn ich Dein Skript komplett in die Powershell-ISE kloppe und starte, bekomme ich einen Fehler angezeigt:

Get-ADUser : Eigenschaft "MatrNr" wurde im Objekt vom Typ "System.Management.Automation.PSCustomObject" nicht gefunden.  
In Zeile:9 Zeichen:15
+     $aduser = Get-ADUser -Filter {SamAccountname -eq $user.MatrNr}
+               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-ADUser], ArgumentException
    + FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.ArgumentException,Microsoft.ActiveDirectory.Management.Commands.GetADUser
 
Sende mail an 'user@domain.tld' ...  
149569
149569 14.12.2021 aktualisiert um 16:39:52 Uhr
Goto Top
Ah vergessen, bei manchen AD Versionen will der Filter-String in der Formatierung nicht in dem Fall musst du die Get-ADUser Zeile so schreiben dann klappts auch bei den Nachbarn face-wink, sorry:
  $aduser = Get-ADUser -Filter "SamAccountname -eq '$($user.MatrNr)'"  
Coreknabe
Coreknabe 15.12.2021 aktualisiert um 17:53:10 Uhr
Goto Top
Update, at last...

So funktioniert es jetzt, den CSV-Auslesepart habe ich mal weggelassen:
$Stud = $(try {Get-ADUser $user.MatrNr} catch {$Null})
if ($Stud -eq $Null) 
    {

    if ($($user.Geschlecht) -like "weiblich")  
    {
    Send-MailMessage -SmtpServer $SMTPServer -From $EMailFrom -To $user.EMail -Subject $Subject -Body ($AnredeF + " " + $MailBody) -Encoding ([System.Text.Encoding]::UTF8) -Port $SMTPPort -Credential $EmailCredential  
    } 

    if ($($user.Geschlecht) -like "maennlich")  
    {
    Send-MailMessage -SmtpServer $SMTPServer -From $EMailFrom -To $user.EMail -Subject $Subject -Body ($AnredeM + " " + $MailBody) -Encoding ([System.Text.Encoding]::UTF8) -Port $SMTPPort -Credential $EmailCredential  
    } 

    } 

@149569 @ptr2brain
Euch beiden vielen Dank für die Hilfe und die Geduld mit einem Logik- / Powershell-Legastheniker! face-smile