DSCResources/MSFT_xWebSiteDefaults/MSFT_xWebSiteDefaults.psm1

######################################################################################
# DSC Resource for IIS Server level Web Site Defaults
# ApplicationHost.config: system.applicationHost/sites/siteDefaults
#
# only a limited number of settings are supported at this time
# We try to cover the most common use cases
# We have a single parameter for each setting
######################################################################################
data LocalizedData
{
    # culture="en-US"
    ConvertFrom-StringData @'
NoWebAdministrationModule=Please ensure that WebAdministration module is installed.
SettingValue=Changing default value '{0}' to '{1}'
ValueOk=Default value '{0}' is already '{1}'
'@

}

######################################################################################
# The Get-TargetResource cmdlet.
# This function will get all supported site default values
######################################################################################
function Get-TargetResource
{
    [CmdletBinding()]
    [OutputType([System.Collections.Hashtable])]
    param
    (
        [Parameter(Mandatory)]
        [ValidateSet('Machine')]
        [string]$ApplyTo
    )
    
    # Check if WebAdministration module is present for IIS cmdlets
    CheckIISPoshModule

    return @{LogFormat = (GetValue 'siteDefaults/logFile' 'logFormat')
                                    TraceLogDirectory = ( GetValue 'siteDefaults/traceFailedRequestsLogging' 'directory')
                                    DefaultApplicationPool = (GetValue 'applicationDefaults' 'applicationPool')
                                    AllowSubDirConfig = (GetValue 'virtualDirectoryDefaults' 'allowSubDirConfig')
                                    ApplyTo = 'Machine'
                                    LogDirectory = (GetValue 'siteDefaults/logFile' 'directory')}    
}

######################################################################################
# The Set-TargetResource cmdlet.
# This function will change a default setting if not already set
######################################################################################
function Set-TargetResource
{
    param
    (    
        [ValidateSet('Machine')]
        [parameter(Mandatory = $true)]
        [string]$ApplyTo,
        [ValidateSet('W3C','IIS','NCSA','Custom')]
        [string]$LogFormat,
        [string]$LogDirectory,
        [string]$TraceLogDirectory,
        [string]$DefaultApplicationPool,
        [ValidateSet('true','false')]
        [string]$AllowSubDirConfig
    )

        CheckIISPoshModule

        SetValue 'siteDefaults/logFile' 'logFormat' $LogFormat
        SetValue 'siteDefaults/logFile' 'directory' $LogDirectory
        SetValue 'siteDefaults/traceFailedRequestsLogging' 'directory' $TraceLogDirectory
        SetValue 'applicationDefaults' 'applicationPool' $DefaultApplicationPool
        SetValue 'virtualDirectoryDefaults' 'allowSubDirConfig' $AllowSubDirConfig
}

######################################################################################
# The Test-TargetResource cmdlet.
# This will test whether all given values are already set in the current configuration
######################################################################################
function Test-TargetResource
{
    [OutputType([System.Boolean])]
    param
    (    
        [ValidateSet('Machine')]
        [parameter(Mandatory = $true)]
        [string]$ApplyTo,
        [ValidateSet('W3C','IIS','NCSA','Custom')]
        [string]$LogFormat,
        [string]$LogDirectory,
        [string]$TraceLogDirectory,
        [string]$DefaultApplicationPool,
        [ValidateSet('true','false')]
        [string]$AllowSubDirConfig
    )

    CheckIISPoshModule

    # check for the various given settings:

    if (!(CheckValue -path 'virtualDirectoryDefaults' -name 'allowSubDirConfig' -newValue $AllowSubDirConfig)) 
    { 
        return $false 
    }

    if (!(CheckValue -path 'siteDefaults/logFile' -name 'logFormat' -newValue $LogFormat)) 
    { 
        return $false 
    }

    if (!(CheckValue -path 'siteDefaults/logFile' -name 'directory' -newValue $LogDirectory)) 
    { 
        return $false 
    }

    if (!(CheckValue -path 'siteDefaults/traceFailedRequestsLogging' -name 'directory' -newValue $TraceLogDirectory)) 
    { 
        return $false 
    }

    if (!(CheckValue -path 'applicationDefaults' -name 'applicationPool' -newValue $DefaultApplicationPool)) 
    { 
        return $false 
    }

    # at this point all settings are ok and our desired state is met.
    return $true
}

######################################################################################
# Helper Functions
######################################################################################

Function CheckValue([string]$path,[string]$name,[string]$newValue)
{
    if (!$newValue)
    {
        # if no new value was specified, we assume this value is okay.
        return $true
    }

    $existingValue = GetValue -Path $path -Name $name
    if ($existingValue -ne $newValue)
    {
        return $false
    }
    else
    {
        $relPath = $path + '/' + $name
        Write-Verbose($LocalizedData.ValueOk -f $relPath,$newValue);
        return $true
    }   
}

# some internal helper function to do the actual work:

Function SetValue([string]$path,[string]$name,[string]$newValue)
{
    # if the variable doesn't exist, the user doesn't want to change this value
    if (!$newValue)
    {
        return
    }

    # get the existing value to compare
    $existingValue = GetValue -Path $path -Name $name
    if ($existingValue -ne $newValue)
    {
        Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.applicationHost/sites/$path" -name $name -value "$newValue"
        $relPath = $path + '/' + $name
        Write-Verbose($LocalizedData.SettingValue -f $relPath,$newValue);
    }    
}

Function GetValue([string]$path,[string]$name)
{
    return Get-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.applicationHost/sites/$path" -name $name
}

Function CheckIISPoshModule
{
    # Check if WebAdministration module is present for IIS cmdlets
    if(!(Get-Module -ListAvailable -Name WebAdministration))
    {
        Throw $LocalizedData.NoWebAdministrationModule
    }
}

# FUNCTIONS TO BE EXPORTED
Export-ModuleMember -function Get-TargetResource, Set-TargetResource, Test-TargetResource