You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PowerShell从本地组提取域用户遇异常问题求助

解决本地组成员查询异常及创建含域用户本地组的方案

看起来你在迁移服务时遇到了PowerShell查询本地组成员的问题,同时需要创建包含域用户的本地组。咱们一步步来解决:

一、分析当前脚本的问题

你当前的脚本有两个核心问题:

  1. Members列空值:Get-WMIObject win32_group的GetRelated("Win32_UserAccount")默认只会检索本地用户,域用户不会被包含在内,所以Members列是空的。
  2. 输出拆分:脚本前半段用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:09:06