nagus
Goto Top

Prüfung auf unzulässige Zeichen in Powershell

Frohe Weihnachten zusammen,

ich muss Email Adressen per PS erstellen, die ich von HR erhalte. Da die Kollegen*innen aber manchmal nicht ganz hellwach sind, bekomme ich auch Emailadressen die Sonderzeichen enthalten, weil einfach Vorname + Nachname zusammengesetzt wurden. Die Daten sind in einer CSV enthalten.

Ich möchte eigentlich nur prüfen ob unzulässige Zeichen enthalten sind und dafür True oder einen anderen Wert zurück geliefert bekommen.

Über eine Vergleichsliste alle Zeichen in dem String prüfen scheint mir nicht zielführend. Gibt's was einfacheres?

VG
Nagus

Content-Key: 1663957794

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

Printed on: April 18, 2024 at 00:04 o'clock

Mitglied: 143611
143611 Dec 27, 2021 at 18:19:15 (UTC)
Goto Top
Moin,

eine konkrete Lösung hab' ich nicht, würde aber RegEx verwenden. Im www gibt's massig Beispiele für patterns zur Validierung von Mail-Adressen.

Viel Erfolg!
Member: Nagus
Nagus Dec 27, 2021 at 18:20:26 (UTC)
Goto Top
Hm - regex bin ich noch raus. Und bei der Suche bisher noch nicht fündig geworden ...
Aber ich guck noch ....

Thx
Nagsu
Member: em-pie
Solution em-pie Dec 27, 2021 at 19:05:25 (UTC)
Goto Top
Moin,

RegEx hilft nur bedingt, wie man hier lesen kann: https://stackoverflow.com/questions/48253743/powershell-to-validate-emai ...

Durch RegEx ist es nicht ohne weiteres möglich, die ANSI-Zeichen herauszufiltern.

In obigem Link gibt es aber auch noch einen anderen Ansatz…


Werden die Daten durch eure HR manuell abgetippt? Oder kannst du dort die Mail-Adresse selbst zusammensetzen lassen? Dann müssen die z.B. nur die Spalten Vorname und Nachname füllen und Excel kombiniert die Felder selbst, ergänzt um das statische @company.tld
Mitglied: 149569
Solution 149569 Dec 27, 2021 at 19:51:29 (UTC)
Goto Top
Member: Nagus
Nagus Dec 28, 2021 at 08:24:04 (UTC)
Goto Top
Hi em-pie,
HR Tippt selber in SAP und wir erhalten einen Export. Ich schreibe gerade ein neues Skript für die Useranlage und bin über den Punkt gestolpert.

Danke für den link, der ist ganz interessant. Bin noch am lesen face-smile
Member: Nagus
Nagus Dec 28, 2021 at 09:01:48 (UTC)
Goto Top
@149569, danke für den link, aber so richtig hat der mich auch nicht weiter gebracht.

ich baue mir jetzt eine Funktion die irgendwie so aus sehen wird:
$NotValidEmailChar='äüöàáèéòò'.ToCharArray() # Hier um die Zeichen ergänzen die ausgeschlossen werden sollen  
$testemail = "ör.test@blabla.de"  


foreach($n in $NotValidEmailChar)
    {
       $check = $testemail -match $n
       switch ( $check)
        {
            true
                {
                    write-host "Fehler, Check = TRUE"  
                    $check
                }
            False
                {
                    write-host "OK,  Check = False"  
                    $check
                }
        }
    }

Output
OK,  Check = False
False
OK,  Check = False
False
Fehler, Check = TRUE
True
OK,  Check = False
False
OK,  Check = False
False
OK,  Check = False
False
OK,  Check = False
False
OK,  Check = False
False
OK,  Check = False
False

Beim schreiben gemerkt: meine Lösung so ist einfacher als alles was ich bisher gefunden habe. Mehr Zeit für die Suche als das Schreiben verbraten Oo
Ich denke bei der Massenverarbeitung sollte das auch noch ganz flott sein. Werde das dann noch um eine Prüfung auf zulässige Domains ergänzen und gut ist.
@em-pi, Dein Link hat mich auf den richtigen weg gebracht - thx

Guten Rutsch
Nagus
Member: Nagus
Solution Nagus Dec 29, 2021 at 11:11:33 (UTC)
Goto Top
So, habe jetzt eine Funktion gebaut, die die Emails auf Sonderzeichen prüft, guckt, ob die email bereits im AD verwendet wird und noch schaut ob sie von einer der erlaubten Domänen kommt..
Hier die Funktion

# ----- Festlegen der Werte für Funktion Check-Email - Anfang -----------#
$NotValidEmailChar='äüöàáèéòòß'.ToCharArray()                                # Nicht erlaubte Zeichen für eine Emailadresse  
$AllowedDomains = @("web.de","google.com","xxx.at","spacken.ch")             # Erlaubte Email-Domains  
# ----- Festlegen der Werte für Funktion Check-Email - Ende   -----------#


