PowerShell使用Winforms ListView控件实现AD用户组多列展示问题
WinForm ListView Details模式多列填充逻辑说明
首先明确核心规则:
- ListView的Details视图是按行加载数据的,无法直接整列填充数据
- 每一行对应一个
ListViewItem对象:ListViewItem.Text属性对应第一列的显示内容ListViewItem.SubItems集合从索引1开始,依次对应第二列、第三列...的显示内容
- 如果你需要两个独立滚动的列表(一列全是AD用户、一列全是AD组),不要用单个ListView的两列实现,应该放两个独立的ListView控件并排布局。
你现有代码的问题
你现在的写法每次调用$Listview.Items.Add()都会新增一行,所以实际运行效果是:
- 先新增N行(N为AD用户总数),每行第一列固定为
AD User list,第二列为对应用户名 - 再新增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
相关产品推荐
相关产品推荐

