如何在Azure中提取VM标签的键与值并按行输出至CSV
Azure VM标签键值对CSV输出改造方案
需求说明
现有PowerShell脚本可获取Azure虚拟机(VM)的部分详情,但当前仅将VM标签的值用分号拼接后存入comments字段。需要调整脚本,将VM标签的键和值以独立行的格式输出到CSV文件,示例格式如下:
Key Value
Department MyDepartment
Application MyApp1
Created By MyName
Environment Production
现有脚本
$virtual_machine_object = $null $virtual_machine_object = @() #Iterating over the NIC Interfaces under the subscription foreach($azureNICDetail in $azureNICDetails) { #Fetching the VM Name $azureVMDetail = $azureVMDetails | ? -Property Id -eq $azureNICDetail.VirtualMachine.id #Fetching the VM Status $vm_status = get-azvm -ResourceGroupName $azureVMDetail.resourcegroupname -name $azureVMDetail.name -Status #Fetching the VM Tags $vm_tags = ($azureVMDetail.Tags.values) -join ';' #Fetching the VM Size $vmsize = Get-AzVMSize -VMName $azureVMDetail.Name -ResourceGroupName $azureVMDetail.ResourceGroupName | ? {$_.Name -eq $azureVMDetail.HardwareProfile.VmSize} #Fetching the OS Diks Size in GB $OsDisksize = $azureVMDetail.StorageProfile.OsDisk.DiskSizeGB #VM Details export $virtual_machine_object_temp = new-object PSObject $virtual_machine_object_temp | add-member -membertype NoteProperty -name "name" -Value $azureVMDetail.Name if($vm_status.Statuses[1].DisplayStatus -eq "VM running") { $vm_status.Statuses[1].DisplayStatus = "active" } else { $vm_status.Statuses[1].DisplayStatus = "offline" } $virtual_machine_object_temp | add-member -membertype NoteProperty -name "status" -Value $vm_status.Statuses[1].DisplayStatus $virtual_machine_object_temp | add-member -membertype NoteProperty -name "role" -Value $role $virtual_machine_object_temp | add-member -membertype NoteProperty -name "cluster" -Value $cluster $virtual_machine_object_temp | add-member -membertype NoteProperty -name "tenant" -Value $tenant $virtual_machine_object_temp | add-member -membertype NoteProperty -name "vcpus" -Value $vmsize.NumberOfCores $virtual_machine_object_temp | add-member -membertype NoteProperty -name "memory" -Value $vmsize.MemoryInMB $virtual_machine_object_temp | add-member -membertype NoteProperty -name "disk" -Value $OsDisksize $virtual_machine_object_temp | add-member -membertype NoteProperty -name "comments" -Value $vm_tags $virtual_machine_object += $virtual_machine_object_temp } #Report format and path $virtual_machine_object | Export-Csv "C:\Users\JOHN\Desktop\Inventory\Final Scripts\VM_details_$(get-date -f dd.MM.yyyy).csv" -NoTypeInformation -Force
修改后的脚本
$virtual_machine_object = @() # 遍历订阅下的NIC接口 foreach($azureNICDetail in $azureNICDetails) { # 获取VM详情 $azureVMDetail = $azureVMDetails | Where-Object -Property Id -eq $azureNICDetail.VirtualMachine.id # 获取VM状态 $vm_status = Get-AzVM -ResourceGroupName $azureVMDetail.resourcegroupname -Name $azureVMDetail.name -Status $status = if($vm_status.Statuses[1].DisplayStatus -eq "VM running") { "active" } else { "offline" } # 获取VM规格信息 $vmsize = Get-AzVMSize -VMName $azureVMDetail.Name -ResourceGroupName $azureVMDetail.ResourceGroupName | Where-Object {$_.Name -eq $azureVMDetail.HardwareProfile.VmSize} $OsDisksize = $azureVMDetail.StorageProfile.OsDisk.DiskSizeGB # 处理VM标签:将键值对转为独立对象 if($azureVMDetail.Tags) { foreach($tag in $azureVMDetail.Tags.GetEnumerator()) { $vm_tag_object = [PSCustomObject]@{ "VM名称" = $azureVMDetail.Name "状态" = $status "角色" = $role "集群" = $cluster "租户" = $tenant "vCPU数" = $vmsize.NumberOfCores "内存(MB)" = $vmsize.MemoryInMB "系统盘大小(GB)" = $OsDisksize "Key" = $tag.Key "Value" = $tag.Value } $virtual_machine_object += $vm_tag_object } } else { # 无标签时仍输出VM基础信息,标签字段留空 $vm_tag_object = [PSCustomObject]@{ "VM名称" = $azureVMDetail.Name "状态" = $status "角色" = $role "集群" = $cluster "租户" = $tenant "vCPU数" = $vmsize.NumberOfCores "内存(MB)" = $vmsize.MemoryInMB "系统盘大小(GB)" = $OsDisksize "Key" = $null "Value" = $null } $virtual_machine_object += $vm_tag_object } } # 导出CSV文件 $outputPath = "C:\Users\JOHN\Desktop\Inventory\Final Scripts\VM_details_$(Get-Date -f dd.MM.yyyy).csv" $virtual_machine_object | Export-Csv -Path $outputPath -NoTypeInformation -Force
关键改动说明
- 替换标签处理逻辑:不再拼接标签值,而是遍历
Tags字典的键值对(用GetEnumerator()),为每个标签生成一条独立记录 - 保留VM基础信息:每条标签记录都关联对应的VM名称、状态、规格等信息,方便关联查看
- 兼容无标签场景:当VM没有标签时,仍输出基础信息,标签字段留空
- 优化语法:将
if-else状态判断简化为一行,使用[PSCustomObject]替代New-Object提升效率
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

