Finally completed.
Ok, finally updated a few key entries to update based on a dynamic URL.
In your ansible folder you’ll require a Template Folder for the ultravnc.inf to be created from ultravnc.inf.j2 file. see the files contents at the bottom of this post.
Here is the playbook I currently have together.
---
- name: Silently update Windows software using Chocolatey
hosts:
- windows
gather_facts: no
tasks:
- name: Remove PowerShell Execution Policy from Group Policy
win_regedit:
path: HKLM:\Software\Policies\Microsoft\Windows\PowerShell
name: ExecutionPolicy
state: absent
- name: Ensure C:\temp exists
ansible.windows.win_file:
path: C:\temp
state: directory
- name: Check if Chocolatey is installed
win_stat:
path: C:\ProgramData\chocolatey\bin\choco.exe
register: choco_installed
- name: Set execution policy to allow script execution
win_shell: Set-ExecutionPolicy Bypass -Scope Process -Force
- name: Install Chocolatey
win_shell: |
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Set-ExecutionPolicy Bypass -Scope Process -Force
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
args:
executable: powershell.exe
when: not choco_installed.stat.exists
register:
- name: Upgrade Chocolatey
win_shell: choco upgrade chocolatey -y
args:
executable: cmd.exe
when: choco_installed.stat.exists
register: choco_upgrade
- name: Show upgrade result
debug:
var: choco_upgrade.stdout_lines
when: choco_installed.stat.exists
##########################################################################
- name: Copy Chrome installer to Windows UNC path
win_get_url:
url: "https://dl.google.com/dl/chrome/install/googlechromestandaloneenterprise64.msi"
dest: "C:\\temp\\chrome.msi" # UNC path for shared location
force: yes
- name: Copy Firefox ESR installer to Windows UNC path
win_get_url:
url: "https://download.mozilla.org/?product=firefox-esr-latest-ssl&os=win64&lang=en-US"
dest: "C:\\temp\\FirefoxESR.exe" # UNC path for shared location
force: yes
- name: Download Visual C++ Redistributable
win_get_url:
url: https://aka.ms/vs/17/release/vc_redist.x64.exe
dest: C:\temp\vc_redist.x64.exe
- name: Download PowerShell 7 installer
win_get_url:
url: https://github.com/PowerShell/PowerShell/releases/download/v7.5.0/PowerShell-7.5.0-win-x64.msi
dest: C:\\temp\\PowerShell-x64.msi
- name: Download TortoiseGit Installer
win_get_url:
url: "https://download.tortoisegit.org/tgit/2.17.0.0/TortoiseGit-2.17.0.2-64bit.msi"
dest: C:\\temp\\TortoiseGit.msi
#########################################################################
- name: Run OfficeC2RClient update command
win_command: '"C:\Program Files\Common Files\microsoft shared\ClickToRun\OfficeC2RClient.exe" /update user displaylevel=false forceappshutdown=true'
ignore_errors: yes
- name: Verify EXE file exists
win_stat:
path: "C:\\temp\\chrome.msi"
register: chrome_msi
- name: Fail if MSI file is missing or empty
fail:
msg: "Chrome MSI download failed or file is missing."
when: not chrome_msi.stat.exists or chrome_msi.stat.size == 0
- name: Install Chrome MSI
win_package:
path: "C:\\temp\\chrome.msi"
arguments: "/qn /norestart"
state: present
register: install_chrome
ignore_errors: yes
- name: Ensure no other MSI installations are running
win_shell: |
$count = 0
while (Get-Process -Name "msiexec" -ErrorAction SilentlyContinue) {
Start-Sleep -Seconds 10
$count++
if ($count -ge 30) { Stop-Process -Name "msiexec" -Force }
}
register: msiexec_check
changed_when: msiexec_check.rc == 0
- name: Verify EXE file exists
win_stat:
path: "C:\\temp\\FirefoxESR.exe"
register: firefox_exe
- name: Fail if EXE file is missing or empty
fail:
msg: "Firefox EXE download failed or file is missing."
when: not firefox_exe.stat.exists or firefox_exe.stat.size == 0
- name: Wait for WinRM to stabilize
wait_for:
port: 5985
delay: 10
timeout: 120
host: "{{ inventory_hostname }}"
delegate_to: localhost
- name: Install Firefox ESR using EXE
win_command: 'C:\\temp\\FirefoxESR.exe /S'
async: 600 # Max runtime in seconds
poll: 0 # Fire and forget
register: install_firefox
- name: Upgrade Microsoft Edge using Chocolatey
win_chocolatey:
name: microsoft-edge
state: latest
- name: Install Visual C++ Redistributable
win_command: C:\\temp\\vc_redist.x64.exe /quiet /norestart
register: vc_install
ignore_errors: yes
failed_when: vc_install.rc not in [0, 3010]
- name: Install TortoiseGit
win_package:
path: C:\\temp\\TortoiseGit.msi
state: present
arguments: /quiet /norestart
- name: Install PowerShell 7 silently
win_package:
path: C:\\temp\\PowerShell-x64.msi
product_id: PowerShell
state: present
arguments: /quiet /norestart
- name: Ensure PuTTY is installed and updated via Chocolatey
win_chocolatey:
name: putty
state: latest
timeout: 3600
- name: Install 7-Zip via Chocolatey
win_chocolatey:
name: 7zip.install
state: present
timeout: 600
- name: Install Python using Chocolatey
win_chocolatey:
name: python
state: latest
- name: Uninstall older Python versions while keeping the latest
win_shell: |
$python_versions = Get-WmiObject -Query "SELECT * FROM Win32_Product WHERE Name LIKE 'Python%'" | Sort-Object Version -Descending
if ($python_versions.Count -gt 1) {
$old_versions = $python_versions[1..$python_versions.Count] # Exclude the latest version
foreach ($version in $old_versions) {
Write-Output "Uninstalling: $($version.Name) - $($version.Version)"
$version.Uninstall() | Out-Null
}
} else {
Write-Output "Only one Python version detected. No need to uninstall."
}
args:
executable: powershell.exe
- name: Silently update Notepad++
win_chocolatey:
name: notepadplusplus
state: latest
- name: Silently update Git
win_chocolatey:
name: git
state: latest
- name: Silently update WinSCP
win_chocolatey:
name: winscp
state: latest
- name: Install FileZilla
win_chocolatey:
name: filezilla
state: present
- name: Create UltraVNC INF file
win_template:
src: ultravnc_setup.inf.j2
dest: C:\Temp\ultravnc.inf
force: yes
# - name: Ensure the correct file is copied
# template:
# src: templates/ultravnc_setup.inf.j2
# dest: C:\Temp\ultravnc.inf
# force: yes
- name: Install UltraVNC with custom parameters
win_chocolatey:
name: ultravnc
state: latest
install_args: '/loadinf="C:\\temp\\ultravnc.inf" /verysilent'
force: yes
- name: Check if UltraVNC service exists
win_shell: |
Get-Service | Where-Object { $_.Name -like '*uvnc*' }
register: uvnc_service
ignore_errors: yes
- name: Stop UltraVNC service if found
win_service:
name: '*uvnc*'
state: stopped
when: uvnc_service.stdout != ""
- name: Disable UltraVNC service if found
win_service:
name: '*uvnc*'
start_mode: disabled
when: uvnc_service.stdout != ""
# - name: Remove UltraVNC executable if service is not found
# win_file:
# path: "C:\\Program Files\\uvnc bvba\\UltraVNC\\winvnc.exe"
# state: absent
# when: uvnc_service.stdout == ""
- name: Parse latest version from Advanced IP Scanner download page using curl
win_shell: |
$html = curl.exe -s "https://www.advanced-ip-scanner.com/download/"
$match = [regex]::Match($html, 'Advanced_IP_Scanner_(\d+\.\d+\.\d+\.\d+)\.exe')
if ($match.Success) {
$match.Groups[1].Value
} else {
"Not found"
}
register: download_version
- name: Show download Version
debug:
var: download_version.stdout
- name: Show download Version
debug:
msg: "{{ download_version.stdout | regex_replace('\\r\\n$', '') }}"
- name: Build the download URL
set_fact:
download_url: "https://download.advanced-ip-scanner.com/download/files/Advanced_IP_Scanner_{{ download_version.stdout | regex_replace('\\r\\n$', '') }}.exe"
- name: Show download URL
debug:
msg: "{{ download_url }}"
- name: Download Advanced IP Scanner installer to target
win_get_url:
url: "{{ download_url }}"
dest: C:\temp\AdvancedIPScannerSetup.exe
- name: Install Advanced IP Scanner using EXE
win_command: "C:\\temp\\AdvancedIPScannerSetup.exe /VERYSILENT /NORESTART /LOG=C:\\windows\\Temp\\AdvIPScanner.log"
register: install_result
ignore_errors: yes
- name: Install Wireshark using Chocolatey
win_chocolatey:
name: wireshark
state: present
- name: Reboot Workstations
win_reboot:
msg: "Rebooting Workstation"
reboot_timeout: 600
when: vc_install.rc == 3010
register: reboot_result
- name: Show reboot status
debug:
msg: "Workstation was rebooted: {{ reboot_result.rebooted | default(false) }}"
when: vc_install.rc == 3010
And here is the content of ultravnc.inf.j2 file.
This is because I want to install just the UltraVNC Viewer and not the complete Server Instance.
[Setup]
Lang=en
Group=UltraVNC
NoIcons=1
SetupType=custom
Components=ultravnc_viewer