使用PowerShell从本地组提取域用户遇异常问题求助
解决本地组成员查询异常及创建含域用户本地组的方案
看起来你在迁移服务时遇到了PowerShell查询本地组成员的问题,同时需要创建包含域用户的本地组。咱们一步步来解决:
一、分析当前脚本的问题
你当前的脚本有两个核心问题:
- Members列空值:
Get-WMIObject win32_group的GetRelated("Win32_UserAccount")默认只会检索本地用户,域用户不会被包含在内,所以Members列是空的。 - 输出拆分:脚本前半段用ADSI获取成员的代码和后半段WMI查询是分开执行的,没有整合到同一输出中,导致结果混乱。
二、修正本地组成员查询(包含域用户)
如果你的PowerShell版本是5.1及以上,推荐用Get-LocalGroupMember,它能直接识别本地组里的域用户,用法更简洁:
$server = $env:COMPUTERNAME # 查询所有本地组及其成员 Get-LocalGroup -ComputerName $server | ForEach-Object { $group = $_ Get-LocalGroupMember -Group $group.Name -ComputerName $server | ForEach-Object { [PSCustomObject]@{ Server = $server GroupName = $group.Name Member = $_.Name } } } | Group-Object Server, GroupName | ForEach-Object { [PSCustomObject]@{ Server = $_.Group[0].Server GroupName = $_.Group[0].GroupName Members = $_.Group.Member -join ", " } }
如果需要兼容旧版本PowerShell,用ADSI的方式来查询(修正你的原始脚本):
$server = $env:COMPUTERNAME # 获取所有本地组 Get-WMIObject win32_group -Filter "LocalAccount='True'" -ComputerName $server | ForEach-Object { $groupPath = "WinNT://$server/$($_.Name),group" $group = [ADSI]$groupPath $members = $group.psbase.Invoke("Members") | ForEach-Object { # 解析成员名称,区分本地用户和域用户 $memberPath = $_.GetType().InvokeMember("ADsPath", 'GetProperty', $null, $_, $null) if ($memberPath -match "WinNT://(.+)/(.+)") { if ($matches[1] -eq $server) { "$server\$($matches[2])" } else { "$($matches[1])\$($matches[2])" } } } # 输出整合结果 [PSCustomObject]@{ PSComputerName = $server Name = $_.Name Members = $members -join ", " } }
三、创建本地组并添加域用户的脚本
针对你的核心需求(在新服务器创建本地组并添加域用户),可以用下面的脚本:
# 定义要创建的组和成员映射,格式:组名 = @("域\用户1", "域\用户2") $groupMembersMap = @{ "Group1" = @("Domain\User1", "Domain\User2") "Group2" = @("Domain\User2", "Domain\User3") } $server = $env:COMPUTERNAME foreach ($groupName in $groupMembersMap.Keys) { $groupPath = "WinNT://$server/$groupName,group" # 检查组是否已存在 try { $existingGroup = [ADSI]$groupPath $existingGroup.Name | Out-Null # 尝试访问属性,判断是否存在 Write-Host "组 $groupName 已存在,跳过创建" } catch { # 创建新组 $computer = [ADSI]"WinNT://$server,computer" $newGroup = $computer.Create("group", $groupName) $newGroup.SetInfo() Write-Host "成功创建组 $groupName" } # 添加域用户到组 $group = [ADSI]$groupPath foreach ($member in $groupMembersMap[$groupName]) { try { # 解析域用户路径 if ($member -match "^(.+)\\(.+)$") { $domain = $matches[1] $user = $matches[2] $memberPath = "WinNT://$domain/$user,user" $group.Add($memberPath) Write-Host "成功添加成员 $member 到组 $groupName" } else { Write-Warning "成员格式不正确:$member,需为 域\用户名 格式" } } catch { Write-Warning "添加成员 $member 失败:$_" } } }
这个脚本会先检查组是否存在,不存在则创建,然后批量添加指定的域用户到对应组里,完全满足你迁移时的需求。
内容的提问来源于stack exchange,提问作者blfuentes
相关产品推荐
相关产品推荐

