summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Borean <jborean93@gmail.com>2017-03-02 16:17:16 +1000
committerMatt Davis <nitzmahone@users.noreply.github.com>2017-03-01 22:17:16 -0800
commitf4f09c9dbf9320d7d8f10b8c188d14b26486dcf8 (patch)
tree8a9085791093b4d36e75687e3a0290a59463e5fc
parent98b978d1d109be3375a808b9f0b9d359999e4654 (diff)
downloadansible-f4f09c9dbf9320d7d8f10b8c188d14b26486dcf8.tar.gz
Rewrote win_service with more options/check_mode (#19143)
-rw-r--r--lib/ansible/modules/windows/win_service.ps1449
-rw-r--r--lib/ansible/modules/windows/win_service.py219
-rw-r--r--test/integration/targets/win_service/defaults/main.yml9
-rw-r--r--test/integration/targets/win_service/tasks/main.yml840
4 files changed, 1361 insertions, 156 deletions
diff --git a/lib/ansible/modules/windows/win_service.ps1 b/lib/ansible/modules/windows/win_service.ps1
index 4ea4e2697a..5f568d1bf7 100644
--- a/lib/ansible/modules/windows/win_service.ps1
+++ b/lib/ansible/modules/windows/win_service.ps1
@@ -19,87 +19,438 @@
# WANT_JSON
# POWERSHELL_COMMON
-$params = Parse-Args $args;
+$ErrorActionPreference = "Stop"
-$result = New-Object PSObject;
-Set-Attr $result "changed" $false;
+$params = Parse-Args $args -supports_check_mode $true
+$check_mode = Get-AnsibleParam -obj $params "_ansible_check_mode" -type "bool" -default $false
-$name = Get-Attr $params "name" -failifempty $true
-$state = Get-Attr $params "state" $false
-$startMode = Get-Attr $params "start_mode" $false
+$dependencies = Get-AnsibleParam -obj $params -name 'dependencies' -failifempty $false -default $null
+$dependency_action = Get-AnsibleParam -obj $params -name 'dependency_action' -failifempty $false -ValidateSet 'add', 'remove', 'set' -default 'set'
+$description = Get-AnsibleParam -obj $params -name 'description' -failifempty $false -default $null
+$desktop_interact = Get-AnsibleParam -obj $params -name 'desktop_interact' -type "bool" -failifempty $false -default $false
+$display_name = Get-AnsibleParam -obj $params -name 'display_name' -failifempty $false -default $null
+$name = Get-AnsibleParam -obj $params -name 'name' -failifempty $true
+$password = Get-AnsibleParam -obj $params -name 'password' -failifempty $false -default $null
+$path = Get-AnsibleParam -obj $params -name 'path' -failifempty $false -default $null
+$start_mode = Get-AnsibleParam -obj $params -name 'start_mode' -failifempty $false -ValidateSet 'auto', 'manual', 'disabled', 'delayed'
+$state = Get-AnsibleParam -obj $params -name 'state' -failifempty $false -ValidateSet 'started', 'stopped', 'restarted', 'absent'
+$username = Get-AnsibleParam -obj $params -name 'username' -failifempty $false -default $null
-If ($state) {
- $state = $state.ToString().ToLower()
- If (($state -ne 'started') -and ($state -ne 'stopped') -and ($state -ne 'restarted')) {
- Fail-Json $result "state is '$state'; must be 'started', 'stopped', or 'restarted'"
+$result = @{
+ changed = $false
+ warnings = @()
+}
+
+# Check if dependencies is a string and convert to a list
+if ($dependencies -is [System.String]) {
+ $dependencies = @($dependencies)
+}
+
+if ($username -ne $null -and $password -eq $null) {
+ Fail-Json $result "The argument 'password' must be supplied with 'username'"
+}
+if ($password -ne $null -and $username -eq $null) {
+ Fail-Json $result "The argument 'username' must be supplied with 'password'"
+}
+if ($desktop_interact -eq $true -and (-not ($username -eq "LocalSystem" -or $username -eq $null))) {
+ Fail-Json $result "Can only set 'desktop_interact' to true when 'username' equals 'LocalSystem'"
+}
+
+Function Get-ServiceInfo($name) {
+ # Need to get new objects so we have the latest info
+ $svc = Get-Service -Name $name
+ $wmi_svc = Get-WmiObject Win32_Service | Where-Object { $_.Name -eq $svc.Name }
+
+ # Delayed start_mode is in reality Automatic (Delayed), need to check reg key for type
+ $delayed = Get-DelayedStatus -name $svc.Name
+ $actual_start_mode = $wmi_svc.StartMode.ToString().ToLower()
+ if ($delayed -and $actual_start_mode -eq 'auto') {
+ $actual_start_mode = 'delayed'
+ }
+
+ $existing_depenencies = @()
+ $existing_depended_by = @()
+ if ($svc.ServicesDependedOn.Count -gt 0) {
+ foreach ($dependency in $svc.ServicesDependedOn.Name) {
+ $existing_depenencies += $dependency
+ }
}
+ if ($svc.DependentServices.Count -gt 0) {
+ foreach ($dependency in $svc.DependentServices.Name) {
+ $existing_depended_by += $dependency
+ }
+ }
+
+ $result.exists = $true
+ $result.name = $svc.Name
+ $result.display_name = $svc.DisplayName
+ $result.state = $svc.Status.ToString().ToLower()
+ $result.start_mode = $actual_start_mode
+ $result.path = $wmi_svc.PathName
+ $result.description = $wmi_svc.Description
+ $result.username = $wmi_svc.startname
+ $result.desktop_interact = (ConvertTo-Bool $wmi_svc.DesktopInteract)
+ $result.dependencies = $existing_depenencies
+ $result.depended_by = $existing_depended_by
}
-If ($startMode) {
- $startMode = $startMode.ToString().ToLower()
- If (($startMode -ne 'auto') -and ($startMode -ne 'manual') -and ($startMode -ne 'disabled')) {
- Fail-Json $result "start mode is '$startMode'; must be 'auto', 'manual', or 'disabled'"
+Function Get-WmiErrorMessage($return_value) {
+ # These values are derived from https://msdn.microsoft.com/en-us/library/aa384901(v=vs.85).aspx
+ switch ($return_value) {
+ 1 { "Not Supported: The request is not supported" }
+ 2 { "Access Denied: The user did not have the necessary access" }
+ 3 { "Dependent Servies Running: The service cannot be stopped because other services that are running are dependent on it" }
+ 4 { "Invalid Service Control: Thre requested control code is not valid, or it is unacceptable to the service" }
+ 5 { "The requested control code cannot be sent to the service because the state of the service is equal to 0, 1, or 2" }
+ 6 { "Service Not Ative: The service has not been started" }
+ 7 { "Service Request Timeout: The service did not response to the start request in a timely fashion" }
+ 8 { "Unknown Failure: Unknown failure when starting the service" }
+ 9 { "Path Not Found: THe directory path to the service executable file was not found" }
+ 10 { "Service Already Running: The service is already running" }
+ 11 { "Service Database Locked: The database to add a new service is locked" }
+ 12 { "Service Dependency Deleted: A dependency this service relies on has been removed from the system" }
+ 13 { "Service Dependency Failure: The service failed to find the service needed from a dependent service" }
+ 14 { "Servoce Disabled: The service has been disbaled from the system" }
+ 15 { "Service Logon Failed: The service does not have the correct authentication to run on this system" }
+ 16 { "Service Marked For Deletion: This service is being removed from the system" }
+ 17 { "Service No Thread: The service has no execution thread" }
+ 18 { "Status Circular Dependecy: The service has circular dependencies when it starts" }
+ 19 { "Status Duplicate Name: A service is running under the same name" }
+ 20 { "Status Invalid Name: The service name has invalide characters" }
+ 21 { "Status Invalid Paramter: Invalid paramters have been passed to the service" }
+ 22 { "Status Invalid Service Account: The account under which this service runs is either invalid or lacks the permissions to run the service" }
+ 23 { "Status Service Exists: The service exists in the database of services available from the system" }
+ 24 { "Service Already Paused: The service is currently paused in the system" }
+ default { "Other Error" }
}
}
-$svcName = $name
-$svc = Get-Service -Name $svcName -ErrorAction SilentlyContinue
-If (-not $svc) {
- Fail-Json $result "Service '$svcName' not installed"
+Function Get-DelayedStatus($name) {
+ $delayed_key = "HKLM:\System\CurrentControlSet\Services\$name"
+ try {
+ $delayed = ConvertTo-Bool ((Get-ItemProperty -Path $delayed_key).DelayedAutostart)
+ } catch {
+ $delayed = $false
+ }
+
+ $delayed
}
-# Use service name instead of display name for remaining actions.
-If ($svcName -ne $svc.ServiceName) {
- $svcName = $svc.ServiceName
+
+Function Set-ServiceStartMode($svc, $start_mode) {
+ if ($result.start_mode -ne $start_mode) {
+ try {
+ $delayed_key = "HKLM:\System\CurrentControlSet\Services\$($svc.Name)"
+
+ if ($check_mode) {
+ # Original start up type was auto (delayed) and we want auto, need to removed delayed key
+ if ($start_mode -eq 'auto' -and $result.start_mode -eq 'delayed') {
+ Set-ItemProperty -Path $delayed_key -Name "DelayedAutostart" -Value 0 -Type DWORD -WhatIf
+ # Original start up type was auto and we want auto (delayed), need to add delayed key
+ } elseif ($start_mode -eq 'delayed' -and $result.start_mode -eq 'auto') {
+ Set-ItemProperty -Path $delayed_key -Name "DelayedAutostart" -Value 1 -Type DWORD -WhatIf
+ # Original start up type was not auto or auto (delayed), need to change to auto and add delayed key
+ } elseif ($start_mode -eq 'delayed') {
+ $svc | Set-Service -StartupType "auto" -WhatIf
+ Set-ItemProperty -Path $delayed_key -Name "DelayedAutostart" -Value 1 -Type DWORD -WhatIf
+ # Original start up type was not what we were looking for, just change to that type
+ } else {
+ $svc | Set-Service -StartupType $start_mode -WhatIf
+ }
+ } else {
+ if ($start_mode -eq 'auto' -and $result.start_mode -eq 'delayed') {
+ Set-ItemProperty -Path $delayed_key -Name "DelayedAutostart" -Value 0 -Type DWORD
+ } elseif ($start_mode -eq 'delayed' -and $result.start_mode -eq 'auto') {
+ Set-ItemProperty -Path $delayed_key -Name "DelayedAutostart" -Value 1 -Type DWORD
+ } elseif ($start_mode -eq 'delayed') {
+ $svc | Set-Service -StartupType "auto"
+ Set-ItemProperty -Path $delayed_key -Name "DelayedAutostart" -Value 1 -Type DWORD
+ } else {
+ $svc | Set-Service -StartupType $start_mode
+ }
+ }
+ } catch {
+ Fail-Json $result $_.Exception.Message
+ }
+
+ $result.changed = $true
+ }
}
-Set-Attr $result "name" $svc.ServiceName
-Set-Attr $result "display_name" $svc.DisplayName
+Function Set-ServiceAccount($wmi_svc, $username, $password) {
+ if ($result.username -ne $username) {
+ #WMI.Change doesn't support -WhatIf, cannot fully test with check_mode
+ if (-not $check_mode) {
+ $return = $wmi_svc.Change($null,$null,$null,$null,$null,$false,$username,$password,$null,$null,$null)
+ if ($return.ReturnValue -ne 0) {
+ Fail-Json $result "$($return.ReturnValue): $(Get-WmiErrorMessage -return_value $return.ReturnValue)"
+ }
+ }
-$svcMode = Get-WmiObject -Class Win32_Service -Property StartMode -Filter "Name='$svcName'"
-If ($startMode) {
- If ($svcMode.StartMode.ToLower() -ne $startMode) {
- Set-Service -Name $svcName -StartupType $startMode
- Set-Attr $result "changed" $true
- Set-Attr $result "start_mode" $startMode
+ $result.changed = $true
}
- Else {
- Set-Attr $result "start_mode" $svcMode.StartMode.ToLower()
+}
+
+Function Set-ServiceDesktopInteract($wmi_svc, $desktop_interact) {
+ if ($result.desktop_interact -ne $desktop_interact) {
+ if (-not $check_mode) {
+ $return = $wmi_svc.Change($null,$null,$null,$null,$null,$desktop_interact,$null,$null,$null,$null,$null)
+ if ($return.ReturnValue -ne 0) {
+ Fail-Json $result "$($return.ReturnValue): $(Get-WmiErrorMessage -return_value $return.ReturnValue)"
+ }
+ }
+
+ $result.changed = $true
}
}
-Else {
- Set-Attr $result "start_mode" $svcMode.StartMode.ToLower()
+
+Function Set-ServiceDisplayName($svc, $display_name) {
+ if ($result.display_name -ne $display_name) {
+ try {
+ if ($check_mode) {
+ $svc | Set-Service -DisplayName $display_name -WhatIf
+ } else {
+ $svc | Set-Service -DisplayName $display_name
+ }
+ } catch {
+ Fail-Json $result $_.Exception.Message
+ }
+
+ $result.changed = $true
+ }
}
-If ($state) {
- If ($state -eq "started" -and $svc.Status -ne "Running") {
+Function Set-ServiceDescription($svc, $description) {
+ if ($result.description -ne $description) {
try {
- Start-Service -Name $svcName -ErrorAction Stop
+ if ($check_mode) {
+ $svc | Set-Service -Description $description -WhatIf
+ } else {
+ $svc | Set-Service -Description $description
+ }
+ } catch {
+ Fail-Json $result $_.Exception.Message
}
- catch {
+
+ $result.changed = $true
+ }
+}
+
+Function Set-ServicePath($name, $path) {
+ if ($result.path -ne $path) {
+ try {
+ if ($check_mode) {
+ Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Services\$name" -Name ImagePath -Value $path -WhatIf
+ } else {
+ Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Services\$name" -Name ImagePath -Value $path
+ }
+ } catch {
Fail-Json $result $_.Exception.Message
}
- Set-Attr $result "changed" $true;
+
+ $result.changed = $true
+ }
+}
+
+Function Set-ServiceDependencies($wmi_svc, $dependency_action, $dependencies) {
+ $existing_dependencies = $result.dependencies
+ [System.Collections.ArrayList]$new_dependencies = @()
+
+ if ($dependency_action -eq 'set') {
+ $new_dependencies = $dependencies
+ } else {
+ $new_dependencies = $existing_dependencies
+ foreach ($dependency in $dependencies) {
+ if ($dependency_action -eq 'remove') {
+ if ($new_dependencies -contains $dependency) {
+ $new_dependencies.Remove($dependency)
+ }
+ } elseif ($dependency_action -eq 'add') {
+ if ($new_dependencies -notcontains $dependency) {
+ $new_dependencies.Add($dependency)
+ }
+ }
+ }
+ }
+
+ $will_change = $false
+ foreach ($dependency in $new_dependencies) {
+ if ($existing_dependencies -notcontains $dependency) {
+ $will_change = $true
+ }
}
- ElseIf ($state -eq "stopped" -and $svc.Status -ne "Stopped") {
+ foreach ($dependency in $existing_dependencies) {
+ if ($new_dependencies -notcontains $dependency) {
+ $will_change = $true
+ }
+ }
+
+ if ($will_change -eq $true) {
+ if (-not $check_mode) {
+ $return = $wmi_svc.Change($null,$null,$null,$null,$null,$null,$null,$null,$null,$null,$new_dependencies)
+ if ($return.ReturnValue -ne 0) {
+ Fail-Json $result "$($return.ReturnValue): $(Get-WmiErrorMessage -return_value $return.ReturnValue)"
+ }
+ }
+
+ $result.changed = $true
+ }
+}
+
+Function Set-ServiceState($svc, $wmi_svc, $state) {
+ if ($state -eq "started" -and $result.state -ne "running") {
try {
- Stop-Service -Name $svcName -ErrorAction Stop
+ if ($check_mode) {
+ Start-Service -Name $svc.Name -WhatIf
+ } else {
+ Start-Service -Name $svc.Name
+ }
+ } catch {
+ Fail-Json $result $_.Exception.Message
}
- catch {
+
+ $result.changed = $true
+ }
+
+ if ($state -eq "stopped" -and $result.state -ne "stopped") {
+ try {
+ if ($check_mode) {
+ Stop-Service -Name $svc.Name -Force -WhatIf
+ } else {
+ Stop-Service -Name $svc.Name -Force
+ }
+ } catch {
Fail-Json $result $_.Exception.Message
}
- Set-Attr $result "changed" $true;
+
+ $result.changed = $true
}
- ElseIf ($state -eq "restarted") {
+
+ if ($state -eq "restarted") {
try {
- Restart-Service -Name $svcName -ErrorAction Stop
+ if ($check_mode) {
+ Restart-Service -Name $svc.Name -Force -WhatIf
+ } else {
+ Restart-Service -Name $svc.Name -Force
+ }
+ } catch {
+ Fail-Json $result $_.Exception.Message
}
- catch {
+
+ $result.changed = $true
+ }
+
+ if ($state -eq "absent") {
+ try {
+ if ($check_mode) {
+ Stop-Service -Name $svc.Name -Force -WhatIf
+ } else {
+ Stop-Service -Name $svc.Name -Force
+ }
+ } catch {
Fail-Json $result $_.Exception.Message
}
- Set-Attr $result "changed" $true;
+ if (-not $check_mode) {
+ $return = $wmi_svc.Delete()
+ if ($return.ReturnValue -ne 0) {
+ Fail-Json $result "$($return.ReturnValue): $(Get-WmiErrorMessage -return_value $return.ReturnValue)"
+ }
+ }
+
+ $result.changed = $true
+ }
+}
+
+Function Set-ServiceConfiguration($svc) {
+ $wmi_svc = Get-WmiObject Win32_Service | Where-Object { $_.Name -eq $svc.Name }
+ Get-ServiceInfo -name $svc.Name
+ if ($desktop_interact -eq $true -and (-not ($result.username -eq 'LocalSystem' -or $username -eq 'LocalSystem'))) {
+ Fail-Json $result "Can only set desktop_interact to true when service is run with or 'username' equals 'LocalSystem'"
+ }
+
+ if ($start_mode -ne $null) {
+ Set-ServiceStartMode -svc $svc -start_mode $start_mode
+ }
+
+ if ($username -ne $null) {
+ Set-ServiceAccount -wmi_svc $wmi_svc -username $username -password $password
+ }
+
+ if ($display_name -ne $null) {
+ Set-ServiceDisplayName -svc $svc -display_name $display_name
+ }
+
+ if ($desktop_interact -ne $null) {
+ Set-ServiceDesktopInteract -wmi_svc $wmi_svc -desktop_interact $desktop_interact
+ }
+
+ if ($description -ne $null) {
+ Set-ServiceDescription -svc $svc -description $description
+ }
+
+ if ($path -ne $null) {
+ Set-ServicePath -name $svc.Name -path $path
+ }
+
+ if ($dependencies -ne $null) {
+ Set-ServiceDependencies -wmi_svc $wmi_svc -dependency_action $dependency_action -dependencies $dependencies
+ }
+
+ if ($state -ne $null) {
+ Set-ServiceState -svc $svc -wmi_svc $wmi_svc -state $state
+ }
+}
+
+$svc = Get-Service -Name $name -ErrorAction SilentlyContinue
+if ($svc) {
+ Set-ServiceConfiguration -svc $svc
+} else {
+ $result.exists = $false
+ if ($state -ne 'absent') {
+ # Check if path is defined, if so create the service
+ if ($path -ne $null) {
+ try {
+ if ($check_mode) {
+ New-Service -Name $name -BinaryPathname $path -WhatIf
+ } else {
+ New-Service -Name $name -BinaryPathname $path
+ }
+ } catch {
+ Fail-Json $result $_.Exception.Message
+ }
+ $result.changed = $true
+
+ $svc = Get-Service -Name $name
+ Set-ServiceConfiguration -svc $svc
+ } else {
+ # We will only reach here if the service is installed and the state is not absent
+ # Will check if any of the default actions are set and fail as we cannot action it
+ if ($start_mode -ne $null -or
+ $state -ne $null -or
+ $username -ne $null -or
+ $password -ne $null -or
+ $display_name -ne $null -or
+ $description -ne $null -or
+ $desktop_interact -ne $false -or
+ $dependencies -ne $null -or
+ $dependency_action -ne 'set') {
+ Fail-Json $result "Service '$name' is not installed, need to set 'path' to create a new service"
+ }
+ }
+ }
+}
+
+# After making a change, let's get the service info again unless we deleted it
+if ($state -eq 'absent') {
+ # Recreate result so it doesn't have the extra meta data now that is has been deleted
+ $changed = $result.changed
+ $warnings = $result.warnings
+ $result = @{
+ changed = $changed
+ warnings = $warnings
+ exists = $false
}
+} elseif ($svc -ne $null) {
+ Get-ServiceInfo -name $name
}
-$svc.Refresh()
-Set-Attr $result "state" $svc.Status.ToString().ToLower()
-Exit-Json $result;
+Exit-Json $result
diff --git a/lib/ansible/modules/windows/win_service.py b/lib/ansible/modules/windows/win_service.py
index 9cb33ba76c..2eb91d20c6 100644
--- a/lib/ansible/modules/windows/win_service.py
+++ b/lib/ansible/modules/windows/win_service.py
@@ -33,32 +33,91 @@ short_description: Manages Windows services
description:
- Manages Windows services
options:
+ dependencies:
+ description:
+ - A list of service dependencies to set for this particular service.
+ - This should be a list of service names and not the display name of the
+ service.
+ - This works by C(dependency_action) to either add/remove or set the
+ services in this list.
+ required: False
+ version_added: "2.3"
+ dependency_action:
+ description:
+ - Used in conjunction with C(dependency) to either add the dependencies to
+ the existing service dependencies.
+ - Remove the dependencies to the existing dependencies.
+ - Set the dependencies to only the values in the list replacing the
+ existing dependencies.
+ required: False
+ default: set
+ choices:
+ - set
+ - add
+ - remove
+ version_added: "2.3"
+ desktop_interact:
+ description:
+ - Whether to allow the service user to interact with the desktop.
+ - This should only be set to true when using the LocalSystem username.
+ required: False
+ default: False
+ version_added: "2.3"
+ description:
+ description:
+ - The description to set for the service.
+ required: False
+ version_added: "2.3"
+ display_name:
+ description:
+ - The display name to set for the service.
+ required: False
+ version_added: "2.3"
name:
description:
- Name of the service
required: true
- default: null
- aliases: []
+ path:
+ description:
+ - The path to the executable to set for the service.
+ required: False
+ version_added: "2.3"
+ password:
+ description:
+ - The password to set the service to start as.
+ - This and the C(username) argument must be supplied together.
+ - If specifying LocalSystem, NetworkService or LocalService this field
+ must be an empty string and not null.
+ required: False
+ version_added: "2.3"
start_mode:
description:
- - Set the startup type for the service
+ - Set the startup type for the service.
+ - C(delayed) added in Ansible 2.3
required: false
choices:
- auto
- manual
- disabled
+ - delayed
state:
description:
- - C(started)/C(stopped) are idempotent actions that will not run
- commands unless necessary. C(restarted) will always bounce the
- service.
+ - C(started)/C(stopped)/C(absent) are idempotent actions that will not run
+ commands unless necessary.
+ - C(restarted) will always bounce the service.
+ - C(absent) added in Ansible 2.3
required: false
choices:
- started
- stopped
- restarted
- default: null
- aliases: []
+ - absent
+ username:
+ description:
+ - The username to set the service to start as.
+ - This and the C(password) argument must be supplied together.
+ required: False
+ version_added: "2.3"
author: "Chris Hoffman (@chrishoffman)"
'''
@@ -73,4 +132,148 @@ EXAMPLES = r'''
name: spooler
start_mode: auto
state: started
+
+# a new service will also default to the following values:
+# - username: LocalSystem
+# - state: stopped
+# - start_mode: auto
+- name: create a new service
+ win_service:
+ name: service name
+ path: C:\temp\test.exe
+
+- name: create a new service with extra details
+ win_service:
+ name: service name
+ path: C:\temp\test.exe
+ display_name: Service Name
+ description: A test service description
+
+- name: remove a service
+ win_service:
+ name: service name
+ state: absent
+
+- name: check if a service is installed
+ win_service:
+ name: service name
+ register: service_info
+
+- name: set the log on user to a domain account
+ win_service:
+ name: service name
+ state: restarted
+ username: DOMAIN\User
+ password: Password
+
+- name: set the log on user to a local account
+ win_service:
+ name: service name
+ state: restarted
+ username: .\Administrator
+ password: Password
+
+- name: set the log on user to Local System
+ win_service:
+ name: service name
+ state: restarted
+ username: LocalSystem
+ password: ""
+
+- name: set the log on user to Local System and allow it to interact with the desktop
+ win_service:
+ name: service name
+ state: restarted
+ username: LocalSystem
+ password: ""
+ desktop_interact: True
+
+- name: set the log on user to Network Service
+ win_service:
+ name: service name
+ state: restarted
+ username: NT AUTHORITY\NetworkService
+ password: ""
+
+- name: set the log on user to Local Service
+ win_service:
+ name: service name
+ state: restarted
+ username: NT AUTHORITY\LocalService
+ password: ""
+
+- name: set dependencies to ones only in the list
+ win_service:
+ name: service name
+ dependencies: ['service1', 'service2']
+
+- name: add dependencies to existing dependencies
+ win_service:
+ name: service name
+ dependencies: ['service1', 'service2']
+ dependency_action: add
+
+- name: remove dependencies from existing dependencies
+ win_service:
+ name: service name
+ dependencies: ['service1', 'service2']
+ dependency_action: remove
+'''
+
+RETURN = r'''
+exists:
+ description: whether the service exists or not
+ returned: success
+ type: boolean
+ sample: true
+name:
+ description: the service name or id of the service
+ returned: success and service exists
+ type: string
+ sample: CoreMessagingRegistrar
+display_name:
+ description: the display name of the installed service
+ returned: success and service exists
+ type: string
+ sample: CoreMessaging
+status:
+ description: the current running status of the service
+ returned: success and service exists
+ type: string
+ sample: stopped
+start_mode:
+ description: the startup type of the service
+ returned: success and service exists
+ type: string
+ sample: manual
+path:
+ description:
+ returned: success and service exists
+ type: string
+ sample: C:\Windows\system32\svchost.exe -k LocalServiceNoNetwork
+description:
+ description: the path to the executable of the service
+ returned: success and service exists
+ type: string
+ sample: Manages communication between system components.
+username:
+ description: the username that runs the service
+ returned: success and service exists
+ type: string
+ sample: LocalSystem
+desktop_interact:
+ description: Whether the current user is allowed to interact with the desktop
+ returned: success and service exists
+ type: boolean
+ sample: False
+dependencies:
+ description: A list of dependencies the service relies on
+ returned: success and service exists
+ type: List
+ sample: False
+depended_by:
+ description: A list of dependencies this service relies on
+ returned: success and service exists
+ type: List
+ sample: False
'''
diff --git a/test/integration/targets/win_service/defaults/main.yml b/test/integration/targets/win_service/defaults/main.yml
index 1f38717aa4..4d4d0eca6b 100644
--- a/test/integration/targets/win_service/defaults/main.yml
+++ b/test/integration/targets/win_service/defaults/main.yml
@@ -1,5 +1,6 @@
---
-
-# Service is commonly available and usually disabled/stopped by default.
-test_win_service_name: SSDPSRV
-test_win_service_display_name: "SSDP Discovery"
+# parameters set here for creating new service in tests
+test_win_service_name: TestService
+test_win_service_display_name: Test Service
+test_win_service_description: Test Service description
+test_win_service_path: C:\Windows\System32\snmptrap.exe
diff --git a/test/integration/targets/win_service/tasks/main.yml b/test/integration/targets/win_service/tasks/main.yml
index 39562c4dcf..51f0cb50e5 100644
--- a/test/integration/targets/win_service/tasks/main.yml
+++ b/test/integration/targets/win_service/tasks/main.yml
@@ -16,181 +16,831 @@
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+- name: remove the dummy test services if it is left over from previous tests
+ win_service:
+ name: "{{item}}"
+ state: absent
+ with_items:
+ - "{{test_win_service_name}}"
+ - TestServiceParent2
+ - TestServiceDependency
+
+- name: create new dummy test service
+ win_service:
+ name: "{{test_win_service_name}}"
+ path: "{{test_win_service_path}}"
+ display_name: "{{test_win_service_display_name}}"
+ description: "{{test_win_service_description}}"
+ register: win_service_added
+
+- name: check that creating a new service succeeds with a change
+ assert:
+ that:
+ - "win_service_added|changed"
+ - "win_service_added.name == test_win_service_name"
+ - "win_service_added.display_name == test_win_service_display_name"
+ - "win_service_added.description == test_win_service_description"
+ - "win_service_added.path == test_win_service_path"
+ - "win_service_added.state == 'stopped'"
+ - "win_service_added.start_mode == 'auto'"
+ - "win_service_added.username == 'LocalSystem'"
+ - "win_service_added.desktop_interact == False"
+ - "win_service_added.dependencies == []"
+ - "win_service_added.depended_by == []"
+ - "win_service_added.exists == True"
+
- name: test win_service module with short name
- win_service: name="{{ test_win_service_name }}"
+ win_service:
+ name: "{{test_win_service_name}}"
register: win_service_name
- name: check win_service result with short name
assert:
that:
- - "not win_service_name|changed"
- - "win_service_name.name"
- - "win_service_name.display_name"
- - "win_service_name.start_mode"
- - "win_service_name.state"
+ - "not win_service_name|changed"
+ - "win_service_name.name == test_win_service_name"
+ - "win_service_name.display_name == test_win_service_display_name"
+ - "win_service_name.start_mode == 'auto'"
+ - "win_service_name.state == 'stopped'"
+ - "win_service_name.description == test_win_service_description"
+ - "win_service_name.exists == True"
+ - "win_service_name.path == test_win_service_path"
+ - "win_service_name.username == 'LocalSystem'"
+ - "win_service_name.desktop_interact == False"
+ - "win_service_name.dependencies == []"
+ - "win_service_name.depended_by == []"
- name: test win_service module with display name
- win_service: name="{{ test_win_service_display_name }}"
+ win_service:
+ name: "{{test_win_service_display_name}}"
register: win_service_display_name
- name: check win_service result with display name
assert:
that:
- - "not win_service_display_name|changed"
- - "win_service_display_name.name"
- - "win_service_display_name.display_name"
- - "win_service_display_name.start_mode"
- - "win_service_display_name.state"
+ - "not win_service_display_name|changed"
+ - "win_service_display_name.name == test_win_service_name"
+ - "win_service_display_name.display_name == test_win_service_display_name"
+ - "win_service_display_name.start_mode == 'auto'"
+ - "win_service_display_name.state == 'stopped'"
+ - "win_service_display_name.description == test_win_service_description"
+ - "win_service_display_name.exists == True"
+ - "win_service_display_name.path == test_win_service_path"
+ - "win_service_display_name.username == 'LocalSystem'"
+ - "win_service_display_name.desktop_interact == False"
+ - "win_service_display_name.dependencies == []"
+ - "win_service_display_name.depended_by == []"
- name: test win_service module with invalid name
- win_service: name="iamnotaservice"
- ignore_errors: true
+ win_service:
+ name: iamnotaservice
register: win_service_invalid
-- name: check win_service result with invalid_name
+- name: check win_service result with invalid name
assert:
that:
- - "win_service_invalid|failed"
- - "win_service_invalid.msg"
+ - "not win_service_invalid|changed"
+ - "win_service_invalid.exists == False"
-- name: make sure the service is stopped and disabled
- win_service: name="{{ test_win_service_name }}" state=stopped start_mode=disabled
- register: win_service_stopped_disabled
+- name: test win_service module with invalid name and absent state
+ win_service:
+ name: iamnotaservice
+ state: absent
+ register: win_service_invalid_with_absent
-- name: check result of disabling and stopping the service
+- name: check win_service result with invalid name and absent state
assert:
that:
- - "win_service_stopped_disabled.start_mode == 'disabled'"
- - "win_service_stopped_disabled.state == 'stopped'"
+ - "not win_service_invalid_with_absent|changed"
+ - "win_service_invalid_with_absent.exists == False"
+
+- name: test win_service module with invalid name and startup
+ win_service:
+ name: iamnotaservice
+ state: started
+ register: win_service_invalid_with_action
+ ignore_errors: True
+
+- name: check win_service result with invalid name and startup
+ assert:
+ that:
+ - "win_service_invalid_with_action|failed"
+ - "win_service_invalid_with_action.msg == 'Service \\'iamnotaservice\\' is not installed, need to set \\'path\\' to create a new service'"
+
+- name: make sure the service is stopped and disabled for next tests
+ win_service:
+ name: "{{test_win_service_name}}"
+ state: stopped
+ start_mode: disabled
+ register: win_service_stopped_disabled
- name: try to start the disabled service
- win_service: name="{{ test_win_service_name }}" state=started
+ win_service:
+ name: "{{test_win_service_name}}"
+ state: started
register: win_service_start_disabled
- ignore_errors: true
+ ignore_errors: True
-- name: check that starting the disabled service fails
+- name: check that trying to start a disabled service failed
assert:
that:
- - "win_service_start_disabled|failed"
- - "win_service_start_disabled.msg"
+ - "win_service_start_disabled|failed"
+ - "win_service_start_disabled.msg"
- name: enable the service for manual startup
- win_service: name="{{ test_win_service_name }}" start_mode=manual
+ win_service:
+ name: "{{test_win_service_name}}"
+ start_mode: manual
register: win_service_manual_start_mode
-- name: check that enabling the service succeeds for manual startup
+- name: check that enabling the service for manual startup succeeded
assert:
that:
- - "win_service_manual_start_mode|changed"
- - "win_service_manual_start_mode.start_mode == 'manual'"
- - "win_service_manual_start_mode.state == 'stopped'"
-
-- name: enable the service again for manual startup
- win_service: name="{{ test_win_service_name }}" start_mode=manual
+ - "win_service_manual_start_mode|changed"
+ - "win_service_manual_start_mode.start_mode == 'manual'"
+ - "win_service_manual_start_mode.state == 'stopped'"
+
+- name: enable the service for manual startup again
+ win_service:
+ name: "{{test_win_service_name}}"
+ start_mode: manual
register: win_service_manual_start_mode_again
-- name: check that enabling the service succeeds for manual startup
+- name: check that enabling service for manual startup again didn't change anything
assert:
that:
- - "not win_service_manual_start_mode_again|changed"
- - "win_service_manual_start_mode_again.start_mode == 'manual'"
- - "win_service_manual_start_mode_again.state == 'stopped'"
+ - "not win_service_manual_start_mode_again|changed"
+ - "win_service_manual_start_mode_again.start_mode == 'manual'"
+ - "win_service_manual_start_mode_again.state == 'stopped'"
-- name: try to start the manual service
- win_service: name="{{ test_win_service_name }}" state=started
- register: win_service_start_manual
+- name: enable the service for delayed startup from non automatic
+ win_service:
+ name: "{{test_win_service_name}}"
+ start_mode: delayed
+ register: win_service_delayed_start_mode
-- name: check that starting the manual service succeeds
+- name: check that that enabling the service for delayed startup succeeded
assert:
that:
- - "win_service_start_manual|changed"
- - "win_service_start_manual.start_mode == 'manual'"
- - "win_service_start_manual.state == 'running'"
+ - "win_service_delayed_start_mode|changed"
+ - "win_service_delayed_start_mode.start_mode == 'delayed'"
+ - "win_service_delayed_start_mode.state == 'stopped'"
-- name: try to start the manual service again
- win_service: name="{{ test_win_service_name }}" state=started
- register: win_service_start_manual_again
+- name: enable the service for delayed startup from non automatic again
+ win_service:
+ name: "{{test_win_service_name}}"
+ start_mode: delayed
+ register: win_service_delayed_start_mode_again
-- name: check that starting the manual service again succeeds without changes
+- name: check that enabling the service for delayed startup again no changes
assert:
that:
- - "not win_service_start_manual_again|changed"
- - "win_service_start_manual_again.start_mode == 'manual'"
- - "win_service_start_manual_again.state == 'running'"
+ - "not win_service_delayed_start_mode_again|changed"
+ - "win_service_delayed_start_mode_again.start_mode == 'delayed'"
+ - "win_service_delayed_start_mode_again.state == 'stopped'"
- name: enable the service for automatic startup
- win_service: name="{{ test_win_service_name }}" start_mode=auto
+ win_service:
+ name: "{{test_win_service_name}}"
+ start_mode: auto
register: win_service_auto_start_mode
-- name: check that enabling the service succeeds for automatic startup
+- name: check that enabling the service for auto startup succeeded
assert:
that:
- - "win_service_auto_start_mode|changed"
- - "win_service_auto_start_mode.start_mode == 'auto'"
- - "win_service_auto_start_mode.state == 'running'"
-
-- name: enable the service again for automatic startup
- win_service: name="{{ test_win_service_name }}" start_mode=auto
+ - "win_service_auto_start_mode|changed"
+ - "win_service_auto_start_mode.start_mode == 'auto'"
+ - "win_service_auto_start_mode.state == 'stopped'"
+
+- name: enable the service for automatic startup again
+ win_service:
+ name: "{{test_win_service_name}}"
+ start_mode: auto
register: win_service_auto_start_mode_again
-- name: check that enabling the service succeeds for automatic startup without changes
+- name: check that enabling the service for auto startup again no changes
assert:
that:
- - "not win_service_auto_start_mode_again|changed"
- - "win_service_auto_start_mode_again.start_mode == 'auto'"
- - "win_service_auto_start_mode_again.state == 'running'"
+ - "not win_service_auto_start_mode_again|changed"
+ - "win_service_auto_start_mode_again.start_mode == 'auto'"
+ - "win_service_auto_start_mode_again.state == 'stopped'"
+
+- name: enable the service for delayed startup from automatic
+ win_service:
+ name: "{{test_win_service_name}}"
+ start_mode: delayed
+ register: win_service_delayed_start_mode_from_auto
+
+- name: check that enabling the service for delayed startup from auto succeeded
+ assert:
+ that:
+ - "win_service_delayed_start_mode_from_auto|changed"
+ - "win_service_delayed_start_mode_from_auto.start_mode == 'delayed'"
+ - "win_service_delayed_start_mode_from_auto.state == 'stopped'"
+
+- name: enable the service for delayed startup from automatic again
+ win_service:
+ name: "{{test_win_service_name}}"
+ start_mode: delayed
+ register: win_service_delayed_start_mode_from_auto_again
+
+- name: check that enabling the service for delayed startup from auto succeeded again no change
+ assert:
+ that:
+ - "not win_service_delayed_start_mode_from_auto_again|changed"
+ - "win_service_delayed_start_mode_from_auto_again.start_mode == 'delayed'"
+ - "win_service_delayed_start_mode_from_auto_again.state == 'stopped'"
+
+- name: start the service
+ win_service:
+ name: "{{test_win_service_name}}"
+ state: started
+ register: win_service_start
+
+- name: check that starting the service succeeds with changes
+ assert:
+ that:
+ - "win_service_start|changed"
+ - "win_service_start.state == 'running'"
+
+- name: start the service again
+ win_service:
+ name: "{{test_win_service_name}}"
+ state: started
+ register: win_service_start_again
+
+- name: check that starting the service succeeds again with no changes
+ assert:
+ that:
+ - "not win_service_start_again|changed"
+ - "win_service_start_again.state == 'running'"
+
- name: restart the service
- win_service: name="{{ test_win_service_name }}" state=restarted
- register: win_service_restart_auto
+ win_service:
+ name: "{{test_win_service_name}}"
+ state: restarted
+ register: win_service_restart
- name: check that restarting the service succeeds with changes
assert:
that:
- - "win_service_restart_auto|changed"
- - "win_service_restart_auto.start_mode == 'auto'"
- - "win_service_restart_auto.state == 'running'"
+ - "win_service_restart|changed"
+ - "win_service_restart.state =='running'"
+
+- name: restart the service again
+ win_service:
+ name: "{{test_win_service_name}}"
+ state: restarted
+ register: win_service_restart_again
+
+- name: check that restarting the service again succeeds with changes
+ assert:
+ that:
+ - "win_service_restart_again|changed"
+ - "win_service_restart_again.state =='running'"
-- name: disable the service again
- win_service: name="{{ test_win_service_name }}" start_mode=disabled
- register: win_service_disabled_start_mode
+- name: disable the service while running
+ win_service:
+ name: "{{test_win_service_name}}"
+ start_mode: disabled
+ register: win_service_disabled_while_running
- name: check that disabling the service succeeds, service is still running
assert:
that:
- - "win_service_disabled_start_mode|changed"
- - "win_service_disabled_start_mode.start_mode == 'disabled'"
- - "win_service_disabled_start_mode.state == 'running'"
+ - "win_service_disabled_while_running|changed"
+ - "win_service_disabled_while_running.start_mode == 'disabled'"
+ - "win_service_disabled_while_running.state == 'running'"
-- name: disable the service again
- win_service: name="{{ test_win_service_name }}" start_mode=disabled
- register: win_service_disabled_start_mode_again
+- name: disable the service while running again
+ win_service:
+ name: "{{test_win_service_name}}"
+ start_mode: disabled
+ register: win_service_disabled_while_running_again
-- name: check that disabling the service succeeds again
+- name: check that disabling the service again succeeds, service is still running but with no changes
assert:
that:
- - "not win_service_disabled_start_mode_again|changed"
- - "win_service_disabled_start_mode_again.start_mode == 'disabled'"
- - "win_service_disabled_start_mode_again.state == 'running'"
+ - "not win_service_disabled_while_running_again|changed"
+ - "win_service_disabled_while_running_again.start_mode == 'disabled'"
+ - "win_service_disabled_while_running_again.state == 'running'"
- name: stop the service
- win_service: name="{{ test_win_service_name }}" state=stopped
- register: win_service_stop_disabled
+ win_service:
+ name: "{{test_win_service_name}}"
+ state: stopped
+ register: win_service_stopped
- name: check that stopping the service succeeds with changes
assert:
that:
- - "win_service_stop_disabled|changed"
- - "win_service_stop_disabled.start_mode == 'disabled'"
- - "win_service_stop_disabled.state == 'stopped'"
+ - "win_service_stopped|changed"
+ - "win_service_stopped.state == 'stopped'"
- name: stop the service again
- win_service: name="{{ test_win_service_name }}" state=stopped
- register: win_service_stop_disabled_again
+ win_service:
+ name: "{{test_win_service_name}}"
+ state: stopped
+ register: win_service_stopped_again
+
+- name: check that stopping the service again succeeds with no changes
+ assert:
+ that:
+ - "not win_service_stopped_again|changed"
+ - "win_service_stopped_again.state == 'stopped'"
+
+- name: set username without password
+ win_service:
+ name: "{{test_win_service_name}}"
+ username: username
+ register: win_service_change_user_without_password
+ ignore_errors: True
+
+- name: check that setting a user without a password fails
+ assert:
+ that:
+ - "win_service_change_user_without_password|failed"
+ - "win_service_change_user_without_password.msg"
+
+- name: set password without username
+ win_service:
+ name: "{{test_win_service_name}}"
+ password: password
+ register: win_service_change_password_without_user
+ ignore_errors: True
+
+- name: check that setting a user without a password fails
+ assert:
+ that:
+ - "win_service_change_password_without_user|failed"
+ - "win_service_change_password_without_user.msg"
+
+- name: set service username to Network Service and desktop interact fail
+ win_service:
+ name: "{{test_win_service_name}}"
+ username: NT AUTHORITY\NetworkService
+ password: ""
+ desktop_interact: True
+ register: win_desktop_interact_not_local_system
+ ignore_errors: True
+
+- name: check that setting desktop interact with non LocalSystem failed
+ assert:
+ that:
+ - "win_desktop_interact_not_local_system|failed"
+ - "win_desktop_interact_not_local_system.msg"
+
+- name: set service username to Network Service
+ win_service:
+ name: "{{test_win_service_name}}"
+ username: NT AUTHORITY\NetworkService
+ password: ""
+ register: win_service_change_password_network_service
+
+- name: check that the service user has been set to Network Service
+ assert:
+ that:
+ - "win_service_change_password_network_service|changed"
+ - "win_service_change_password_network_service.username == 'NT AUTHORITY\\\\NetworkService'"
+ - "win_service_change_password_network_service.desktop_interact == False"
+
+- name: set service username to Network Service again
+ win_service:
+ name: "{{test_win_service_name}}"
+ username: NT AUTHORITY\NetworkService
+ password: ""
+ register: win_service_change_password_network_service_again
+
+- name: check that the service user has been set to Network Service and nothing changed
+ assert:
+ that:
+ - "not win_service_change_password_network_service_again|changed"
+ - "win_service_change_password_network_service_again.username == 'NT AUTHORITY\\\\NetworkService'"
+ - "win_service_change_password_network_service_again.desktop_interact == False"
+
+- name: set service username to interact with desktop with existing user to fail
+ win_service:
+ name: "{{test_win_service_name}}"
+ desktop_interact: True
+ register: win_service_desktop_interact_current_user_fail
+ ignore_errors: True
+
+- name: check that setting desktop interact with current user not LocalSystem failed
+ assert:
+ that:
+ - "win_service_desktop_interact_current_user_fail|failed"
+ - "win_service_desktop_interact_current_user_fail.msg"
+
+- name: set service username to Local Service
+ win_service:
+ name: "{{test_win_service_name}}"
+ username: NT AUTHORITY\LocalService
+ password: ""
+ register: win_service_change_password_local_service
+
+- name: check that the service user has been set to Local Service
+ assert:
+ that:
+ - "win_service_change_password_local_service|changed"
+ - "win_service_change_password_local_service.username == 'NT AUTHORITY\\\\LocalService'"
+ - "win_service_change_password_local_service.desktop_interact == False"
+
+- name: set service username to Local Service again
+ win_service:
+ name: "{{test_win_service_name}}"
+ username: NT AUTHORITY\LocalService
+ password: ""
+ register: win_service_change_password_local_service_again
+
+- name: check that the service user has been set to Local Service and nothing changed
+ assert:
+ that:
+ - "not win_service_change_password_local_service_again|changed"
+ - "win_service_change_password_local_service_again.username == 'NT AUTHORITY\\\\LocalService'"
+ - "win_service_change_password_local_service_again.desktop_interact == False"
+
+- name: set service username to Local System
+ win_service:
+ name: "{{test_win_service_name}}"
+ username: LocalSystem
+ password: ""
+ register: win_service_change_password_local_system
+
+- name: check that the service user has been set to Local System
+ assert:
+ that:
+ - "win_service_change_password_local_system|changed"
+ - "win_service_change_password_local_system.username == 'LocalSystem'"
+ - "win_service_change_password_local_system.desktop_interact == False"
+
+- name: set service username to Local System again
+ win_service:
+ name: "{{test_win_service_name}}"
+ username: LocalSystem
+ password: ""
+ register: win_service_change_password_local_system_again
+
+- name: check that the service user has been set to Local System and nothing changed
+ assert:
+ that:
+ - "not win_service_change_password_local_system_again|changed"
+ - "win_service_change_password_local_system_again.username == 'LocalSystem'"
+ - "win_service_change_password_local_system_again.desktop_interact == False"
+
+- name: set service username to Local System with desktop interaction
+ win_service:
+ name: "{{test_win_service_name}}"
+ username: LocalSystem
+ password: ""
+ desktop_interact: True
+ register: win_service_local_system_desktop
+
+- name: check that the service has been set to Local Sytem with desktop interaction
+ assert:
+ that:
+ - "win_service_local_system_desktop|changed"
+ - "win_service_local_system_desktop.username == 'LocalSystem'"
+ - "win_service_local_system_desktop.desktop_interact == True"
+
+- name: set service username to Local System with desktop interaction again
+ win_service:
+ name: "{{test_win_service_name}}"
+ username: LocalSystem
+ password: ""
+ desktop_interact: True
+ register: win_service_local_system_desktop_again
+
+- name: check that the service has been set to Local System with desktop interaction again
+ assert:
+ that:
+ - "not win_service_local_system_desktop_again|changed"
+ - "win_service_local_system_desktop_again.username == 'LocalSystem'"
+ - "win_service_local_system_desktop_again.desktop_interact == True"
+
+- name: set desktop interaction to disabled
+ win_service:
+ name: "{{test_win_service_name}}"
+ desktop_interact: False
+ register: win_service_desktop_disable
+
+- name: check that desktop interaction has been disabled
+ assert:
+ that:
+ - "win_service_desktop_disable|changed"
+ - "win_service_desktop_disable.username == 'LocalSystem'"
+ - "win_service_desktop_disable.desktop_interact == False"
+
+- name: set desktop interaction to disabled again
+ win_service:
+ name: "{{test_win_service_name}}"
+ desktop_interact: False
+ register: win_service_desktop_disable_again
+
+- name: check that desktop interaction has been disabled again
+ assert:
+ that:
+ - "not win_service_desktop_disable_again|changed"
+ - "win_service_desktop_disable_again.username == 'LocalSystem'"
+ - "win_service_desktop_disable_again.desktop_interact == False"
+
+- name: set desktop interaction to enabled with current user as LocalSystem
+ win_service:
+ name: "{{test_win_service_name}}"
+ desktop_interact: True
+ register: win_service_desktop_enable
+
+- name: check that desktop iteraction has been enabled
+ assert:
+ that:
+ - "win_service_desktop_enable|changed"
+ - "win_service_desktop_enable.username == 'LocalSystem'"
+ - "win_service_desktop_enable.desktop_interact == True"
+
+- name: set desktop interaction to enabled with current user as LocalSystem again
+ win_service:
+ name: "{{test_win_service_name}}"
+ desktop_interact: True
+ register: win_service_desktop_enable_again
+
+- name: check that desktop iteraction has been enabled again
+ assert:
+ that:
+ - "not win_service_desktop_enable_again|changed"
+ - "win_service_desktop_enable_again.username == 'LocalSystem'"
+ - "win_service_desktop_enable_again.desktop_interact == True"
+
+- name: set service username to current user
+ win_service:
+ name: "{{test_win_service_name}}"
+ username: ".\\{{ansible_user}}"
+ password: "{{ansible_password}}"
+ register: win_service_change_password_current_user
+
+- name: check that the service user has been set to current user
+ assert:
+ that:
+ - "win_service_change_password_current_user|changed"
+ - "win_service_change_password_current_user.username == '.\\\\{{ansible_user}}'"
+ - "win_service_change_password_current_user.desktop_interact == False"
+
+- name: set service username to current user again
+ win_service:
+ name: "{{test_win_service_name}}"
+ username: ".\\{{ansible_user}}"
+ password: "{{ansible_password}}"
+ register: win_service_change_password_current_user_again
+
+- name: check that the service user has been set to current user and nothing changed
+ assert:
+ that:
+ - "not win_service_change_password_current_user_again|changed"
+ - "win_service_change_password_current_user_again.username == '.\\\\{{ansible_user}}'"
+ - "win_service_change_password_current_user_again.desktop_interact == False"
+
+- name: set service display name
+ win_service:
+ name: "{{test_win_service_name}}"
+ display_name: Test Service New
+ register: win_service_display_name
+
+- name: check that the service display name has been changed
+ assert:
+ that:
+ - "win_service_display_name|changed"
+ - "win_service_display_name.display_name == 'Test Service New'"
+
+- name: set service display name again
+ win_service:
+ name: "{{test_win_service_name}}"
+ display_name: Test Service New
+ register: win_service_display_name_again
+
+- name: check that the service display name has been changed again
+ assert:
+ that:
+ - "not win_service_display_name_again|changed"
+ - "win_service_display_name_again.display_name == 'Test Service New'"
+
+- name: set service description
+ win_service:
+ name: "{{test_win_service_name}}"
+ description: New Description
+ register: win_service_description
+
+- name: check that the service description has been changed
+ assert:
+ that:
+ - "win_service_description|changed"
+ - "win_service_description.description == 'New Description'"
+
+- name: set service description again
+ win_service:
+ name: "{{test_win_service_name}}"
+ description: New Description
+ register: win_service_description_again
+
+- name: check that the service description has been changed again
+ assert:
+ that:
+ - "not win_service_description_again|changed"
+ - "win_service_description_again.description == 'New Description'"
+
+- name: set service path
+ win_service:
+ name: "{{test_win_service_name}}"
+ path: C:\temp\test.exe
+ register: win_service_path
-- name: check that stopping the service again succeeds without changes
+- name: check that the service path has been changed
+ assert:
+ that:
+ - "win_service_path|changed"
+ - "win_service_path.path == 'C:\\\\temp\\\\test.exe'"
+
+- name: set service path again
+ win_service:
+ name: "{{test_win_service_name}}"
+ path: C:\temp\test.exe
+ register: win_service_path_again
+
+- name: check that the service path has been changed again
+ assert:
+ that:
+ - "not win_service_path_again|changed"
+ - "win_service_path_again.path == 'C:\\\\temp\\\\test.exe'"
+
+- name: revert original service path back to normal
+ win_service:
+ name: "{{test_win_service_name}}"
+ path: "{{test_win_service_path}}"
+
+- name: create new second dependency parent service
+ win_service:
+ name: TestServiceParent2
+ display_name: Test Service Parent 2
+ path: "{{test_win_service_path}}"
+
+- name: create new dependency service
+ win_service:
+ name: TestServiceDependency
+ display_name: Test Service Dependency
+ path: "{{test_win_service_path}}"
+ dependencies: "{{test_win_service_name}}"
+ register: win_service_dependency_string
+
+- name: check that the service with a dependency has been created
+ assert:
+ that:
+ - "win_service_dependency_string|changed"
+ - "win_service_dependency_string.dependencies == ['{{test_win_service_name}}']"
+
+- name: create new dependencys service again
+ win_service:
+ name: TestServiceDependency
+ dependencies: "{{test_win_service_name}}"
+ register: win_service_dependency_string_again
+
+- name: check that the service with a dependency has been created again
+ assert:
+ that:
+ - "not win_service_dependency_string_again|changed"
+ - "win_service_dependency_string_again.dependencies == ['{{test_win_service_name}}']"
+
+- name: add another dependency to service
+ win_service:
+ name: TestServiceDependency
+ dependencies: ['TestServiceParent2']
+ dependency_action: add
+ register: win_service_dependency_add
+
+- name: check that the service with a dependency has been added
+ assert:
+ that:
+ - "win_service_dependency_add|changed"
+ - "win_service_dependency_add.dependencies == ['{{test_win_service_name}}', 'TestServiceParent2']"
+
+- name: add another dependency to service again
+ win_service:
+ name: TestServiceDependency
+ dependencies: ['TestServiceParent2']
+ dependency_action: add
+ register: win_service_dependency_add_again
+
+- name: check that the service with a dependency has been added again
+ assert:
+ that:
+ - "not win_service_dependency_add_again|changed"
+ - "win_service_dependency_add_again.dependencies == ['{{test_win_service_name}}', 'TestServiceParent2']"
+
+- name: remove another dependency to service
+ win_service:
+ name: TestServiceDependency
+ dependencies: ['TestServiceParent2']
+ dependency_action: remove
+ register: win_service_dependency_add
+
+- name: check that the service with a dependency has been remove
+ assert:
+ that:
+ - "win_service_dependency_add|changed"
+ - "win_service_dependency_add.dependencies == ['{{test_win_service_name}}']"
+
+- name: remove another dependency to service again
+ win_service:
+ name: TestServiceDependency
+ dependencies: ['TestServiceParent2']
+ dependency_action: remove
+ register: win_service_dependency_add_again
+
+- name: check that the service with a dependency has been removed again
+ assert:
+ that:
+ - "not win_service_dependency_add_again|changed"
+ - "win_service_dependency_add_again.dependencies == ['{{test_win_service_name}}']"
+
+- name: set dependency with a list
+ win_service:
+ name: TestServiceDependency
+ dependencies: ['{{test_win_service_name}}', 'TestServiceParent2']
+ dependency_action: set
+ register: win_service_dependency_set_list
+
+- name: check that the service with dependencies has been set
+ assert:
+ that:
+ - "win_service_dependency_set_list|changed"
+ - "win_service_dependency_set_list.dependencies == ['{{test_win_service_name}}', 'TestServiceParent2']"
+
+- name: make sure all services are stopped, set to LocalSystem and set to auto start before next test
+ win_service:
+ name: "{{item}}"
+ state: stopped
+ start_mode: auto
+ username: LocalSystem
+ password: ""
+ with_items:
+ - "{{test_win_service_name}}"
+ - TestServiceParent2
+ - TestServiceDependency
+
+- name: start up dependency service
+ win_service:
+ name: TestServiceDependency
+ state: started
+
+- name: wait 5 seconds for service to propogate service startup
+ pause:
+ seconds: 5
+
+- name: get stat of 1st parent service
+ win_service:
+ name: "{{test_win_service_name}}"
+ register: win_service_parent1_stat
+
+- name: get stat of 2nd parent service
+ win_service:
+ name: TestServiceParent2
+ register: win_service_parent2_stat
+
+- name: get stat of dependent service
+ win_service:
+ name: TestServiceDependency
+ register: win_service_dependent_stat
+
+- name: check that the dependency services started correctly and have the correct stats
+ assert:
+ that:
+ - "win_service_parent1_stat.state == 'running'"
+ - "win_service_parent2_stat.state == 'running'"
+ - "win_service_dependent_stat.state == 'running'"
+ - "win_service_parent1_stat.depended_by == ['TestServiceDependency']"
+ - "win_service_parent2_stat.depended_by == ['TestServiceDependency']"
+
+- name: remove the service
+ win_service:
+ name: "{{test_win_service_name}}"
+ state: absent
+ register: win_service_removed
+
+- name: check that removing the service succeeds with changes
assert:
that:
- - "not win_service_stop_disabled_again|changed"
- - "win_service_stop_disabled_again.start_mode == 'disabled'"
- - "win_service_stop_disabled_again.state == 'stopped'"
+ - "win_service_removed|changed"
+ - "win_service_removed.exists == False"
+ - "win_service_removed.description is not defined"
+ - "win_service_removed.display_name is not defined"
+ - "win_service_removed.name is not defined"
+ - "win_service_removed.path is not defined"
+ - "win_service_removed.start_mode is not defined"
+ - "win_service_removed.state is not defined"
+ - "win_service_removed.username is not defined"
+
+- name: make sure all services are removed in the end
+ win_service:
+ name: "{{item}}"
+ state: absent
+ with_items:
+ - "{{test_win_service_name}}"
+ - TestServiceParent2
+ - TestServiceDependency