# Buggy code
def create_task_from_xml(
    name, location="\\", xml_text=None, xml_path=None, user_name="System", password=None
):
    r"""
    Create a task based on XML. Source can be a file or a string of XML.

    :param str name: The name of the task. This will be displayed in the task
        scheduler.

    :param str location: A string value representing the location in which to
        create the task. Default is '\\' which is the root for the task
        scheduler (C:\Windows\System32\tasks).

    :param str xml_text: A string of xml representing the task to be created.
        This will be overridden by `xml_path` if passed.

    :param str xml_path: The path to an XML file on the local system containing
        the xml that defines the task. This will override `xml_text`

    :param str user_name: The user account under which to run the task. To
        specify the 'System' account, use 'System'. The password will be
        ignored.

    :param str password: The password to use for authentication. This should set
        the task to run whether the user is logged in or not, but is currently
        not working.

    :return: True if successful, False if unsuccessful
    :rtype: bool

    CLI Example:

    .. code-block:: bash

        salt 'minion-id' task.create_task_from_xml <task_name> xml_path=C:\task.xml
    """
    # Check for existing task
    if name in list_tasks(location):
        # Connect to an existing task definition
        return "{0} already exists".format(name)

    if not xml_text and not xml_path:
        return "Must specify either xml_text or xml_path"

    # Create the task service object
    pythoncom.CoInitialize()
    task_service = win32com.client.Dispatch("Schedule.Service")
    task_service.Connect()

    # Load xml from file, overrides xml_text
    # Need to figure out how to load contents of xml
    if xml_path:
        xml_text = xml_path

    # Get the folder to list folders from
    task_folder = task_service.GetFolder(location)

    # Determine logon type
    if user_name:
        if user_name.lower() == "system":
            logon_type = TASK_LOGON_SERVICE_ACCOUNT
            user_name = "SYSTEM"
            password = None
        else:
            if password:
                logon_type = TASK_LOGON_PASSWORD
            else:
                logon_type = TASK_LOGON_INTERACTIVE_TOKEN
    else:
        password = None

    # Save the task
    try:
        task_folder.RegisterTask(
            name, xml_text, TASK_CREATE, user_name, password, logon_type
        )

    except pythoncom.com_error as error:
        hr, msg, exc, arg = error.args  # pylint: disable=W0633
        fc = {
            -2147216615: "Required element or attribute missing",
            -2147216616: "Value incorrectly formatted or out of range",
            -2147352571: "Access denied",
        }
        try:
            failure_code = fc[exc[5]]
        except KeyError:
            failure_code = "Unknown Failure: {0}".format(error)

        log.debug("Failed to create task: {0}".format(failure_code))

    # Verify creation
    if name in list_tasks(location):
        return True
    else:
        return False


