You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell脚本手动运行正常,Ansible启动时创建word.application失败

使用Ansible win_psexec执行PowerShell脚本创建Word COM对象失败(错误80080005)

问题描述

通过Ansible的community.windows.win_psexec模块执行PowerShell脚本,任务配置如下:

- name: Running my-script.ps1
  community.windows.win_psexec:
    executable: D:\Repos\my-repo\ansible\roles\PsExec\files\PsExec.exe
    command: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy ByPass -File "D:\Repos\my-repo\my-script.ps1" -param1 {{ param1_value }} -param2 {{ param2_value }} -switchParam
    elevated: yes
    interactive: yes
  no_log: false

脚本执行到创建Word COM对象时抛出错误:

TerminatingError(New-Object): "Retrieving the COM class factory for component with CLSID {000209FF-0000-0000-C000-000000000046} failed due to the following error: 80080005 Server execution failed (Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE))." New-Object : Retrieving the COM class factory for component with CLSID {000209FF-0000-0000-C000-000000000046} failed due to the following error: 80080005 Server execution failed (Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)).

手动登录目标主机运行脚本一切正常,但通过Ansible执行时失败。已尝试以下操作但无效:

  • 添加Add-Type -AssemblyName Microsoft.Office.Interop.Word(注:原提问中拼写错误为Officer,已修正)
  • 将创建对象代码改为$word = [Microsoft.Office.Interop.Word.ApplicationClass]::new()

问题原因

  1. COM组件的桌面会话依赖:Microsoft Word的COM对象属于需要用户桌面环境的交互式组件,无法在无桌面的非交互式会话中运行。
  2. PsExec的默认会话问题:即使设置了interactive: yes,win_psexec默认会在Windows的会话0(系统服务专用会话)中执行,该会话没有用户桌面;而手动登录属于用户交互式会话(通常为会话1及以上),具备完整桌面环境。
  3. 权限上下文差异:Ansible通过win_psexec执行时的用户上下文,未关联到当前登录用户的桌面会话,导致COM对象初始化时无法获取必要的系统资源。

解决办法

方法1:指定PsExec运行到用户交互式会话

修改Ansible任务,通过win_psexec的session参数指定目标主机当前登录用户的会话ID,或直接指定console会话:

- name: Running my-script.ps1
  community.windows.win_psexec:
    executable: D:\Repos\my-repo\ansible\roles\PsExec\files\PsExec.exe
    command: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy ByPass -File "D:\Repos\my-repo\my-script.ps1" -param1 {{ param1_value }} -param2 {{ param2_value }} -switchParam
    elevated: yes
    interactive: yes
    # 指定会话ID,可通过目标主机执行query session获取当前登录用户的会话ID
    session: 1
    # 或直接指定console会话(对应当前登录的控制台会话)
    # session: console
  no_log: false

若不确定会话ID,可先通过Ansible任务自动获取:

- name: Get active user session ID
  ansible.windows.win_command: query session
  register: session_output

- name: Extract session ID
  set_fact:
    target_session_id: "{{ session_output.stdout | regex_search('>(\\d+)\\s+Active') | regex_replace('>(\\d+)\\s+Active', '\\1') }}"

方法2:改用无需桌面的Word操作方案

如果业务允许,建议使用Open XML SDK(如DocumentFormat.OpenXml NuGet包)代替Word COM对象操作文档,该方案无需依赖桌面会话,更适合自动化脚本场景:

# 示例:使用PSWriteWord模块(基于Open XML SDK)操作Word文档
Install-PackageProvider -Name NuGet -Force
Install-Module -Name PSWriteWord -Force
$doc = Get-WordDocument -Path "D:\test.docx"
# 后续文档操作...

方法3:调整Windows组策略(不推荐,存在安全风险)

修改组策略允许服务与桌面交互:

  1. 打开gpedit.msc
  2. 导航到计算机配置>管理模板>系统>服务
  3. 启用允许服务与桌面交互

内容的提问来源于stack exchange,提问作者jerdub1993

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 01:20:42