mirror of https://github.com/ansible/ansible.git
win_user_profile - new module (#50637)
* win_user_profile - new module * Fix typo * Fix 2012 CI issues * changed bool in docs and revert other test changespull/51347/head
parent
828df4b336
commit
6c26256945
@ -0,0 +1,170 @@
|
||||
#!powershell
|
||||
|
||||
# Copyright: (c) 2019, Ansible Project
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
#AnsibleRequires -CSharpUtil Ansible.Basic
|
||||
|
||||
$spec = @{
|
||||
options = @{
|
||||
name = @{ type = "str" }
|
||||
remove_multiple = @{ type = "bool"; default = $false }
|
||||
state = @{ type = "str"; default = "present"; choices = @("absent", "present") }
|
||||
username = @{ type = "sid"; }
|
||||
}
|
||||
required_if = @(
|
||||
@("state", "present", @("username")),
|
||||
@("state", "absent", @("name", "username"), $true)
|
||||
)
|
||||
supports_check_mode = $true
|
||||
}
|
||||
|
||||
$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec)
|
||||
$module.Result.path = $null
|
||||
|
||||
$name = $module.Params.name
|
||||
$remove_multiple = $module.Params.remove_multiple
|
||||
$state = $module.Params.state
|
||||
$username = $module.Params.username
|
||||
|
||||
Add-CSharpType -AnsibleModule $module -References @'
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Ansible.WinUserProfile
|
||||
{
|
||||
public class NativeMethods
|
||||
{
|
||||
[DllImport("Userenv.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern int CreateProfile(
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string pszUserSid,
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string pszUserName,
|
||||
[Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszProfilePath,
|
||||
UInt32 cchProfilePath);
|
||||
|
||||
[DllImport("Userenv.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
public static extern bool DeleteProfileW(
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string lpSidString,
|
||||
IntPtr lpProfile,
|
||||
IntPtr lpComputerName);
|
||||
|
||||
[DllImport("Userenv.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
public static extern bool GetProfilesDirectoryW(
|
||||
[Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder lpProfileDir,
|
||||
ref UInt32 lpcchSize);
|
||||
}
|
||||
}
|
||||
'@
|
||||
|
||||
Function Get-LastWin32ExceptionMessage {
|
||||
param([int]$ErrorCode)
|
||||
|
||||
# Need to throw a Win32Exception with the error code to get the actual error message assigned to that code
|
||||
try {
|
||||
throw [System.ComponentModel.Win32Exception]$ErrorCode
|
||||
} catch [System.ComponentModel.Win32Exception] {
|
||||
$exp_msg = "{0} (Win32 ErrorCode {1} - 0x{1:X8})" -f $_.Exception.Message, $ErrorCode
|
||||
}
|
||||
|
||||
return $exp_msg
|
||||
}
|
||||
|
||||
Function Get-ExpectedProfilePath {
|
||||
param([String]$BaseName)
|
||||
|
||||
# Environment.GetFolderPath does not have an enumeration to get the base profile dir, use PInvoke instead
|
||||
# and combine with the base name to return back to the user - best efforts
|
||||
$raw_profile_path = New-Object -TypeName System.Text.StringBuilder -ArgumentList 0
|
||||
$profile_path_length = 0
|
||||
[Ansible.WinUserProfile.NativeMethods]::GetProfilesDirectoryW($raw_profile_path,
|
||||
[ref]$profile_path_length) > $null
|
||||
|
||||
$raw_profile_path.EnsureCapacity($profile_path_length) > $null
|
||||
$res = [Ansible.WinUserProfile.NativeMethods]::GetProfilesDirectoryW($raw_profile_path,
|
||||
[ref]$profile_path_length)
|
||||
|
||||
if ($res -eq $false) {
|
||||
$msg = Get-LastWin32ExceptionMessage -Error ([System.Runtime.InteropServices.Marshal]::GetLastWin32Error())
|
||||
$module.FailJson("Failed to determine profile path with the base name '$BaseName': $msg")
|
||||
}
|
||||
$profile_path = Join-Path -Path $raw_profile_path.ToString() -ChildPath $BaseName
|
||||
|
||||
return $profile_path
|
||||
}
|
||||
|
||||
$profiles = Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
|
||||
|
||||
if ($state -eq "absent") {
|
||||
if ($null -ne $username) {
|
||||
$user_profiles = $profiles | Where-Object { $_.PSChildName -eq $username.Value }
|
||||
} else {
|
||||
# If the username was not provided, or we are removing a profile for a deleted user, we need to try and find
|
||||
# the correct SID to delete. We just verify that the path matches based on the name passed in
|
||||
$expected_profile_path = Get-ExpectedProfilePath -BaseName $name
|
||||
|
||||
$user_profiles = $profiles | Where-Object {
|
||||
$profile_path = (Get-ItemProperty -Path $_.PSPath -Name ProfileImagePath).ProfileImagePath
|
||||
$profile_path -eq $expected_profile_path
|
||||
}
|
||||
|
||||
if ($user_profiles.Length -gt 1 -and -not $remove_multiple) {
|
||||
$module.FailJson("Found multiple profiles matching the path '$expected_profile_path', set 'remove_multiple=True' to remove all the profiles for this match")
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($user_profile in $user_profiles) {
|
||||
$profile_path = (Get-ItemProperty -Path $user_profile.PSPath -Name ProfileImagePath).ProfileImagePath
|
||||
if (-not $module.CheckMode) {
|
||||
$res = [Ansible.WinUserProfile.NativeMethods]::DeleteProfileW($user_profile.PSChildName, [IntPtr]::Zero,
|
||||
[IntPtr]::Zero)
|
||||
if ($res -eq $false) {
|
||||
$msg = Get-LastWin32ExceptionMessage -Error ([System.Runtime.InteropServices.Marshal]::GetLastWin32Error())
|
||||
$module.FailJson("Failed to delete the profile for $($user_profile.PSChildName): $msg")
|
||||
}
|
||||
}
|
||||
|
||||
# While we may have multiple profiles when the name option was used, it will always be the same path due to
|
||||
# how we match name to a profile so setting it mutliple time sis fine
|
||||
$module.Result.path = $profile_path
|
||||
$module.Result.changed = $true
|
||||
}
|
||||
} elseif ($state -eq "present") {
|
||||
# Now we know the SID, see if the profile already exists
|
||||
$user_profile = $profiles | Where-Object { $_.PSChildName -eq $username.Value }
|
||||
if ($null -eq $user_profile) {
|
||||
# In case a SID was set as the username we still need to make sure the SID is mapped to a valid local account
|
||||
try {
|
||||
$account_name = $username.Translate([System.Security.Principal.NTAccount])
|
||||
} catch [System.Security.Principal.IdentityNotMappedException] {
|
||||
$module.FailJson("Fail to map the account '$($username.Value)' to a valid user")
|
||||
}
|
||||
|
||||
# If the basename was not provided, determine it from the actual username
|
||||
if ($null -eq $name) {
|
||||
$name = $account_name.Value.Split('\', 2)[-1]
|
||||
}
|
||||
|
||||
if ($module.CheckMode) {
|
||||
$profile_path = Get-ExpectedProfilePath -BaseName $name
|
||||
} else {
|
||||
$raw_profile_path = New-Object -TypeName System.Text.StringBuilder -ArgumentList 260
|
||||
$res = [Ansible.WinUserProfile.NativeMethods]::CreateProfile($username.Value, $name, $raw_profile_path,
|
||||
$raw_profile_path.Capacity)
|
||||
|
||||
if ($res -ne 0) {
|
||||
$exp = [System.Runtime.InteropServices.Marshal]::GetExceptionForHR($res)
|
||||
$module.FailJson("Failed to create profile for user '$username': $($exp.Message)")
|
||||
}
|
||||
$profile_path = $raw_profile_path.ToString()
|
||||
}
|
||||
|
||||
$module.Result.changed = $true
|
||||
$module.Result.path = $profile_path
|
||||
} else {
|
||||
$module.Result.path = (Get-ItemProperty -Path $user_profile.PSPath -Name ProfileImagePath).ProfileImagePath
|
||||
}
|
||||
}
|
||||
|
||||
$module.ExitJson()
|
||||
|
@ -0,0 +1,113 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright: (c) 2019, Ansible Project
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: win_user_profile
|
||||
version_added: '2.8'
|
||||
short_description: Manages the Windows user profiles.
|
||||
description:
|
||||
- Used to create or remove user profiles on a Windows host.
|
||||
- This can be used to create a profile before a user logs on or delete a
|
||||
profile when removing a user account.
|
||||
- A profile can be created for both a local or domain account.
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- Specifies the base name for the profile path.
|
||||
- When I(state) is C(present) this is used to create the profile for
|
||||
I(username) at a specific path within the profile directory.
|
||||
- This cannot be used to specify a path outside of the profile directory
|
||||
but rather it specifies a folder(s) within this directory.
|
||||
- If a profile for another user already exists at the same path, then a 3
|
||||
digit incremental number is appended by Windows automatically.
|
||||
- When I(state) is C(absent) and I(username) is not set, then the module
|
||||
will remove all profiles that point to the profile path derived by this
|
||||
value.
|
||||
- This is useful if the account no longer exists but the profile still
|
||||
remains.
|
||||
type: str
|
||||
remove_multiple:
|
||||
description:
|
||||
- When I(state) is C(absent) and the value for I(name) matches multiple
|
||||
profiles the module will fail.
|
||||
- Set this value to C(yes) to force the module to delete all the profiles
|
||||
found.
|
||||
default: no
|
||||
type: bool
|
||||
state:
|
||||
description:
|
||||
- Will ensure the profile exists when set to C(present).
|
||||
- When creating a profile the I(username) option must be set to a valid
|
||||
account.
|
||||
- Will remove the profile(s) when set to C(absent).
|
||||
- When removing a profile either I(username) must be set to a valid
|
||||
account, or I(name) is set to the profile's base name.
|
||||
default: present
|
||||
choices:
|
||||
- absent
|
||||
- present
|
||||
type: str
|
||||
username:
|
||||
description:
|
||||
- The account name of security identifier (SID) for the profile.
|
||||
- This must be set when I(state) is C(present) and must be a valid account
|
||||
or the SID of a valid account.
|
||||
- When I(state) is C(absent) then this must still be a valid account number
|
||||
but the SID can be a deleted user's SID.
|
||||
seealso:
|
||||
- module: win_user
|
||||
- module: win_domain_user
|
||||
author:
|
||||
- Jordan Borean (@jborean93)
|
||||
'''
|
||||
|
||||
EXAMPLES = r'''
|
||||
- name: Create a profile for an account
|
||||
win_user_profile:
|
||||
username: ansible-account
|
||||
state: present
|
||||
|
||||
- name: Create a profile for an account at C:\Users\ansible
|
||||
win_user_profile:
|
||||
username: ansible-account
|
||||
name: ansible
|
||||
state: present
|
||||
|
||||
- name: Remove a profile for a still valid account
|
||||
win_user_profile:
|
||||
username: ansible-account
|
||||
state: absent
|
||||
|
||||
- name: Remove a profile for a deleted account
|
||||
win_user_profile:
|
||||
name: ansible
|
||||
state: absent
|
||||
|
||||
- name: Remove a profile for a deleted account based on the SID
|
||||
win_user_profile:
|
||||
username: S-1-5-21-3233007181-2234767541-1895602582-1305
|
||||
state: absent
|
||||
|
||||
- name: Remove multiple profiles that exist at the basename path
|
||||
win_user_profile:
|
||||
name: ansible
|
||||
state: absent
|
||||
remove_multiple: yes
|
||||
'''
|
||||
|
||||
RETURN = r'''
|
||||
path:
|
||||
description: The full path to the profile for the account. This will be null
|
||||
if C(state=absent) and no profile was deleted.
|
||||
returned: always
|
||||
type: str
|
||||
sample: C:\Users\ansible
|
||||
'''
|
@ -0,0 +1 @@
|
||||
shippable/windows/group1
|
@ -0,0 +1,42 @@
|
||||
---
|
||||
- name: set custom user facts
|
||||
set_fact:
|
||||
test_username: ansible_test
|
||||
test_password: '{{ "password123!" + lookup("password", "/dev/null chars=ascii_letters,digits length=9") }}'
|
||||
|
||||
- name: create test account
|
||||
win_user:
|
||||
name: '{{ test_username }}'
|
||||
password: '{{ test_password }}'
|
||||
state: present
|
||||
register: test_username_info
|
||||
|
||||
- block:
|
||||
- name: check if profile exists
|
||||
win_stat:
|
||||
path: C:\temp\{{ test_username }}
|
||||
register: profile_path
|
||||
|
||||
- name: assert that profile doesn't exist before the test
|
||||
assert:
|
||||
that:
|
||||
- not profile_path.stat.exists
|
||||
|
||||
- name: run tests
|
||||
include_tasks: tests.yml
|
||||
|
||||
always:
|
||||
- name: remove test account
|
||||
win_user:
|
||||
name: '{{ test_username }}'
|
||||
state: absent
|
||||
|
||||
- name: remove test account profile
|
||||
win_user_profile:
|
||||
name: '{{ item }}'
|
||||
state: absent
|
||||
remove_multiple: True
|
||||
with_items:
|
||||
- '{{ test_username }}'
|
||||
- '{{ test_username }}.000'
|
||||
- test_username_profile
|
@ -0,0 +1,374 @@
|
||||
---
|
||||
- name: create profile (check mode)
|
||||
win_user_profile:
|
||||
username: '{{ test_username }}'
|
||||
state: present
|
||||
register: create_profile_check
|
||||
check_mode: True
|
||||
|
||||
- name: check if profile was created (check mode)
|
||||
win_stat:
|
||||
path: C:\Users\{{ test_username }}
|
||||
register: create_profile_actual_check
|
||||
|
||||
- name: assert create profile (check mode)
|
||||
assert:
|
||||
that:
|
||||
- create_profile_check is changed
|
||||
- create_profile_check.path|lower == "c:\\users\\" + test_username
|
||||
- not create_profile_actual_check.stat.exists
|
||||
|
||||
- name: create profile
|
||||
win_user_profile:
|
||||
username: '{{ test_username }}'
|
||||
state: present
|
||||
register: create_profile
|
||||
|
||||
- name: check if profile was created
|
||||
win_stat:
|
||||
path: C:\Users\{{ test_username }}
|
||||
register: create_profile_actual
|
||||
|
||||
- name: assert create profile
|
||||
assert:
|
||||
that:
|
||||
- create_profile is changed
|
||||
- create_profile.path|lower == "c:\\users\\" + test_username
|
||||
- create_profile_actual.stat.exists
|
||||
|
||||
- name: create profile (idempotent)
|
||||
win_user_profile:
|
||||
username: '{{ test_username }}'
|
||||
state: present
|
||||
register: create_profile_again
|
||||
|
||||
- name: assert create profile (idempotent)
|
||||
assert:
|
||||
that:
|
||||
- not create_profile_again is changed
|
||||
- create_profile_again.path|lower == "c:\\users\\" + test_username
|
||||
|
||||
- name: remove profile (check mode)
|
||||
win_user_profile:
|
||||
username: '{{ test_username }}'
|
||||
state: absent
|
||||
register: remove_profile_check
|
||||
check_mode: True
|
||||
|
||||
- name: check if profile was removed (check mode)
|
||||
win_stat:
|
||||
path: C:\Users\{{ test_username }}
|
||||
register: remove_profile_actual_check
|
||||
|
||||
- name: assert remove profile (check mode)
|
||||
assert:
|
||||
that:
|
||||
- remove_profile_check is changed
|
||||
- remove_profile_check.path|lower == "c:\\users\\" + test_username
|
||||
- remove_profile_actual_check.stat.exists
|
||||
|
||||
- name: remove profile
|
||||
win_user_profile:
|
||||
username: '{{ test_username }}'
|
||||
state: absent
|
||||
register: remove_profile
|
||||
|
||||
- name: check if profile was removed
|
||||
win_stat:
|
||||
path: C:\Users\{{ test_username }}
|
||||
register: remove_profile_actual
|
||||
|
||||
- name: assert remove profile
|
||||
assert:
|
||||
that:
|
||||
- remove_profile is changed
|
||||
- remove_profile.path|lower == "c:\\users\\" + test_username
|
||||
- not remove_profile_actual.stat.exists
|
||||
|
||||
- name: remove profile (idempotent)
|
||||
win_user_profile:
|
||||
username: '{{ test_username }}'
|
||||
state: absent
|
||||
register: remove_profile_again
|
||||
|
||||
- name: assert remove profile (idempotent)
|
||||
assert:
|
||||
that:
|
||||
- not remove_profile_again is changed
|
||||
- remove_profile_again.path == None
|
||||
|
||||
- name: create profile with specific base path
|
||||
win_user_profile:
|
||||
username: '{{ test_username }}'
|
||||
name: test_username_profile
|
||||
state: present
|
||||
register: create_profile_basename
|
||||
|
||||
- name: check if profile with specific base path was created
|
||||
win_stat:
|
||||
path: C:\Users\test_username_profile
|
||||
register: create_profile_basename_actual
|
||||
|
||||
- name: assert create profile with specific base path
|
||||
assert:
|
||||
that:
|
||||
- create_profile_basename is changed
|
||||
- create_profile_basename.path|lower == "c:\\users\\test_username_profile"
|
||||
- create_profile_basename_actual.stat.exists
|
||||
|
||||
- name: remove profile with specific base path
|
||||
win_user_profile:
|
||||
username: '{{ test_username }}'
|
||||
state: absent
|
||||
register: remove_profile_basename
|
||||
|
||||
- name: check if profile with specific base path was removed
|
||||
win_stat:
|
||||
path: C:\Users\test_username_profile
|
||||
register: remove_profile_basename_actual
|
||||
|
||||
- name: assert remove profile with specific base path
|
||||
assert:
|
||||
that:
|
||||
- remove_profile_basename is changed
|
||||
- remove_profile_basename.path|lower == "c:\\users\\test_username_profile"
|
||||
- not remove_profile_basename_actual.stat.exists
|
||||
|
||||
- name: create dummy profile folder
|
||||
win_file:
|
||||
path: C:\Users\{{ test_username }}
|
||||
state: directory
|
||||
|
||||
- block:
|
||||
- name: create profile folder with conflict (check mode)
|
||||
win_user_profile:
|
||||
username: '{{ test_username }}'
|
||||
state: present
|
||||
register: create_profile_conflict_check
|
||||
check_mode: True
|
||||
|
||||
- name: get result of create profile folder with conflict (check mode)
|
||||
win_stat:
|
||||
path: C:\Users\{{ test_username }}.000
|
||||
register: create_profile_conflict_actual_check
|
||||
|
||||
- name: assert create profile folder with conflict (check mode)
|
||||
assert:
|
||||
that:
|
||||
- create_profile_conflict_check is changed
|
||||
# The check mode path calc is dumb, doesn't check for conflicts
|
||||
- create_profile_conflict_check.path|lower == "c:\\users\\" + test_username
|
||||
- not create_profile_conflict_actual_check.stat.exists
|
||||
|
||||
- name: create profile folder with conflict
|
||||
win_user_profile:
|
||||
username: '{{ test_username }}'
|
||||
state: present
|
||||
register: create_profile_conflict
|
||||
|
||||
- name: get result of create profile with conflict
|
||||
win_stat:
|
||||
path: C:\Users\{{ test_username }}.000
|
||||
register: create_profile_conflict_actual
|
||||
|
||||
- name: assert create profile folder with conflict
|
||||
assert:
|
||||
that:
|
||||
- create_profile_conflict is changed
|
||||
- create_profile_conflict.path|lower == "c:\\users\\" + test_username + ".000"
|
||||
- create_profile_conflict_actual.stat.exists
|
||||
|
||||
- name: remove profile with conflict
|
||||
win_user_profile:
|
||||
username: '{{ test_username }}'
|
||||
state: absent
|
||||
register: remove_profile_conflict
|
||||
|
||||
- name: get result of profile folder after remove
|
||||
win_stat:
|
||||
path: C:\Users\{{ test_username }}.000
|
||||
register: remove_profile_conflict_actual
|
||||
|
||||
- name: get result of dummy folder after remove
|
||||
win_stat:
|
||||
path: C:\Users\{{ test_username }}
|
||||
register: remove_profile_conflict_dummy
|
||||
|
||||
- name: assert remove profile with conflict
|
||||
assert:
|
||||
that:
|
||||
- remove_profile_conflict is changed
|
||||
- remove_profile_conflict.path|lower == "c:\\users\\" + test_username + ".000"
|
||||
- not remove_profile_conflict_actual.stat.exists
|
||||
- remove_profile_conflict_dummy.stat.exists
|
||||
|
||||
always:
|
||||
- name: remove dummy profile folder
|
||||
win_file:
|
||||
path: C:\Users\{{ test_username }}
|
||||
state: absent
|
||||
|
||||
- name: create profile for deleted user by sid test
|
||||
win_user_profile:
|
||||
username: '{{ test_username_info.sid }}'
|
||||
state: present
|
||||
|
||||
- name: delete user for deleted user with sid test
|
||||
win_user:
|
||||
name: '{{ test_username }}'
|
||||
state: absent
|
||||
|
||||
- name: remove profile for remove profile by sid test
|
||||
win_user_profile:
|
||||
username: '{{ test_username_info.sid }}'
|
||||
state: absent
|
||||
register: remove_profile_deleted_sid
|
||||
|
||||
- name: check if profile was deleted for deleted user using a SID
|
||||
win_stat:
|
||||
path: C:\Users\{{ test_username }}
|
||||
register: remove_profile_deleted_sid_actual
|
||||
|
||||
- name: assert remove profile for deleted user using a SID
|
||||
assert:
|
||||
that:
|
||||
- remove_profile_deleted_sid is changed
|
||||
- remove_profile_deleted_sid.path|lower == "c:\\users\\" + test_username
|
||||
- not remove_profile_deleted_sid_actual.stat.exists
|
||||
|
||||
- name: recreate user for deleted user by name test
|
||||
win_user:
|
||||
name: '{{ test_username }}'
|
||||
password: '{{ test_password }}'
|
||||
state: present
|
||||
register: test_orphan_user1
|
||||
|
||||
- name: create profile for deleted user by name test
|
||||
win_user_profile:
|
||||
username: '{{ test_username }}'
|
||||
state: present
|
||||
|
||||
- name: delete user for remove profile by name test
|
||||
win_user:
|
||||
name: '{{ test_username }}'
|
||||
state: absent
|
||||
|
||||
- name: remove profile for deleted user using a name
|
||||
win_user_profile:
|
||||
name: '{{ test_username }}'
|
||||
state: absent
|
||||
register: remove_profile_deleted_name
|
||||
|
||||
- name: check if profile was deleted for deleted user using a name
|
||||
win_stat:
|
||||
path: C:\Users\{{ test_username }}
|
||||
register: remove_profile_deleted_name_actual
|
||||
|
||||
- name: assert remove profile for deleted user using a name
|
||||
assert:
|
||||
that:
|
||||
- remove_profile_deleted_name is changed
|
||||
- remove_profile_deleted_name.path|lower == "c:\\users\\" + test_username
|
||||
- not remove_profile_deleted_name_actual.stat.exists
|
||||
|
||||
- name: remove profile for deleted user using a name (idempotent)
|
||||
win_user_profile:
|
||||
name: '{{ test_username }}'
|
||||
state: absent
|
||||
register: remove_profile_deleted_name_again
|
||||
|
||||
- name: assert remove profile for deleted user using a name (idempotent)
|
||||
assert:
|
||||
that:
|
||||
- not remove_profile_deleted_name_again is changed
|
||||
|
||||
- name: recreate user for remove multiple user test
|
||||
win_user:
|
||||
name: '{{ test_username }}'
|
||||
password: '{{ test_password }}'
|
||||
state: present
|
||||
register: test_orphan_user1
|
||||
|
||||
- name: create new profile for remove multiple user test
|
||||
win_user_profile:
|
||||
username: '{{ test_username }}'
|
||||
state: present
|
||||
register: orphan_user1_profile
|
||||
|
||||
- name: remove user 1 for remove multiple user test
|
||||
win_user:
|
||||
name: '{{ test_username }}'
|
||||
state: absent
|
||||
|
||||
# win_file has issues with paths exceeding MAX_PATH, need to use rmdir instead
|
||||
- name: remove profile folder for user 1
|
||||
win_shell: rmdir /S /Q {{ orphan_user1_profile.path}}
|
||||
args:
|
||||
executable: cmd.exe
|
||||
|
||||
- name: create user 2 for remove multiple user test
|
||||
win_user:
|
||||
name: '{{ test_username }}'
|
||||
password: '{{ test_password }}'
|
||||
state: present
|
||||
register: test_orphan_user2
|
||||
|
||||
- name: create new profile for orphan user 2
|
||||
win_user_profile:
|
||||
username: '{{ test_username }}'
|
||||
state: present
|
||||
register: orphan_user2_profile
|
||||
|
||||
- name: remove orphan user 2 for remove multiple user test
|
||||
win_user:
|
||||
name: '{{ test_username }}'
|
||||
state: present
|
||||
|
||||
- name: fail to remove multiple profiles without flag
|
||||
win_user_profile:
|
||||
name: '{{ test_username }}'
|
||||
state: absent
|
||||
register: fail_remove_multiple
|
||||
ignore_errors: True
|
||||
|
||||
- name: check if profile was removed
|
||||
win_stat:
|
||||
path: C:\Users\{{ test_username }}
|
||||
register: fail_remove_multiple_actual
|
||||
|
||||
- name: assert that profile was not actually deleted
|
||||
assert:
|
||||
that:
|
||||
- fail_remove_multiple.msg == "Found multiple profiles matching the path 'C:\\Users\\" + test_username + "', set 'remove_multiple=True' to remove all the profiles for this match"
|
||||
- fail_remove_multiple_actual.stat.exists
|
||||
|
||||
- name: remove multiple profiles
|
||||
win_user_profile:
|
||||
name: '{{ test_username }}'
|
||||
state: absent
|
||||
remove_multiple: True
|
||||
register: remove_multiple
|
||||
|
||||
- name: get result of remove multiple profiles
|
||||
win_stat:
|
||||
path: C:\Users\{{ test_username }}
|
||||
register: remove_multiple_actual
|
||||
|
||||
- name: check that orphan user 1 reg profile has been removed
|
||||
win_reg_stat:
|
||||
path: HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\{{ test_orphan_user1.sid }}
|
||||
register: remove_orphan1_actual
|
||||
|
||||
- name: check that orphan user 2 reg profile has been removed
|
||||
win_reg_stat:
|
||||
path: HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\{{ test_orphan_user2.sid }}
|
||||
register: remove_orphan2_actual
|
||||
|
||||
- name: assert remove multiple profiles
|
||||
assert:
|
||||
that:
|
||||
- remove_multiple is changed
|
||||
- remove_multiple.path|lower == "c:\\users\\" + test_username
|
||||
- not remove_multiple_actual.stat.exists
|
||||
- not remove_orphan1_actual.exists
|
||||
- not remove_orphan2_actual.exists
|
Loading…
Reference in New Issue