Install NuGet and Other Package Providers on Windows Using Ansible

Learn how to install the NuGet Package Provider using Ansible for Windows systems. This is essential for Ansible projects targeting Microsoft Windows hosts, such as those in the RWS GIS Platform.

Projects: c2platform/rws/ansible-gis, c2platform.wincore


Introduction

When working with Ansible projects that target Windows hosts, you’ll often need to install the NuGet Package Provider. Without it, you may encounter the following message:

PowerShellGet requires NuGet provider version ‘2.8.5.201’ or newer to interact with NuGet-based repositories

Ansible, currently, does not provide dedicated modules for this task, but you can manually install the NuGet Package Provider with the following PowerShell command:

Find-PackageProvider -name Nuget -ForceBootstrap -IncludeDependencies -Force

Alternatively, you can use the win_powershell Ansible module to accomplish this task.

Using the c2platform.wincore.win Role

An even more convenient approach is to use the c2platform.wincore.win Ansible role. This role offers a template install_package_provider.ps.j2 for installing package providers like NuGet and Chocolatey in a controlled manner.

The advantage of using the c2platform.wincore.win role is that it requires minimal Ansible engineering; you only need to configure it. The RWS reference implementation project, c2platform/rws/ansible-gis provides an example of how to configure this role in the group_vars/windows/main.yml file. Here’s a snippet from that file:

win_resources:
  1-windows:
    - name: Chocolatey Package Provider
      type: win_powershell
      script: "{{ lookup('ansible.builtin.template', 'install_package_provider.ps.j2', template_vars={'win_package_provider': 'Chocolatey'}) }}"
      # debug_path: C:\vagrant\logs\chocolately-package-provider.yml
    - name: NuGet Package Provider
      type: win_powershell
      script: "{{ lookup('ansible.builtin.template', 'install_package_provider.ps.j2', template_vars={'win_package_provider': 'Nuget'}) }}"

Template for Installing Package Providers

The install_package_provider.ps.j2 template, part of the c2platform.wincore.win Ansible role, is included below for your convenience:

$Ansible.Failed = $false
$Ansible.Changed = $false
{% if win_proxy_url is defined %}
$proxy = '{{ win_proxy_url }}'
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
[system.net.webrequest]::defaultwebproxy = new-object system.net.webproxy($proxy)
[system.net.webrequest]::defaultwebproxy.BypassProxyOnLocal = $true
{% endif %}

Write-Output "Install {{ win_package_provider }} Package Provider (if not installed already)"

try {
    $packageProvider = Get-PackageProvider -Name {{ win_package_provider }}

    if (-not $packageProvider) {
        Write-Output "Installing {{ win_package_provider }} Package Provider"
        $result = Install-PackageProvider -Name {{ win_package_provider }} -Force -Confirm:$false

        if ($result -eq $null) {
            $Ansible.Failed = $true
            Write-Error "Failed to install {{ win_package_provider }} Package Provider"
        } else {
            $Ansible.Changed = $true
        }
    }

    if ($Ansible.Changed) {
        Write-Output "{{ win_package_provider }} Package Provider has been installed or updated."
    } elseif ($Ansible.Failed) {
        Write-Output "{{ win_package_provider }} Package Provider failed to install."
    }
    else {
        Write-Output "{{ win_package_provider }} Package Provider is installed, and the installation was not changed"
    }
}
catch {
    $Ansible.Failed = $true
    Write-Error "An error occurred: $_"
}