Set the value of the setting for an IIS container.

    .. versionadded:: 2016.11.0

    Args:
        name (str): The name of the IIS container.
        container (str): The type of IIS container. The container types are:
            AppPools, Sites, SslBindings
        settings (dict): A dictionary of the setting names and their values.

    Returns:
        bool: True if successful, otherwise False

    CLI Example:

    .. code-block:: bash

        salt '*' win_iis.set_container_setting name='MyTestPool' container='AppPools'
            settings="{'managedPipeLineMode': 'Integrated'}"

def set_container_setting(name, container, settings):
    '''
    Set the value of the setting for an IIS container.

    .. versionadded:: 2016.11.0

    Args:
        name (str): The name of the IIS container.
        container (str): The type of IIS container. The container types are:
            AppPools, Sites, SslBindings
        settings (dict): A dictionary of the setting names and their values.

    Returns:
        bool: True if successful, otherwise False

    CLI Example:

    .. code-block:: bash

        salt '*' win_iis.set_container_setting name='MyTestPool' container='AppPools'
            settings="{'managedPipeLineMode': 'Integrated'}"
    '''

    identityType_map2string = {'0': 'LocalSystem', '1': 'LocalService', '2': 'NetworkService', '3': 'SpecificUser', '4': 'ApplicationPoolIdentity'}
    identityType_map2numeric = {'LocalSystem': '0', 'LocalService': '1', 'NetworkService': '2', 'SpecificUser': '3', 'ApplicationPoolIdentity': '4'}
    ps_cmd = list()
    container_path = r"IIS:\{0}\{1}".format(container, name)

    if not settings:
        log.warning('No settings provided')
        return False

    # Treat all values as strings for the purpose of comparing them to existing values.
    for setting in settings:
        settings[setting] = six.text_type(settings[setting])

    current_settings = get_container_setting(
        name=name, container=container, settings=settings.keys())

    if settings == current_settings:
        log.debug('Settings already contain the provided values.')
        return True

    for setting in settings:
        # If the value is numeric, don't treat it as a string in PowerShell.
        try:
            complex(settings[setting])
            value = settings[setting]
        except ValueError:
            value = "'{0}'".format(settings[setting])

        # Map to numeric to support server 2008
        if setting == 'processModel.identityType' and settings[setting] in identityType_map2numeric.keys():
            value = identityType_map2numeric[settings[setting]]

        ps_cmd.extend(['Set-ItemProperty',
                       '-Path', "'{0}'".format(container_path),
                       '-Name', "'{0}'".format(setting),
                       '-Value', '{0};'.format(value)])

    cmd_ret = _srvmgr(ps_cmd)

    if cmd_ret['retcode'] != 0:
        msg = 'Unable to set settings for {0}: {1}'.format(container, name)
        raise CommandExecutionError(msg)

    # Get the fields post-change so that we can verify tht all values
    # were modified successfully. Track the ones that weren't.
    new_settings = get_container_setting(
        name=name, container=container, settings=settings.keys())

    failed_settings = dict()

    for setting in settings:
        # map identity type from numeric to string for comparing
        if setting == 'processModel.identityType' and settings[setting] in identityType_map2string.keys():
            settings[setting] = identityType_map2string[settings[setting]]

        if six.text_type(settings[setting]) != six.text_type(new_settings[setting]):
            failed_settings[setting] = settings[setting]

    if failed_settings:
        log.error('Failed to change settings: %s', failed_settings)
        return False

    log.debug('Settings configured successfully: %s', settings.keys())
    return True