# Traceback (AttributeError)
[DEBUG   ] Reading configuration from /etc/salt/master
[DEBUG   ] Missing configuration file: /root/.saltrc
[TRACE   ] The required configuration section, 'fluent_handler', was not found the in the configuration. Not loading the fluent logging handlers module.
[TRACE   ] None of the required configuration sections, 'logstash_udp_handler' and 'logstash_zmq_handler', were found in the configuration. Not loading the Logstash logging handlers module.
[DEBUG   ] Configuration file path: /etc/salt/master
[WARNING ] Insecure logging configuration detected! Sensitive data may be logged.
[DEBUG   ] Reading configuration from /etc/salt/master
[DEBUG   ] Missing configuration file: /root/.saltrc
[DEBUG   ] MasterEvent PUB socket URI: /var/run/salt/master/master_event_pub.ipc
[DEBUG   ] MasterEvent PULL socket URI: /var/run/salt/master/master_event_pull.ipc
[DEBUG   ] Initializing new AsyncZeroMQReqChannel for ('/etc/salt/pki/master', 'ux.disc0rd.com_master', 'tcp://127.0.0.1:6506', 'clear')
[TRACE   ] Inserted key into loop_instance_map id 140313310181424 for key ('/etc/salt/pki/master', 'ux.disc0rd.com_master', 'tcp://127.0.0.1:6506', 'clear') and process 27072
[DEBUG   ] Initializing new IPCClient for path: /var/run/salt/master/master_event_pub.ipc
[TRACE   ] IPCClient: Connecting to socket: /var/run/salt/master/master_event_pub.ipc
[TRACE   ] func get_cli_event_returns()
[DEBUG   ] LazyLoaded local_cache.get_load
[DEBUG   ] Reading minion list from /var/cache/salt/master/jobs/b8/29f5a7366ad73111d97d309a60cfbce5bcd48bce686f2a96013cecf41b8bed/.minions.p
[DEBUG   ] get_iter_returns for jid 20171025020027377960 sent to set(['gs-desktop']) will timeout at 02:00:32.388436
[TRACE   ] _get_event() waited 0 seconds and received nothing
[TRACE   ] get_event() received = {'tag': 'salt/job/20171025020027377960/new', 'data': {'tgt_type': 'glob', 'jid': '20171025020027377960', 'tgt': 'gs*', '_stamp': '2017-10-25T02:00:27.380124', 'user': 'root', 'arg': [{'location': '\\Microsoft\\XblGameSave', 'name': 'XblGameSaveTaskLogon', '__kwarg__': True}], 'fun': 'task.info', 'minions': ['gs-desktop']}}
[TRACE   ] _get_event() waited 0 seconds and received nothing
[TRACE   ] _get_event() waited 0 seconds and received nothing
[TRACE   ] _get_event() waited 0 seconds and received nothing
[TRACE   ] _get_event() waited 0 seconds and received nothing
[TRACE   ] _get_event() waited 0 seconds and received nothing
[TRACE   ] _get_event() waited 0 seconds and received nothing
[TRACE   ] _get_event() waited 0 seconds and received nothing
[TRACE   ] _get_event() waited 0 seconds and received nothing
[TRACE   ] _get_event() waited 0 seconds and received nothing
[TRACE   ] _get_event() waited 0 seconds and received nothing
[TRACE   ] _get_event() waited 0 seconds and received nothing
[TRACE   ] _get_event() waited 0 seconds and received nothing
[TRACE   ] _get_event() waited 0 seconds and received nothing
[TRACE   ] _get_event() waited 0 seconds and received nothing
[TRACE   ] _get_event() waited 0 seconds and received nothing
[TRACE   ] _get_event() waited 0 seconds and received nothing
[TRACE   ] _get_event() waited 0 seconds and received nothing
[TRACE   ] _get_event() waited 0 seconds and received nothing
[TRACE   ] get_event() received = {'tag': 'salt/job/20171025020027377960/ret/gs-desktop', 'data': {'fun_args': [{'location': '\\Microsoft\\XblGameSave', 'name': 'XblGameSaveTaskLogon'}], 'jid': '20171025020027377960', 'return': 'The minion function caused an exception: Traceback (most recent call last):\n  File "c:\\salt\\bin\\lib\\site-packages\\salt\\minion.py", line 1468, in _thread_return\n    return_data = executor.execute()\n  File "c:\\salt\\bin\\lib\\site-packages\\salt\\executors\\direct_call.py", line 28, in execute\n    return self.func(*self.args, **self.kwargs)\n  File "c:\\salt\\bin\\lib\\site-packages\\salt\\modules\\win_task.py", line 1383, in info\n    if triggerObj.RandomDelay == \'\':\n  File "c:\\salt\\bin\\lib\\site-packages\\win32com\\client\\dynamic.py", line 522, in __getattr__\n    raise AttributeError("%s.%s" % (self._username_, attr))\nAttributeError: <unknown>.RandomDelay\n', 'success': False, 'cmd': '_return', '_stamp': '2017-10-25T02:00:29.425738', 'fun': 'task.info', 'id': 'gs-desktop', 'out': 'nested'}}
[DEBUG   ] jid 20171025020027377960 return from gs-desktop
[DEBUG   ] return event: {'gs-desktop': {'jid': '20171025020027377960', 'ret': 'The minion function caused an exception: Traceback (most recent call last):\n  File "c:\\salt\\bin\\lib\\site-packages\\salt\\minion.py", line 1468, in _thread_return\n    return_data = executor.execute()\n  File "c:\\salt\\bin\\lib\\site-packages\\salt\\executors\\direct_call.py", line 28, in execute\n    return self.func(*self.args, **self.kwargs)\n  File "c:\\salt\\bin\\lib\\site-packages\\salt\\modules\\win_task.py", line 1383, in info\n    if triggerObj.RandomDelay == \'\':\n  File "c:\\salt\\bin\\lib\\site-packages\\win32com\\client\\dynamic.py", line 522, in __getattr__\n    raise AttributeError("%s.%s" % (self._username_, attr))\nAttributeError: <unknown>.RandomDelay\n', 'out': 'nested'}}
[DEBUG   ] LazyLoaded nested.output
[TRACE   ] data = {'gs-desktop': 'The minion function caused an exception: Traceback (most recent call last):\n  File "c:\\salt\\bin\\lib\\site-packages\\salt\\minion.py", line 1468, in _thread_return\n    return_data = executor.execute()\n  File "c:\\salt\\bin\\lib\\site-packages\\salt\\executors\\direct_call.py", line 28, in execute\n    return self.func(*self.args, **self.kwargs)\n  File "c:\\salt\\bin\\lib\\site-packages\\salt\\modules\\win_task.py", line 1383, in info\n    if triggerObj.RandomDelay == \'\':\n  File "c:\\salt\\bin\\lib\\site-packages\\win32com\\client\\dynamic.py", line 522, in __getattr__\n    raise AttributeError("%s.%s" % (self._username_, attr))\nAttributeError: <unknown>.RandomDelay\n'}
gs-desktop:
The minion function caused an exception: Traceback (most recent call last):
File "c:\salt\bin\lib\site-packages\salt\minion.py", line 1468, in _thread_return
return_data = executor.execute()
File "c:\salt\bin\lib\site-packages\salt\executors\direct_call.py", line 28, in execute
return self.func(*self.args, **self.kwargs)
File "c:\salt\bin\lib\site-packages\salt\modules\win_task.py", line 1383, in info
if triggerObj.RandomDelay == '':
File "c:\salt\bin\lib\site-packages\win32com\client\dynamic.py", line 522, in __getattr__
raise AttributeError("%s.%s" % (self._username_, attr))
AttributeError: <unknown>.RandomDelay
[TRACE   ] _get_event() waited 0 seconds and received nothing
[DEBUG   ] jid 20171025020027377960 found all minions set(['gs-desktop'])

