如何使用Ansible win_service模块停止含$符号的Windows服务?
使用Ansible停止含$符号的SQL Server服务报错修复
问题场景
尝试用Ansible的win_service模块停止名称包含$的SQL Server服务(如SQLAgent$SQL01、MSSQL$SSQLS01)时,出现通配符模式无效的错误。
原Playbook
- name: Get MSSSQL Services ansible.windows.win_service_info: name: "MSSQL*" register: mssql_info - name: Set MSSQL services set_fact: mssql_services: "{{ mssql_info.services | selectattr('state', '==', 'started') | map(attribute='name') | list | replace('$', '%24') }}" - name: Get SQL Agent Services ansible.windows.win_service_info: name: "SQLA*" register: sqla_info - name: Set Agent services set_fact: sqla_services: "{{ sqla_info.services | selectattr('state', '==', 'started') | map(attribute='name') | list | replace('$', '%24') }}" - name: Stop SQL services win_service: name: "{{ item }}" state: "stopped" loop: - "{{ sqla_services }}" - "{{ mssql_services }}" register: stop_output ignore_errors: yes - debug: msg: "{{ stop_output }}"
错误信息
{ "exception": "The specified wildcard character pattern is not valid: System.Object[]\r\nAt line:282 char:5\r\n+ Get-Service -Name $Name -ErrorAction SilentlyContinue\r\n+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n + CategoryInfo : NotSpecified: (:) [Get-Service], WildcardPatternException\r\n + FullyQualifiedErrorId : RuntimeException,Microsoft.PowerShell.Commands.GetServiceCommand\r\n\r\nScriptStackTrace:\r\nat Get-ServiceFromName, <No file>: line 282\r\nat <ScriptBlock>, <No file>: line 952\r\n\r\nSystem.Management.Automation.WildcardPatternException: The specified wildcard character pattern is not valid: System.Object[]\r\n at System.Management.Automation.WildcardPatternParser.Parse(WildcardPattern pattern, WildcardPatternParser parser)\r\n at System.Management.Automation.WildcardPatternMatcher.MyWildcardPatternParser.Parse(WildcardPattern pattern, CharacterNormalizer characterNormalizer)\r\n at System.Management.Automation.WildcardPatternMatcher..ctor(WildcardPattern wildcardPattern)\r\n at System.Management.Automation.WildcardPattern.Init()\r\n at System.Management.Automation.WildcardPattern.IsMatch(String input)\r\n at Microsoft.PowerShell.Commands.MultipleServiceCommandBase.MatchingServicesByServiceName()\r\n at Microsoft.PowerShell.Commands.MultipleServiceCommandBase.MatchingServices()\r\n at Microsoft.PowerShell.Commands.GetServiceCommand.ProcessRecord()\r\n at System.Management.Automation.CommandProcessor.ProcessRecord()", "msg": "Unhandled exception while executing module: The specified wildcard character pattern is not valid: System.Object[]", "_ansible_no_log": null, "changed": false, "item": [], "ansible_loop_var": "item", "_ansible_item_label": [] }
错误原因分析
- 循环层级错误:
loop中直接传入两个列表变量,导致每次循环处理的是整个列表而非单个服务名,PowerShell将数组识别为无效的通配符模式,触发WildcardPatternException。 - 多余的转义操作:
replace('$', '%24')完全不必要,win_service模块支持直接使用包含$的服务名,无需进行URL编码转义。
修复后的Playbook
- name: Get MSSQL Services ansible.windows.win_service_info: name: "MSSQL*" register: mssql_info - name: Set MSSQL services set_fact: mssql_services: "{{ mssql_info.services | selectattr('state', '==', 'started') | map(attribute='name') | list }}" - name: Get SQL Agent Services ansible.windows.win_service_info: name: "SQLA*" register: sqla_info - name: Set Agent services set_fact: sqla_services: "{{ sqla_info.services | selectattr('state', '==', 'started') | map(attribute='name') | list }}" - name: Stop SQL services win_service: name: "{{ item }}" state: "stopped" loop: "{{ sqla_services + mssql_services }}" register: stop_output ignore_errors: yes - debug: msg: "{{ stop_output }}"
修复说明
- 移除了所有
replace('$', '%24')的转义操作,直接使用原始服务名。 - 将两个服务列表用
+合并成一维列表,loop直接遍历合并后的列表,确保每次处理单个服务名。 - 若需要处理更复杂的列表嵌套场景,可使用
| flatten过滤器确保列表为一维结构。
内容的提问来源于stack exchange,提问作者Jbarboza09
相关产品推荐
相关产品推荐

