summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Saraceni <andrew.saraceni@gmail.com>2017-07-10 00:18:17 -0400
committerJordan Borean <jborean93@gmail.com>2017-07-10 14:18:17 +1000
commit7d3951d065429ea3e55cc1dc6c599358030df559 (patch)
treecf8a97a45665eccd2bf3da431d4241969d544bb6
parent52c1a1936dda6fa55d4b9dde2af320fcc0ab4fd0 (diff)
downloadansible-7d3951d065429ea3e55cc1dc6c599358030df559.tar.gz
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
-rw-r--r--lib/ansible/modules/windows/win_scheduled_task.ps138
-rw-r--r--lib/ansible/modules/windows/win_scheduled_task.py63
-rw-r--r--test/integration/targets/win_scheduled_task/tasks/tests.yml121
3 files changed, 215 insertions, 7 deletions
diff --git a/lib/ansible/modules/windows/win_scheduled_task.ps1 b/lib/ansible/modules/windows/win_scheduled_task.ps1
index 06cfb3c38b..d3606a5258 100644
--- a/lib/ansible/modules/windows/win_scheduled_task.ps1
+++ b/lib/ansible/modules/windows/win_scheduled_task.ps1
@@ -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
$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" -type "str" -failifempty $present
+$user = Get-AnsibleParam -obj $params -name "user" -default "$env:USERDOMAIN\$env:USERNAME" -type "str"
+$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"
$days_of_week = Get-AnsibleParam -obj $params -name "days_of_week" -type "str" -failifempty $weekly
@@ -165,7 +167,23 @@ try {
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){
$settings = New-ScheduledTaskSettingsSet
@@ -186,7 +204,7 @@ try {
$pathResults = Invoke-TaskPathCheck -Path $path
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
@@ -200,7 +218,15 @@ try {
# Check task path prior to registering
$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
$result.msg = "No change in task $name"
}
@@ -209,7 +235,7 @@ try {
if (-not $check_mode) {
$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.msg = "Updated task $name"
diff --git a/lib/ansible/modules/windows/win_scheduled_task.py b/lib/ansible/modules/windows/win_scheduled_task.py
index 82c9038bda..70e4608b68 100644
--- a/lib/ansible/modules/windows/win_scheduled_task.py
+++ b/lib/ansible/modules/windows/win_scheduled_task.py
@@ -57,7 +57,27 @@ options:
- absent
user:
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:
description:
- Command the scheduled task should execute
@@ -99,4 +119,45 @@ EXAMPLES = r'''
state: present
enabled: yes
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
'''
diff --git a/test/integration/targets/win_scheduled_task/tasks/tests.yml b/test/integration/targets/win_scheduled_task/tasks/tests.yml
index 15e1cfd1ba..db62136b10 100644
--- a/test/integration/targets/win_scheduled_task/tasks/tests.yml
+++ b/test/integration/targets/win_scheduled_task/tasks/tests.yml
@@ -211,3 +211,124 @@
that:
- remove_scheduled_task_new_path_1.msg == 'Task does not exist'
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