PowerCLI获取VM标签分配并自定义列输出的技术求助
PowerCLI提取虚拟机标签并重新格式化输出
我是PowerCLI新手,需要提取虚拟机(VM)的所有标签分配信息。获取信息本身不难,但调整成想要的格式很麻烦。
当前使用的代码:
Get-VM | Get-TagAssignment | select entity, Tag | sort Entity | format-table -AutoSize
当前输出格式:
| 实体(Entity) | 标签(Tag) |
|---|---|
| Server1 | VM:TagCategory1/Content1 |
| Server1 | VM:TagCategory2/Content2 |
| Server1 | VM:TagCategory3/Content3 |
| Server1 | VM:TagCategory4/Content4 |
| Server1 | VM:TagCategory5/Content5 |
| Server2 | VM:TagCategory2/Content2 |
| Server2 | VM:TagCategory3/Content3 |
| Server2 | VM:TagCategory1/Content1 |
| Server2 | VM:TagCategory4/Content4 |
| Server2 | VM:TagCategory5/Content5 |
| Server3 | VM:TagCategory2/Content2 |
| Server3 | VM:TagCategory3/Content3 |
| Server3 | VM:TagCategory1/Content1 |
| Server3 | VM:TagCategory4/Content4 |
| Server3 | VM:TagCategory5/Content5 |
| Server3 | VM:TagCategory2/Content2 |
| Server3 | VM:TagCategory3/Content3 |
| Server3 | VM:TagCategory1/Content1 |
| Server3 | VM:TagCategory4/Content4 |
| Server3 | VM:TagCategory5/Content5 |
| Server4 | VM:TagCategory2/Content2 |
| Server4 | VM:TagCategory3/Content3 |
| Server4 | VM:TagCategory1/Content1 |
| Server4 | VM:TagCategory4/Content4 |
| Server4 | VM:TagCategory5/Content5 |
可以看到,服务器名称重复,和标签一一对应;标签顺序不固定,部分服务器(比如Server3)同一分类下有多个标签。我想要去掉重复的服务器名称,把标签按分类做成自定义列,目标格式如下:
| 实体(Entity) | VM:TagCategory1 | VM:TagCategory2 | VM:TagCategory3 | VM:TagCategory4 | VM:TagCategory5 |
|---|---|---|---|---|---|
| Server1 | Content1 | Content2 | Content3 | Content4 | Content5 |
| Server2 | Content1 | Content2 | Content3 | Content4 | Content5 |
| Server3 | Content1 | Content2 | Content3 | Content4 | Content5 |
| Content1 | Content2 | Content3 | Content4 | Content5 | |
| Server4 | Content1 | Content2 | Content3 | Content4 | Content5 |
我在PowerShell/PowerCLI里做这种自定义格式表格遇到了困难,求帮助和建议。
解决方案
可以通过分组、拆分标签属性,再结合Select-Object和自定义属性来实现目标格式,具体代码如下:
# 获取所有VM的标签分配,拆分标签分类和内容 $tagData = Get-VM | Get-TagAssignment | ForEach-Object { [PSCustomObject]@{ VMName = $_.Entity.Name Category = "VM:$($_.Tag.Category.Name)" TagValue = $_.Tag.Name } } # 获取所有唯一的标签分类,作为表格列名 $allCategories = $tagData.Category | Select-Object -Unique | Sort-Object # 按VM名称分组处理标签 $groupedData = $tagData | Group-Object -Property VMName # 构建最终输出对象 $finalOutput = foreach ($group in $groupedData) { # 把当前VM的标签按分类分组,统计每个分类下的标签数量 $tagGroups = $group.Group | Group-Object -Property Category $maxRowCount = $tagGroups | Measure-Object -Property Count -Maximum | Select-Object -ExpandProperty Maximum # 为同一VM的多组标签生成对应行数 for ($i = 0; $i -lt $maxRowCount; $i++) { $outputObj = [PSCustomObject]@{ "实体(Entity)" = if ($i -eq 0) { $group.Name } else { "" } } # 为每个分类列填充对应标签值 foreach ($category in $allCategories) { $categoryTags = $tagGroups | Where-Object Name -eq $category | Select-Object -ExpandProperty Group $outputObj | Add-Member -MemberType NoteProperty -Name $category -Value ($categoryTags[$i].TagValue ?? "") } $outputObj } } # 输出格式化表格 $finalOutput | Format-Table -AutoSize
代码说明
- 先拆分每个标签的分类和内容,转换成易处理的自定义对象,避免直接解析字符串的麻烦。
- 提取所有唯一的标签分类作为表格列,确保不会遗漏任何分类。
- 按VM分组后,统计每个分类下的标签数量,生成对应行数(比如Server3有2组相同标签,就生成2行)。
- 第一行显示VM名称,后续行留空,同时填充对应位置的标签值。
如果需要导出到CSV文件,替换最后一行代码为:
$finalOutput | Export-Csv -Path "VM_Tags.csv" -NoTypeInformation -Encoding UTF8
内容的提问来源于stack exchange,提问作者NuckinFutz
相关产品推荐
相关产品推荐

