PowerShell批量查询vCenter虚拟机Windows激活状态并格式化输出
实现方案
以下提供两种可行实现方式,你可以按需选择:
方式一:批量调用(推荐,执行效率更高)
Invoke-Command本身支持批量传入目标主机列表并行执行,返回结果会自动附加PSComputerName字段标识数据来源机器,不需要手动做额外处理:
# 假设你第一步获取的已开机Windows虚拟机列表存在 $vmList 变量中,$vmList.Name 为虚拟机可解析的主机名 $licenseData = Invoke-Command -ComputerName $vmList.Name -ScriptBlock { Get-CimInstance SoftwareLicensingProduct -Filter "Name like 'Windows%'" | Where-Object { $_.PartialProductKey } | Select-Object Description, LicenseStatus } -ErrorAction SilentlyContinue # 格式化输出为要求的字段,同时把许可证状态从数字转成可读文本 $licenseData | Select-Object ` @{Name = '机器名'; Expression = {$_.PSComputerName}}, @{Name = '描述'; Expression = {$_.Description}}, @{Name = '许可证状态'; Expression = { switch ($_.LicenseStatus) { 0 { "未激活" } 1 { "已激活" } 2 { "试用期" } 3 { "延期试用期" } 4 { "未授权" } default { "未知状态" } } }} | Format-Table -AutoSize
如果需要导出为CSV文件,把最后一行的Format-Table -AutoSize替换为Export-Csv -Path "C:\Windows授权状态.csv" -Encoding UTF8 -NoTypeInformation即可。
方式二:foreach循环逐台处理
如果你需要逐台控制执行逻辑、单独处理每台机器的连接异常,可以用foreach循环实现:
$outputResult = @() foreach ($vm in $vmList) { $currentVmName = $vm.Name try { # 对当前虚拟机执行查询 $licInfo = Invoke-Command -ComputerName $currentVmName -ScriptBlock { Get-CimInstance SoftwareLicensingProduct -Filter "Name like 'Windows%'" | Where-Object { $_.PartialProductKey } | Select-Object Description, LicenseStatus } -ErrorAction Stop # 构造自定义输出对象,手动加入机器名字段 $outputResult += [PSCustomObject]@{ 机器名 = $currentVmName 描述 = $licInfo.Description 许可证状态 = switch ($licInfo.LicenseStatus) { 0 { "未激活" } 1 { "已激活" } 2 { "试用期" } 3 { "延期试用期" } 4 { "未授权" } default { "未知状态" } } } } catch { # 连接/查询失败的机器单独标记 $outputResult += [PSCustomObject]@{ 机器名 = $currentVmName 描述 = "远程连接失败/无权限查询" 许可证状态 = "无数据" } } } # 输出最终结果 $outputResult | Format-Table -AutoSize
注意事项
- 执行脚本的设备需要和所有目标虚拟机网络连通,且目标虚拟机已开启WinRM服务,当前执行账号有远程管理权限
- 如果虚拟机名称无法被DNS解析,可以将
$vm.Name替换为虚拟机的Guest OS内网IP地址 - 加入
-ErrorAction SilentlyContinue或try-catch逻辑是为了避免单台机器连接失败导致整个脚本中断
内容的提问来源于stack exchange,提问作者Dan Lewis
相关产品推荐
相关产品推荐

