Uninstall the updates passed in the updates collection. Load the updates
        collection using the ``search`` or ``available`` functions.

        .. note:: Starting with Windows 10 the Windows Update Agent is unable to
        uninstall updates. An ``Uninstall Not Allowed`` error is returned. If
        this error is encountered this function will instead attempt to use
        ``dism.exe`` to perform the uninstallation. ``dism.exe`` may fail to
        to find the KB number for the package. In that case, removal will fail.

        Args:

            updates (Updates): An instance of the Updates class containing a
            the updates to be uninstalled.

        Returns:
            dict: A dictionary containing the results of the uninstallation

        Code Example:

        .. code-block:: python

            import salt.utils.win_update
            wua = salt.utils.win_update.WindowsUpdateAgent()

            # uninstall KB3195454
            updates = wua.search('KB3195454')
            results = wua.uninstall(updates)

def uninstall(self, updates):
        '''
        Uninstall the updates passed in the updates collection. Load the updates
        collection using the ``search`` or ``available`` functions.

        .. note:: Starting with Windows 10 the Windows Update Agent is unable to
        uninstall updates. An ``Uninstall Not Allowed`` error is returned. If
        this error is encountered this function will instead attempt to use
        ``dism.exe`` to perform the uninstallation. ``dism.exe`` may fail to
        to find the KB number for the package. In that case, removal will fail.

        Args:

            updates (Updates): An instance of the Updates class containing a
            the updates to be uninstalled.

        Returns:
            dict: A dictionary containing the results of the uninstallation

        Code Example:

        .. code-block:: python

            import salt.utils.win_update
            wua = salt.utils.win_update.WindowsUpdateAgent()

            # uninstall KB3195454
            updates = wua.search('KB3195454')
            results = wua.uninstall(updates)
        '''
        # This doesn't work with the WUA API since Windows 10. It always returns
        # "0x80240028 # Uninstall not allowed". The full message is: "The update
        # could not be uninstalled because the request did not originate from a
        # Windows Server Update Services (WSUS) server.

        # Check for empty list
        if updates.count() == 0:
            ret = {'Success': False,
                   'Updates': 'Nothing to uninstall'}
            return ret

        installer = self._session.CreateUpdateInstaller()
        self._session.ClientApplicationID = 'Salt: Install Update'
        with salt.utils.winapi.Com():
            uninstall_list = win32com.client.Dispatch('Microsoft.Update.UpdateColl')

        ret = {'Updates': {}}

        # Check for updates that aren't already installed
        for update in updates.updates:

            # Define uid to keep the lines shorter
            uid = update.Identity.UpdateID
            ret['Updates'][uid] = {}
            ret['Updates'][uid]['Title'] = update.Title
            ret['Updates'][uid]['AlreadyUninstalled'] = \
                not bool(update.IsInstalled)

            # Make sure the update has actually been Uninstalled
            if salt.utils.data.is_true(update.IsInstalled):
                log.debug('To Be Uninstalled: %s', uid)
                log.debug('\tTitle: %s', update.Title)
                uninstall_list.Add(update)

        # Check the install list
        if uninstall_list.Count == 0:
            ret = {'Success': False,
                   'Updates': 'Nothing to uninstall'}
            return ret

        # Send the list to the installer
        installer.Updates = uninstall_list

        # Uninstall the list
        try:
            log.debug('Uninstalling Updates')
            result = installer.Uninstall()

        except pywintypes.com_error as error:
            # Something happened, return error or try using DISM
            hr, msg, exc, arg = error.args  # pylint: disable=W0633
            try:
                failure_code = self.fail_codes[exc[5]]
            except KeyError:
                failure_code = 'Unknown Failure: {0}'.format(error)

            # If "Uninstall Not Allowed" error, try using DISM
            if exc[5] == -2145124312:
                log.debug('Uninstall Failed with WUA, attempting with DISM')
                try:

                    # Go through each update...
                    for item in uninstall_list:

                        # Look for the KB numbers
                        for kb in item.KBArticleIDs:

                            # Get the list of packages
                            cmd = ['dism', '/Online', '/Get-Packages']
                            pkg_list = self._run(cmd)[0].splitlines()

                            # Find the KB in the pkg_list
                            for item in pkg_list:

                                # Uninstall if found
                                if 'kb' + kb in item.lower():
                                    pkg = item.split(' : ')[1]

                                    ret['DismPackage'] = pkg

                                    cmd = ['dism',
                                           '/Online',
                                           '/Remove-Package',
                                           '/PackageName:{0}'.format(pkg),
                                           '/Quiet',
                                           '/NoRestart']

                                    self._run(cmd)

                except CommandExecutionError as exc:
                    log.debug('Uninstall using DISM failed')
                    log.debug('Command: %s', ' '.join(cmd))
                    log.debug('Error: %s', exc)
                    raise CommandExecutionError(
                        'Uninstall using DISM failed: {0}'.format(exc))

                # DISM Uninstall Completed Successfully
                log.debug('Uninstall Completed using DISM')

                # Populate the return dictionary
                ret['Success'] = True
                ret['Message'] = 'Uninstalled using DISM'
                ret['NeedsReboot'] = needs_reboot()
                log.debug('NeedsReboot: %s', ret['NeedsReboot'])

                # Refresh the Updates Table
                self.refresh()

                reboot = {0: 'Never Reboot',
                          1: 'Always Reboot',
                          2: 'Poss Reboot'}

                # Check the status of each update
                for update in self._updates:
                    uid = update.Identity.UpdateID
                    for item in uninstall_list:
                        if item.Identity.UpdateID == uid:
                            if not update.IsInstalled:
                                ret['Updates'][uid]['Result'] = \
                                    'Uninstallation Succeeded'
                            else:
                                ret['Updates'][uid]['Result'] = \
                                    'Uninstallation Failed'
                            ret['Updates'][uid]['RebootBehavior'] = \
                                reboot[update.InstallationBehavior.RebootBehavior]

                return ret

            # Found a differenct exception, Raise error
            log.error('Uninstall Failed: %s', failure_code)
            raise CommandExecutionError(failure_code)

        # Lookup dictionary
        result_code = {0: 'Uninstallation Not Started',
                       1: 'Uninstallation In Progress',
                       2: 'Uninstallation Succeeded',
                       3: 'Uninstallation Succeeded With Errors',
                       4: 'Uninstallation Failed',
                       5: 'Uninstallation Aborted'}

        log.debug('Uninstall Complete')
        log.debug(result_code[result.ResultCode])
        ret['Message'] = result_code[result.ResultCode]

        if result.ResultCode in [2, 3]:
            ret['Success'] = True
            ret['NeedsReboot'] = result.RebootRequired
            log.debug('NeedsReboot: %s', result.RebootRequired)
        else:
            log.debug('Uninstall Failed')
            ret['Success'] = False

        reboot = {0: 'Never Reboot',
                  1: 'Always Reboot',
                  2: 'Poss Reboot'}
        for i in range(uninstall_list.Count):
            uid = uninstall_list.Item(i).Identity.UpdateID
            ret['Updates'][uid]['Result'] = \
                result_code[result.GetUpdateResult(i).ResultCode]
            ret['Updates'][uid]['RebootBehavior'] = reboot[
                uninstall_list.Item(i).InstallationBehavior.RebootBehavior]

        return ret