code: def _clean_error_msg(self, msg):
          
          # TODO prepare unit test, beautify code
          # if the msg does not start with this, return it as is
          if msg.startswith(b"#< CLIXML\r\n"):
              # for proper xml, we need to remove the CLIXML part
              # (the first line)
              msg_xml = msg[11:]
              try:
                  # remove the namespaces from the xml for easier processing
                  msg_xml = self._strip_namespace(msg_xml)
                  root = ET.fromstring(msg_xml)
                  # the S node is the error message, find all S nodes
                  nodes = root.findall("./S")
                  new_msg = ""
                  for s in nodes:
                      # append error msg string to result, also
                      # the hex chars represent CRLF so we replace with newline
                      new_msg += s.text.replace("_x000D__x000A_", "\n")
              except Exception as e:
                  # if any of the above fails, the msg was not true xml
                  # print a warning and return the orignal string
                  # TODO do not print, raise user defined error instead
                  print("Warning: there was a problem converting the Powershell"
                        " error message: %s" % (e))
              else:
                  # if new_msg was populated, that's our error message
                  # otherwise the original error message will be used
                  if len(new_msg):
                      # remove leading and trailing whitespace while we are here
                      return new_msg.strip().encode('utf-8')
  
          # either failed to decode CLIXML or there was nothing to decode
          # just return the original message
          return msg
docs: converts a Powershell CLIXML message to a more human readable string