以前寫過一些簡單的script發信通知,不過後來忘記保存,現在要再找也找不到了,要重寫又不知道花多少時間,幸好現在ChatGPT方便,把完整的需求丟給它,就幾乎可以做到我要的程式結果,而且寫出的內容非常不錯,必須說現在寫程式土法煉鋼的日子愈來愈少了,以後懂程式的人不知道還有沒有高薪上的優勢?雖然方便又快速,但還是把過程紀錄一下,誰知道以後會不會再用到。
一.基本需求
1.篩選 AD帳號 中 EmployeeID 以「A」開頭的帳號
2. 計算帳號密碼剩餘天數,不處理時間細節,只留年月日
3. 剩餘天數為 1~5 天內發送提醒郵件(跳過已過期或未啟用帳號)
4. 使用 Office 365 SMTP 發信(支援應用程式密碼)
5. UTF-8 編碼
6. 可排入工作排程器每天上午9點執行
2. 計算帳號密碼剩餘天數,不處理時間細節,只留年月日
3. 剩餘天數為 1~5 天內發送提醒郵件(跳過已過期或未啟用帳號)
4. 使用 Office 365 SMTP 發信(支援應用程式密碼)
5. UTF-8 編碼
6. 可排入工作排程器每天上午9點執行
二.產出應用程式密碼
現在不論是GWS還是M365,都已經改掉了以往用登入帳號當應用程式的登入密碼了,取而代之的是用戶要自己產出一支專用的應用程式密碼,改組密碼屬於單一用途,用在其他地方就會沒效,這是比較新且安全的機制。
![]() |
選定要發信的M365帳號,然後在安全性資訊>新增登入方法>應用程式密碼,讓系統產出一組專用密碼 |
三.Powershell內容
將以下內容做一些修改,然後存檔命名為account_notification.ps1,然後放在C:\底下。路徑:C:\account_notification.ps1。
# region ===== 設定參數 =====# Office 365 發信資訊$smtpServer = "smtp.office365.com"$smtpPort = 587$smtpUser = "it@abc.com" # 發信者信箱$smtpPass = "klhykvzxlvhbbtyk" # M365 應用程式密碼
# 發信者名稱與主旨$from = "資訊部 <it@abc.com>"$subject = "您的AD帳號密碼即將到期通知"
# 取得今日日期(只保留年月日)$today = (Get-Date).Date
# 匯入AD模組Import-Module ActiveDirectory
# 取得所有 EmployeeID 開頭為 "A" 的啟用帳號$users = Get-ADUser -Filter {Enabled -eq $true -and EmployeeID -like "A*"} -Properties DisplayName, EmailAddress, PasswordLastSet, PasswordNeverExpires, msDS-UserPasswordExpiryTimeComputed
foreach ($user in $users) {
# 跳過沒有 Email 的帳號 if ([string]::IsNullOrEmpty($user.EmailAddress)) { continue }
# 跳過永不過期的帳號 if ($user.PasswordNeverExpires) { continue }
# 密碼到期日(只保留年月日) $expiryDate = [datetime]::FromFileTime($user."msDS-UserPasswordExpiryTimeComputed").Date
# 計算剩餘天數(忽略具體時間,只算日期) $daysLeft = ($expiryDate - $today).Days
# 跳過已過期或不在 1~5 天內的帳號 if ($daysLeft -lt 1 -or $daysLeft -gt 5) { continue }
# 通過條件後,開始發信 $LastDay = $daysLeft $CName = $user.GivenName $to = $user.EmailAddress
# 郵件內容(UTF8 編碼) $body = @"親愛的 $CName您的AD帳號剩下 $LastDay 天將到期,為了維護資訊安全,請盡快更新您的AD密碼。
密碼規則為:1.共8碼以上2.數字、英文大小寫、特殊符號的複雜度3.不可用與帳號相同的內容,例如英文姓名
修改方式:1.在您的電腦上輸入Ctrl+Alt+Del,然後選擇「變更密碼」2.到遠端主機上(RDS)上,輸入Ctrl+Alt+End,再選擇「變更密碼」
若有問題請洽資訊部,謝謝!
"@
# 建立郵件物件 $mailParams = @{ From = $from To = $to Subject = $subject Body = $body SmtpServer = $smtpServer Port = $smtpPort UseSsl = $true Credential = New-Object System.Management.Automation.PSCredential($smtpUser, (ConvertTo-SecureString $smtpPass -AsPlainText -Force)) Encoding = ([System.Text.Encoding]::UTF8) }
try { Send-MailMessage @mailParams Write-Host "發送成功: $to" } catch { Write-Warning "發送失敗: $to - $_" }}
第一次寫完並放到排程測試跑幾天後,發現一個小問題,如果某帳戶的密碼到期間是在我設定排程發信時間點之後,那麼他隔天會收到兩封信,其中一封是前一天錯過排程時間、後來又補寄的,這樣會讓用戶感到困惑,為了避免造成麻煩並簡化程式邏輯,所有時間的計算都建議調整只要年月日,時和分的細節就忽略它。
四.排程器設定
排程器的設定跟以前用的Windows 2012也有點不一樣了,為了安全性,目前改用的Windows 2022支援powershell執行ps1也變得很嚴謹,這個過程也需要留意和紀錄一下。
![]() |
建立一個基本的工作排程 |
![]() |
命名工作「名稱」,設定「不論使用者登入與否都執行」,最後「以最高權限執行」 |
![]() |
觸發程序設定成每天的9:00一次性執行 |
![]() |
確認好執行時間 |
![]() |
重要步驟之一,執行powershell指令現在必須要用PowerShell7的pwsh.exe,要記得事先安裝好。下面的「新增引數」要填「-ExecutionPolicy Bypass -File "C:\account_notification.ps1"」 |
![]() |
因為用最高權限執行此排程,所以設定完畢後,要正確輸入管理員帳密 |
![]() |
最後可以開始測試排程是否正常執行 |
這應該會是一個滿實用的腳本,一般使用者總是希望系統會主動通知密碼到期的問題,留下這篇當作今後若還有需求時使用。
沒有留言:
張貼留言