3. vSphere对象模型与PowerCLI导航

PowerCLI 的所有自动化能力,本质上都建立在 vSphere 的对象模型之上。如果把这个模型想象成一棵倒置的树,那么根节点是 vCenter Server,向下依次是数据中心、集群/主机文件夹、ESXi 主机、虚拟机、网络、存储等对象。理解这棵树的层级关系,是写出可靠脚本的第一步——因为绝大多数 Get-* 命令的返回值,都是这棵树上的某个节点或节点集合。

一、vSphere 对象层级:从 vCenter 到虚拟机

vSphere 的对象模型可以按“容器对象”和“受管对象”两类来理解。容器对象用于组织和管理,例如 Datacenter、Cluster、Folder;受管对象则是实际提供资源的实体,例如 VMHost(ESXi 主机)、VirtualMachine、Datastore、DistributedSwitch 等。它们之间的典型层级如下:

  • vCenter Server:整个清单的根,所有对象都注册在它下面。
  • Datacenter:逻辑边界,通常按机房或业务区域划分,一个 vCenter 可以有多个数据中心。
  • Cluster:计算资源池,包含多台 ESXi 主机,提供 HA、DRS 等能力;也可以不建集群,直接使用独立主机。
  • VMHost:ESXi 主机,是虚拟机实际运行的物理载体。
  • VirtualMachine:运行在主机或集群上的虚拟机实例。
  • Network / Datastore:网络与存储对象,既可能挂在数据中心级别,也可能挂在集群或主机级别。

需要特别注意的是,网络和存储对象在清单中的位置并不完全一致。标准交换机(vSwitch)和端口组通常挂在主机下,而分布式交换机(vDS)挂在数据中心下;数据存储则通常挂在数据中心下,但通过主机挂载关系被主机访问。这种“跨层级引用”是 PowerCLI 导航时最容易出错的地方。

vCenter Server Datacenter Cluster 独立 ESXi 主机 ESXi-01 ESXi-02 VM-App-01 VM-DB-01 分布式交换机 vDS 数据存储 Datastore 根对象 容器对象 计算集群 ESXi 主机 虚拟机 网络对象 存储对象

二、常用 Get-* 命令与导航路径

PowerCLI 提供了与对象层级一一对应的 Get-* 命令。掌握这些命令的返回类型和参数,就能像在图形界面中点击一样,在命令行中逐层导航。

对象层级常用命令典型用途
vCenterConnect-VIServer建立会话,后续命令的上下文
DatacenterGet-Datacenter列出所有数据中心,按名称过滤
ClusterGet-Cluster获取集群对象,查看 HA/DRS 配置
VMHostGet-VMHost列出主机,按集群或连接状态过滤
VirtualMachineGet-VM列出虚拟机,按主机、电源状态过滤
NetworkGet-VirtualSwitch / Get-VDPortgroup查看标准交换机与分布式端口组
DatastoreGet-Datastore查看存储容量、类型与挂载主机

这些命令之间可以通过管道自然衔接。例如,要查看某个集群下所有主机的名称和版本,可以这样写:

Connect-VIServer -Server vcsa01.lab.local -User administrator@vsphere.local

Get-Cluster -Name "Prod-Cluster" |
  Get-VMHost |
  Select-Object Name, Version, ConnectionState, NumCpu, MemoryTotalGB

这里的关键在于:Get-Cluster 返回的是集群对象,而 Get-VMHost 接受集群对象作为管道输入,自动返回该集群下的所有主机。这种“对象管道”是 PowerCLI 区别于普通文本命令行的核心特征。

三、用 -Name、-Location 与 Where-Object 精确定位

实际环境中对象数量往往很多,直接 Get-VM 会返回成百上千条记录。此时需要组合使用参数过滤和 Where-Object 进行精确筛选。常见做法有三种:

  1. 按名称通配:Get-VM -Name "Web-*",适合命名规范统一的场景。
  2. 按位置限定:Get-VM -Location (Get-Cluster "Prod-Cluster"),把范围缩小到某个集群或主机。
  3. 按属性筛选:Get-VM | Where-Object {$_.PowerState -eq "PoweredOn" -and $_.NumCpu -gt 4},适合复杂条件。

需要注意的是,-Location 参数对不同类型的对象含义不同:对虚拟机来说,它可以是集群、主机或文件夹;对主机来说,它通常是集群或数据中心。使用前建议先用 Get-Help Get-VM -Parameter Location 确认参数类型。

实用技巧:在编写脚本前,先用 Get-VM | Get-Member 查看对象有哪些属性,再用 Select-Object 只保留需要的字段。这样既能减少输出噪音,也能避免在后续逻辑中引用不存在的属性。

四、对象引用与跨层级查询

vSphere 对象之间除了父子关系,还存在引用关系。例如,一台虚拟机通过 VMHost 属性引用所在主机,通过 DatastoreIdList 引用所用存储,通过 NetworkAdapters 引用网络适配器。PowerCLI 允许直接展开这些引用:

Get-VM -Name "VM-App-01" |
  Select-Object Name,
    @{N="Host";E={$_.VMHost.Name}},
    @{N="Cluster";E={$_.VMHost.Parent.Name}},
    @{N="Datastores";E={($_.DatastoreIdList | Get-Datastore).Name -join ", "}}

这段代码展示了从虚拟机反向导航到主机、集群和存储的路径。理解这种双向导航能力,才能在排障时快速回答“这台虚拟机到底跑在哪台主机、用了哪个存储”这类问题。

注意:当对象数量较大时,频繁在 ForEach-Object 中调用 Get-Datastore 等命令会造成大量重复查询,显著拖慢脚本。更高效的做法是先一次性获取所有数据存储并建立哈希表,再在循环中查表引用。

五、导航检查清单

在编写任何批量操作脚本之前,建议按以下顺序完成一次导航确认:

  • 确认已连接正确的 vCenter,并检查 $global:DefaultVIServer 的 Name 与 Version。
  • 用 Get-Datacenter、Get-Cluster、Get-VMHost 逐层确认目标对象存在且名称拼写正确。
  • 用 -WhatIf 或先只输出 Select-Object Name 验证筛选结果数量是否符合预期。
  • 确认对象属性名称,避免在脚本中引用已废弃或拼写错误的属性。
  • 对跨层级查询,先在小范围(单集群、单主机)验证,再扩展到全量。

掌握对象模型与 Get-* 导航,相当于拿到了 vSphere 自动化的“地图”。后续无论是批量创建虚拟机、调整集群配置,还是做资源报表,都离不开在这棵对象树上准确定位目标节点。