# Fixed code
def create_task_from_xml(
    name, location="\\", xml_text=None, xml_path=None, user_name="System", password=None
):
    r"""
    Create a task based on XML. Source can be a file or a string of XML.

    Args:

        name (str):
            The name of the task. This will be displayed in the task scheduler.

        location (str):
            A string value representing the location in which to create the
            task. Default is ``\`` which is the root for the task scheduler
            (``C:\Windows\System32\tasks``).

        xml_text (str):
            A string of xml representing the task to be created. This will be
            overridden by ``xml_path`` if passed.

        xml_path (str):
            The path to an XML file on the local system containing the xml that
            defines the task. This will override ``xml_text``

        user_name (str):
            The user account under which to run the task. To specify the
            'System' account, use 'System'. The password will be ignored.

        password (str):
            The password to use for authentication. This should set the task to
            run whether the user is logged in or not, but is currently not
            working.

    Returns:
        bool: ``True`` if successful, otherwise ``False``

    CLI Example:

    .. code-block:: bash

        salt '*' task.create_task_from_xml <task_name> xml_path=C:\task.xml
    """
    # Check for existing task
    if name in list_tasks(location):
        # Connect to an existing task definition
        return "{0} already exists".format(name)

    if not xml_text and not xml_path:
        return "Must specify either xml_text or xml_path"

    # Create the task service object
    pythoncom.CoInitialize()
    task_service = win32com.client.Dispatch("Schedule.Service")
    task_service.Connect()

    # Load xml from file, overrides xml_text
    # Need to figure out how to load contents of xml
    if xml_path:
        xml_text = xml_path

    # Get the folder to list folders from
    task_folder = task_service.GetFolder(location)

    # Determine logon type
    if user_name:
        if user_name.lower() == "system":
            logon_type = TASK_LOGON_SERVICE_ACCOUNT
            user_name = "SYSTEM"
            password = None
        else:
            if password:
                logon_type = TASK_LOGON_PASSWORD
            else:
                logon_type = TASK_LOGON_INTERACTIVE_TOKEN
    else:
        password = None

    # Save the task
    try:
        task_folder.RegisterTask(
            name, xml_text, TASK_CREATE, user_name, password, logon_type
        )

    except pythoncom.com_error as error:
        hr, msg, exc, arg = error.args  # pylint: disable=W0633
        fc = {
            -2147216615: "Required element or attribute missing",
            -2147216616: "Value incorrectly formatted or out of range",
            -2147352571: "Access denied",
        }
        try:
            failure_code = fc[exc[5]]
        except KeyError:
            failure_code = "Unknown Failure: {0}".format(error)

        log.debug("Failed to create task: {0}".format(failure_code))

    # Verify creation
    if name in list_tasks(location):
        return True
    else:
        return False