如何在Ansible Playbook中提取Windows注册表卸载命令至变量
我之前处理Windows软件卸载的Playbook时也踩过类似的坑,来帮你一步步解决这个问题~
首先,你提到用{{ desinstala.results.value }}没成功,大概率是混淆了单任务查询和循环查询的返回结构,先从最常见的情况说起:
1. 单注册表项查询(无loop)
如果你的win_reg_stat任务是直接查询7-Zip的单个注册表项,比如:
- name: 获取7-Zip的UninstallString注册表项 win_reg_stat: path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\7-Zip name: UninstallString register: desinstala
这时候register的变量desinstala是一个直接的结果对象,没有results层级,正确的取值应该是:
{{ desinstala.value }}
你可以先加个debug任务确认返回结构,避免瞎猜:
- name: 打印注册表查询结果的完整结构 debug: var: desinstala
执行后就能看到,成功的情况下desinstala里会直接有value字段,存着你要的卸载命令。
2. 循环查询多个软件(有loop)
如果是用loop批量查询多个软件的注册表项,这时候返回结果才会在desinstala.results里。比如:
- name: 批量查询多个软件的UninstallString win_reg_stat: path: "{{ item.path }}" name: UninstallString loop: - { path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\7-Zip } - { path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Chrome } register: desinstala
这时候需要筛选出7-Zip对应的条目,再提取value,可以用selectattr和map来处理:
- name: 提取7-Zip的卸载命令 set_fact: sevenzip_uninstall_cmd: "{{ desinstala.results | selectattr('item.path', 'equalto', 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\7-Zip') | map(attribute='value') | first }}"
注意路径里的反斜杠要转义,或者用单引号包裹路径字符串避免转义。
3. 额外注意:32位/64位注册表的差异
有些32位软件的注册表项会存在HKLM:\SOFTWARE\Wow6432Node路径下,如果上面的查询没结果,可以指定架构参数重试:
- name: 查询32位7-Zip的注册表项 win_reg_stat: path: HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\7-Zip name: UninstallString architecture: 32 register: desinstala_32
取值同样用{{ desinstala_32.value }}即可。
4. 处理带引号的卸载命令
很多UninstallString会带双引号,比如"C:\Program Files\7-Zip\Uninstall.exe",如果后续要执行这个命令,建议去掉引号:
- name: 清理卸载命令的引号 set_fact: sevenzip_uninstall_clean: "{{ desinstala.value | regex_replace('^\"|\"$', '') }}"
这样处理后,你就能得到一个可以直接在win_shell或win_command里使用的变量啦~
内容的提问来源于stack exchange,提问作者carrotcakeslayer

