PowerShell脚本优化:查询到同名AD用户时支持手动选择
解决AD同名用户选择问题的PowerShell脚本优化
刚接触PowerShell就能写出带GUI的脚本已经很棒了!针对你遇到的“同名用户全部被添加”的问题,我帮你优化了脚本,现在当查询到多个匹配的AD用户时,会弹出一个选择窗口让你挑选正确的用户,确认后再执行添加操作。
核心优化点
- 唯一匹配自动处理:如果查询到唯一对应的AD用户,直接执行添加,无需额外操作
- 多匹配用户选择:当返回多个同名用户时,弹出列表窗口展示用户的
DisplayName、SamAccountName和UserPrincipalName(帮你区分不同用户),手动选择后再添加 - 异常场景提示:处理空用户名、安全组不存在、用户未找到等情况,弹出友好提示避免遗漏问题
完整优化后的脚本
Import-Module ActiveDirectory [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") # 主窗口创建 $Form = New-Object System.Windows.Forms.Form $Form.Text = "Security Group Tool" $Form.Size = New-Object System.Drawing.Size(390,150) $Form.StartPosition = "CenterScreen" $Form.KeyPreview = $True $Form.MaximumSize = $Form.Size $Form.MinimumSize = $Form.Size try { $Icon = New-Object System.Drawing.Icon("H:\test\favicon.ico") $Form.Icon = $Icon } catch { # 图标不存在时不中断脚本,使用默认图标 Write-Host "图标文件未找到,将使用系统默认图标" } $label = New-Object System.Windows.Forms.Label $label.Location = New-Object System.Drawing.Size(10, 10) $label.Size = New-Object System.Drawing.Size(360, 15) $label.Text = "Please enter The name of the Security Group You want to add users too" $Form.Controls.Add($label) $textbox = New-Object System.Windows.Forms.TextBox $textbox.Location = New-Object System.Drawing.Size(10,50) $textbox.Size = New-Object System.Drawing.Size(240,40) $Form.Controls.Add($textbox) # 核心业务逻辑:处理用户查询与添加,新增选择分支 $test = { $secgrp = $textbox.Text.Trim() # 校验安全组名称是否为空 if (-not $secgrp) { [System.Windows.Forms.MessageBox]::Show("请输入安全组名称!", "提示", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Warning) return } # 校验安全组是否存在于AD中 try { Get-ADGroup -Identity $secgrp -ErrorAction Stop | Out-Null } catch { [System.Windows.Forms.MessageBox]::Show("指定的安全组不存在!", "错误", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error) return } $names = Import-Csv "H:\test\Groups2.csv" foreach ($name in $names.DisplayName) { $cleanName = $name.Trim() if (-not $cleanName) { continue } # 跳过空的DisplayName条目 # 查询匹配的AD用户,获取完整属性用于区分 $matchedUsers = Get-ADUser -Filter { DisplayName -like $cleanName } -Properties DisplayName, SamAccountName, UserPrincipalName | Sort-Object SamAccountName switch ($matchedUsers.Count) { 0 { [System.Windows.Forms.MessageBox]::Show("未找到匹配DisplayName为`"$cleanName`"的用户!", "提示", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Information) } 1 { # 唯一匹配,直接执行添加 try { Add-ADGroupMember -Identity $secgrp -Members $matchedUsers.SamAccountName -ErrorAction Stop Write-Host "已添加用户 $($matchedUsers.SamAccountName) 到组 $secgrp" } catch { [System.Windows.Forms.MessageBox]::Show("添加用户 $($matchedUsers.SamAccountName) 失败:$_", "错误", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error) } } default { # 多用户匹配,弹出选择窗口 $selectForm = New-Object System.Windows.Forms.Form $selectForm.Text = "选择用户 - $cleanName" $selectForm.Size = New-Object System.Drawing.Size(500,300) $selectForm.StartPosition = "CenterScreen" $selectForm.TopMost = $true $listBox = New-Object System.Windows.Forms.ListBox $listBox.Location = New-Object System.Drawing.Size(10,10) $listBox.Size = New-Object System.Drawing.Size(460,220) $listBox.SelectionMode = "One" # 添加用户信息到列表,展示多维度标识便于区分 foreach ($user in $matchedUsers) { $listBox.Items.Add("$($user.DisplayName) | $($user.SamAccountName) | $($user.UserPrincipalName)") } $selectForm.Controls.Add($listBox) # 确认选择按钮 $okBtn = New-Object System.Windows.Forms.Button $okBtn.Location = New-Object System.Drawing.Size(150,240) $okBtn.Size = New-Object System.Drawing.Size(100,30) $okBtn.Text = "确认选择" $okBtn.Add_Click({ if ($listBox.SelectedIndex -ge 0) { # 提取选中用户的SamAccountName $selectedItem = $listBox.SelectedItem.ToString() $selectedSam = ($selectedItem -split '\|')[1].Trim() try { Add-ADGroupMember -Identity $secgrp -Members $selectedSam -ErrorAction Stop Write-Host "已选择并添加用户 $selectedSam 到组 $secgrp" $selectForm.Close() } catch { [System.Windows.Forms.MessageBox]::Show("添加用户 $selectedSam 失败:$_", "错误", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error) } } else { [System.Windows.Forms.MessageBox]::Show("请选择一个用户!", "提示", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Warning) } }) $selectForm.Controls.Add($okBtn) # 取消按钮 $cancelBtn = New-Object System.Windows.Forms.Button $cancelBtn.Location = New-Object System.Drawing.Size(260,240) $cancelBtn.Size = New-Object System.Drawing.Size(100,30) $cancelBtn.Text = "取消" $cancelBtn.Add_Click({ $selectForm.Close() }) $selectForm.Controls.Add($cancelBtn) $selectForm.Add_Shown({ $selectForm.Activate() }) [void] $selectForm.ShowDialog() } } } # 所有用户处理完成后提示 [System.Windows.Forms.MessageBox]::Show("用户添加操作已完成!", "完成", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Information) } $OKButton = New-Object System.Windows.Forms.Button $OKButton.Location = New-Object System.Drawing.Size(260,45) $OKButton.Size = New-Object System.Drawing.Size(75,30) $OKButton.Text = "OK" $OKButton.Add_Click($test) $Form.Controls.Add($OKButton) $Form.Add_KeyDown({ if ($_.KeyCode -eq "Enter") { & $test } }) $Form.Add_KeyDown({ if ($_.KeyCode -eq "Escape") { $Form.Close() } }) $Form.TopMost = $True $Form.Add_Shown({ $Form.Activate() }) [void] $Form.ShowDialog()
额外优化说明
我还加了几个实用的小功能:
- 安全组存在性校验,避免输入错误组名导致批量操作失败
- 跳过CSV中的空DisplayName条目,减少无效操作
- 错误捕获与提示,操作失败时能看到具体原因
- 图标加载容错,即使图标文件不存在也不影响脚本运行
内容的提问来源于stack exchange,提问作者James Marshall
相关产品推荐
相关产品推荐

