如何使用ansible扩展Windows路径变量

时间:2015-10-16 04:25:35

标签: windows path ansible

使用win_environment,可以向Windows主机添加/删除环境变量。 但是要修改已经存在的变量,win_environment似乎没有用,因为你无法读取旧值来修改和更新变量。正确?

6 个答案:

答案 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