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

PowerShell使用Winforms ListView控件实现AD用户组多列展示问题

WinForm ListView Details模式多列填充逻辑说明

首先明确核心规则:

  • ListView的Details视图是按行加载数据的,无法直接整列填充数据
  • 每一行对应一个ListViewItem对象:
    • ListViewItem.Text 属性对应第一列的显示内容
    • ListViewItem.SubItems 集合从索引1开始,依次对应第二列、第三列...的显示内容
  • 如果你需要两个独立滚动的列表(一列全是AD用户、一列全是AD组),不要用单个ListView的两列实现,应该放两个独立的ListView控件并排布局。

你现有代码的问题

你现在的写法每次调用$Listview.Items.Add()都会新增一行,所以实际运行效果是:

  1. 先新增N行(N为AD用户总数),每行第一列固定为AD User list,第二列为对应用户名
  2. 再新增M行(M为AD组总数),每行第一列固定为AD Grouplist,第二列为对应组名
    完全不符合你预期的两列分别展示用户、组的需求。

修正方案(适配你原有的选用户管理组的需求)

推荐用两个独立ListView实现,逻辑更清晰,符合你的业务场景:

Add-Type -AssemblyName "System.Windows.Forms"
Add-Type -AssemblyName "System.Drawing"
Add-Type -AssemblyName PresentationFramework

Clear-Host

# 创建主窗体
$form=New-Object System.Windows.Forms.Form
$form.topmost=$true
$form.Text="AD用户组管理"
$form.Size=New-Object System.Drawing.Size(665,330)
$Form.MaximumSize=$Form.Size
$Form.MinimumSize=$Form.Size

# 用户列表标签
$userLbl=New-Object System.Windows.Forms.label
$userLbl.Location=New-Object System.Drawing.Point(5,2)
$userLbl.Font=New-Object System.Drawing.Font("Comic Sans MS",10,[System.Drawing.FontStyle]::Regular)
$userLbl.Text="AD用户列表"
$userLbl.AutoSize=$true

# 用户ListView
$userListView = New-Object System.Windows.Forms.ListView 
$userListView.Location = New-Object System.Drawing.Point(3,25)
$userListView.Size = New-Object System.Drawing.Size(300,256)
$userListView.Font=New-Object System.Drawing.Font("Tahoma",8,[System.Drawing.FontStyle]::regular)
$userListView.CheckBoxes=$true
$userListView.GridLines=$true
$userListView.MultiSelect=$false
$userListView.View = "Details"
$userListView.BackColor = "Black"
$userListView.ForeColor = "LightGreen"
$userListView.Columns.Add("用户名") | Out-Null
$userListView.Columns[0].Width = -2

# 加载所有AD用户
Get-ADUser -Filter * -Properties name -SearchBase "OU=TS Tech Users,DC=smallhome,DC=local" | Sort-Object name | ForEach-Object {
    $item = New-Object System.Windows.Forms.ListViewItem($_.Name)
    $userListView.Items.Add($item) | Out-Null
}

# 组列表标签
$groupLbl=New-Object System.Windows.Forms.label
$groupLbl.Location=New-Object System.Drawing.Point(310,2)
$groupLbl.Font=New-Object System.Drawing.Font("Comic Sans MS",10,[System.Drawing.FontStyle]::Regular)
$groupLbl.Text="AD组列表"
$groupLbl.AutoSize=$true

# 组ListView
$groupListView = New-Object System.Windows.Forms.ListView 
$groupListView.Location = New-Object System.Drawing.Point(310,25)
$groupListView.Size = New-Object System.Drawing.Size(300,256)
$groupListView.Font=New-Object System.Drawing.Font("Tahoma",8,[System.Drawing.FontStyle]::regular)
$groupListView.CheckBoxes=$true
$groupListView.GridLines=$true
$groupListView.MultiSelect=$false
$groupListView.View = "Details"
$groupListView.BackColor = "Black"
$groupListView.ForeColor = "LightGreen"
$groupListView.Columns.Add("组名") | Out-Null
$groupListView.Columns[0].Width = -2

# 选中用户时加载对应用户的组
$userListView.add_SelectedIndexChanged({
    $groupListView.Items.Clear()
    $selectedUser = $userListView.SelectedItems[0].Text
    if(-not $selectedUser){return}
    # 获取该用户所属的所有组
    $user = Get-ADUser -Filter {Name -eq $selectedUser} -Properties memberOf
    $userGroups = $user.MemberOf | ForEach-Object {($_ -split 'CN=|,OU=')[1]}
    # 加载所有AD组,已加入的默认勾选
    Get-ADGroup -Filter * | Sort-Object Name | ForEach-Object {
        $item = New-Object System.Windows.Forms.ListViewItem($_.Name)
        if($userGroups -contains $_.Name){
            $item.Checked = $true
        }
        $groupListView.Items.Add($item) | Out-Null
    }
})

# 控件添加到窗体
$form.Controls.AddRange(@($userLbl,$userListView,$groupLbl,$groupListView))

$form.ShowDialog() | Out-Null

原错误代码运行效果

代码运行输出结果

内容的提问来源于stack exchange,提问作者mark baker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 06:06:04