task
This commit is contained in:
@@ -1,55 +1,118 @@
|
||||
---
|
||||
- name: Run DC patch task via JEA-PatchOps
|
||||
- name: Diagnose & start patch task via JEA-PatchOps
|
||||
hosts: domain_controllers
|
||||
gather_facts: no
|
||||
|
||||
vars:
|
||||
task_path: '\\' # root folder
|
||||
task_name: 'Patching-windows-task'
|
||||
poll_delay: 60
|
||||
finish_retries: 3 # up to 6h
|
||||
task_path: '\\' # root
|
||||
task_name: 'Patching-windows-task' # your task
|
||||
poll_delay: 30
|
||||
finish_retries: 3 # up to 2h
|
||||
|
||||
tasks:
|
||||
- name: Ensure the task is enabled
|
||||
- name: Show effective identity (who JEA runs as)
|
||||
ansible.windows.win_powershell:
|
||||
script: "[System.Security.Principal.WindowsIdentity]::GetCurrent().Name"
|
||||
register: whoami
|
||||
|
||||
- name: Read task details (state/enabled/last run)
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
$ErrorActionPreference = 'Stop'
|
||||
Import-Module ScheduledTasks
|
||||
$tp='{{ task_path }}'; $tn='{{ task_name }}'
|
||||
$t = Get-ScheduledTask -TaskPath $tp -TaskName $tn
|
||||
$i = Get-ScheduledTaskInfo -TaskPath $tp -TaskName $tn
|
||||
[PSCustomObject]@{
|
||||
Enabled = $t.Settings.Enabled
|
||||
State = $i.State
|
||||
LastRunTime = $i.LastRunTime
|
||||
LastTaskResult= $i.LastTaskResult
|
||||
Actions = ($t.Actions | Select-Object -ExpandProperty Execute -ErrorAction SilentlyContinue) -join ';'
|
||||
RunAs = $t.Principal.UserId
|
||||
} | ConvertTo-Json -Compress
|
||||
register: pre
|
||||
|
||||
- name: Compute on-disk task file path (C:\Windows\System32\Tasks\...)
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
$tp='{{ task_path }}'.Trim()
|
||||
if (-not $tp.EndsWith('\')) { $tp += '\' }
|
||||
$rel = $tp.Trim('\') -replace '\\','\'
|
||||
if ([string]::IsNullOrEmpty($rel)) { $rel = '' }
|
||||
$p = Join-Path 'C:\Windows\System32\Tasks' (Join-Path $rel '{{ task_name }}')
|
||||
$p
|
||||
register: taskfile
|
||||
|
||||
- name: Show ACL on the task file
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
$p='{{ taskfile.stdout | trim }}'
|
||||
if (Test-Path $p) { (Get-Acl $p).Access | Select IdentityReference,FileSystemRights,AccessControlType | Out-String } else { "MISSING: $p" }
|
||||
register: aclinfo
|
||||
|
||||
- name: Ensure JEA RunAs group can Start (RX,WD) the task file (adjust your group!)
|
||||
ansible.windows.win_command: >
|
||||
icacls "{{ taskfile.stdout | trim }}"
|
||||
/grant "TS-LABS25\SEC-PatchOperators:(RX,WD)"
|
||||
register: aclgrant
|
||||
changed_when: "'processed' in (aclgrant.stdout | default(''))"
|
||||
failed_when: false
|
||||
|
||||
- name: Enable task if disabled
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
Import-Module ScheduledTasks
|
||||
$tp='{{ task_path }}'; $tn='{{ task_name }}'
|
||||
$t = Get-ScheduledTask -TaskPath $tp -TaskName $tn
|
||||
if (-not $t.Settings.Enabled) { Enable-ScheduledTask -TaskPath $tp -TaskName $tn | Out-Null }
|
||||
register: enabled
|
||||
failed_when: false
|
||||
|
||||
- name: Start the SYSTEM patch task
|
||||
- name: Start via schtasks.exe (most reliable under JEA)
|
||||
ansible.windows.win_command: >
|
||||
schtasks /Run /TN "{{ task_path }}{{ task_name }}"
|
||||
register: start_task
|
||||
register: start_out
|
||||
failed_when: false
|
||||
changed_when: >
|
||||
(start_task.rc | default(1)) == 0
|
||||
or ('SUCCESS' in (start_task.stdout | default('')))
|
||||
(start_out.rc | default(1)) == 0
|
||||
or ('SUCCESS' in (start_out.stdout | default('')))
|
||||
|
||||
- name: Poll until Ready/Disabled with LastTaskResult 0
|
||||
- name: Confirm it actually started (LastRunTime changed)
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
Import-Module ScheduledTasks
|
||||
$tp='{{ task_path }}'; $tn='{{ task_name }}'
|
||||
(Get-ScheduledTaskInfo -TaskPath $tp -TaskName $tn).LastRunTime.ToString('o')
|
||||
register: started
|
||||
retries: 20
|
||||
delay: 15
|
||||
until: >
|
||||
(started.stdout | default('') | length > 0) and
|
||||
(started.stdout != ((pre.stdout | default('{}') | from_json).LastRunTime))
|
||||
|
||||
- name: Poll to finish (Ready/Disabled) and success (0 or 3010)
|
||||
ansible.windows.win_powershell:
|
||||
script: |
|
||||
$ErrorActionPreference = 'Stop'
|
||||
Import-Module ScheduledTasks
|
||||
$tp='{{ task_path }}'; $tn='{{ task_name }}'
|
||||
$i = Get-ScheduledTaskInfo -TaskPath $tp -TaskName $tn
|
||||
[PSCustomObject]@{ State=$i.State; LastTaskResult=$i.LastTaskResult; LastRunTime=$i.LastRunTime } |
|
||||
ConvertTo-Json -Compress
|
||||
register: task_info
|
||||
[PSCustomObject]@{ State=$i.State; LastTaskResult=$i.LastTaskResult; LastRunTime=$i.LastRunTime } | ConvertTo-Json -Compress
|
||||
register: info
|
||||
failed_when: false
|
||||
retries: "{{ finish_retries }}"
|
||||
delay: "{{ poll_delay }}"
|
||||
until: >
|
||||
((task_info.stdout | default('')) | length > 0)
|
||||
and (((task_info.stdout | default('{}')) | from_json).State in ['Ready','Disabled'])
|
||||
and ((((task_info.stdout | default('{}')) | from_json).LastTaskResult | int) in [0,3010])
|
||||
(info.stdout | default('') | length > 0)
|
||||
and ((info.stdout | from_json).State in ['Ready','Disabled'])
|
||||
and (((info.stdout | from_json).LastTaskResult | int) in [0,3010])
|
||||
|
||||
- name: Parse task info safely
|
||||
ansible.builtin.set_fact:
|
||||
task_info_parsed: "{{ (task_info.stdout | default('{}')) | from_json }}"
|
||||
|
||||
- name: Reboot if needed (state Ready)
|
||||
ansible.windows.win_reboot:
|
||||
reboot_timeout: 5400
|
||||
when: task_info_parsed.State == 'Ready'
|
||||
- name: Debug summary
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
- "RunAs (JEA): {{ whoami.stdout | default('n/a') }}"
|
||||
- "Task file: {{ taskfile.stdout | trim }}"
|
||||
- "ACL before grant (snippet): {{ aclinfo.stdout | default('n/a') | regex_replace('\\s+$','') }}"
|
||||
- "Start output rc/stdout: {{ start_out.rc | default('n/a') }} / {{ start_out.stdout | default('') | trim }}"
|
||||
- "Final State/Result: {{ (info.stdout | from_json).State }} / {{ (info.stdout | from_json).LastTaskResult }}"
|
||||
|
||||
Reference in New Issue
Block a user