多用户场景下AD与MSOL账户创建PowerShell脚本报错求助
Hey there, let's break down what's causing that frustrating error and fix it step by step. The core issue here is how you're accessing user properties inside your ForEach loop—you're pulling values from the entire CSV list instead of the single user you're processing right now. That's why all your variables are turning into arrays instead of strings!
What Went Wrong
When you write $Firstname = $AccountList.pFirstName, you're grabbing the entire pFirstName column from your CSV (an array of every first name) instead of just the first name of the current $Person in the loop. AD cmdlets like New-ADUser expect a single string for parameters like -SamAccountName, not an array of values—hence the conversion error.
Fixed Script
Here's the corrected version with all issues addressed:
# Import the CSV once $AccountList = Import-Csv "C:\File\path\input.csv" # Process one user at a time in a single loop ForEach ($Person in $AccountList) { # Get values from the CURRENT user ($Person), not the entire list $Firstname = $Person.pFirstName.Trim() $LastName = $Person.pLastName.Trim() $Department = $Person.pDepartment $Location = $Person.pLocation # Generate account-related values using the single user's data $Accountname = "$($Firstname.ToLower()).$($LastName.ToLower())" $UPN = "$Accountname@company.com" $displayname = "$Firstname $LastName" # Create AD User with string values (no more arrays!) New-ADUser -SamAccountName $Accountname ` -Name $displayname ` -DisplayName $displayname ` -Surname $LastName ` -GivenName $Firstname ` -UserPrincipalName $UPN ` -Department $Department ` -Office $Location ` -AccountPassword (ConvertTo-SecureString -AsPlainText "X" -Force) ` -ChangePasswordAtLogon $true ` -Enabled $true ` -PasswordNeverExpires $false ` -Path "CN=Users,DC=medsinmotion,DC=local" # Create MSOL User New-MsolUser -DisplayName $displayname ` -FirstName $Firstname ` -LastName $LastName ` -UserPrincipalName $UPN ` -Department $Department ` -UsageLocation US ` -LicenseAssignment reseller-account:DESKLESSPACK ` -ForceChangePassword $true # Fix the conditional logic (original was broken!) if ($Department -match "Call Center" -or $Department -match "Retail") { Add-MailboxPermission -Identity CallCenter -User $Accountname -AccessRights FullAccess Add-DistributionGroupMember -Identity callctr@company.com -Member $Accountname } else { # Swap licenses for non-call center/retail users Set-MsolUserLicense -UserPrincipalname $UPN ` -AddLicenses O365_BUSINESS_PREMIUM ` -RemoveLicenses reseller-account:DESKLESSPACK } # Add all users to the "all" distribution group Add-DistributionGroupMember -Identity all -Member $UPN }
Key Fixes Explained
- Use
$Personinstead of$AccountListfor user properties: Every time you need data for the user you're currently processing, reference$Person.pFirstName,$Person.pLastName, etc. This gives you a single string value instead of an array. - Fixed variable order: You were trying to generate
$Accountnamebefore assigning$Firstnameand$LastName—now we grab those values first. - Corrected conditional logic: The original
if ($Department -match "Call Center" -or "Retail")would always evaluate to$true(because "Retail" is a non-empty string, which PowerShell treats as$true). We now check$Departmentagainst both values explicitly. - Combined loops: Your original script had two separate
ForEachloops over the same CSV. Combining them into one makes the code cleaner and avoids potential variable scope issues.
Additional Tips
- Always test with a small CSV (2-3 users) after making changes to catch issues early.
- Add error handling with
try/catchblocks if you want to handle failures gracefully (e.g., skip a user if their account already exists).
内容的提问来源于stack exchange,提问作者AJSKRILLA

