Invoke-Command 是什么
Invoke-Command 把一段脚本或一个脚本文件送到目标主机上执行,并把结果对象带回来。它最实用的地方在于「一次写、批量跑」:把主机名写成数组,一条命令就能在多台机器上完成同一件事,返回的结果会自动带上来源主机名这一列,直接分组或导出就是一份全量报告。执行依赖远程管理通道,所以前提是目标主机已启用相应服务且网络与权限到位;脚本块里引用外部变量需要显式传参,否则取到的是空值。
基本信息
| 适用平台 | Windows PowerShell 5.1 与 PowerShell 7 及以上 |
|---|---|
| 语法 | Invoke-Command -ComputerName a,b -ScriptBlock { ... } [-ThrottleLimit n] [-ArgumentList 参数] |
| 执行文件 | 用文件参数指定脚本路径,适合较长的部署脚本 |
| 结果特征 | 返回对象带来源主机名列,可按主机分组统计 |
| 依赖条件 | 目标主机启用远程管理、防火墙放行、账号具备相应权限 |
| 错误控制 | 用错误变量收集失败信息,避免整批中断 |
典型使用场景
- 批量查询服务状态、磁盘空间或补丁版本,汇总成一份巡检报告
- 批量执行部署脚本,把参数随命令一起传过去
- 汇总失败清单:收集错误变量,统计哪些主机没有执行成功
- 临时排障:在目标主机上直接读取日志或进程信息,不必逐台登录
- 控制并发:对上百台主机时限制并发数量,避免压垮网络与管理端点
- 配合会话复用:多次操作同一批主机时减少反复握手开销
常用示例
常用示例
# 批量查询服务状态并带上主机名
$hosts = 'app01','app02','app03'
Invoke-Command -ComputerName $hosts -ScriptBlock { Get-Service -Name W3SVC | Select-Object Status, StartType } |
Select-Object PSComputerName, Status, StartType
# 执行脚本文件并传参
Invoke-Command -ComputerName $hosts -FilePath .\deploy.ps1 -ArgumentList 'v1.2'
# 收集错误:不让单台失败中断整批
Invoke-Command -ComputerName $hosts -ScriptBlock { throw 'test' } -ErrorVariable errs -ErrorAction SilentlyContinue
$errs.Count
# 限制并发,控制对目标端的压力
Invoke-Command -ComputerName $hosts -ScriptBlock { Get-Date } -ThrottleLimit 8
# 引用外部变量要用传参
$path = 'D:\Logs'
Invoke-Command -ComputerName $hosts -ScriptBlock { Get-ChildItem $using:path }参数与注意事项
| 参数 | 作用 | 注意点 |
|---|---|---|
| -ComputerName | 指定目标主机列表 | 主机名需可解析且通道可达 |
| -ScriptBlock | 要执行的脚本块 | 写短逻辑最方便 |
| -FilePath | 执行本地脚本文件 | 适合较长或需复用的脚本 |
| -ArgumentList | 向脚本传参 | 脚本块里引用外部变量必须走这条路 |
| -ThrottleLimit | 限制并发数量 | 默认并发较高,大集群要下调 |
| -ErrorVariable | 收集错误对象 | 配合静默参数避免整批中断 |
执行失败往往不是脚本问题:目标主机的远程管理服务没启动、防火墙没放行或账号权限不足,都会让整批任务失败。上线前先用一两台做试探,确认通道可用再全量执行。
脚本块在目标主机上执行,本地的变量不会自动带过去。需要传值时用参数或专用前缀显式引用,否则脚本块里取到的是空值,而结果看起来像是目标机器没有数据。