# ---- Funktion zum prüfen ob eine Emailadresse bereits in Benutzung ist, unerlaubte Sonderzeichen enthält,
#----- oder eine falsche Domain angegeben wurde. Rückgabe von OK und NOK. Schreibt genauen Fehler in das LOG
Function check-email ([string]$emailadress)
{
    #write-host "Prüfe Email: $($emailadress)" 
    $CheckChar =  "ok"  
    $CheckDomain =  "NotAllowed"  

    foreach($n in $NotValidEmailChar) # Prüfung auf unzulässige Zeichen
        {
            $check = $emailadress -match $n
            if ( $check -eq $true)
                {
                    #write-host "Emailadresse enthält ungültiges Zeichen: $($n)" 
                    $DeniedChar += $n
                    $CheckChar =  "NotAllowed"  
                }
        }
   foreach($a in $AllowedDomains)
        {
            
            $check = $emailadress -match $a
            Switch ($check)
                {
                    True { $CheckDomain =  "ok" }   # Domain allowed  
                    False {                     }   # Domain not allowed, kein Wert Notwendig
                 }
          }
   
        $users= Get-ADUser -SearchBase "OU=Ascena_Security,DC=ascena,DC=net" -Filter "proxyAddresses -eq 'smtp:$emailadress'" -Properties proxyAddresses  
        if($users -eq $null)
            {
                $CheckUse =  "Ok"  
            }
        else
            {
                $CheckUse =  "InUse"  
            }
    # Hier folgt das Logging und der Return Code
    if($CheckChar -ne "ok")  
        {
            write-log "Folgende unerlaubte Zeichen in Email-Adresse $($emailadress) entdeckt: $($DeniedChar)" 2  
            $Returnstatus = "NOK"  
        }
    elseif($checkDomain -ne "ok")  
        {
            write-log "Unerlaubte Domain in Email-Adresse $($emailadress) entdeckt" 2  
            $Returnstatus = "NOK"  
        }
    elseif($CheckUse -ne "ok")  
        {
            write-log "Emailadresse $($emailadress) bereits in Benutzung" 2  
            $Returnstatus = "NOK"  
        }
    else
        {
            write-log "Emailadresse $($emailadress) noch nicht in Benutzung" 4  
            $Returnstatus = "OK"  
        }
    return $ReturnStatus 
}

Achtung: ich habe auch eine Funktion für das Logging gebaut und mit eingebunden. Wenn ihr das nicht braucht, einfach write-log in Write-host ändern und die Zahlen am Ende entfernen.
Als Rückgabe erfolgt NOK oder OK, wobei der genaue Fehler in das Log geschrieben wird

VG
Nagus
Mitglied: 149569
149569 Dec 29, 2021 updated at 11:49:46 (UTC)
Goto Top
$NotValidEmailChar='äüöàáèéòòß'.ToCharArray()
Tja, schreiben deine lieben Kollegen ausversehen einen Backslash oder sonstige ebenfalls nicht erlaubte Zeichen für E-MailAdressen rein geht dein Skript hops .... Kann bei meiner Variante mit der [System.Net.Mail.emailaddress] Klasse nicht passieren weil keinerlei Zeichen definiert werden müssen und alle ungültigen Zeichen bereits berücksichtigt werden, deswegen habe ich die ja gepostet face-wink. Des weiteren arbeitet der -match Parameter auf Regex-Basis, was das Skript ohne Escaping des Arrays ebenfalls vor die Wand fahren lässt wenn sich darin Regex-Sonderzeichen befinden.

Kannst du dir auch ne einfach Funktion draus machen falls du das Where-Objekt aus dem Code nicht verstanden hast

function Validate-EMailAddress([string]$email) {
    try{
        $null=[mailaddress]$email
        return $true
    }catch{return $false}
}

Validate-EMailAddress 'user@domain.tld'   # not valid, returns $false  
Validate-EMailAddress 'user@domain.tld'     # valid, returns $true  

$check = $emailadress -match $a
Das ist ebenso fehlerhaft, wie oben gesagt benutzt -match Regex Syntax, richtig wäre
$check = $emailadress -match [regex]::escape($a)
aber eine Schleife braucht man hier nicht da reicht der -in Vergeleichsoperator
$check = $emailadress.split("@")[1] -in $allowedDomains  
Member: em-pie
em-pie Dec 29, 2021 at 11:23:56 (UTC)
Goto Top
Moin,

So überflogen schaut das ganz passabel aus. Danke für das Feedback face-smile

Ich würde aber anstelle von ok bzw. nok als Rückgabewerte $true bzw. $false wählen. Dann musst du bei den Ipf-Abfrahen nicht mit -eq arbeiten. Es reiche dann auch ein:
if ($checkDomain) { 
  Do sth 
}
Member: Nagus
Nagus Dec 29, 2021 updated at 12:14:00 (UTC)
Goto Top
Moin hacktor,

