I try to manipulate the ouptut of following powershell command:
Get-CimInstance -ClassName Win32_UserProfile | Select-Object -ExpandProperty LocalPath
Which could look like this:
[
"C:\\Users\\LocalUser",
"C:\\Users\\LocalUser.001",
"C:\\Users\\Admin",
"C:\\Windows\\ServiceProfiles\\NetworkService",
"C:\\Windows\\ServiceProfiles\\LocalService",
"C:\\Windows\\system32\\config\\systemprofile"
]
My goal is to reject the profiles, like Admin and them under Windows path.
My approach so far looks like this:
- hosts: windows10
gather_facts: false
tasks:
- name: Get a list of all user profiles
ansible.windows.win_powershell:
script: |
Get-CimInstance -ClassName Win32_UserProfile |
Select-Object -ExpandProperty LocalPath
register: all_user_profiles
changed_when: false
- name: Filter profiles for deletion
set_fact:
profiles_to_delete: >-
{{ all_user_profiles.output |
reject('search', '\\\\Users\\\\(' + (keep_users | join("|")) + ')') |
list }}
vars:
keep_users:
- Admin
- debug:
var: profiles_to_delete
The Expected result from the last debug:
[
"C:\\Users\\LocalUser",
"C:\\Users\\LocalUser.001",
"C:\\Windows\\ServiceProfiles\\NetworkService",
"C:\\Windows\\ServiceProfiles\\LocalService",
"C:\\Windows\\system32\\config\\systemprofile"
]
But instead it still includes the Admin line, from above.
I tested also the following based on @β.εηοιτ.βε gist from the comments:
- hosts: localhost
gather_facts: false
tasks:
- name: Filter profiles for deletion
set_fact:
profiles_to_delete: >-
{{ all_user_profiles.output |
reject('search', '\\\\Users\\\\(' + (keep_users | join("|")) + ')') |
list }}
vars:
keep_users:
- Admin
all_user_profiles:
output:
- C:\\Users\\LocalUser
- C:\\Users\\LocalUser.001
- C:\\Users\\Admin
- C:\\Windows\\ServiceProfiles\\NetworkService
- C:\\Windows\\ServiceProfiles\\LocalService
- C:\\Windows\\system32\\config\\systemprofile
- debug:
var: profiles_to_delete
And here it works fine as expected.
So I compared the two lists and came to the conclusion, that the issue is originating from the difference, that the content of the shell output is quoted and the content of the hardcoded variable is not.
As soon as I update the hardcoded variable, I get the same unwanted result as my MWE creates:
all_user_profiles:
output:
- "C:\\Users\\LocalUser"
- "C:\\Users\\LocalUser.001"
- "C:\\Users\\Admin"
- "C:\\Windows\\ServiceProfiles\\NetworkService"
- "C:\\Windows\\ServiceProfiles\\LocalService"
- "C:\\Windows\\system32\\config\\systemprofile"
So, why does the search not work if the values are quoted?
Since all_user_profile.output
just seems to be list and you like to remove (reject
) an item from that list, a minimal example playbook
---
- hosts: localhost
become: false
gather_facts: false
vars:
all_user_profile:
output: [
"C:\\Users\\LocalUser",
"C:\\Users\\LocalUser.001",
"C:\\Users\\Admin",
"C:\\Windows\\ServiceProfiles\\NetworkService",
"C:\\Windows\\ServiceProfiles\\LocalService",
"C:\\Windows\\system32\\config\\systemprofile"
]
tasks:
- name: Profiles to delete
debug:
msg: "{{ all_user_profile.output | reject('search', user) | list }}"
vars:
user: Admin
will result into an output of
TASK [Profiles to delete] *******************
ok: [localhost] =>
msg:
- C:\Users\LocalUser
- C:\Users\LocalUser.001
- C:\Windows\ServiceProfiles\NetworkService
- C:\Windows\ServiceProfiles\LocalService
- C:\Windows\system32\config\systemprofile
It is also possible to specify the path in more detail, see in example
- name: Profiles to delete
debug:
msg: "{{ all_user_profile.output | reject('search', keep) | list }}"
vars:
keep: Users\\Admin