首页/系统/Windows 运维速查/Invoke-Expression 执行字符串命令
PowerShell 基础66 条

Invoke-Expression 执行字符串命令

把字符串当命令执行(类似 eval),灵活但风险高:涉及外部输入时可能造成命令注入。

Windows 运维速查系统更新于 2026-10-13

Invoke-Expression 是干什么的

Invoke-Expression(别名 iex)把一段字符串当作 PowerShell 代码来执行,效果类似其他语言的 eval。它的存在价值是执行动态拼出来的命令,代价是失去了静态解析与语法检查:命令里的错误只有运行时才暴露,而如果把外部输入拼进字符串再交给 iex,就等于把任意代码执行的入口交给了外部。

基本信息

适用平台Windows PowerShell 5.1 与 PowerShell 7+
语法Invoke-Expression -Command <字符串>;别名 iex
高危点字符串含外部可控内容时形成命令注入
更安全的替代调用运算符 & $exe $args;脚本块 & { ... };Get-Command 后再调用

典型使用场景

  • 执行用户输入的表达式:做简单计算器或查询工具时读取一行表达式求值
  • 动态拼装命令:参数来自配置文件且无法预先固定时(应先验证白名单)
  • 运行已有字符串:从文件或数据库读出命令文本后执行
  • 老脚本迁移:理解遗留脚本里 iex 的实际作用再替换为安全写法
  • 安全审计:识别日志中 iex 出现的位置,作为可疑执行的线索

常用示例

常用示例
# 最基础的用法:执行字符串命令
$cmd = 'Get-Date -Format yyyy-MM-dd'
Invoke-Expression $cmd
# 调用运算符:能表达同样意图时优先用它
& 'C:\Windows\System32\notepad.exe' D:\logs\a.txt
# 脚本块写法
& { Get-Process | Sort-Object CPU -Descending | Select-Object -First 5 }
# 未加校验的拼接是典型注入入口(反面示例,勿在生产使用)
# Invoke-Expression "ping $userInput"
# 需要外部输入时先做白名单校验
$allow = 'status','version'
if ($userInput -in $allow) { Invoke-Expression "mycli $userInput" }

执行方式对比

写法解析方式安全与可维护性
& $exe $args直接调用可执行文件参数不经二次解析,较安全
& { ... }脚本块,静态解析推荐,语法错误可提前发现
Invoke-Expression运行时解析字符串最灵活也最危险
Start-Process启动独立进程适合带参数的命令行调用
只要字符串中有一部分来自用户输入、文件名、网页内容或数据库,就不该送进 iex。安全日志里 iex 是重点监控对象,被滥用时既是攻击者的手段,也会让你自己的脚本被安全团队标记。
iex 报错通常指向被拼接出来的内部命令,行号与真实原因对不上,调试体验很差。能确定命令结构时,改用调用运算符能显著改善报错可读性。
PowerShell 也提供了更专用的动态求值途径,例如执行算术表达式用 Invoke-Command 配合脚本块或直接使用 [scriptblock]::Create 并校验来源;通道越窄,风险越小。

易错点

  • 把用户输入拼进 iex:等于主动打开任意代码执行入口,可能是最严重的脚本缺陷
  • 用 iex 拼路径含空格的外部程序:参数被二次解析,路径被拆开执行失败或执行了错误目标
  • 依赖 iex 的报错定位问题:错误指向内部命令,排查时间被大幅拉长
  • 在脚本安全审查中被标记:iex 本身是攻击链高频特征,滥用会引来额外审查
  • 用 iex 执行下载来的文本:来源不可信时直接等于运行未知代码

数据来源与参考

  • Microsoft Learn:Invoke-Expression
  • Microsoft Security:PowerShell 可疑执行与日志审计

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