使用win_environment,可以向Windows主机添加/删除环境变量。 但是要修改已经存在的变量,win_environment似乎没有用,因为你无法读取旧值来修改和更新变量。正确?
答案 0 :(得分:2)
编辑:自Ansible 2.3起,win_path模块为您完成了所有繁重的任务。只需给它一个应该存在于路径中的项目列表,它将确保它们存在并且按照您指定的相对顺序存在。
(如果您仍然使用古老版本的Ansible,以下仍然是可行的方法)
为了让这项功能得到理智,您需要与替换和搜索过滤器结合使用,只有在您想要的值不存在时才进行更改。例如(这是Ansible 1.9):
- raw: echo %PATH%
register: path_out
- win_environment:
name: path
value: "{{ path_out.stdout | regex_replace('[\r\n]*', '') + ';C:\\\\newpath' }}"
state: present
level: machine
when: not (path_out.stdout | search("(?i)c:\\\\newpath"))
这比应该的要困难得多 - 我已经半心半意地破解了一个win_path模块,让它变得更容易......
对于2.0,raw
在Powershell下运行,因此您需要Get-Item env:PATH
代替。
答案 1 :(得分:2)
使用Ansible 2.0
尝试此操作- name: Get actual PATH
raw: $ENV:PATH
register: path_out
tags: path
- name: Add Notepad++ to PATH
raw: SETX /M PATH "$ENV:PATH;C:\Program Files (x86)\Notepad++"
when: path_out.stdout.find('Notepad') == -1
tags: path
答案 2 :(得分:2)
我花了几个小时与Ansible,Jinja2和JSON反斜杠地狱战斗,最后找到了一个通用的解决方案 - 即,允许你将任何目录添加到系统路径,并且不会添加相同的路径两次。我改编了Devis'解决方案但同时使SETX命令和when:子句接受(相同){{item}},因此可以参数化。这就是我想出来的。
将其另存为extend-path.yml
:
---
- name: Get current machine PATH.
raw: $ENV:PATH
register: path_out
- name: "Add {{ item }} to PATH."
raw: SETX /M PATH "$ENV:PATH;{{ item }}"
when: "not (path_out.stdout | urlencode | search( '{{ item | urlencode }}' ) )"
changed_when: true
然后,例如,在playbook.yml
:
---
tasks:
- name: Add tools to PATH.
include: extend-path.yml
with_items:
- C:\bin
- C:\Program Files (x86)\CMake\bin
- C:\Program Files\git\cmd
(如你所见,我实际上已经失去了反斜杠战争,并决定使用urlencode
完全绕过它。)
答案 3 :(得分:0)
您可以使用Powershell为Path添加字符串。下面的代码为PATH变量添加了一个给定的路径,同时如果给定的路径已经存在于PATH中,则不会修改路径。
$env = [Environment]::GetEnvironmentVariable('path','machine') -split ';'
$msdeploypath = 'C:\Program Files\IIS\Microsoft Web Deploy'
if ($env -notcontains $msdeploypath) {
$env += $msdeploypath
[Environment]::SetEnvironmentVariable('path', ($env -join ';'), 'machine')
Write-Host "changed"
}
在Ansible 2中,您也可以使用原始模块,因为它使用Powershell
- name: Set Path
raw: $env = [Environment]::GetEnvironmentVariable('path','machine') -split ';' ; $msdeploypath = 'C:\Program Files\IIS\Microsoft Web Deploy' ; if ($env -notcontains $msdeploypath) { $env += $msdeploypath ; [Environment]::SetEnvironmentVariable('path', ($env -join ';'), 'machine') ; Write-Host "changed" }
register: pathchange
changed_when: pathchange.stdout.find('changed') != -1
答案 4 :(得分:0)
以下是将msbuild设置为计算机路径的示例。如果需要,您可以添加更多项目。在修改机器路径之前,只检索机器路径非常重要。如果你只是调用$ ENV:PATH,你将获得与用户路径相结合的机器路径。如果您使用它来设置机器路径,那么您将所有用户路径值复制到我假设不是您想要的机器路径。
- name: Get System PATH
raw: '[Environment]::GetEnvironmentVariables("Machine").Path'
register: path_out
- name: Modify System PATH
raw: SETX /M PATH "$([Environment]::GetEnvironmentVariables("Machine").Path | Out-String);{{ item }}"
when: path_out.stdout.find(item) == -1
with_items:
- 'C:\Program Files (x86)\MSBuild\14.0\Bin'
答案 5 :(得分:0)
凯西的解决方案非常接近。唯一的问题是[Environment] :: SetEnvironmentVariable在PATH末尾添加换行符。因此,当您添加它时,它会将所有新值放在另一行上,使PATH无法正常工作。这就是我所做的,而且效果非常好。
只需在换行符上添加拆分...然后系统PATH变量设置正确。
这是Casey的解决方案和Chris Hillery的组合:
在名为extend-path.yml
的文件中:
---
- name: Get current machine PATH.
raw: "$([Environment]::GetEnvironmentVariables(\"Machine\").Path -split '\r\n')"
register: path_out
- name: Print Out PATH
debug:
msg: "PATH: {{ path_out }}"
- name: "Add {{ item }} to PATH."
raw: SETX /M PATH "$($([Environment]::GetEnvironmentVariables("Machine").Path -split '\r\n'));{{ item }}"
when: path_out.stdout.find(item) == -1
changed_when: true
然后在你的剧本中调用它:
- name: Update system PATH
include: tasks/win_system_path.yml
with_items:
- C:\Program Files\Git\bin