# Buggy code
def _getDataFromRegPolData(search_string, policy_data, return_value_name=False):
    """
    helper function to do a search of Policy data from a registry.pol file
    returns the "data" field
    https://msdn.microsoft.com/en-us/library/aa374407(VS.85).aspx
    [key;value;type;size;data]
    """
    value = None
    values = []
    if return_value_name:
        values = {}
    if search_string:
        registry = Registry()
        if len(search_string.split("{0};".format(chr(0)))) >= 3:
            vtype = registry.vtype_reverse[
                ord(search_string.split("{0};".format(chr(0)))[2])
            ]
        else:
            vtype = None
        search_string = re.escape(search_string)
        matches = re.finditer(search_string, policy_data, re.IGNORECASE)
        matches = [m for m in matches]
        if matches:
            for match in matches:
                pol_entry = policy_data[
                    match.start() : (policy_data.index("]", match.end()))
                ].split("{0};".format(chr(0)))
                if len(pol_entry) >= 2:
                    valueName = pol_entry[1]
                if len(pol_entry) >= 5:
                    value = pol_entry[4]
                    if vtype == "REG_DWORD" or vtype == "REG_QWORD":
                        if value:
                            vlist = list(ord(v) for v in value)
                            if vtype == "REG_DWORD":
                                for v in struct.unpack("I", struct.pack("2H", *vlist)):
                                    value = v
                            elif vtype == "REG_QWORD":
                                for v in struct.unpack("I", struct.pack("4H", *vlist)):
                                    value = v
                        else:
                            value = 0
                    elif vtype == "REG_MULTI_SZ":
                        value = value.rstrip(chr(0)).split(chr(0))
                    else:
                        value = value.rstrip(chr(0))
                if return_value_name:
                    log.debug("we want value names and the value")
                    values[valueName] = value
                elif len(matches) > 1:
                    log.debug("we have multiple matches, we will return a list")
                    values.append(value)
    if values:
        value = values

    return value


# Traceback (UnicodeEncodeError)
win2016-3:
----------
ID: router_gpo_1
Function: lgpo.set
Result: False
Comment: An exception occurred in this state: Traceback (most recent call last):
File "c:\salt\bin\lib\site-packages\salt\state.py", line 1843, in call
**cdata['kwargs'])
File "c:\salt\bin\lib\site-packages\salt\loader.py", line 1795, in wrapper
return f(*args, **kwargs)
File "c:\salt\bin\lib\site-packages\salt\states\win_lgpo.py", line 244, in set_
hierarchical_return=False)
File "c:\salt\var\cache\salt\minion\extmods\modules\win_lgpo.py", line 5021, in get
return_not_configured=return_not_configured))
File "c:\salt\var\cache\salt\minion\extmods\modules\win_lgpo.py", line 3810, in _checkAllAdmxPolicies
policy_filedata):
File "c:\salt\var\cache\salt\minion\extmods\modules\win_lgpo.py", line 3250, in _checkValueItemParent
check_deleted=check_deleted)
File "c:\salt\var\cache\salt\minion\extmods\modules\win_lgpo.py", line 3501, in _processValueItem
six.unichr(len(this_element_value.encode('utf-16-le'))),
UnicodeEncodeError: 'utf-16-le' codec can't encode character '\udd00' in position 0: surrogates not allowed
Started: 18:44:09.868773
Duration: 6765.204 ms
Changes:

Summary for win2016-3
------------
Succeeded: 0
Failed:    1
------------
Total states run:     1
Total run time:   6.765 s

# Fixed code
def _getDataFromRegPolData(search_string, policy_data, return_value_name=False):
    """
    helper function to do a search of Policy data from a registry.pol file
    returns the "data" field
    https://msdn.microsoft.com/en-us/library/aa374407(VS.85).aspx
    [key;value;type;size;data]
    """
    value = None
    values = []
    encoded_semicolon = ";".encode("utf-16-le")
    if return_value_name:
        values = {}
    if search_string:
        registry = Registry()
        if len(search_string.split(encoded_semicolon)) >= 3:
            vtype = registry.vtype_reverse[
                ord(search_string.split(encoded_semicolon)[2].decode("utf-32-le"))
            ]
        else:
            vtype = None
        search_string = re.escape(search_string)
        matches = re.finditer(search_string, policy_data, re.IGNORECASE)
        matches = [m for m in matches]
        if matches:
            for match in matches:
                pol_entry = policy_data[
                    match.start() : (
                        policy_data.index("]".encode("utf-16-le"), match.end())
                    )
                ].split(encoded_semicolon)
                if len(pol_entry) >= 2:
                    valueName = pol_entry[1]
                if len(pol_entry) >= 5:
                    value = pol_entry[4]
                    if vtype == "REG_DWORD" or vtype == "REG_QWORD":
                        if value:
                            if vtype == "REG_DWORD":
                                for v in struct.unpack("I", value):
                                    value = v
                            elif vtype == "REG_QWORD":
                                for v in struct.unpack("Q", value):
                                    value = v
                        else:
                            value = 0
                    elif vtype == "REG_MULTI_SZ":
                        value = value.decode("utf-16-le").rstrip(chr(0)).split(chr(0))
                    else:
                        value = value.decode("utf-16-le").rstrip(chr(0))
                if return_value_name:
                    log.debug("we want value names and the value")
                    values[valueName] = value
                elif len(matches) > 1:
                    log.debug("we have multiple matches, we will return a list")
                    values.append(value)
    if values:
        value = values

    return value