Ansible执行PowerShell命令报错:Unexpected token ':' in expression or statement 求助
你遇到的Unexpected token ':'错误,本质是因为你把Ansible register返回的完整字典对象直接传给了PowerShell命令,而不是提取字典里的实际值。比如你用debug模块register的packagefamilyname,它的结构是{'msg': 'Postman_qyy7z89j1cgve', 'failed': False, 'changed': False},当你在后续命令里用{{ packagefamilyname }}时,Ansible会把整个字典转成字符串传给PowerShell,PowerShell自然无法解析这种Python风格的字典语法,从而触发语法错误。
另外,你的playbook还有个可以优化的点:重复执行了两次Expand-AzWvdMsixImage命令,这不仅浪费资源,还可能因为环境变化导致两次返回结果不一致,完全可以把这个命令的结果一次性保存下来,再从中提取需要的字段。
下面是修改后的完整playbook,我标注了关键修改点:
- hosts: localhost connection: local vars: subscription_id: "" workspace_name: "WVD-WorkSpace" hostpool_name: "WVD-HostPool" rg_name: "WVD" uri_path: '\\certsign\MSIXAppAttach_Store\Postman_8.0.7.0_x64.vhdx' DisplayName: "postman" appgroup_name: "WVD-DesktopAG" tasks: # 关键修改1:一次性执行Expand命令并保存结果,避免重复调用 - name: Get MSIX Image details shell: | $obj = Expand-AzWvdMsixImage -HostPoolName {{ hostpool_name }} -ResourceGroupName {{ rg_name }} -SubscriptionId {{ subscription_id }} -Uri {{ uri_path }} # 把需要的两个字段用JSON输出,方便Ansible解析 [PSCustomObject]@{ PackageAppId = $obj.PackageApplication.AppId PackageFamilyName = $obj.PackageFamilyName } | ConvertTo-Json args: executable: /usr/local/bin/pwsh register: msix_image_details changed_when: false # 关键修改2:从保存的结果里解析出需要的字段 - name: Parse MSIX details from JSON set_fact: package_app_id: "{{ (msix_image_details.stdout | from_json).PackageAppId }}" package_family_name: "{{ (msix_image_details.stdout | from_json).PackageFamilyName }}" # 可选:验证提取的变量值 - name: Show extracted values debug: msg: - "Package App ID: {{ package_app_id }}" - "Package Family Name: {{ package_family_name }}" - name: Add MSIX Package to HostPool shell: New-AzWvdMsixPackage -HostPoolName {{ hostpool_name }} -ResourceGroupName {{ rg_name }} -SubscriptionId {{ subscription_id }} -PackageAlias {{ DisplayName }} -DisplayName {{ DisplayName }} -ImagePath {{ uri_path }} -IsActive:$true args: executable: /usr/local/bin/pwsh # 关键修改3:使用提取后的单一值变量,而不是整个字典 - name: Add MSIX Package to App group shell: New-AzWvdApplication -ResourceGroupName {{ rg_name }} -SubscriptionId {{ subscription_id }} -Name Postman -ApplicationType MsixApplication -ApplicationGroupName {{ appgroup_name }} -MsixPackageFamilyName {{ package_family_name }} -CommandLineSetting 0 args: executable: /usr/local/bin/pwsh
合并重复的Expand命令:
把两次Expand-AzWvdMsixImage调用合并成一次,将需要的字段封装成PSCustomObject并转成JSON输出。这样Ansible可以轻松解析JSON格式的结果,避免了写入文件再读取的繁琐(还能避免文件读写带来的权限或路径问题)。用set_fact提取变量:
使用from_json过滤器解析PowerShell输出的JSON,然后把需要的字段保存为单独的Ansible变量package_app_id和package_family_name,这些变量是单一字符串值,完全符合后续PowerShell命令的要求。修正变量引用:
在最后一步的New-AzWvdApplication命令里,使用{{ package_family_name }}而不是原来的{{ packagefamilyname }},确保传递的是单一字符串值,而不是整个字典对象。
- 如果你的PowerShell版本支持,也可以直接在
Expand-AzWvdMsixImage命令后直接输出需要的字段,比如只输出$obj.PackageFamilyName,然后用msix_image_details.stdout直接获取值,但用JSON的方式更灵活,能一次性获取多个字段。 - 记得给
subscription_id变量填入实际的订阅ID,否则命令会执行失败。
内容的提问来源于stack exchange,提问作者devops_coder

