PowerShell批量导入CSV创建AD用户脚本故障排查求助
问题描述
尝试用PowerShell脚本批量将指定文件夹中CSV文件的用户添加到Active Directory(AD),要求:
- 验证用户是否创建成功
- 归档并删除CSV文件,准备接收新文件
- 可设置定时执行
同时需要类似脚本批量删除AD用户。
目前脚本运行无报错,但未创建AD用户、未生成日志、CSV未归档,请求排查。
CSV文件内容
"givenName","displayName","sAMAccountName","EmailAddress","OU",password "DummyUser","DummyUser","dummy.user.customer1.com","dummy.user@customer1.com","OU=customer1,OU=Customers,DC=customerservice,DC=customerdomain,DC=com","**********"
原PowerShell脚本
<# This script is used to add Customers users in bulk to active directory using CSV file This script will be scheduled to run every hour or everyday to add new customer users to the AD Customers OU A new AD User based attributes CSV file with .csv extension and name format LDAP_Users***####.csv must be placed in a shared folder called LDAPExport. The folder... ..LDAPExport is located in thg C: drive of the server. Access to the folder from permitted servers is through the FTP server service running on this server where the script is running#> try { set-location = c:\ldapexport <# I just added this line after posting the question #> $CustomerAddADUserCSV = Get-ChildItem -Path C:\ldapexport\ -Name *adduser*.csv $CustomerAddADUserLogFolder = "c:\ldapexport\CustomerADUsersLogs" $LdapExportLog = "c:\ldapexport\LdapExportLog" <#the next lines check if AddUser csv file exists and then processed the file to add the Customer user/s account to Active Directory #> if($CustomerAddADUserCSV){ foreach ($CustomerCSVfile in $CustomeraddADUserCSV){ $NewADUsers = Import-Csv -Path $CustomerCSVfile ; foreach ($User in $NewADUsers) { $Displayname = $User.displayName $UserFirstname = $User.Firstname $UserLastname = $User.Lastname $OU = $User.OU $SAM = $User.sAMAccountName $Password = $User.Password $EmailAddress = $User.EmailAddress New-ADUser -Name "$Displayname" -DisplayName "$Displayname" -SamAccountName $SAM -AccountPassword (ConvertTo-SecureString $Password -AsPlainText -Force) -Enabled $true -Path "$OU" -ChangePasswordAtLogon $false > "$LdapExportLog\csvdeAdUsers_$(get-date -f ddMMyyyy_HHmmss).log" 2>&1 -ErrorAction stop; Get-ADUser -Identity $SAM -ErrorAction Stop > "$LdapExportLog\csvdeAdUsersAdded_$(get-date -f ddMMyyyy_HHmmss).log" 2>&1 } ; <#the next lines archive the AddUser csv files into a zipped files and store them the "Archive" located in the "ldapexport" directory.#> $CustomerAddADUserCSVFileArchive = Compress-Archive -Path "C:\ldapexport\$CustomerCSVfile" -DestinationPath C:\ldapexport\Archives\$CustomerCSVfile.$(get-date -f ddMMyyyy_HHmmss).zip -force; Compress-Archive -Path $CustomerAddADUserLogFolder -DestinationPath C:\ldapexport\Archives\CustomerADUsersLogs_$(get-date -f ddMMyyyy_HHmmss).zip -force > $LdapExportLog\csvdeArchive_$(get-date -f ddMMyyyy_HHmmss).log 2>&1; } else{ Write-Host "No new AddUser csv file exists. Quiting..." > $LdapExportLog\csvdeAdUsers_$(get-date -f ddMMyyyy_HHmmss).log 2>&1; exit } } } catch { write-host "Please, check the script of the referenced .csv file for any error logs" }
问题排查与修复点
- 语法错误:
set-location = c:\ldapexport多了等号,正确应为Set-Location C:\ldapexport - 变量大小写不匹配:
foreach ($CustomerCSVfile in $CustomeraddADUserCSV)中$CustomeraddADUserCSV应为$CustomerAddADUserCSV(PowerShell变量大小写敏感) - CSV字段不匹配:脚本调用
$User.Firstname和$User.Lastname,但CSV仅包含givenName字段,导致变量为空 - 目录未预创建:脚本未检查
$LdapExportLog、$CustomerAddADUserLogFolder、C:\ldapexport\Archives是否存在,目录不存在会直接导致日志写入、归档失败 - 文件路径处理错误:
Get-ChildItem -Name仅返回文件名,若当前路径切换失败,Import-Csv会找不到文件;应改用-File参数获取完整文件对象 - AD用户创建参数缺失:
New-ADUser未指定-GivenName必填参数,且-Name参数需符合AD命名规范 - 日志逻辑混乱:循环内每次创建新日志文件,会导致日志碎片化;应改为按CSV文件生成单一日志,或追加写入
- 未删除原CSV:脚本仅归档未删除原文件,会导致下次执行重复处理相同数据
修复后的批量添加AD用户脚本
<# 批量添加AD用户脚本:读取CSV、创建用户、验证、归档日志与CSV #> # 初始化路径与配置 $basePath = "C:\ldapexport" $logPath = Join-Path $basePath "LdapExportLog" $archivePath = Join-Path $basePath "Archives" $userLogPath = Join-Path $basePath "CustomerADUsersLogs" # 确保必要目录存在 foreach ($path in ($logPath, $archivePath, $userLogPath)) { if (-not (Test-Path $path)) { New-Item -Path $path -ItemType Directory -Force | Out-Null } } # 获取CSV文件(匹配*adduser*.csv,仅文件) $csvFiles = Get-ChildItem -Path $basePath -Filter *adduser*.csv -File try { if ($csvFiles.Count -eq 0) { $logMsg = "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] 未找到待处理的AddUser CSV文件" $logMsg | Out-File -Path (Join-Path $logPath "csvdeAdUsers_$(Get-Date -Format ddMMyyyy_HHmmss).log") -Append exit } foreach ($csvFile in $csvFiles) { $csvFullPath = $csvFile.FullName $logFile = Join-Path $logPath "csvdeAdUsers_$(Get-Date -Format ddMMyyyy_HHmmss).log" $userLogFile = Join-Path $userLogPath "AddedUsers_$(Get-Date -Format ddMMyyyy_HHmmss).log" # 导入CSV $users = Import-Csv -Path $csvFullPath foreach ($user in $users) { # 映射CSV字段(修正字段不匹配问题) $displayName = $user.displayName $givenName = $user.givenName $samAccountName = $user.sAMAccountName $email = $user.EmailAddress $ou = $user.OU $password = $user.password # 检查SAM账户是否已存在 if (Get-ADUser -Filter "SamAccountName -eq '$samAccountName'" -ErrorAction SilentlyContinue) { $msg = "[$(Get-Date)] 账户 $samAccountName 已存在,跳过创建" $msg | Out-File -Path $logFile -Append continue } # 创建AD用户 try { New-ADUser -Name $displayName ` -DisplayName $displayName ` -GivenName $givenName ` -SamAccountName $samAccountName ` -UserPrincipalName "$samAccountName@customerdomain.com" ` -EmailAddress $email ` -AccountPassword (ConvertTo-SecureString $password -AsPlainText -Force) ` -Enabled $true ` -Path $ou ` -ChangePasswordAtLogon $false ` -ErrorAction Stop # 验证创建并记录 $createdUser = Get-ADUser -Identity $samAccountName -Properties EmailAddress, Enabled $msg = "[$(Get-Date)] 成功创建用户:$displayName ($samAccountName) | OU: $ou | 邮箱: $email" $msg | Out-File -Path $logFile -Append $createdUser | Select-Object Name, SamAccountName, EmailAddress, Enabled, DistinguishedName | Out-File -Path $userLogFile -Append } catch { $errMsg = "[$(Get-Date)] 创建用户 $samAccountName 失败:$($_.Exception.Message)" $errMsg | Out-File -Path $logFile -Append } } # 归档CSV文件并删除原文件 $archiveCsv = Join-Path $archivePath "$($csvFile.BaseName)_$(Get-Date -Format ddMMyyyy_HHmmss).zip" Compress-Archive -Path $csvFullPath -DestinationPath $archiveCsv -Force -ErrorAction Stop Remove-Item -Path $csvFullPath -Force -ErrorAction Stop "[$(Get-Date)] 已归档并删除CSV文件:$($csvFile.Name)" | Out-File -Path $logFile -Append # 归档用户日志 $archiveLog = Join-Path $archivePath "CustomerADUsersLogs_$(Get-Date -Format ddMMyyyy_HHmmss).zip" Compress-Archive -Path $userLogPath\*.log -DestinationPath $archiveLog -Force -ErrorAction Stop "[$(Get-Date)] 已归档用户日志" | Out-File -Path $logFile -Append } } catch { $errMsg = "[$(Get-Date)] 脚本执行出错:$($_.Exception.Message)" $errMsg | Out-File -Path (Join-Path $logPath "csvdeError_$(Get-Date -Format ddMMyyyy_HHmmss).log") -Append Write-Host $errMsg }
批量删除AD用户脚本
<# 批量删除AD用户脚本:读取CSV删除用户,记录日志并归档 #> # 初始化路径与配置 $basePath = "C:\ldapexport" $logPath = Join-Path $basePath "LdapExportLog" $archivePath = Join-Path $basePath "Archives" # 确保必要目录存在 foreach ($path in ($logPath, $archivePath)) { if (-not (Test-Path $path)) { New-Item -Path $path -ItemType Directory -Force | Out-Null } } # 获取删除用户的CSV文件(匹配*deleteuser*.csv) $csvFiles = Get-ChildItem -Path $basePath -Filter *deleteuser*.csv -File try { if ($csvFiles.Count -eq 0) { $logMsg = "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] 未找到待处理的DeleteUser CSV文件" $logMsg | Out-File -Path (Join-Path $logPath "csvdeDeleteUsers_$(Get-Date -Format ddMMyyyy_HHmmss).log") -Append exit } foreach ($csvFile in $csvFiles) { $csvFullPath = $csvFile.FullName $logFile = Join-Path $logPath "csvdeDeleteUsers_$(Get-Date -Format ddMMyyyy_HHmmss).log" # 导入CSV(CSV需包含sAMAccountName字段) $users = Import-Csv -Path $csvFullPath foreach ($user in $users) { $samAccountName = $user.sAMAccountName if (-not $samAccountName) { "[$(Get-Date)] 无效的用户条目:缺少sAMAccountName" | Out-File -Path $logFile -Append continue } # 检查用户是否存在 $adUser = Get-ADUser -Filter "SamAccountName -eq '$samAccountName'" -ErrorAction SilentlyContinue if (-not $adUser) { "[$(Get-Date)] 用户 $samAccountName 不存在,跳过删除" | Out-File -Path $logFile -Append continue } # 删除用户 try { Remove-ADUser -Identity $adUser -Confirm:$false -ErrorAction Stop $msg = "[$(Get-Date)] 成功删除用户:$($adUser.Name) ($samAccountName)" $msg | Out-File -Path $logFile -Append } catch { $errMsg = "[$(Get-Date)] 删除用户 $samAccountName 失败:$($_.Exception.Message)" $errMsg | Out-File -Path $logFile -Append } } # 归档并删除CSV文件 $archiveCsv = Join-Path $archivePath "$($csvFile.BaseName)_$(Get-Date -Format ddMMyyyy_HHmmss).zip" Compress-Archive -Path $csvFullPath -DestinationPath $archiveCsv -Force -ErrorAction Stop Remove-Item -Path $csvFullPath -Force -ErrorAction Stop "[$(Get-Date)] 已归档并删除CSV文件:$($csvFile.Name)" | Out-File -Path $logFile -Append } } catch { $errMsg = "[$(Get-Date)] 脚本执行出错:$($_.Exception.Message)" $errMsg | Out-File -Path (Join-Path $logPath "csvdeDeleteError_$(Get-Date -Format ddMMyyyy_HHmmss).log") -Append Write-Host $errMsg }
内容的提问来源于stack exchange,提问作者rmon
相关产品推荐
相关产品推荐

