Uninstall a package

    Args:
        name (str): The full path to the package. Can be either a .cab file or a
            folder. Should point to the original source of the package, not to
            where the file is installed. This can also be the name of a package as listed in
            ``dism.installed_packages``
        image (Optional[str]): The path to the root directory of an offline
            Windows image. If `None` is passed, the running operating system is
            targeted. Default is None.
        restart (Optional[bool]): Reboot the machine if required by the install

    Example:

        .. code-block:: yaml

            # Example using source
            remove_KB1231231:
              dism.package_installed:
                - name: C:\\Packages\\KB1231231.cab

            # Example using name from ``dism.installed_packages``
            remove_KB1231231:
              dism.package_installed:
                - name: Package_for_KB1231231~31bf3856ad364e35~amd64~~10.0.1.3

def package_removed(name, image=None, restart=False):
    '''
    Uninstall a package

    Args:
        name (str): The full path to the package. Can be either a .cab file or a
            folder. Should point to the original source of the package, not to
            where the file is installed. This can also be the name of a package as listed in
            ``dism.installed_packages``
        image (Optional[str]): The path to the root directory of an offline
            Windows image. If `None` is passed, the running operating system is
            targeted. Default is None.
        restart (Optional[bool]): Reboot the machine if required by the install

    Example:

        .. code-block:: yaml

            # Example using source
            remove_KB1231231:
              dism.package_installed:
                - name: C:\\Packages\\KB1231231.cab

            # Example using name from ``dism.installed_packages``
            remove_KB1231231:
              dism.package_installed:
                - name: Package_for_KB1231231~31bf3856ad364e35~amd64~~10.0.1.3
    '''
    ret = {'name': name,
           'result': True,
           'comment': '',
           'changes': {}}

    # Fail if using a non-existent package path
    if '~' not in name and not os.path.exists(name):
        if __opts__['test']:
            ret['result'] = None
        else:
            ret['result'] = False
        ret['comment'] = 'Package path {0} does not exist'.format(name)
        return ret

    old = __salt__['dism.installed_packages']()

    # Get package info so we can see if it's already removed
    package_info = __salt__['dism.package_info'](name)

    # If `Package Identity` isn't returned or if they passed a cab file, if
    # `Package Identity` isn't in the list of installed packages
    if 'Package Identity' not in package_info or \
            package_info['Package Identity'] not in old:
        ret['comment'] = 'The package {0} is already removed'.format(name)
        return ret

    if __opts__['test']:
        ret['changes']['package'] = '{0} will be removed'.format(name)
        ret['result'] = None
        return ret

    # Remove the package
    status = __salt__['dism.remove_package'](name, image, restart)

    if status['retcode'] not in [0, 1641, 3010]:
        ret['comment'] = 'Failed to remove {0}: {1}' \
            .format(name, status['stdout'])
        ret['result'] = False

    new = __salt__['dism.installed_packages']()
    changes = salt.utils.data.compare_lists(old, new)

    if changes:
        ret['comment'] = 'Removed {0}'.format(name)
        ret['changes'] = status
        ret['changes']['package'] = changes

    return ret