PowerShell处理Hyper-V多IP/MAC虚拟机名称重复问题
解决Hyper-V虚拟机多IP/MAC时名称重复的问题
我明白你遇到的困扰了——当虚拟机有多个网卡(对应多组IP/MAC)时,原代码会重复输出虚拟机名称,这是因为你处理$virtm的逻辑没切中要害。让我帮你修正代码:
问题根源
原代码里$virtm=($out.VMName | ForEach-Object { $_ | Get-Unique }),但$out是同一个虚拟机的所有网卡记录,每条记录的VMName都是完全相同的,Get-Unique在这里无法将数组压缩成单个值,最终输出时数组会被展开成重复的名称串。
修正后的代码
$vms = Get-VM | Where { $_.State -eq 'Running' } | Select-Object -ExpandProperty Name foreach($vm in $vms) { $out = Get-VMNetworkAdapter -VMName $vm | Select-Object VMName, MacAddress, IPAddresses # 直接取第一条记录的VMName即可,同一虚拟机的所有网卡记录VMName必然一致 $virtm = $out.VMName[0] # 过滤IPv6地址(仅保留IPv4)并拼接成空格分隔的字符串 $ip = ($out.IPAddresses | ForEach-Object { $_ | Where-Object { $_ -notmatch ':' } }) -join " " # 格式化MAC地址(添加冒号分隔符)并拼接成空格分隔的字符串 $mac = ($out.MacAddress | ForEach-Object { $_.Insert(2,":").Insert(5,":").Insert(8,":").Insert(11,":").Insert(14,":") }) -join ' ' Write-Output "$virtm, $ip, $mac" }
额外优化方案
如果你想简化代码逻辑,也可以直接合并虚拟机查询与网卡信息获取的步骤,减少一次循环:
Get-VM | Where { $_.State -eq 'Running' } | ForEach-Object { $vmName = $_.Name $adapters = Get-VMNetworkAdapter -VM $_ $ipList = ($adapters.IPAddresses | Where-Object { $_ -notmatch ':' }) -join " " $macList = ($adapters.MacAddress | ForEach-Object { $_.Insert(2,":").Insert(5,":").Insert(8,":").Insert(11,":").Insert(14,":") }) -join " " Write-Output "$vmName, $ipList, $macList" }
运行修正后的代码后,就能得到你期望的输出格式:
OAP80, 192.168.1.45 192.168.2.45, 00:15:5D:58:12:5E 00:15:5D:58:12:5F
内容的提问来源于stack exchange,提问作者overflowed




