PowerShell脚本运行异常及邮件变量不显示问题求助
Let's tackle your two problems step by step:
1. Script Fails When Running as .ps1 File (Works Line-by-Line)
The error messages point to invalid special characters in your Set-AdUser line. You're using full-width (Chinese) quotation marks and a full-width dash instead of standard half-width symbols, which PowerShell can't parse correctly.
The Problem Line:
Set-AdUser -identity $username –replace @{info=â€trueâ€}
Notice the corrupted – (full-width dash) and â€true†(full-width quotes) — these break PowerShell's syntax parsing, leading to errors about missing terminators and unclosed braces.
The Fix:
Replace all full-width symbols with standard half-width equivalents:
Set-AdUser -Identity $username -Replace @{info="true"}
- Use
-Replace(half-width hyphen) instead of the full-width dash - Use
"true"(half-width double quotes) instead of the full-width quotes
This resolves the parser errors entirely.
2. $name Field Doesn't Appear in Email Body
You're trying to access $user.name, but your Select-Object command doesn't include the name property from AD. The $user object only has the properties you explicitly selected: whenCreated,mail,givenname,surname,SAMAccountName,info — so there's no name value to pull.
Two Fix Options:
Option 1: Add name to your Select-Object
Update your Get-ADUser pipeline to include the name property:
$users = Get-ADUser -Filter {whenCreated -ge $when} -Properties whenCreated,mail,givenname,surname,SAMAccountName,info | Select-Object name,whenCreated,mail,givenname,surname,SAMAccountName,info | Where-Object { $_.info -ne "true" }
Now $name = $user.name will work as expected.
Option 2: Build the name from givenname and surname
If you want more control over the displayed name (e.g., using first + last name directly), use:
$name = "$($user.givenname) $($user.surname)"
This avoids relying on the AD name field entirely.
Full Fixed Script
Here's the complete script with all fixes and minor improvements:
Clear Import-Module ActiveDirectory # Security Note: Storing plaintext passwords is insecure. Use Get-Credential or encrypted credentials instead. $secpasswd = ConvertTo-SecureString "xxxx" -AsPlainText -Force $mycreds = New-Object System.Management.Automation.PSCredential ("xxx@xxx.com", $secpasswd) $PSEmailServer = "xxx@xxx.com" $SMTPPort = 587 $SMTPUsername = "xxx@xxx.com" $MailFrom = "xxx@xxx.com" $MailSubject = "Your user account has been created" # Simplified calculation for users created in the last 24 hours $when = (Get-Date).AddHours(-24) $when $users = Get-ADUser -Filter {whenCreated -ge $when} -Properties whenCreated,mail,givenname,surname,SAMAccountName,info | Select-Object name,whenCreated,mail,givenname,surname,SAMAccountName,info | Where-Object { $_.info -ne "true" } # String comparison since info is a text attribute foreach ($user in $users) { # Uncomment below to debug user data # Write-Output $user $name = $user.name $emailTo = $user.mail $username = $user.SAMAccountName $MailBody = @" <p>Dear $name, Your CDAT Account has been created.<br><br> Your Username is $username<br><br> Please contact CDAT support for further assistance.<br><br> CDAT Support Team<br><br> This email was auto-generated. Please do not reply. If you need assistance, please contact CDAT Support.<br><br> Confidentiality Notice: This email message, including any attachments, is for the sole use of the intended recipient(s), and may contain confidential and privileged information. Any unauthorized review, use, disclosure, or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message.</p> "@ # Add error handling to avoid script crashes try { Send-MailMessage -From $MailFrom -To $emailTo -Subject $MailSubject -Body $MailBody -BodyAsHtml -Port $SMTPPort -UseSsl -Credential $mycreds Set-AdUser -Identity $username -Replace @{info="true"} Write-Output "Successfully processed user $username" } catch { Write-Error "Failed to process user $username : $_" } }
Additional Tips:
- Security: Avoid plaintext passwords. Use
Export-Clixmlto store encrypted credentials securely. - Date Logic:
AddHours(-24)is clearer thanAddDays(-2).addMinutes(-0)for targeting the last 24 hours. - Error Handling: The
try-catchblock ensures the script continues processing other users if one email/AD update fails.
内容的提问来源于stack exchange,提问作者Justin Ngayan