wenn ich Deinen Code von TIO verwende. dann wird nur der Backslash als Fehler geworfen.
add-type -A System.Net.Mail
$csv = @'  
Email
usèr@domain.de
usßr2@domain.com
us\er@domain.it
'@ | ConvertFrom-Csv -delimiter ";"  

$csv | ?{try{$null=[mailaddress]$_.Email;$false}catch{$true}}

Ausgabe
PS C:\windows\system32\windowspowershell\v1.0> add-type -A System.Net.Mail
$csv = @'  
Email
usèr@domain.de
usßr2@domain.com
us\er@domain.it
'@ | ConvertFrom-Csv -delimiter ";"  

$csv | ?{try{$null=[mailaddress]$_.Email;$false}catch{$true}}


Email          
-----          
us\er@domain.it

Und das hilft mir nicht.

Auch Deine Funktion
function Validate-EMailAddress([string]$email) {
    try{
        $null=[mailaddress]$email
        return $true
    }catch{return $false}
}

Validate-EMailAddress 'user@domain.tld'   # not valid, returns $false  
Validate-EMailAddress 'usèr@domain.tld'     # valid, returns $true  
Liefert mir nicht das erwartete Ergebnis_
PS C:\windows\system32\windowspowershell\v1.0> function Validate-EMailAddress([string]$email) {
    try{
        $null=[mailaddress]$email
        return $true
    }catch{return $false}
}

Validate-EMailAddress 'user@domain.tld'   # not valid, returns $false  
Validate-EMailAddress 'usèr@domain.tld'     # valid, returns $true  
False
True

Insofern bleibe ich bei meiner Funktion und vertraue darauf das SAP den Backslash abfängt
[2021-12-29 13:13:02] - [ERROR] Folgende unerlaubte Zeichen in Email-Adresse abscdèddd@web.de entdeckt: è
Member: Nagus
Nagus Dec 29, 2021 updated at 12:09:30 (UTC)
Goto Top
Zitat von @em-pie:

Moin,

So überflogen schaut das ganz passabel aus. Danke für das Feedback face-smile

Ich würde aber anstelle von ok bzw. nok als Rückgabewerte $true bzw. $false wählen. Dann musst du bei den Ipf-Abfrahen nicht mit -eq arbeiten. Es reiche dann auch ein:
if ($checkDomain) { 
  Do sth 
}

Hatte ich mir am Anfang auch überlegt, aber weil ich das ganze nachher so darstelle dagegen entschieden.

0                  : 173
ID                 : MAXMUS
Vorname            : Max
Nachname           : Mustermann
Email              : Max.Mustermann@Web.de
Mitarbeiter-Status : Aktiv
Eintritt           : 01.01.2022
PersNr             : 0000000
Durchwahl          : 110
Standort           : Tuhn
Planstelle         : Ja
Team               : Brandmeister
Abteilung          : Brandschutz
Bereich            : Waldbrände
Einsatzbereich     : Fahrer
Linienvorgesetzter : SUAMUS
Rechte Wie         : KLEKSA
AD                 : 
Exchange           : 
Cal                : 
Skype              : 
Bemerkung          : 
Kontoablaufdatum   : 
Xphone             : 
InitialPassword    : 
UserTyp            : 
RefernzGruppen     : 
StandardGruppen    : 
UserDC             : 
UserDCStatus       : 
Country            : CH
CountryCode        : 756
ValidEmail         : OK
Aber danke für den Tipp face-smile
Member: rubberman
rubberman Dec 29, 2021 at 16:19:09 (UTC)
Goto Top
Zufällig hier drüber gestolpert ...

Erstmal gefällt mir der Ansatz von @149569, denn alles was die .NET Klasse aussortiert, entspricht schon mal nicht den validen Mailadressen. Allerdings würde ich "Prüfung auf unzulässige Zeichen" dann zu "Prüfung auf zulässige Zeichen" umkehren. Einfach weil ich davon überzeugt bin dass die Menge der Zeichen die euren internen Konventionen entspricht ungleich kleiner ist, als die Menge der unzulässigen Zeichen.
Function Get-IsValidMailAddress([string]$addr) {
  try {$null = [Net.Mail.MailAddress]$addr} catch {return $False} # pass only if .NET treats it to be valid
  if ($addr -notmatch '^[a-z0-9@\.]+$') {return $False} # pass only if custom requirements are met  
  # more checks?
  return $True
}

Get-IsValidMailAddress 'us\er@domain.tld' #false  
Get-IsValidMailAddress 'user@dom@in.tld' #false  
Get-IsValidMailAddress 'user@domain.tld' #false  
Get-IsValidMailAddress 'usèr@domain.tld' #false  
Get-IsValidMailAddress 'UsEr@domain.tld' #true  

Steffen