适用于 PowerShell 7.0 及以上版本
很多运维人员习惯在终端里做所有事情,却忽略了 PowerShell 与桌面环境交互的能力。日常工作中,我们经常需要在浏览器里复制一段 JSON、在 Excel 里复制一列数据、在日志系统中截取错误信息,然后粘贴到脚本中处理。如果能直接在脚本中读写剪贴板,就能省去中间的文件保存步骤,让数据流转更顺畅。
除了剪贴板操作,PowerShell 还可以通过 .NET 的互操作能力枚举系统窗口、控制窗口焦点,甚至模拟键盘输入来自动化 GUI 应用。这些技巧在处理那些没有提供命令行接口的传统软件时尤为实用——比如操作老旧的 ERP 系统、向不支持 API 的工具批量输入数据等。
本文将从三个层面展开:首先介绍剪贴板的读写与数据转换,然后演示如何枚举和管理系统窗口,最后通过 SendKeys 实现简单的 GUI 自动化操作。
剪贴板读写与数据转换
PowerShell 内置了 Get-Clipboard 和 Set-Clipboard 两个 cmdlet,可以方便地读取和设置剪贴板内容。结合正则表达式和对象转换,可以快速对剪贴板中的数据进行提取、清洗和格式化处理。这在处理从网页或 Excel 中复制的表格数据时特别高效。
1 | # 基础剪贴板操作 |
执行结果示例:
1 | 当前剪贴板内容(前 100 字符): |
窗口枚举与焦点管理
在自动化 GUI 操作之前,通常需要先找到目标窗口。Windows 系统通过句柄(Handle)标识每个窗口,PowerShell 可以借助 .NET 的 System.Diagnostics.Process 类和 P/Invoke 调用 Win32 API 来枚举、定位和控制系统窗口。这在需要对特定应用程序进行自动化操作时是关键的准备步骤。
1 | # 使用 Add-Type 加载 Win32 API |
执行结果示例:
1 | 当前可见窗口(共 8 个): |
SendKeys 与 GUI 自动化
当目标应用没有提供命令行接口或 API 时,SendKeys 模拟键盘输入就成了最后的自动化手段。PowerShell 可以通过 [System.Windows.Forms.SendKeys] 类向当前活动窗口发送按键指令,实现自动填写表单、执行菜单操作等功能。结合前面的窗口管理能力,可以先激活目标窗口再发送按键,形成完整的自动化链路。
1 | # 加载必要的程序集 |
执行结果示例:
1 | Key SendKeys |
注意事项
剪贴板是共享资源:Windows 剪贴板是全局共享的,如果在脚本读写剪贴板的过程中用户手动进行了复制操作,会导致数据被覆盖。对于关键的自动化流程,建议先读取并保存到变量中再处理,避免中间过程依赖剪贴板状态。
SendKeys 的时序问题:
SendKeys发送的是按键事件而非直接输入,目标窗口必须在前台且已就绪。网络延迟、应用启动速度等因素都可能导致按键发送到错误的窗口。建议在每步操作之间加入适当的Start-Sleep延迟,并在发送前验证目标窗口确实获得了焦点。Win32 API 调用需要管理员权限:部分窗口操作(如操控其他用户会话的窗口、系统进程的窗口)需要以管理员身份运行 PowerShell。普通用户权限只能操控同一会话下的窗口。
跨平台限制:
Get-Clipboard和Set-Clipboard在 PowerShell 7 中支持 Windows、macOS 和 Linux,但窗口管理和 SendKeys 功能仅限 Windows 平台。在 macOS 上可以考虑使用osascript配合 AppleScript 实现类似的 GUI 自动化。SendKeys 特殊字符需要转义:
SendKeys中+、^、%、{、}等字符有特殊含义(分别代表 Shift、Ctrl、Alt 和特殊键定界符)。如果要发送这些字符本身,需要用{}包裹,例如发送加号应使用{+}而非+。GUI 自动化的脆弱性:基于窗口标题匹配和按键模拟的自动化方案非常脆弱——界面布局变化、分辨率调整、系统语言切换都可能导致脚本失效。对于有命令行接口或 API 的应用,应优先使用这些更稳定的方案;SendKeys 仅作为没有其他选择时的补充手段。