
简介这套用于vSphere环境的PowerShell模块集合是VMware官方推出的期望状态配置DSC管理工具面向需要自动化配置虚拟机和相关资源的系统管理员与运维工程师。它通过声明式配置文件定义系统期望状态并自动应用到vSphere环境从而减少手动配置错误、提升标准化水平。资源包共735个文件以616个PowerShell脚本.ps1为主辅以Markdown文档、模块清单.psm1/.psd1及说明文件完整覆盖了VMware_vSphereDSC与VMware_PSDesiredStateConfig两大核心模块压缩包仅1.91MB。除了模块本体还包含使用技巧、编码规范、贡献指南等文档并附赠DOCX版说明方便快速上手非常适合希望利用PowerShell DSC简化vSphere管理的中高级运维人员目前已有177人学习下载。1. 为什么 vSphere 运维会需要一套 PowerShell 实现的 DSC 模块集合当你面对几十台甚至上百台虚拟机要统一调整内存预留、批量创建端口组、确保每台虚拟机都接入指定网络时依次在 vSphere Client 里点鼠标不仅慢而且极易漏掉一两台。期望状态配置DSC解决的就是这个“期望状态”的描述问题把最终状态写成代码让机器自己去对齐。标题里的 VMware.vSphereDSC 和 VMware.PSDesiredStateConfiguration就是 VMware 为 vSphere 环境准备的 PowerShell DSC 资源集合让管理员可以用声明式脚本管理虚拟机、主机、网络等对象。这篇文章会把“这套模块怎么装、怎么写、怎么排错”完整过一遍适合已经能用 PowerCLI 做批量操作的工程师也适合刚接触 DSC 但想直接落地到 vSphere 的新手。内容围绕实际环境能跑通的最小路径展开不绕理论。2. 理解 vSphereDSC 之前先拆开 DSC 的 LCM、MOF 与资源供应商2.1 DSC 的运行机制LCM 把 MOF 文件当成“对齐目标”PowerShell DSC 的核心思路是声明式配置脚本里不写“先连接 vCenter 再创建虚拟机”这样的过程式步骤而是声明“这台虚拟机的内存是 4096MB、状态是开机”这样的最终结果。DSC 会把这段声明编译成一个 MOFManaged Object Format文件然后交给目标机器上的 LCMLocal Configuration Manager去执行。LCM 负责对比当前状态与 MOF 中的期望状态不一致就调用资源供应商的Set方法去改一致就直接跳过。在 vSphere 场景里LCM 运行在哪台机器上决定了你的 DSC 脚本怎么设计。常见做法是在一台能访问 vCenter 的 Windows 跳板机或运维服务器上装好 PowerShell 5.1 及以上版本以这台机器作为 DSC 执行节点通过 VMware.vSphereDSC 里的资源去操作远程的 vCenter。这与传统 DSC 在目标节点本机做配置的模式不同因为虚拟机的“期望状态”并不由虚拟机内部决定而是由 vCenter 统一管理。2.2 VMware.vSphereDSC 与 VMware.PSDesiredStateConfiguration 各自管什么从包名可以看出来这个 zip 里包含了两个模块。VMware.vSphereDSC 是真正的 vSphere 资源库它提供VMwareVM、VMwareHost、VMwareVSwitch、VMwarePortGroup等资源每个资源对应 vSphere 里的一个或一类对象。VMware.PSDesiredStateConfiguration 则是 DSC 引擎相关的支撑模块在 PowerShell 5.1 环境中系统自带的PSDesiredStateConfiguration模块已经提供了 LCM 和编译器但离线安装或特定版本环境下你很可能需要把 VMware 打包的这个版本一并导入避免因为模块缺失导致配置编译失败。安装模块之后我一般会先执行下面这段命令确认资源可用Get-ChildItem -Path $env:ProgramFiles\WindowsPowerShell\Modules\VMware.vSphereDSC -Recurse -Filter *.psd1 | Select-Object FullName Import-Module VMware.vSphereDSC -Verbose Get-DscResource -Module VMware.vSphereDSC逻辑说明第一条命令查看模块目录下是否存在模块清单文件.psd1确认包解压路径正确第二条命令导入模块-Verbose用于观察依赖模块加载过程第三条命令列出该模块注册的所有 DSC 资源这一步能帮你确认当前版本支持哪些资源名称避免后边写脚本时用错资源名。参数说明如果Get-DscResource返回为空优先检查 PowerShell 执行策略是否限制了模块加载用Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass临时放行其次检查模块目录是否在PSModulePath里可以用$env:PSModulePath查看。常见可用资源大致如下表资源名管理对象常见用途VMwareVM虚拟机调整 CPU、内存、开机状态、CD/DVD 挂载VMwareHostESXi 主机主机维护模式、NTP 配置VMwareVSwitch虚拟交换机标准交换机属性VMwarePortGroup端口组端口组创建、VLAN ID 绑定VMwareVMHostAccount主机本地账号批量创建本地用户需要说明的是不同版本模块提供的资源名称可能有差异以上是使用频率较高的几个具体以Get-DscResource的输出为准。2.3 离线环境下安装这套 PowerShell 模块集合的最小步骤对于很多生产环境跳板机和外网是隔离的。标题给出的 zip 包本身就是离线分发的形式安装路径一般是C:\Program Files\WindowsPowerShell\Modules每个模块一个独立子目录。如果用Install-Module从 PowerShell Gallery 安装则要求能访问外网两端做法不同生产环境我更推荐离线方式因为版本可控。$modulesRoot C:\Program Files\WindowsPowerShell\Modules Expand-Archive -Path C:\Packages\VMware_vSphereDSC.zip -DestinationPath $env:TEMP -Force Copy-Item -Path $env:TEMP\VMware.vSphereDSC -Destination $modulesRoot\VMware.vSphereDSC -Recurse -Force Copy-Item -Path $env:TEMP\VMware.PSDesiredStateConfiguration -Destination $modulesRoot\VMware.PSDesiredStateConfiguration -Recurse -Force逻辑说明先把 zip 解压到临时目录再分别拷贝两个模块目录到当前用户的模块根目录。这里没有使用Install-Module因为 DSC 资源模块不注册服务只是文件放置PowerShell 在导入时会按目录名去PSModulePath中查找。拷贝完成后新开的 PowerShell 进程里执行Get-Module -ListAvailable VMware.*验证。参数说明$env:ProgramFiles\WindowsPowerShell\Modules是系统级模块目录写入需要管理员权限如果当前用户没权限可以改用$HOME\Documents\WindowsPowerShell\Modules作用域仅限当前用户。部署到多台机器时直接把整个目录复制过去即可不需要重新执行安装程序。3. 用 VMware.vSphereDSC 写第一份 vSphere 状态配置脚本3.1 准备 PowerCLI 连接环境与运行上下文写配置脚本之前先把依赖理顺。VMware.vSphereDSC 底层要连接 vCenter它本质上是封装了 VMware PowerCLI 的调用逻辑所以机器上需要安装VMware.PowerCLI模块并且版本与 vCenter 版本兼容。很多人在这一步踩坑DSC 配置脚本本身没问题但Set-DscConfiguration执行时报“无法加载 VMware VimAutomation.Core”就是因为 PowerCLI 没装好。Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Scope Session -Confirm:$false Import-Module VMware.PowerCLI -MinimumVersion 12.0 Connect-VIServer -Server vc.example.com -User dsc-account -Password 主密码逻辑说明第一行忽略证书校验如果 vCenter 用的是自签名证书PowerCLI 默认会阻止连接第二行导入 PowerCLI 并声明最低版本防止旧版导致的参数不兼容第三行先手动连接一次 vCenter目的是验证凭据和网络可达性。DSC 脚本内部执行时模块会复用当前会话或自行建立会话取决于是用Server参数传 vCenter 地址还是依赖默认连接这块在后面的资源参数里再细说。参数说明dsc-account建议使用 vCenter 里权限受限的专用账号至少要有虚拟机、网络和主机相关权限。生产环境不要在这里写明文密码具体做法见第 4 章。3.2 定义VMwareVM资源把虚拟机状态写成声明式配置下面这段配置的目标是确保web-01这台虚拟机存在且处于开机状态内存被调整为 4096MBCPU 核数为 4并接入指定端口组。在 DSC 配置块里每个资源都有一个实例名这个名称可以是任意字符串但为了日志清晰我一般直接用虚拟机名字。Configuration vSphereBaseline { Import-DscResource -ModuleName VMware.vSphereDSC param( [Parameter(Mandatory)] [PSCredential] $Credential ) Node localhost { VMwareVM web-01 { Server vc.example.com Credential $Credential Name web-01 Ensure Present State PoweredOn MemoryMB 4096 CpuCount 4 PortGroupName production-101 } } }逻辑说明Configuration关键字是 DSC 的入口编译后会生成一个同名函数Import-DscResource指明使用 VMware.vSphereDSC 模块里的资源类型Node localhost表示在本地机器上执行 LCM 操作由于 vSphere 对象在远端这个 localhost 指的是执行配置的跳板机VMwareVM资源段落里Ensure控制虚拟机是否存在State控制电源状态两者的区别要分清Ensure Present表示创建或保留Ensure Absent表示删除State只是在虚拟机存在的前提下设置电源状态。参数说明MemoryMB是整数单位是 MB4096 就是 4GBCpuCount是插槽上的核心数总和需要注意与 vCenter 中“每个插槽的内核数”参数存在换算关系如果虚拟机设置为 2 插槽 2 核则应写CpuCount 4并配合CoresPerSocket 2本例只设置总数vCenter 会按默认插槽数分配。PortGroupName指定的端口组必须已存在于目标主机或分布式交换机上否则资源应用时会报错。3.3 编译与应用从.ps1配置到 MOF 再到执行的完整命令写完配置文件后保存为vSphereBaseline.ps1然后执行编译和部署。这一步要区分两个环节编译会把配置脚本生成 MOF 文件夹应用则让 LCM 读取 MOF 并开始对齐状态。很多初学者在这里遗漏-Path参数或-Wait参数导致 MOF 生成了但没真正推送。# 当前目录下执行点然后用编译 . .\vSphereBaseline.ps1 $cred Get-Credential -UserName dsc-accountvsphere.local -Message 请输入 vCenter 凭据 vSphereBaseline -Credential $cred -OutputPath .\vSphereBaseline_Output逻辑说明第一行把配置函数加载到当前会话第二行弹出凭据输入框第三行调用配置函数生成 MOF 文件到指定输出目录。生成后目录下会有一个localhost.mof文件这就是 LCM 要消费的格式。应用阶段有两种方式Push 模式和 Pull 模式。vSphereDSC 场景下绝大多数人用的是 Push 模式命令如下Start-DscConfiguration -Path .\vSphereBaseline_Output -Wait -Verbose -Force逻辑说明-Path指向包含 MOF 文件的目录-Wait让命令同步等待配置完成不加上它命令会立即返回但配置仍在后台跑-Verbose输出详细日志方便观察资源执行到哪一步-Force强制重新应用即使当前状态已经一致也会再跑一遍校验排错时尤其有用。参数说明如果只改了一台虚拟机的属性不必重新生成全部 MOF直接改配置脚本后重新编译再执行Start-DscConfiguration即可-Force会覆盖旧配置。执行完成后用Get-DscConfigurationStatus查看上一次配置的一致性结果Success表示资源应用全部正确Failed则需要看Status里的错误信息通常是凭据错误或 SSL 证书问题。4. 权限、凭据与常见排错让 DSC 在 vSphere 里稳定跑起来4.1 凭据安全传递避免把密码写在配置脚本里第 3 章的示例里凭据通过参数传入这是最基础的安全做法。但还有一个坑MOF 文件里面、配置时会以明文形式存放凭据如果Start-DscConfiguration的 MOF 目录被其他低权限用户读到vCenter 密码就泄露了。生产环境我一般会做两层处理一是在配置函数里使用PsDscAllowPlainTextPassword显式声明这是实验环境二是对 MOF 文件加密只允许系统账户读取。Configuration vSphereBaseline { Import-DscResource -ModuleName VMware.vSphereDSC param([PSCredential]$Credential) Node localhost { VMwareVM web-01 { Server vc.example.com Credential $Credential Name web-01 Ensure Present State PoweredOn MemoryMB 4096 CpuCount 4 PortGroupName production-101 PsDscAllowPlainTextPassword $true } } }逻辑说明PsDscAllowPlainTextPassword $true这个参数告诉编译器允许明文密码出现在 MOF 中。如果不加编译时会直接报错提示需要证书加密凭据。这个参数只影响编译阶段不改变运行时的行为。实际环境中建议用证书方式加密 MOF配置示例改为$cert Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Subject -like *DSC* } vSphereBaseline -Credential $cred -CertificateId $cert.Thumbprint -OutputPath .\Output参数说明-CertificateId指定用于加密凭据的证书指纹编译后的 MOF 中凭据就是密文。LCM 执行时会使用机器账户自动解密。证书需要提前部署到执行 DSC 的这台机器上并在信任链上有效。如果没有现成的内部 CA 证书也可以用New-SelfSignedCertificate生成一张但需要手动信任。4.2 三类高发错误与对应检查路径vSphereDSC 报错大多数集中在这几类模块找不到、vCenter 连不上、资源参数不正确。下面这张表总结了我实际处理过的问题与排查顺序错误现象可能原因排查命令或操作导入模块提示“找不到指定的模块”模块目录不在 PSModulePath 内检查模块目录名是否与模块名完全一致无法验证 SSL 证书vCenter 证书是自签发的执行Set-PowerCLIConfiguration -InvalidCertificateAction Ignore其中的资源不识别“Ensure”属性模块版本过旧或资源名错误执行Get-DscResource重新确认参数集连接 vCenter 超时凭据缺少必要权限用 PowerCLI 手动执行Connect-VIServer复现4.3 用 vCenter 任务记录反推配置生效情况DSC 执行完毕只是表示“LCM 调用了资源方法”并不代表 vCenter 端操作成功。资源模块内部如果调用了New-VM或Set-VM命令vCenter 会留下任务记录。当Start-DscConfiguration -Verbose显示服务模块执行成功了但虚拟机和预期不一致就应该去 vCenter 的事件控制台确认。Get-VIEvent -Server vc.example.com -Start (Get-Date).AddMinutes(-10) | Where-Object { $_.FullFormattedMessage -match web-01 } | Select-Object -First 10 FullFormattedMessage, CreatedTime, UserName逻辑说明Get-VIEvent拉取最近十分钟内 vCenter 的事件过滤出与web-01相关的记录用来确认是哪个账号在什么时间对虚拟机做了什么操作。如果事件记录显示操作来自你的 dsc-account说明资源调用已经下发如果事件列表里根本没有记录说明 LCM 虽然报告成功但实际没有把指令送到 vCenter此时优先检查Start-DscConfiguration执行时是否仍然维持着 vCenter 会话。参数说明-Start是过滤条件事件多时可以扩到AddMinutes(-30)UserName字段看到dsc-account就说明指令来源正确。如果看到SYSTEM或其他账号就要检查是不是有其他自动化任务在同时操作同一台虚拟机避免状态互相覆盖。5. 进阶用法把Test-DscConfiguration变成 vSphere 配置漂移巡检工具最后一章不谈新资源讲一个直接能用的技巧用Test-DscConfiguration对一组虚拟机做配置漂移巡检。DSC 的Test方法会检查当前状态是否与 MOF 期望状态一致不一致就返回$false一致返回$true。vSphere 环境里的配置漂移很容易发生比如有人通过 vSphere Client 手动调整了内存或者此前某次变更没有通过配置管理流程利用 DSC 巡检能很快找出来。# 针对已经生成的配置输出目录执行测试 $status Test-DscConfiguration -Path .\vSphereBaseline_Output -Detailed if ($status.InDesiredState) { Write-Host 全部一致 } else { $status.Resources | Where-Object { -not $_.InDesiredState } | ForEach-Object { Write-Host $_.ResourceId } }逻辑说明-Detailed让返回值携带每个资源的状态细节Resources数组中的InDesiredState字段会标记单个资源是否满足配置。对于巡检场景我一般会把它包在一个循环里对多个 MOF 目录逐个执行输出结果汇总到 CSV 文件然后接到现有的监控告警里。参数说明Test-DscConfiguration -Path只做测试不会对系统做任何修改所以可以安全地放到计划任务中每天运行。如果希望脚本在发现漂移后自动修复可改用Start-DscConfiguration -Path ... -Wait但生产环境建议只告警不做自动修复因为漂移的优先级需要人工判断。巡检脚本里加上-Verbose每条资源的测试结果会输出到日志文件。这个用法在虚拟机数量多、环境变更频繁的场景里收益最大。把模块导入、连 vCenter、加载 MOF 的过程封装成一个计划任务脚本固定每日凌晨执行第二天早上一封邮件就能知道前一天有没有人绕过配置管理直接改了虚拟机。如果你已经用 PowerCLI 在做 vSphere 运维自动化这套 DSC 巡检逻辑可以无缝并进去。本文还有配套的精品资源点击获取