win_scheduled_task: Add enhanced run option support (#24174)
* add enhanced run option support for win_scheduled_task * changed run_level option to runlevel * correct merge conflicts since task path fix * changed run_level option to runlevel * changed do_not_store_password to store_password, and other minor fixes * conditional logic swap, and documentation change for password
This commit is contained in:
parent
52c1a1936d
commit
7d3951d065
3 changed files with 215 additions and 7 deletions
|
@ -87,8 +87,10 @@ $executable = Get-AnsibleParam -obj $params -name "executable" -type "str" -alia
|
||||||
$frequency = Get-AnsibleParam -obj $params -name "frequency" -type "str" -validateset "once","daily","weekly" -failifempty $present
|
$frequency = Get-AnsibleParam -obj $params -name "frequency" -type "str" -validateset "once","daily","weekly" -failifempty $present
|
||||||
$time = Get-AnsibleParam -obj $params -name "time" -type "str" -failifempty $present
|
$time = Get-AnsibleParam -obj $params -name "time" -type "str" -failifempty $present
|
||||||
|
|
||||||
# TODO: We should default to the current user
|
$user = Get-AnsibleParam -obj $params -name "user" -default "$env:USERDOMAIN\$env:USERNAME" -type "str"
|
||||||
$user = Get-AnsibleParam -obj $params -name "user" -type "str" -failifempty $present
|
$password = Get-AnsibleParam -obj $params -name "password" -type "str"
|
||||||
|
$runlevel = Get-AnsibleParam -obj $params -name "runlevel" -default "limited" -type "str" -validateset "limited", "highest"
|
||||||
|
$store_password = Get-AnsibleParam -obj $params -name "store_password" -default $true -type "bool"
|
||||||
|
|
||||||
$weekly = $frequency -eq "weekly"
|
$weekly = $frequency -eq "weekly"
|
||||||
$days_of_week = Get-AnsibleParam -obj $params -name "days_of_week" -type "str" -failifempty $weekly
|
$days_of_week = Get-AnsibleParam -obj $params -name "days_of_week" -type "str" -failifempty $weekly
|
||||||
|
@ -165,7 +167,23 @@ try {
|
||||||
Exit-Json $result
|
Exit-Json $result
|
||||||
}
|
}
|
||||||
|
|
||||||
$principal = New-ScheduledTaskPrincipal -UserId "$user" -LogonType ServiceAccount
|
# Handle RunAs/RunLevel options for the task
|
||||||
|
|
||||||
|
if ($store_password) {
|
||||||
|
# Specify direct credential and run-level values to add to Register-ScheduledTask
|
||||||
|
$registerRunOptionParams = @{
|
||||||
|
User = $user
|
||||||
|
RunLevel = $runlevel
|
||||||
|
}
|
||||||
|
if ($password) {
|
||||||
|
$registerRunOptionParams.Password = $password
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Create a ScheduledTaskPrincipal for the task to run under
|
||||||
|
$principal = New-ScheduledTaskPrincipal -UserId $user -LogonType S4U -RunLevel $runlevel -Id Author
|
||||||
|
$registerRunOptionParams = @{Principal = $principal}
|
||||||
|
}
|
||||||
|
|
||||||
if ($enabled){
|
if ($enabled){
|
||||||
$settings = New-ScheduledTaskSettingsSet
|
$settings = New-ScheduledTaskSettingsSet
|
||||||
|
@ -186,7 +204,7 @@ try {
|
||||||
$pathResults = Invoke-TaskPathCheck -Path $path
|
$pathResults = Invoke-TaskPathCheck -Path $path
|
||||||
|
|
||||||
if (-not $check_mode) {
|
if (-not $check_mode) {
|
||||||
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName $name -Description $description -TaskPath $path -Settings $settings -Principal $principal
|
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName $name -Description $description -TaskPath $path -Settings $settings @registerRunOptionParams
|
||||||
}
|
}
|
||||||
|
|
||||||
$result.changed = $true
|
$result.changed = $true
|
||||||
|
@ -200,7 +218,15 @@ try {
|
||||||
# Check task path prior to registering
|
# Check task path prior to registering
|
||||||
$pathResults = Invoke-TaskPathCheck -Path $path
|
$pathResults = Invoke-TaskPathCheck -Path $path
|
||||||
|
|
||||||
if ($task.Description -eq $description -and $task.TaskName -eq $name -and $task.TaskPath -eq $path -and $task.Actions.Execute -eq $executable -and $taskState -eq $enabled -and $task.Principal.UserId -eq $user) {
|
if ((!$store_password -and $task.Principal.LogonType -in @("S4U", "ServiceAccount")) -or ($store_password -and $task.Principal.LogonType -notin @("S4U", "Password") -and !$password)) {
|
||||||
|
$passwordStoreConsistent = $true
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$passwordStoreConsistent = $false
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($task.Description -eq $description -and $task.TaskName -eq $name -and $task.TaskPath -eq $path -and $task.Actions.Execute -eq $executable -and
|
||||||
|
$taskState -eq $enabled -and $task.Principal.UserId -eq $user -and $task.Principal.RunLevel -eq $runlevel -and $passwordStoreConsistent) {
|
||||||
# No change in the task
|
# No change in the task
|
||||||
$result.msg = "No change in task $name"
|
$result.msg = "No change in task $name"
|
||||||
}
|
}
|
||||||
|
@ -209,7 +235,7 @@ try {
|
||||||
|
|
||||||
if (-not $check_mode) {
|
if (-not $check_mode) {
|
||||||
$oldPathResults = Invoke-TaskPathCheck -Path $task.TaskPath -Remove
|
$oldPathResults = Invoke-TaskPathCheck -Path $task.TaskPath -Remove
|
||||||
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName $name -Description $description -TaskPath $path -Settings $settings -Principal $principal
|
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName $name -Description $description -TaskPath $path -Settings $settings @registerRunOptionParams
|
||||||
}
|
}
|
||||||
$result.changed = $true
|
$result.changed = $true
|
||||||
$result.msg = "Updated task $name"
|
$result.msg = "Updated task $name"
|
||||||
|
|
|
@ -57,7 +57,27 @@ options:
|
||||||
- absent
|
- absent
|
||||||
user:
|
user:
|
||||||
description:
|
description:
|
||||||
- User to run scheduled task as
|
- User to run the scheduled task as; defaults to the current user
|
||||||
|
default: DOMAIN\user
|
||||||
|
password:
|
||||||
|
description:
|
||||||
|
- Password for the user account to run the scheduled task as. This is required for running a task without the user being
|
||||||
|
logged in, excluding Windows built-in service accounts. This should be used for specifying credentials during initial
|
||||||
|
task creation, and changing stored user credentials, as setting this value will cause the task to be recreated.
|
||||||
|
version_added: "2.4"
|
||||||
|
runlevel:
|
||||||
|
description:
|
||||||
|
- The level of user rights used to run the task
|
||||||
|
default: limited
|
||||||
|
choices:
|
||||||
|
- limited
|
||||||
|
- highest
|
||||||
|
version_added: "2.4"
|
||||||
|
store_password:
|
||||||
|
description:
|
||||||
|
- Store the password for the user running the task. If C(false), the task will only have access to local resources.
|
||||||
|
default: true
|
||||||
|
version_added: "2.4"
|
||||||
executable:
|
executable:
|
||||||
description:
|
description:
|
||||||
- Command the scheduled task should execute
|
- Command the scheduled task should execute
|
||||||
|
@ -99,4 +119,45 @@ EXAMPLES = r'''
|
||||||
state: present
|
state: present
|
||||||
enabled: yes
|
enabled: yes
|
||||||
user: SYSTEM
|
user: SYSTEM
|
||||||
|
|
||||||
|
- name: Create a task to run a PowerShell script as NETWORK SERVICE at the highest user rights level
|
||||||
|
win_scheduled_task:
|
||||||
|
name: TaskName2
|
||||||
|
description: Run a PowerShell script
|
||||||
|
executable: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
|
||||||
|
arguments: -ExecutionPolicy Unrestricted -NonInteractive -File C:\TestDir\Test.ps1
|
||||||
|
time: 6pm
|
||||||
|
frequency: once
|
||||||
|
state: present
|
||||||
|
enabled: yes
|
||||||
|
user: NETWORK SERVICE
|
||||||
|
runlevel: highest
|
||||||
|
|
||||||
|
- name: Change the above task to run under a domain user account, storing credentials for the task
|
||||||
|
win_scheduled_task:
|
||||||
|
name: TaskName2
|
||||||
|
description: Run a PowerShell script
|
||||||
|
executable: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
|
||||||
|
arguments: -ExecutionPolicy Unrestricted -NonInteractive -File C:\TestDir\Test.ps1
|
||||||
|
time: 6pm
|
||||||
|
frequency: once
|
||||||
|
state: present
|
||||||
|
enabled: yes
|
||||||
|
user: DOMAIN\user
|
||||||
|
password: passwordGoesHere
|
||||||
|
runlevel: highest
|
||||||
|
|
||||||
|
- name: Change the above task again, choosing not to store the password for the account
|
||||||
|
win_scheduled_task:
|
||||||
|
name: TaskName2
|
||||||
|
description: Run a PowerShell script
|
||||||
|
executable: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
|
||||||
|
arguments: -ExecutionPolicy Unrestricted -NonInteractive -File C:\TestDir\Test.ps1
|
||||||
|
time: 6pm
|
||||||
|
frequency: once
|
||||||
|
state: present
|
||||||
|
enabled: yes
|
||||||
|
user: DOMAIN\user
|
||||||
|
runlevel: highest
|
||||||
|
store_password: no
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -211,3 +211,124 @@
|
||||||
that:
|
that:
|
||||||
- remove_scheduled_task_new_path_1.msg == 'Task does not exist'
|
- remove_scheduled_task_new_path_1.msg == 'Task does not exist'
|
||||||
when: in_check_mode
|
when: in_check_mode
|
||||||
|
|
||||||
|
|
||||||
|
# Test scheduled task RunAs and RunLevel options
|
||||||
|
|
||||||
|
- name: Remove potentially leftover run options task 1
|
||||||
|
win_scheduled_task: &wstr1_absent
|
||||||
|
name: Ansible Test Run Options 1
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
|
||||||
|
- name: Add scheduled task run options 1
|
||||||
|
win_scheduled_task: &wstr1_present
|
||||||
|
name: Ansible Test Run Options 1
|
||||||
|
description: A test of run options functionality
|
||||||
|
executable: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
|
||||||
|
arguments: -ExecutionPolicy Unrestricted -NonInteractive -File C:\TestDir\Test.ps1
|
||||||
|
time: "6pm"
|
||||||
|
frequency: once
|
||||||
|
state: present
|
||||||
|
enabled: yes
|
||||||
|
user: SYSTEM
|
||||||
|
register: add_scheduled_task_run_options_1
|
||||||
|
|
||||||
|
- name: Test add_scheduled_task_run_options_1
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- add_scheduled_task_run_options_1.changed == true
|
||||||
|
- add_scheduled_task_run_options_1.exists == false
|
||||||
|
|
||||||
|
|
||||||
|
- name: Execute run options tests for normal mode only (expects scheduled task)
|
||||||
|
when: not in_check_mode
|
||||||
|
block:
|
||||||
|
|
||||||
|
- name: Change scheduled task run options user
|
||||||
|
win_scheduled_task:
|
||||||
|
<<: *wstr1_present
|
||||||
|
user: NETWORK SERVICE
|
||||||
|
register: change_scheduled_task_run_options_user
|
||||||
|
|
||||||
|
- name: Test change_scheduled_task_run_options_user
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- change_scheduled_task_run_options_user.changed == true
|
||||||
|
- change_scheduled_task_run_options_user.exists == true
|
||||||
|
|
||||||
|
|
||||||
|
- name: Change scheduled task run options user (again)
|
||||||
|
win_scheduled_task:
|
||||||
|
<<: *wstr1_present
|
||||||
|
user: NETWORK SERVICE
|
||||||
|
register: change_scheduled_task_run_options_user_again
|
||||||
|
|
||||||
|
- name: Test change_scheduled_task_run_options_user_again
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- change_scheduled_task_run_options_user_again.changed == false
|
||||||
|
- change_scheduled_task_run_options_user_again.exists == true
|
||||||
|
|
||||||
|
|
||||||
|
- name: Change scheduled task run options run level
|
||||||
|
win_scheduled_task:
|
||||||
|
<<: *wstr1_present
|
||||||
|
user: NETWORK SERVICE
|
||||||
|
runlevel: highest
|
||||||
|
register: change_scheduled_task_run_options_runlevel
|
||||||
|
|
||||||
|
- name: Test change_scheduled_task_run_options_runlevel
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- change_scheduled_task_run_options_runlevel.changed == true
|
||||||
|
- change_scheduled_task_run_options_runlevel.exists == true
|
||||||
|
|
||||||
|
|
||||||
|
- name: Change scheduled task run options run level (again)
|
||||||
|
win_scheduled_task:
|
||||||
|
<<: *wstr1_present
|
||||||
|
user: NETWORK SERVICE
|
||||||
|
runlevel: highest
|
||||||
|
register: change_scheduled_task_run_options_runlevel_again
|
||||||
|
|
||||||
|
- name: Test change_scheduled_task_run_options_runlevel_again
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- change_scheduled_task_run_options_runlevel_again.changed == false
|
||||||
|
- change_scheduled_task_run_options_runlevel_again.exists == true
|
||||||
|
|
||||||
|
|
||||||
|
# Should ignore change as account being tested is a built-in service account
|
||||||
|
- name: Change scheduled task run options store password
|
||||||
|
win_scheduled_task:
|
||||||
|
<<: *wstr1_present
|
||||||
|
user: NETWORK SERVICE
|
||||||
|
runlevel: highest
|
||||||
|
store_password: no
|
||||||
|
register: change_scheduled_task_run_options_store_password
|
||||||
|
|
||||||
|
- name: Test change_scheduled_task_run_options_store_password
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- change_scheduled_task_run_options_store_password.changed == false
|
||||||
|
- change_scheduled_task_run_options_store_password.exists == true
|
||||||
|
|
||||||
|
|
||||||
|
- name: Remove scheduled task run options 1
|
||||||
|
win_scheduled_task: *wstr1_absent
|
||||||
|
register: remove_scheduled_task_run_options_1
|
||||||
|
|
||||||
|
- name: Test remove_scheduled_task_run_options_1 (normal mode)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- remove_scheduled_task_run_options_1.changed == true
|
||||||
|
- remove_scheduled_task_run_options_1.exists == true
|
||||||
|
when: not in_check_mode
|
||||||
|
|
||||||
|
- name: Test remove_scheduled_task_run_options_1 (check-mode)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- remove_scheduled_task_run_options_1.changed == false
|
||||||
|
- remove_scheduled_task_run_options_1.exists == false
|
||||||
|
when: in_check_mode
|
||||||
|
|
Loading…
Reference in a new issue