In diesem Artikel hatte ich bereits beschrieben, wie eine Webseite eingerichtet werden kann, auf der Benutzer ihr Passwort ändern können. Gerade Benutzer die mit einem Rechner arbeiten der nicht Mitglied des Active Directory ist, stellt die Passwortänderung oft ein Problem dar.
Mittels der Webseite haben diese Benutzer nun die Möglichkeit ihr Passwort rechtzeitig zu ändern. Allerdings müssen die Benutzer auch informiert werden, wenn das Passwort in naher Zukunft abläuft. Die einfachste Möglichkeit ist wohl eine Mail zu dem Benutzer zu schicken, so können auch externe Benutzer erreicht werden.
Um Benutzern rechtzeitig an die Passwortänderung zu erinnern, habe ich ein kleines PowerShell Script erstellt. Das Script kann hier runtergeladen werden:
PasswordReminder
Das Script muss natürlich noch etwas an die jeweilige Umgebung angepasst werden. Im wesentlichen müssen nur die Zeilen 1 – 32 an die eigenen Bedürfnisse angepasst werden:
Zeile 2 enthält die Anzahl der Tage nachdem ein Passwort geändert werden muss. In Zeile 3 wird festgelegt wie viele Tage vor Ablauf des Passwortes der Benutzer informiert werden soll.
Die Zeilen 6 – 8 enthalten die Angaben zum Mail Server über den die E-Mails versendet werden sollen.
Zeile 14 – 29 enthält den Text der Mail der dem Benutzer zugesendet wird. Folgende Variablen können benutzt werden:
- $GivenName: Vorname des AD Benutzers
- $Surname: Nachname des AD Benutzers
- $DaysBeforePasswordchange: Anzahl Tage bis zur Passwort Änderung
- $PasswordExpireDate: Datum an dem das Passwort abläuft
Das Script benötigt die PowerShell CMDLets für das Active Directory (Get-ADUser). Die E-Mail wird im HTML Format an die E-Mail Adresse verschickt die dem Benutzer im Active Directory zugeordnet ist.
Update 05.01.17: Vielen Dank für die Kommentare. Die Hinweise habe ich entsprechend im Script ergänzt und eine neue Version hochgeladen.
Hallo,
falls die Kommentare für diesen doch schon in die Jahre gekommenen Artikel noch gelesen werden…
Wie geht ihr damit um, wenn ein Benutzer zwar all das bekommt aber bis zum Tag des Passwortablaufs ignoriert? (oder auf Urlaub ist, …)
Szenario:
Passwort läuft am Montag, 1.1 um 09:00 Uhr ab
User meldet sich um 07:00 Uhr an, ignoriert alles und kann sich ja noch anmelden, da noch 2 Stunden Zeit. Arbeitet also normal weiter. Ab 09:00 Uhr dann seltsame Probleme, dass plötzlich „etwas nicht mehr geht“
Admin/Helpdesk hat das ggf. nicht im Blick und findet erst nach Zeit Y heraus, dass das Pwd abgelaufen ist, User aber eingeloggt.
Ich habe deshalb im Script so gesetzt, dass es gegen 23 Uhr läuft und wenn ein Passwort am nächsten Tag abläuft, jetzt schon der Flag „User must change password at next logon“ gesetzt wird.
In dem Szenario müsste der User also beim Anmelden um 07:00 Uhr schon erzwungenermaßen das Pwd ersetzten. Es wurde informiert, dass das Pwd am 1.1. abläuft – Uhrzeit wird hier dann ignoriert (bzw. gar nicht informiert)
just my 5 cent
Bei mir stimmt da was leider nicht, einige User bekommen diese Nachricht.
Your Active Directory password will expire on 10/20/2022 20:28:02.
You have -4 days before your password will expire, you should consider to change your password now.
Das Passwort wurde aber am 10/20/2022 schon geändert.
Wie wäre es mit diesem Vorschlag: Sende die E-Mail 14 Tage, 7 Tage und 1 Tag vor dem Passwortverfall ab. Dazu einfach die If-Bedingung in Zeile 50 entsprechend modifizieren.
Mal die Frage an alle, das Script bereits einsetzen? Wann und wie oft lasst ihr das laufen? Das Script merkt sich ja nicht, wen es schon gewarnt hat. So bombadiert man dann die Nutzer, bis „von ganz oben“ der Befehl kommt „den Sch*** sein zu lassen“ oder die User bauen sich Filterregel, die die Mails dirkt löschen. Ziel in jedem Fall verfehlt.
Wie wäre es mit diesem Vorschlag: Sende die E-Mail 14 Tage, 7 Tage und 1 Tag vor dem Passwortverfall ab. Dazu einfach die If-Bedingung in Zeile 50 entsprechend modifizieren.
Hier die Lösung:
Zeile #3 ändern nach: $WarningLevel = @(14, 7, 1, 0)
Zeile #50 ändern nach: if ($DaysBeforePasswordchange -in $WarningLevel)
Servus,
da ich absoluter Powershell Neuling bin, kurz die Frage, wie ich dieses Problem Lösen kann…
You cannot call a method on a null-valued expression.
At line:47 char:3
+ $PasswordExpireDate = $PasswordLastSet.AddDays(+$MaxPasswordAge)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Hallo,
kann mir bitte jemand sagen was folgende Fehlermeldung zu bedeuten hat?
Es ist nicht möglich, eine Methode für einen Ausdruck aufzurufen, der den NULL hat.
In C:\Install\PasswodReminder.ps1:48 Zeichen:3
+ $PasswordExpireDate = $PasswordLastSet.AddDays(+$MaxPasswordAge)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Verstehe nicht wie der Wert NULL sein kann, jeder der Ausdrucke hat einen Wert und wenn ich es richtig verstehe hat angeblich der Ausdruck MaxPasswordAge einen Wert von NULL, was auch nicht sein kann. Übersehe ich etwas?
Viele Grüße,
Dysis
Zur Info für andere mit der gleichen Fehlermeldung
(Es ist nicht möglich, eine Methode für einen Ausdruck aufzurufen, der den NULL hat….): Ich habe nun herausgefunden, dass bei mir die Werte (Ablaufdatum & Tage bis Ablauf) im Minusbereich herausgelesen bzw. angezeigt werden, wie man das löst oder woran das liegt, weiß ich leider noch nicht…. aber vielleicht jemand anderes:
Displayname ExpiryDate ExpirationDays
———– ———- ————–
User1 01.01.1601 01:00:00 -152803
User2 01.01.1601 01:00:00 -152803
User3 01.01.1601 01:00:00 -152803
User4 01.01.1601 01:00:00 -152803
Viele Grüße,
Numan
Hallo,
ich habe eure Kommentare gelesen um zu verstehen, wie ich das Script einschränken kann.
so habe ich eingegeben:
$AllADUsers = Get-ADUser -Filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} -Searchbase „OU=.Ausb,OU=Produktiv(Abteilungen),OU=Test,DC=UnsereDomain,DC=local“ -Properties PasswordLastSet,mail
Aber passiert folgender Fehler:
Get-ADUser : Die Benennung „Get-ADUser“ wurde nicht als Name eines Cmdlet, einer Funktion, einer Skriptdatei oder eines ausführbaren Programms erkannt. Überprüfen Sie
die Schreibweise des Namens, oder ob der Pfad korrekt ist (sofern enthalten), und wiederholen Sie den Vorgang.
+ $AllADUsers = Get-ADUser -Filter {Enabled -eq $True -and PasswordNeverExpires -e …
+ ~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-ADUser:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Ich freue mich auf eure Antwort.
Danke & viele Grüße
Hozan
Tolles Skript, vielen Dank für den Input.
eine vermutlich doofe Frage, vielleicht übersehe ich den Hinweis auch:
Das Skript muss doch dann täglich ausgeführt werden, z.b. per Aufgabenplanung, richtig?
Viele Grüße,
Basti
Hallo Bastian,
ja das Script muss zyklisch laufen. Du kannst das Script durch einen geplanten Task ausführen lassen.
Gruß,
Frank
Weiterhin wäre die Frage geht dies auch mit SSL verschlüsselten SMTP Serven und wie kann ich mein Passwort dort eingeben?
Kurze Frage kann man dies auch für eine angelegte Gruppen einrichten und auch nur für User aus dieser Gruppe? Kann mir da jemand helfen?
Guten Tag,
ich habe alle Parameter angepasst und auch leider noch einen Fehler:
PS C:\> C:\PasswodReminder.ps1
Es ist nicht möglich, eine Methode für einen Ausdruck aufzurufen, der den NULL hat.
In C:\PasswodReminder.ps1:44 Zeichen:3
+ $PasswordExpireDate = $PasswordLastSet.AddDays(+$MaxPasswordAge)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Weiß wer, wie ich den Fehler ausmerzen kann?!
Dieses Problem haben ich auch… und komme nicht weiter.
Konntest du es zwischenzeitig schon lösen?
Beste Grüße
Hi,
ich möchte gerne ein Log haben, wer von meine User das Mail bekommen hast.
Kann man das leicht einbauen?
Ich habe noch ein Problem: Ich habe bei einigen Usern die Tage falsch bei $DaysBeforePasswordchange. Es kommt zum Beispiel -4400 Tage wenn ich mir den User genau anschaue hat er vor 88 Tage das Passwort geändert.
Hallo Frank,
super Lösung die du da hast !
Ich hätte anbei auch noch eine Alternative, schau doch mal vorbei :-)
https://www.itnator.net/password-expire-mail/
Gruß Johannes
Hallo Frank
Wir lassen bei unserem Script MaxPasswordAge ermitteln:
$MaxPasswordAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge
Gruss, M
Hi,
danke für den Hinweis, daran hatte ich gar nicht gedacht. :-)
Gruß,
Frank
Hallo Frank,
vielen Dank für deine Hilfe. Damit wird das Datum in dem Format angezeigt wie ich es haben will.
Habe allerdings noch ein Problem mit den Umlauten. Trotz der Zeile
Send-MailMessage -SmtpServer $SMTPServer -To $MailAddress -From $From -Body $Body -BodyAsHtml -Subject $Subject -encoding ([System.Text.Encoding]::UTF8)
werden die Umlaute in der Mail nicht richtig dargestellt.
Gruß Stefan
Hi Stefan,
schau mal ob du die PS1 Datei mit ANSI Kodierung gespeichert hast.
Gruß, Frank
Hallo,
hat jemand eine Lösung/Idee wie man das Datum in DD/MM/YYYY Format angeben kann?
Gruß
Stefan
Hi Stefan,
füge mal in Zeile 67 die folgende Zeile ein:
$PasswordExpireDate = $PasswordExpireDate | get-date -Format dd.MM.yyyy
Gruß, Frank
Hallo,
habe zum Script eine frage.. bin eher fremdling was Scripte angehen tut, habe es aber nun so wie es mir passt für mein Unternehmen abgeändert, kann mir aber jemand sagen wo ich das Script ablegen / Einbinden muss etc ?
Vielen danke
Adnan
Hallo zusammen,
hat jemand eine Idee wie ich User welche eine Mail Adresse außerhalb der Domain haben angesprochen bekomme? Als Kontakte sind diese angelegt um sie im globalen Adressbuch zu sehen. Ein Eintrag einer „fremden“ E-Mail im AD User Objekt führt nicht zum Erfolg.
Danke
Ingo
Hallo Frank!
Nach der Migration unseres Mailservers von Ex13 (Server 2008 R2) auf Ex16 (Server 2012 R2) habe ich das Skript angepasst indem ich den neuen Server hinterlege. Nun bekomme ich folgende Fehlermeldung:
„Get-ADUser : Die Benennung „Get-ADUser“ wurde nicht als Name eines Cmdlet, einer Funktion, einer Skriptdatei
oder eines ausführbaren Programms erkannt. Überprüfen Sie die Schreibweise des Namens, oder ob der Pfad
korrekt ist (sofern enthalten), und wiederholen Sie den Vorgang.
In C:\Users\administrator.MEPPEN\Desktop\PasswordReminder.ps1:33 Zeichen:15
+ $AllADUsers = Get-ADUser -Filter {Enabled -eq $True -and PasswordNeverExpires -e …
+ ~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-ADUser:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException“
Hast du ne Lösung?
Gruß
Hendrik
Hallo!
Werden User ausgeschlossen, deren Kennwörter nicht ablaufen?
Gruß
Hendrik
Hallo,
die deutschen Umlaute werden trotz dieser Zeile
Send-MailMessage -SmtpServer $SMTPServer -To $MailAddress -From $From -Body $Body -BodyAsHtml -Subject $Subject -encoding ([System.Text.Encoding]::UTF8)
noch falsch dargestellt.
Zweites Problem. Das Datum wird im amerikanischen Format angezeigt, also MM/DD/YYYY.
Kann man das noch irgendwie ändern in DD/MM/YYYY
Gruß
Sven
Hallo zusammen,
gibt es evtl. die Möglichkeit zu sagen x Werktage vor Ablauf des PW soll die Mail verschickt werden? Oder müsste man das umständlich Skripten?
Wir haben Accounts ohne Mailadresse wo es aber auch gut wäre eine Benachrichtigung zu bekommen, wie müsste man eine Abfrage des Managers und Mailversand an diesen, bewerkstelligen?
Grüße
Oliver
Als Ergänzung zu Björn seinem OWA Link:
Es geht auch etwas schlichter ;)
https://MEINEXCHANGESERVER/owa/?ae=Options&t=ChangePassword
VG,
Flo
Moin,
falls jemand nicht die Muße hat, die von Franky beschriebene Website zur Passwortänderung zu erstellen, jedoch einen Exchange-Server im Einsatz hat, so kann man als Verweis auch folgenden Link in die Hinweismail einsetzen:
https://MEINEXCHANGESERVER/ecp/?rfr=owa&owaparam=modurl%3D0&p=PersonalSettings/Password.aspx
Das ist zwar kein Link, den sich jemand merken wird; aber als Hyperlink zum Anklicken reicht es…
Ein schönes Wochenende allerseits!
VG,
Björn
Moin,
ich habe die Zeile 34 wie folgt geändert um nur die User einer OU abzufragen:
$AllADUsers = Get-ADUser -Filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} -Searchbase „OU=KanzleiOU,DC=test,DC=local“ -Properties PasswordLastSet,mail
Klappt auch ! Aber wie kann ich in diesem Kontext noch eine zweite OU abfragen?
Danke….
Hi Ingo,
du kannst eine zweite OU wie folgt angeben:
Zeile 34+35:
$AllADUsers = Get-ADUser -Filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} -Searchbase „OU=KanzleiOU,DC=test,DC=local“ -Properties PasswordLastSet,mail
$AllADUsers += Get-ADUser -Filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} -Searchbase „OU=ANDEREOU,DC=test,DC=local“ -Properties PasswordLastSet,mail
Das erzeugt zwei Abfragen (KanzleiOU und ANDEREOU) beide Abfragen werden in $AllADUsers gespeichert (+=).
Gruß, Frank
@Ingo:
– Die Deutschen Umlaute sollten durch die Ergänzung der vorletzten Zeile funktionieren:
Send-MailMessage -SmtpServer $SMTPServer -To $MailAddress -From $From -Body $Body -BodyAsHtml -Subject $Subject -encoding ([System.Text.Encoding]::UTF8)
– Die Uhrzeit wird bei uns korrekt dargestellt – sowohl via net user, als auch in der Mail aus dem Script.
HHmm,
Umlaute sind geklärt. Das mit der Zeit finde ich seltsam…… Muss ich mir mal weitere Gedanken machen. Vielleicht fällt noch jemanden dazu etwas ein ?
Danke vorerst…..
@Björn:
Danke schön, soeben wollte ich auch darauf hinweisen das in Zeile 64 das Problem sich mit der Lösung wie von Dir beschrieben lösen lässt. Habe bis eben rumprobiert, aber auch nur so lernt man etwas.
Auch beim zweiten Fehler gebe ich dir recht – wenn ich es auf die User bzw OU beschränke in welcher auch Passwörter gesetzt wurden ist auch dieser Fehler weg.
Jetzt habe ich nur noch 2 Kleinigkeiten:
– deutsche Umlaute im Mailtext werden nicht dargestellt? Hatte ich schon mal weiß aber die Lösung nicht mehr :-(
– Uhrzeit bei Passwortablauf ist falsch und zwar genau um eine Stunde. net user Benutzername gibt als Uhrzeit 08:00 an, das Script genau eine Stunde später. Ist sicherlich ein Problem mit der MEZ, aber wie bekommt dies hin? Ideen ?
Danke,
@Ingo:
Der erste Fehler lässt sich durch ändern der Zeile 64 in $MailAddress = $ADUser.mailaddress beheben.
Der zweite Fehler taucht bei mir nicht auf; ich hatte erst den Verschreiber („Passwoord…) im Verdacht, aber der zieht sich durch alle anderen Zeilen durch und wirkt sich somit nicht aus… Hattest du mal die Konten ohne Ablauf (wie in meinem ersten Kommentar beschrieben) gefiltert?
Eine andere Idee: gibt es User, die angelegt wurden, denen aber nie ein Passwort zugeordnet wurde (so dass möglicherweise die Variable leer ist)?
VG,
Björn
Hi,
gute Idee. Ich habe es mal probiert, allerdings bräuchte ich noch eine Einschränkung der Userabfrage auf eine bestimmte OU. Geht das, wenn ja wie ?
Es läuft bei mir ansonsten auf einen Fehler welcher aus meiner Sicht darin begründet ist, das nicht alle User eine Mail haben.
Fehlertext:
end-MailMessage : Das Argument für den Parameter „To“ kann nicht überprüft werden. Das Argument ist NULL oder leer. Geben Sie ein Argument an, das nicht NULL oder leer ist,
und führen Sie den Befehl erneut aus.
In D:\PasswodReminder\PasswodReminder.ps1:70 Zeichen:48
+ Send-MailMessage -SmtpServer $SMTPServer -To $MailAddress -From $From -Body $B …
+ ~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Send-MailMessage], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.SendMailMessage
Ein anderer Fehler ist vollkommen unklar:
Es ist nicht möglich, eine Methode für einen Ausdruck aufzurufen, der den NULL hat.
In D:\PasswodReminder\PasswodReminder.ps1:47 Zeichen:3
+ $PasswoordExpireDate = $PasswordLastSet.AddDays(+$MaxPasswordAge)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Herzlichen Dank im voraus,
Ingo
Herzlichen Dank für die tollen Beiträge und praktischen Lösungskonzepte!
$MaxPasswordAge hat mich etwas irritiert, denn das AD müsste ja wissen, wann das Passwort abläuft :-)
Mit dem nachfolgenden Zweizeiler erhält man die Liste der User, deren Passwort innerhalb der nächsten 14 Tage abläuft.
Mit lieben Grüssen,
Tom
$WarningLevel = 14
Get-ADUser -Filter { Enabled -Eq $True -And PasswordNeverExpires -Eq $False} -Properties DisplayName, ‚msDS-UserPasswordExpiryTimeComputed‘ | Select-Object -Property Displayname, @{ Name=’ExpiryDate‘; Expression={[datetime]::FromFileTime($_.’msDS-UserPasswordExpiryTimeComputed‘)}}, @{ Name=’ExpirationDays‘; Expression={(([datetime]::FromFileTime($_.’msDS-UserPasswordExpiryTimeComputed‘))-(Get-Date)).Days }} | Where-Object ExpirationDays -le $WarningLevel
Hi Franky,
ich würde die Zeile 35 folgendermaßen ergänzen, um User ohne Passwortablauf auszuklammern:
$AllADUsers = Get-ADUser -Filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} -Properties PasswordLastSet,mail
Sonst bekämen mail-aktivierte Dienstuser auch unnötigerweise einen Hinweis (so zumindest bei uns).
Ansonsten wie immer ein sehr hilfreicher Artikel! Besten Dank dafür!
VG,
Björn