I have a playbook that reads a few files, some of which are formatted in utf-16-le rather than utf-8. When reading them I am getting a bunch of useless garbage and I seem to struggle with decoding/encoding it back to something useable.
file is read using: lookup('file', file)
output of debug task:
"msg": "��W\u0000i\u0000n\u0000d\u0000o\u0000w\u0000s\u0000 \u0000R\u0000e\u0000g\u0000i\u0000s\u0000t\u0000r\u0000y\u0000 \u0000E\u0000d\u0000i\u0000t\u0000o\u0000r\u0000 \u0000V\u0000e\u0000r\u0000s\u0000i\u0000o\u0000n\u0000 \u00005\u0000.\u00000\u00000\u0000\r\u0000\n\u0000\r\u0000\n\u0000[\u0000H\u0000K\u0000E\u0000Y\u0000_\u0000L\u0000O\u0000C\u0000A\u0000L\u0000_\u0000M\u0000A\u0000C\u0000H\u0000I\u0000N\u0000E\u0000\\\u0000S\u0000O\u0000F\u0000T\u0000W\u0000A\u0000R\u0000E\u0000\\\u0000M\u0000i\u0000c\u0000r\u0000o\u0000s\u0000o\u0000f\u0000t\u0000\\\u0000W\u0000i\u0000n\u0000d\u0000o\u0000w\u0000s\u0000\\\u0000C\u0000u\u0000r\u0000r\u0000e\u0000n\u0000t\u0000V\u0000e\u0000r\u0000s\u0000i\u0000o\u0000n\u0000\\\u0000P\u0000o\u0000l\u0000i\u0000c\u0000i\u0000e\u0000s\u0000\\\u0000S\u0000y\u0000s\u0000t\u0000e\u0000m\u0000]\u0000\r\u0000\n\u0000\"\u0000C\u0000o\u0000n\u0000s\u0000e\u0000n\u0000t\u0000P\u0000r\u0000o\u0000m\u0000p\u0000t\u0000B\u0000e\u0000h\u0000a\u0000v\u0000i\u0000o\u0000r\u0000A\u0000d\u0000m\u0000i\u0000n\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00001\u0000\r\u0000\n\u0000\"\u0000C\u0000o\u0000n\u0000s\u0000e\u0000n\u0000t\u0000P\u0000r\u0000o\u0000m\u0000p\u0000t\u0000B\u0000e\u0000h\u0000a\u0000v\u0000i\u0000o\u0000r\u0000U\u0000s\u0000e\u0000r\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00003\u0000\r\u0000\n\u0000\"\u0000D\u0000S\u0000C\u0000A\u0000u\u0000t\u0000o\u0000m\u0000a\u0000t\u0000i\u0000o\u0000n\u0000H\u0000o\u0000s\u0000t\u0000E\u0000n\u0000a\u0000b\u0000l\u0000e\u0000d\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00002\u0000\r\u0000\n\u0000\"\u0000E\u0000n\u0000a\u0000b\u0000l\u0000e\u0000C\u0000u\u0000r\u0000s\u0000o\u0000r\u0000S\u0000u\u0000p\u0000p\u0000r\u0000e\u0000s\u0000s\u0000i\u0000o\u0000n\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00001\u0000\r\u0000\n\u0000\"\u0000E\u0000n\u0000a\u0000b\u0000l\u0000e\u0000F\u0000u\u0000l\u0000l\u0000T\u0000r\u0000u\u0000s\u0000t\u0000S\u0000t\u0000a\u0000r\u0000t\u0000u\u0000p\u0000T\u0000a\u0000s\u0000k\u0000s\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00002\u0000\r\u0000\n\u0000\"\u0000E\u0000n\u0000a\u0000b\u0000l\u0000e\u0000I\u0000n\u0000s\u0000t\u0000a\u0000l\u0000l\u0000e\u0000r\u0000D\u0000e\u0000t\u0000e\u0000c\u0000t\u0000i\u0000o\u0000n\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00001\u0000\r\u0000\n\u0000\"\u0000E\u0000n\u0000a\u0000b\u0000l\u0000e\u0000L\u0000U\u0000A\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00001\u0000\r\u0000\n\u0000\"\u0000E\u0000n\u0000a\u0000b\u0000l\u0000e\u0000S\u0000e\u0000c\u0000u\u0000r\u0000e\u0000U\u0000I\u0000A\u0000P\u0000a\u0000t\u0000h\u0000s\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00001\u0000\r\u0000\n\u0000\"\u0000E\u0000n\u0000a\u0000b\u0000l\u0000e\u0000U\u0000I\u0000A\u0000D\u0000e\u0000s\u0000k\u0000t\u0000o\u0000p\u0000T\u0000o\u0000g\u0000g\u0000l\u0000e\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u0000\r\u0000\n\u0000\"\u0000E\u0000n\u0000a\u0000b\u0000l\u0000e\u0000U\u0000w\u0000p\u0000S\u0000t\u0000a\u0000r\u0000t\u0000u\u0000p\u0000T\u0000a\u0000s\u0000k\u0000s\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00002\u0000\r\u0000\n\u0000\"\u0000E\u0000n\u0000a\u0000b\u0000l\u0000e\u0000V\u0000i\u0000r\u0000t\u0000u\u0000a\u0000l\u0000i\u0000z\u0000a\u0000t\u0000i\u0000o\u0000n\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00001\u0000\r\u0000\n\u0000\"\u0000P\u0000r\u0000o\u0000m\u0000p\u0000t\u0000O\u0000n\u0000S\u0000e\u0000c\u0000u\u0000r\u0000e\u0000D\u0000e\u0000s\u0000k\u0000t\u0000o\u0000p\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00001\u0000\r\u0000\n\u0000\"\u0000S\u0000u\u0000p\u0000p\u0000o\u0000r\u0000t\u0000F\u0000u\u0000l\u0000l\u0000T\u0000r\u0000u\u0000s\u0000t\u0000S\u0000t\u0000a\u0000r\u0000t\u0000u\u0000p\u0000T\u0000a\u0000s\u0000k\u0000s\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00001\u0000\r\u0000\n\u0000\"\u0000S\u0000u\u0000p\u0000p\u0000o\u0000r\u0000t\u0000U\u0000w\u0000p\u0000S\u0000t\u0000a\u0000r\u0000t\u0000u\u0000p\u0000T\u0000a\u0000s\u0000k\u0000s\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00001\u0000\r\u0000\n\u0000\"\u0000V\u0000a\u0000l\u0000i\u0000d\u0000a\u0000t\u0000e\u0000A\u0000d\u0000m\u0000i\u0000n\u0000C\u0000o\u0000d\u0000e\u0000S\u0000i\u0000g\u0000n\u0000a\u0000t\u0000u\u0000r\u0000e\u0000s\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u0000\r\u0000\n\u0000\"\u0000d\u0000o\u0000n\u0000t\u0000d\u0000i\u0000s\u0000p\u0000l\u0000a\u0000y\u0000l\u0000a\u0000s\u0000t\u0000u\u0000s\u0000e\u0000r\u0000n\u0000a\u0000m\u0000e\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u0000\r\u0000\n\u0000\"\u0000l\u0000e\u0000g\u0000a\u0000l\u0000n\u0000o\u0000t\u0000i\u0000c\u0000e\u0000c\u0000a\u0000p\u0000t\u0000i\u0000o\u0000n\u0000\"\u0000=\u0000\"\u0000\"\u0000\r\u0000\n\u0000\"\u0000l\u0000e\u0000g\u0000a\u0000l\u0000n\u0000o\u0000t\u0000i\u0000c\u0000e\u0000t\u0000e\u0000x\u0000t\u0000\"\u0000=\u0000\"\u0000\"\u0000\r\u0000\n\u0000\"\u0000s\u0000c\u0000f\u0000o\u0000r\u0000c\u0000e\u0000o\u0000p\u0000t\u0000i\u0000o\u0000n\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u0000\r\u0000\n\u0000\"\u0000s\u0000h\u0000u\u0000t\u0000d\u0000o\u0000w\u0000n\u0000w\u0000i\u0000t\u0000h\u0000o\u0000u\u0000t\u0000l\u0000o\u0000g\u0000o\u0000n\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00001\u0000\r\u0000\n\u0000\"\u0000u\u0000n\u0000d\u0000o\u0000c\u0000k\u0000w\u0000i\u0000t\u0000h\u0000o\u0000u\u0000t\u0000l\u0000o\u0000g\u0000o\u0000n\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00001\u0000\r\u0000\n\u0000\r\u0000\n\u0000[\u0000H\u0000K\u0000E\u0000Y\u0000_\u0000L\u0000O\u0000C\u0000A\u0000L\u0000_\u0000M\u0000A\u0000C\u0000H\u0000I\u0000N\u0000E\u0000\\\u0000S\u0000O\u0000F\u0000T\u0000W\u0000A\u0000R\u0000E\u0000\\\u0000M\u0000i\u0000c\u0000r\u0000o\u0000s\u0000o\u0000f\u0000t\u0000\\\u0000W\u0000i\u0000n\u0000d\u0000o\u0000w\u0000s\u0000\\\u0000C\u0000u\u0000r\u0000r\u0000e\u0000n\u0000t\u0000V\u0000e\u0000r\u0000s\u0000i\u0000o\u0000n\u0000\\\u0000P\u0000o\u0000l\u0000i\u0000c\u0000i\u0000e\u0000s\u0000\\\u0000S\u0000y\u0000s\u0000t\u0000e\u0000m\u0000\\\u0000A\u0000u\u0000d\u0000i\u0000t\u0000]\u0000\r\u0000\n\u0000\r\u0000\n\u0000[\u0000H\u0000K\u0000E\u0000Y\u0000_\u0000L\u0000O\u0000C\u0000A\u0000L\u0000_\u0000M\u0000A\u0000C\u0000H\u0000I\u0000N\u0000E\u0000\\\u0000S\u0000O\u0000F\u0000T\u0000W\u0000A\u0000R\u0000E\u0000\\\u0000M\u0000i\u0000c\u0000r\u0000o\u0000s\u0000o\u0000f\u0000t\u0000\\\u0000W\u0000i\u0000n\u0000d\u0000o\u0000w\u0000s\u0000\\\u0000C\u0000u\u0000r\u0000r\u0000e\u0000n\u0000t\u0000V\u0000e\u0000r\u0000s\u0000i\u0000o\u0000n\u0000\\\u0000P\u0000o\u0000l\u0000i\u0000c\u0000i\u0000e\u0000s\u0000\\\u0000S\u0000y\u0000s\u0000t\u0000e\u0000m\u0000\\\u0000U\u0000I\u0000P\u0000I\u0000]\u0000\r\u0000\n\u0000\r\u0000\n\u0000[\u0000H\u0000K\u0000E\u0000Y\u0000_\u0000L\u0000O\u0000C\u0000A\u0000L\u0000_\u0000M\u0000A\u0000C\u0000H\u0000I\u0000N\u0000E\u0000\\\u0000S\u0000O\u0000F\u0000T\u0000W\u0000A\u0000R\u0000E\u0000\\\u0000M\u0000i\u0000c\u0000r\u0000o\u0000s\u0000o\u0000f\u0000t\u0000\\\u0000W\u0000i\u0000n\u0000d\u0000o\u0000w\u0000s\u0000\\\u0000C\u0000u\u0000r\u0000r\u0000e\u0000n\u0000t\u0000V\u0000e\u0000r\u0000s\u0000i\u0000o\u0000n\u0000\\\u0000P\u0000o\u0000l\u0000i\u0000c\u0000i\u0000e\u0000s\u0000\\\u0000S\u0000y\u0000s\u0000t\u0000e\u0000m\u0000\\\u0000U\u0000I\u0000P\u0000I\u0000\\\u0000C\u0000l\u0000i\u0000p\u0000b\u0000o\u0000a\u0000r\u0000d\u0000]\u0000\r\u0000\n\u0000\r\u0000\n\u0000[\u0000H\u0000K\u0000E\u0000Y\u0000_\u0000L\u0000O\u0000C\u0000A\u0000L\u0000_\u0000M\u0000A\u0000C\u0000H\u0000I\u0000N\u0000E\u0000\\\u0000S\u0000O\u0000F\u0000T\u0000W\u0000A\u0000R\u0000E\u0000\\\u0000M\u0000i\u0000c\u0000r\u0000o\u0000s\u0000o\u0000f\u0000t\u0000\\\u0000W\u0000i\u0000n\u0000d\u0000o\u0000w\u0000s\u0000\\\u0000C\u0000u\u0000r\u0000r\u0000e\u0000n\u0000t\u0000V\u0000e\u0000r\u0000s\u0000i\u0000o\u0000n\u0000\\\u0000P\u0000o\u0000l\u0000i\u0000c\u0000i\u0000e\u0000s\u0000\\\u0000S\u0000y\u0000s\u0000t\u0000e\u0000m\u0000\\\u0000U\u0000I\u0000P\u0000I\u0000\\\u0000C\u0000l\u0000i\u0000p\u0000b\u0000o\u0000a\u0000r\u0000d\u0000\\\u0000E\u0000x\u0000c\u0000e\u0000p\u0000t\u0000i\u0000o\u0000n\u0000F\u0000o\u0000r\u0000m\u0000a\u0000t\u0000s\u0000]\u0000\r\u0000\n\u0000\"\u0000C\u0000F\u0000_\u0000B\u0000I\u0000T\u0000M\u0000A\u0000P\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00002\u0000\r\u0000\n\u0000\"\u0000C\u0000F\u0000_\u0000D\u0000I\u0000B\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00008\u0000\r\u0000\n\u0000\"\u0000C\u0000F\u0000_\u0000D\u0000I\u0000B\u0000V\u00005\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00001\u00001\u0000\r\u0000\n\u0000\"\u0000C\u0000F\u0000_\u0000O\u0000E\u0000M\u0000T\u0000E\u0000X\u0000T\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00007\u0000\r\u0000\n\u0000\"\u0000C\u0000F\u0000_\u0000P\u0000A\u0000L\u0000E\u0000T\u0000T\u0000E\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00009\u0000\r\u0000\n\u0000\"\u0000C\u0000F\u0000_\u0000T\u0000E\u0000X\u0000T\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u00001\u0000\r\u0000\n\u0000\"\u0000C\u0000F\u0000_\u0000U\u0000N\u0000I\u0000C\u0000O\u0000D\u0000E\u0000T\u0000E\u0000X\u0000T\u0000\"\u0000=\u0000d\u0000w\u0000o\u0000r\u0000d\u0000:\u00000\u00000\u00000\u00000\u00000\u00000\u00000\u0000d\u0000\r\u0000\n\u0000\r\u0000\n\u0000\n"
the file https://raw.githubusercontent.com/YoraiLevi/MyFuckingWikiOfEverything/DEV/etc/Ansible/playbooks/roles/windows-configurations/files/registry_edits/personal_settings/admin_uac_password.reg
Thanks, I can't figure it out...
To my surprise, this was way harder than I thought. Below a quickNdirty solution that I would not run as is on production, which definitely needs hardening, error control, documentation...
As you will see, this required to go through a custom lookup plugin
Here is the layout for a plugin adjacent to the playbook:
$ tree
.
├── lookup_plugins
│ └── file_utf_16.py
└── viewutf16.yml
The /lookup_plugins/file_utf_16.py
:
from ansible.errors import AnsibleError
from ansible.plugins.lookup import LookupBase
from ansible.module_utils.common.text.converters import to_text, to_native
class LookupModule(LookupBase):
def run(self, terms, variables=None, **kwargs):
ret = []
try:
for path in terms:
with open(path, 'rb') as byte_stream:
text = byte_stream.read()
ret.append(to_text(text.decode('UTF-16')))
except Exception as e:
raise AnsibleError(to_native(repr(e)))
return ret
And the test viewutf16.yml
playbook:
- hosts: localhost
gather_facts: false
tasks:
- get_url:
url: https://raw.githubusercontent.com/YoraiLevi/MyFuckingWikiOfEverything/DEV/etc/Ansible/playbooks/roles/windows-configurations/files/registry_edits/personal_settings/admin_uac_password.reg
dest: .
register: download
- debug:
msg: "{{ lookup('file_utf_16', download.dest).split('\n') }}"
Gives (note: I splitted on \n
for reading convenience, the fight for leftover \r
is yours):
$ ansible-playbook viewutf16.yml
PLAY [localhost] ************************************************************
TASK [get_url] **************************************************************
ok: [localhost]
TASK [debug] ****************************************************************
ok: [localhost] => {
"msg": [
"Windows Registry Editor Version 5.00\r",
"\r",
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System]\r",
"\"ConsentPromptBehaviorAdmin\"=dword:00000001\r",
"\"ConsentPromptBehaviorUser\"=dword:00000003\r",
"\"DSCAutomationHostEnabled\"=dword:00000002\r",
"\"EnableCursorSuppression\"=dword:00000001\r",
"\"EnableFullTrustStartupTasks\"=dword:00000002\r",
"\"EnableInstallerDetection\"=dword:00000001\r",
"\"EnableLUA\"=dword:00000001\r",
"\"EnableSecureUIAPaths\"=dword:00000001\r",
"\"EnableUIADesktopToggle\"=dword:00000000\r",
"\"EnableUwpStartupTasks\"=dword:00000002\r",
"\"EnableVirtualization\"=dword:00000001\r",
"\"PromptOnSecureDesktop\"=dword:00000001\r",
"\"SupportFullTrustStartupTasks\"=dword:00000001\r",
"\"SupportUwpStartupTasks\"=dword:00000001\r",
"\"ValidateAdminCodeSignatures\"=dword:00000000\r",
"\"dontdisplaylastusername\"=dword:00000000\r",
"\"legalnoticecaption\"=\"\"\r",
"\"legalnoticetext\"=\"\"\r",
"\"scforceoption\"=dword:00000000\r",
"\"shutdownwithoutlogon\"=dword:00000001\r",
"\"undockwithoutlogon\"=dword:00000001\r",
"\r",
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System\\Audit]\r",
"\r",
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System\\UIPI]\r",
"\r",
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System\\UIPI\\Clipboard]\r",
"\r",
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System\\UIPI\\Clipboard\\ExceptionFormats]\r",
"\"CF_BITMAP\"=dword:00000002\r",
"\"CF_DIB\"=dword:00000008\r",
"\"CF_DIBV5\"=dword:00000011\r",
"\"CF_OEMTEXT\"=dword:00000007\r",
"\"CF_PALETTE\"=dword:00000009\r",
"\"CF_TEXT\"=dword:00000001\r",
"\"CF_UNICODETEXT\"=dword:0000000d\r",
"\r",
""
]
}
PLAY RECAP ******************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
I know this isn't an exact answer for the OP's question, but I just wanted to add that if you're using slurp
instead of a lookup
, you can use the b64decode
with the undocumented argument encoding
to get the native UTF-8 encoded string for normal Ansible usage:
- name: "Slurp file"
slurp:
src: "file"
register: file_contents_encoded
- debug:
msg: "{{ file_contents_encoded.content | b64decode(encoding='utf-16-le') }}"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With