Update role dependencies

This commit is contained in:
2024-02-08 15:55:01 -05:00
parent e09a7f7d45
commit bb21e8d5c6
507 changed files with 1270 additions and 28219 deletions

View File

@@ -14,6 +14,10 @@ Role Variables
Dependencies
------------
A list of roles that this role utilizes:
- oatakan.windows_hotfix
Example Playbook
----------------
@@ -36,7 +40,7 @@ Including an example of how to use your role (for instance, with variables passe
For disconnected environments, you can overwrite this variable to point to a local copy of a script to enable winrm:
**winrm_enable_script_url:** https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1
**winrm_enable_script_url:** https://raw.githubusercontent.com/ansible/ansible-documentation/devel/examples/scripts/ConfigureRemotingForAnsible.ps1
you can also localize virtio-win and update the virtio_iso_url variable to point to your local url:

View File

@@ -1,17 +1,31 @@
---
install_updates_retry_limit: 300
update_retry_count: 0
update_retry_limit: 10
win_update_category_names:
- CriticalUpdates
- DefinitionUpdates
- SecurityUpdates
- UpdateRollups
- Updates
hotfix_download_location: "{{ ansible_env.TEMP }}"
win_update_category_names: '*'
#win_update_category_names:
# - CriticalUpdates
# - DefinitionUpdates
# - FeaturePacks
# - SecurityUpdates
# - UpdateRollups
# - Updates
hotfixes_group_1:
win_update_reject_list: []
win_update_accept_list: []
win_update_server_selection: default
win_update_disable_firewall: yes
failed_kb: []
windows_update_disable_firewall: true
temp_directory: "{{ ansible_env.TEMP }}"
windows_hotfix_role: oatakan.windows_hotfix
hotfixes:
- kb: KB3020369
file: Windows6.1-KB3020369-x64.msu
url: https://download.microsoft.com/download/F/D/3/FD3728D5-0D2F-44A6-B7DA-1215CC0C9B75/Windows6.1-KB3020369-x64.msu

View File

@@ -1,5 +1,17 @@
---
- name: get Windows ADK uninstall command
win_reg_stat:
path: HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{d794748d-72e9-45d7-9ab7-83d6c4c80f7f}
name: QuietUninstallString
register: windows_adk_uninstall_string
- name: uninstall Windows ADK
win_shell: "{{ windows_adk_uninstall_string.value }}"
args:
executable: cmd
when: windows_adk_uninstall_string.value is defined
- name: ensure Windows ADK with DISM is removed
win_chocolatey:
name: windows-adk-deploy

View File

@@ -1,2 +1,2 @@
install_date: Fri Oct 15 18:59:19 2021
install_date: Thu 08 Feb 2024 08:54:03 PM
version: master

View File

@@ -1,18 +1,33 @@
---
- debug:
msg: "win update server: {{ win_update_server }}"
when: win_update_server is defined
- name: disable firewall for Domain, Public and Private profiles
win_shell: Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False
when: "'Windows Server 2012' in ansible_distribution"
when:
- "'Windows Server 2012' in ansible_distribution or 'Windows 8' in ansible_distribution"
- windows_update_disable_firewall | bool
- name: disable firewall for Domain, Public and Private profiles
win_shell: netsh advfirewall set allprofiles state off
when: "'Windows Server 2008' in ansible_distribution or 'Windows 7' in ansible_distribution"
when:
- "'Windows Server 2008' in ansible_distribution or 'Windows 7' in ansible_distribution"
- windows_update_disable_firewall | bool
- name: get used space before update
win_shell: Get-PSDrive C | Select-Object Used | ConvertTo-Json
register: used_space_before_update
ignore_errors: yes
- name: reset some facts
set_fact:
update_retry_count: 0
missing_hotfixes: []
failed_kb: []
_reject_list: []
- include_tasks: updates-all.yml
when:
- "'Windows Server 2008' not in ansible_distribution"
@@ -42,8 +57,12 @@
- name: enabled firewall for Domain, Public and Private profiles
win_shell: Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True
when: "'Windows Server 2012' in ansible_distribution"
when:
- "'Windows Server 2012' in ansible_distribution or 'Windows 8' in ansible_distribution"
- windows_update_disable_firewall | bool
- name: enable firewall for Domain, Public and Private profiles
win_shell: netsh advfirewall set allprofiles state on
when: "'Windows Server 2008' in ansible_distribution or 'Windows 7' in ansible_distribution"
win_shell: netsh advfirewall set allprofiles state on
when:
- "'Windows Server 2008' in ansible_distribution or 'Windows 7' in ansible_distribution"
- windows_update_disable_firewall | bool

View File

@@ -1,19 +1,32 @@
---
- block:
- name: check for available updates
win_updates:
category_names: "{{ win_update_category_names }}"
reject_list: "{{ win_update_reject_list | default(omit) }}"
server_selection: "{{ win_update_server_selection }}"
state: searched
register: available_updates
rescue:
- name: ensure we have connection
wait_for_connection:
- name: check for available updates
win_updates:
category_names: "{{ win_update_category_names }}"
blacklist: "{{ win_update_blacklist | default(omit) }}"
state: searched
register: available_updates
- name: check for available updates (retry)
win_updates:
category_names: "{{ win_update_category_names }}"
reject_list: "{{ win_update_reject_list | default(omit) }}"
server_selection: "{{ win_update_server_selection }}"
state: searched
register: available_updates
- debug:
msg: |
msg: "{{ _msg.split('\n')[:-1] }}"
vars:
_msg: |
{{ inventory_hostname }} has {{ available_updates.found_update_count }} updates available.
{% for update in updates %}
- {{ update.title }}
{% endfor %}
vars:
updates: "{{ (available_updates.updates.values() | list) if (available_updates.updates is mapping) else (available_updates.updates) }}"
when: available_updates.updates is defined
@@ -22,8 +35,20 @@
- available_updates.updates is defined
- available_updates.found_update_count > 0
# see https://learn.microsoft.com/en-us/sharepoint/troubleshoot/administration/800703fa-illegal-operation-error
# error code 0x800703FA happens with some updates when user is not logged in
# remove the registry key if added during the update
- include_tasks: force_user_registry.yml
vars:
task_state: absent
when:
- disable_force_unload_registry is defined
- disable_force_unload_registry is not skipped
- disable_force_unload_registry is changed
- name: check for missing updates
win_updates:
server_selection: "{{ win_update_server_selection }}"
state: searched
register: available_updates

View File

@@ -4,6 +4,7 @@
block:
- name: check for available updates
win_updates:
server_selection: "{{ win_update_server_selection }}"
category_names:
- CriticalUpdates
- DefinitionUpdates
@@ -14,16 +15,23 @@
register: available_updates
- debug:
msg: |
msg: "{{ _msg.split('\n')[:-1] }}"
vars:
_msg: |
{{ inventory_hostname }} has {{ available_updates.found_update_count }} updates available.
{% for update in updates %}
- {{ update.title }}
{% endfor %}
vars:
updates: "{{ (available_updates.updates.values() | list) if (available_updates.updates is mapping) else (available_updates.updates) }}"
when: available_updates.updates is defined
- block:
- name: ensure there is connection
wait_for_connection:
delay: 60
sleep: 10
timeout: 600
- name: install windows updates using powershell script
script: win-updates.ps1
become: yes
@@ -56,6 +64,7 @@
when: update_reboot_required_key.exists
- name: check for missing updates
server_selection: "{{ win_update_server_selection }}"
win_updates:
category_names:
- CriticalUpdates
@@ -67,12 +76,13 @@
register: missing_updates
- debug:
msg: |
msg: "{{ _msg.split('\n')[:-1] }}"
vars:
_msg: |
{{ inventory_hostname }} has {{ missing_updates.found_update_count }} updates still missing.
{% for update in updates %}
- {{ update.title }}
{% endfor %}
vars:
updates: "{{ (missing_updates.updates.values() | list) if (missing_updates.updates is mapping) else (missing_updates.updates) }}"
when: missing_updates.updates is defined

View File

@@ -1,72 +1,40 @@
---
- name: ensure Windows ADK with DISM is installed
win_chocolatey:
name: windows-adk-deploy
state: present
version: 10.0.17134.0
register: install_windows_adk_deploy
notify: ensure Windows ADK with DISM is removed
- include_tasks: install_dism.yml
- name: ensure PATH contains Windows ADK
win_path:
scope: machine
state: present
elements: "C:\\Program Files (x86)\\Windows Kits\\10\\Assessment and Deployment Kit\\Deployment Tools\\amd64\\DISM"
- name: check installed kbs
win_shell: wmic qfe | ConvertTo-Json
register: installed_kbs
- name: download hotfix group 1
win_get_url:
url: '{{ item.url }}'
dest: '{{ hotfix_download_location }}\{{ item.file }}'
loop: "{{ hotfixes_group_1 }}"
- name: missing hotfixes
set_fact:
missing_hotfixes: "{{ hotfixes | json_query(query) }}"
vars:
set_installed_kbs: "{{ (installed_kbs.stdout | from_json) | reject('match', '^$') | reject('match', '^Caption *') | map('regex_replace', '^.* (KB[0-9]+) .*', '\\1') | list }}"
query: "[?!contains(`{{ set_installed_kbs }}`, kb)]"
- block:
- name: install hotfix group 1 (PS >= 4)
win_hotfix:
source: '{{ hotfix_download_location }}\{{ item.file }}'
state: present
register: hotfix_install_group_1
loop: "{{ hotfixes_group_1 }}"
when: ansible_powershell_version is version('4', '>=')
rescue:
- name: install hotfix using shell
win_shell: '{{ hotfix_download_location }}\{{ item.file }} /quiet /norestart'
register: hotfix_install_group_1
loop: "{{ hotfixes_group_1 }}"
- name: install hotfix (PS == 3)
win_shell: '{{ hotfix_download_location }}\{{ item.file }} /quiet /norestart'
register: hotfix_install_group_1
loop: "{{ hotfixes_group_1 }}"
when: ansible_powershell_version is version('3', '==')
- name: debug hotfix installation result
debug:
var: hotfix_install_group_1
- name: ensure hotfix file is removed (group 1)
win_file:
path: '{{ hotfix_download_location }}\{{ item.file }}'
state: absent
loop: "{{ hotfixes_group_1 }}"
- name: reboot from starting update
win_reboot:
- include_role:
name: "{{ windows_hotfix_role }}"
loop: "{{ missing_hotfixes }}"
loop_control:
loop_var: hotfix
- name: check for available updates
win_updates:
server_selection: "{{ win_update_server_selection }}"
category_names: "{{ win_update_category_names }}"
blacklist: "{{ win_update_blacklist | default(omit) }}"
reject_list: "{{ win_update_reject_list | default(omit) }}"
state: searched
register: available_updates
- debug:
msg: |
msg: "{{ _msg.split('\n')[:-1] }}"
vars:
_msg: |
{{ inventory_hostname }} has {{ available_updates.found_update_count }} updates available.
{% for update in updates %}
- {{ update.title }}
{% endfor %}
vars:
updates: "{{ (available_updates.updates.values() | list) if (available_updates.updates is mapping) else (available_updates.updates) }}"
when: available_updates.updates is defined
@@ -77,6 +45,7 @@
- name: check for missing updates.
win_updates:
server_selection: "{{ win_update_server_selection }}"
state: searched
register: available_updates

View File

@@ -3,15 +3,54 @@
- name: update over multiple reboots
block:
- block:
- name: set reject list
set_fact:
_reject_list: "{{ (win_update_reject_list | default([])) + (failed_kb | default([])) }}"
when: (win_update_reject_list | length) or (failed_kb | length)
- name: install all windows updates
win_updates:
server_selection: "{{ win_update_server_selection }}"
category_names: "{{ win_update_category_names }}"
blacklist: "{{ (win_update_blacklist | default([])) + (failed_kb | default([])) }}"
whitelist: "{{ win_update_whitelist | default(omit) }}"
reboot: yes
reject_list: "{{ _reject_list | default(omit) }}"
accept_list: "{{ win_update_accept_list | default(omit) }}"
reboot: false
async: 7200
poll: 0
register: installed_updates_async
- name: wait for updates to finish
async_status:
jid: "{{ installed_updates_async.ansible_job_id }}"
register: installed_updates
until: installed_updates.finished
retries: "{{ install_updates_retry_limit }}"
delay: 30
- name: reboot the system if required
win_reboot:
reboot_timeout: 7200
when: installed_updates.reboot_required
rescue:
- name: ensure there is connection
wait_for_connection:
delay: 60
sleep: 10
timeout: 600
# see https://learn.microsoft.com/en-us/sharepoint/troubleshoot/administration/800703fa-illegal-operation-error
# error code 0x800703FA happens with some updates when user is not logged in
# add the registry key to disable forcefully unloading users registry at user logoff
- include_tasks: force_user_registry.yml
vars:
task_state: present
when:
- installed_updates is defined
- installed_updates is failed
- installed_updates.msg is defined
- ('0x800703FA' in installed_updates.msg)
- name: reboot the system to recover from a failed update
win_reboot:
reboot_timeout: 7200
@@ -36,32 +75,50 @@
delay: 60
sleep: 10
timeout: 600
- block:
- name: work on any skipped KB
win_updates:
server_selection: "{{ win_update_server_selection }}"
category_names: "{{ win_update_category_names }}"
reject_list: "{{ win_update_reject_list | default(omit) }}"
accept_list: "{{ failed_kb | default(omit) }}"
reboot: false
async: 7200
poll: 0
register: installed_updates_retry_skipped_async
- name: work on any skipped KB
win_updates:
category_names: "{{ win_update_category_names }}"
blacklist: "{{ win_update_blacklist | default(omit) }}"
whitelist: "{{ failed_kb | default([]) }}"
reboot: yes
register: installed_updates_retry_skipped
- name: wait for updates to finish
async_status:
jid: "{{ installed_updates_retry_skipped_async.ansible_job_id }}"
register: installed_updates_retry_skipped
until: installed_updates_retry_skipped.finished
retries: "{{ install_updates_retry_limit }}"
delay: 30
- name: reboot the system if required
win_reboot:
reboot_timeout: 7200
when: installed_updates_retry_skipped.reboot_required
when:
- failed_kb is defined
- failed_kb | length > 0
- name: check for missing updates
win_updates:
server_selection: "{{ win_update_server_selection }}"
category_names: "{{ win_update_category_names }}"
blacklist: "{{ win_update_blacklist | default(omit) }}"
reject_list: "{{ win_update_reject_list | default(omit) }}"
state: searched
register: missing_updates
- debug:
msg: |
msg: "{{ _msg.split('\n')[:-1] }}"
vars:
_msg: |
{{ inventory_hostname }} has {{ missing_updates.found_update_count }} updates still missing.
{% for update in updates %}
- {{ update.title }}
{% endfor %}
vars:
updates: "{{ (missing_updates.updates.values() | list) if (missing_updates.updates is mapping) else (missing_updates.updates) }}"
when: missing_updates.updates is defined
@@ -72,7 +129,7 @@
{{ (update_retry_limit | int) - (update_retry_count | int) }} more retries left'
when:
- missing_updates.found_update_count > 0
- ((update_retry_limit | int) - (update_retry_count | int) >= 0)
- ((update_retry_limit | int) - (update_retry_count | int) > 0)
rescue:
- name: set update count
@@ -80,7 +137,14 @@
update_retry_count: '{{ update_retry_count | default(0) | int + 1 }}'
- debug:
msg: "Still more updates remaining - retrying... ({{ update_retry_count }}/{{ update_retry_limit }})"
msg: "Still more updates ({{ current_update_count }}) remaining - retrying... ({{ update_retry_count }}/{{ update_retry_limit }})"
vars:
current_update_count: "{{ missing_updates.found_update_count | default(installed_updates.found_update_count) | default('-') }}"
- name: ensure system is reachable
wait_for_connection:
sleep: 10
timeout: 600
- include_tasks: updates-with-retry.yml
when: ((update_retry_limit | int) - (update_retry_count | int) >= 0)
when: ((update_retry_limit | int) - (update_retry_count | int) > 0)