Unpacking Software Livestream

Join our monthly Unpacking Software livestream to hear about the latest news, chat and opinion on packaging, software deployment and lifecycle management!

Learn More

Chocolatey Product Spotlight

Join the Chocolatey Team on our regular monthly stream where we put a spotlight on the most recent Chocolatey product releases. You'll have a chance to have your questions answered in a live Ask Me Anything format.

Learn More

Chocolatey Coding Livestream

Join us for the Chocolatey Coding Livestream, where members of our team dive into the heart of open source development by coding live on various Chocolatey projects. Tune in to witness real-time coding, ask questions, and gain insights into the world of package management. Don't miss this opportunity to engage with our team and contribute to the future of Chocolatey!

Learn More

Calling All Chocolatiers! Whipping Up Windows Automation with Chocolatey Central Management

Webinar from
Wednesday, 17 January 2024

We are delighted to announce the release of Chocolatey Central Management v0.12.0, featuring seamless Deployment Plan creation, time-saving duplications, insightful Group Details, an upgraded Dashboard, bug fixes, user interface polishing, and refined documentation. As an added bonus we'll have members of our Solutions Engineering team on-hand to dive into some interesting ways you can leverage the new features available!

Watch On-Demand
Chocolatey Community Coffee Break

Join the Chocolatey Team as we discuss all things Community, what we do, how you can get involved and answer your Chocolatey questions.

Watch The Replays
Chocolatey and Intune Overview

Webinar Replay from
Wednesday, 30 March 2022

At Chocolatey Software we strive for simple, and teaching others. Let us teach you just how simple it could be to keep your 3rd party applications updated across your devices, all with Intune!

Watch On-Demand
Chocolatey For Business. In Azure. In One Click.

Livestream from
Thursday, 9 June 2022

Join James and Josh to show you how you can get the Chocolatey For Business recommended infrastructure and workflow, created, in Azure, in around 20 minutes.

Watch On-Demand
The Future of Chocolatey CLI

Livestream from
Thursday, 04 August 2022

Join Paul and Gary to hear more about the plans for the Chocolatey CLI in the not so distant future. We'll talk about some cool new features, long term asks from Customers and Community and how you can get involved!

Watch On-Demand
Hacktoberfest Tuesdays 2022

Livestreams from
October 2022

For Hacktoberfest, Chocolatey ran a livestream every Tuesday! Re-watch Cory, James, Gary, and Rain as they share knowledge on how to contribute to open-source projects such as Chocolatey CLI.

Watch On-Demand

Downloads:

33,505

Downloads of v 2.0.0.20230301-alpha9:

83

Last Update:

03 Jan 2023

Package Maintainer(s):

Software Author(s):

  • SEEK Ltd.

Tags:

admin dsc

SEEK DSC WebAdministration

This is a prerelease version of SEEK DSC WebAdministration.

  • 1
  • 2
  • 3

2.0.0.20230301-alpha9 | Updated: 03 Jan 2023

Downloads:

33,505

Downloads of v 2.0.0.20230301-alpha9:

83

Software Author(s):

  • SEEK Ltd.

Tags:

admin dsc

SEEK DSC WebAdministration 2.0.0.20230301-alpha9

This is a prerelease version of SEEK DSC WebAdministration.

Legal Disclaimer: Neither this package nor Chocolatey Software, Inc. are affiliated with or endorsed by SEEK Ltd. The inclusion of SEEK Ltd. trademark(s), if any, upon this webpage is solely to identify SEEK Ltd. goods or services and not for commercial purposes.

  • 1
  • 2
  • 3

Some Checks Have Failed or Are Not Yet Complete

Not All Tests Have Passed


Validation Testing Failed


Verification Testing Passed

Details

Scan Testing Successful:

No detections found in any package files

Details
Learn More

Deployment Method: Individual Install, Upgrade, & Uninstall

To install SEEK DSC WebAdministration, run the following command from the command line or from PowerShell:

>

To upgrade SEEK DSC WebAdministration, run the following command from the command line or from PowerShell:

>

To uninstall SEEK DSC WebAdministration, run the following command from the command line or from PowerShell:

>

Deployment Method:

NOTE

This applies to both open source and commercial editions of Chocolatey.

1. Enter Your Internal Repository Url

(this should look similar to https://community.chocolatey.org/api/v2/)


2. Setup Your Environment

1. Ensure you are set for organizational deployment

Please see the organizational deployment guide

2. Get the package into your environment

  • Open Source or Commercial:
    • Proxy Repository - Create a proxy nuget repository on Nexus, Artifactory Pro, or a proxy Chocolatey repository on ProGet. Point your upstream to https://community.chocolatey.org/api/v2/. Packages cache on first access automatically. Make sure your choco clients are using your proxy repository as a source and NOT the default community repository. See source command for more information.
    • You can also just download the package and push it to a repository Download

3. Copy Your Script

choco upgrade seek-dsc-webadministration -y --source="'INTERNAL REPO URL'" --prerelease [other options]

See options you can pass to upgrade.

See best practices for scripting.

Add this to a PowerShell script or use a Batch script with tools and in places where you are calling directly to Chocolatey. If you are integrating, keep in mind enhanced exit codes.

If you do use a PowerShell script, use the following to ensure bad exit codes are shown as failures:


choco upgrade seek-dsc-webadministration -y --source="'INTERNAL REPO URL'" --prerelease
$exitCode = $LASTEXITCODE

Write-Verbose "Exit code was $exitCode"
$validExitCodes = @(0, 1605, 1614, 1641, 3010)
if ($validExitCodes -contains $exitCode) {
  Exit 0
}

Exit $exitCode

- name: Install seek-dsc-webadministration
  win_chocolatey:
    name: seek-dsc-webadministration
    version: '2.0.0.20230301-alpha9'
    source: INTERNAL REPO URL
    state: present
    allow_prerelease: yes

See docs at https://docs.ansible.com/ansible/latest/modules/win_chocolatey_module.html.


chocolatey_package 'seek-dsc-webadministration' do
  action    :install
  source   'INTERNAL REPO URL'
  version  '2.0.0.20230301-alpha9'
  options  '--prerelease'
end

See docs at https://docs.chef.io/resource_chocolatey_package.html.


cChocoPackageInstaller seek-dsc-webadministration
{
    Name        = "seek-dsc-webadministration"
    Version     = "2.0.0.20230301-alpha9"
    Source      = "INTERNAL REPO URL"
    chocoParams = "--prerelease"
}

Requires cChoco DSC Resource. See docs at https://github.com/chocolatey/cChoco.


package { 'seek-dsc-webadministration':
  ensure          => '2.0.0.20230301-alpha9',
  install_options => ['--prerelease'],
  provider        => 'chocolatey',
  source          => 'INTERNAL REPO URL',
}

Requires Puppet Chocolatey Provider module. See docs at https://forge.puppet.com/puppetlabs/chocolatey.


4. If applicable - Chocolatey configuration/installation

See infrastructure management matrix for Chocolatey configuration elements and examples.

WARNING

This package is exempt from moderation. While it is likely safe for you, there is more risk involved.

Description

Custom DSC Resources for administration of an IIS web server


tools\chocolateyUninstall.ps1
try
{
	$DSCResourcesRoot = Join-Path $env:ProgramFiles "WindowsPowerShell\Modules"
	$DSCResourceTarget = Join-Path $env:chocolateyPackageFolder "lib"
	Get-ChildItem $DSCResourceTarget | Foreach-Object { cmd /c rmdir "$DSCResourcesRoot\$_" }
} catch {
    throw $_.Exception
}
tools\chocolateyInstall.ps1
try
{
	$DSCResourcesRoot = Join-Path $env:ProgramFiles "WindowsPowerShell\Modules"
	$DSCResourceTarget = Join-Path $env:chocolateyPackageFolder "lib"

	# remove DSC resources that may have been manually installed
	if (Test-Path "$DSCResourcesRoot\SEEK - Modules") {
		cmd /c rmdir "$DSCResourcesRoot\SEEK - Modules"
	}

	
	Get-ChildItem $DSCResourceTarget | Foreach-Object {
		if (Test-Path "$DSCResourcesRoot\$_") {
			# remove previous installation of this package
			cmd /c rmdir "$DSCResourcesRoot\$_"
		}
		cmd /c mklink /j "$DSCResourcesRoot\$_" "$DSCResourceTarget\$_"
		Get-ChildItem -Path "$DSCResourcesRoot\$_" -File -Recurse | Unblock-File
	}

} catch {
	$host.SetShouldExit(1)
	throw $_.Exception
}
lib\cWebAdministration\cWebAdministration.psd1
@{
# Version number of this module.
ModuleVersion = '2.0.0-alpha9'

# ID used to uniquely identify this module
GUID = '5b4f047a-7fca-48f1-81a6-5c4a85fb6cf2'

# Author of this module
Author = 'SEEK Ltd.'

# Company or vendor of this module
CompanyName = 'SEEK Ltd.'

# Copyright statement for this module
Copyright = '(c) 2015 SEEK Ltd. All rights reserved.'

# Description of the functionality provided by this module
Description = 'Custom DSC Resources for administration of an IIS web server'

# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '4.0'

# Minimum version of the common language runtime (CLR) required by this module
CLRVersion = '4.0'

# Functions to export from this module
FunctionsToExport = '*'

# Cmdlets to export from this module
CmdletsToExport = '*'
}
lib\cWebAdministration\DSCResources\SEEK_cWebAppPool\SEEK_cWebAppPool.psm1
function Get-TargetResource
{
    [CmdletBinding()]
    [OutputType([System.Collections.Hashtable])]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String]
        $Name,

        [parameter(Mandatory = $true)]
        [System.String]
        $ApplicationName
    )

    Confirm-Dependencies

    $AppPool = Get-AppPool($Name)
    if($AppPool -eq $null)
    {
        return @{Name = $Name; ApplicationName = $ApplicationName; Ensure = "Absent"; State = "Stopped"}
    }

    $returnValue = @{
        Name   = $Name
        ApplicationName = $ApplicationName
        Ensure = "Present"
        State  = $AppPool.State
        managedRuntimeVersion = $AppPool.managedRuntimeVersion
        managedPipelineMode = $AppPool.managedPipelineMode
        enable32BitAppOnWin64 = $AppPool.enable32BitAppOnWin64
        processModel = @{
            identityType = $AppPool.processModel.identityType
            userName = $AppPool.processModel.userName
            password = $AppPool.processModel.password
        }
    }

    return $returnValue
}


function Set-TargetResource
{
    [CmdletBinding()]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String]
        $Name,

        [parameter(Mandatory = $true)]
        [System.String]
        $ApplicationName,

        [ValidateSet("Present","Absent")]
        [System.String]
        $Ensure  = "Present",

        [ValidateSet("Started","Stopped")]
        [System.String]
        $State = "Started",

        [ValidateSet("v2.0","v4.0", "")]
        [System.String]
        $ManagedRuntimeVersion = "v4.0",

        [ValidateSet("Integrated","Classic")]
        [System.String]
        $ManagedPipelineMode = "Integrated",

        [ValidateSet("true","false")]
        [System.String]
        $Enable32BitAppOnWin64 = "false",

        [ValidateSet("ApplicationPoolIdentity","LocalSystem","LocalService","NetworkService","SpecificUser")]
        [System.String]
        $IdentityType = "SpecificUser",

        [parameter(Mandatory = $true)]
        [System.String]
        $UserName,

        [parameter(Mandatory = $true)]
        [System.String]
        $Password
    )

    Confirm-Dependencies

    if($Ensure -eq "Absent")
    {
        Write-Verbose("Removing the Web App Pool")
        Remove-WebAppPool $Name
    }
    else
    {
        $AppPool = Get-AppPool($Name)
        if($AppPool -eq $null)
        {
            Write-Verbose("Creating the Web App Pool")
            $AppPool = New-WebAppPool $Name
        }

        $AppPool.managedRuntimeVersion = $ManagedRuntimeVersion
        $AppPool.managedPipelineMode = $ManagedPipelineMode
        $AppPool.enable32BitAppOnWin64 = $Enable32BitAppOnWin64
        $AppPool.processModel.identityType = $IdentityType
        $AppPool.processModel.userName = $UserName
        $AppPool.processModel.password = $Password
        $AppPool | Set-Item

        if($AppPool.State -ne $State)
        {
            Execute-RequiredState -Name $Name -State $State
        }
    }
}


function Test-TargetResource
{
    [CmdletBinding()]
    [OutputType([System.Boolean])]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String]
        $Name,

        [parameter(Mandatory = $true)]
        [System.String]
        $ApplicationName,

        [ValidateSet("Present","Absent")]
        [System.String]
        $Ensure  = "Present",

        [ValidateSet("Started","Stopped")]
        [System.String]
        $State = "Started",

        [ValidateSet("v2.0","v4.0", "")]
        [System.String]
        $ManagedRuntimeVersion = "v4.0",

        [ValidateSet("Integrated","Classic")]
        [System.String]
        $ManagedPipelineMode = "Integrated",

        [ValidateSet("true","false")]
        [System.String]
        $Enable32BitAppOnWin64 = "false",

        [ValidateSet("ApplicationPoolIdentity","LocalSystem","LocalService","NetworkService","SpecificUser")]
        [System.String]
        $IdentityType = "SpecificUser",

        [parameter(Mandatory = $true)]
        [System.String]
        $UserName,

        [parameter(Mandatory = $true)]
        [System.String]
        $Password
    )

    Confirm-Dependencies

    $WebAppPool = Get-TargetResource -Name $Name -ApplicationName $ApplicationName

    if($Ensure -eq "Present")
    {
        if($WebAppPool.Ensure -eq $Ensure`
         -and $WebAppPool.State -eq $state`
         -and $WebAppPool.ManagedRuntimeVersion -eq $ManagedRuntimeVersion`
         -and $WebAppPool.ManagedPipelineMode -eq $ManagedPipelineMode`
         -and $WebAppPool.Enable32BitAppOnWin64.toString() -eq $Enable32BitAppOnWin64`
         -and $WebAppPool.ProcessModel.IdentityType -eq $IdentityType`
         -and $WebAppPool.ProcessModel.UserName -eq $UserName`
         -and $WebAppPool.ProcessModel.Password -eq $Password)
        {
            return $true
        }
    }
    elseif($WebAppPool.Ensure -eq $Ensure)
    {
        return $true
    }

    return $false
}


function Get-AppPool([string] $Name)
{
    return $AppPool = Get-Item -Path "IIS:\AppPools\*" | ? {$_.name -eq $Name}
}


function Execute-RequiredState([string] $Name, [string] $State)
{
    if($State -eq "Started")
    {
        Write-Verbose("Starting the Web App Pool")
        Start-WebAppPool -Name $Name
    }
    else
    {
        Write-Verbose("Stopping the Web App Pool")
        Stop-WebAppPool -Name $Name
    }
}

function Confirm-Dependencies
{
    Write-Debug "Checking whether WebAdministration is there in the machine or not."
    Get-Module -ListAvailable -Name WebAdministration -OutVariable webAdministrationModule 4>&1 | Out-Null
    if(-not $webAdministrationModule)
    {
        Throw "Please ensure that the WebAdministration module is installed."
    }
    Import-Module WebAdministration 4>&1 | Out-Null
}

Export-ModuleMember -Function *-TargetResource
lib\cWebAdministration\DSCResources\SEEK_cWebAppPool\SEEK_cWebAppPool.schema.mof
 
lib\cWebAdministration\DSCResources\SEEK_cBindings\SEEK_cBindings.schema.mof
 
lib\cWebAdministration\DSCResources\SEEK_cBindings\SEEK_cBindings.psm1
function Get-TargetResource
{
    [CmdletBinding()]
    [OutputType([System.Collections.Hashtable])]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String] $Site
    )

    Confirm-Dependencies

    get-BindingsResource (get-BindingConfigElements $Site) $Site
}

function Test-TargetResource
{
    [CmdletBinding()]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String] $Site,

        [ValidateSet("Present","Absent")]
        [System.String]
        $Ensure  = "Present",

        [Microsoft.Management.Infrastructure.CimInstance[]]
        $Bindings = @(),

        [System.Boolean]
        $Clear = $false
    )

    Confirm-Dependencies

    $currentCimBindings = get-CurrentCimBindings $Site
    $commonCimBindings = select-CommonCimBindings (new-CimBindingsWithBindingInformation $Bindings) $currentCimBindings

    if (($Ensure -eq "Absent") -and $Clear) { return (@($currentCimBindings).count -eq 0) -and (@($commonCimBindings).count -eq 0) }
    if ($Ensure -eq "Absent") { return @($commonCimBindings).count -eq 0 }

    if ($Clear) { return $currentCimBindings.count -eq $commonCimBindings.count }
    return (@($commonCimBindings).count -eq $Bindings.count)
}

function Set-TargetResource
{
    [CmdletBinding()]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String] $Site,

        [ValidateSet("Present","Absent")]
        [System.String]
        $Ensure  = "Present",

        [Microsoft.Management.Infrastructure.CimInstance[]]
        $Bindings = @(),

        [System.Boolean]
        $Clear = $false
    )

    Confirm-Dependencies
    Stop-AppFabricApplicationServer -SiteName $Site

    try
    {
        $newCimBindings = new-CimBindingsForSite $Ensure $Bindings $Site $Clear
        $sitePath = $("IIS:\Sites\${Site}")
        Set-ItemProperty -Path $sitePath -Name bindings -Value (new-BindingsValue $newCimBindings)
        $newCimBindings | Where-Object Protocol -eq "https" | ForEach-Object { add-SslCertificateForHttpsCimBinding $_ }

        $protocols = $newCimBindings | Select-Object -ExpandProperty Protocol -Unique
        Set-ItemProperty $sitePath -Name EnabledProtocols -Value ($protocols -join ',')
    }
    finally
    {
        Start-AppFabricApplicationServer -SiteName $Site
    }

}

function New-CimBinding
{
    [CmdletBinding()]
    param
    (
        [System.String] $BindingInformation,
        [System.String] $Protocol
    )

    New-CimInstance -ClassName SEEK_cBinding -ClientOnly -Property @{
        BindingInformation = $BindingInformation
        Protocol = $Protocol
    }
}

function New-HttpCimBinding {
    [CmdletBinding()]
    param
    (
        [System.String] $HostName,
        [System.String] $IPAddress,
        [System.UInt16] $Port
    )

    New-CimInstance -ClassName SEEK_cBinding -ClientOnly -Property @{
        HostName = $HostName
        IPAddress = $IPAddress
        Port = $Port
        Protocol = "http"
    }
}

function New-HttpsCimBinding {
    [CmdletBinding()]
    param
    (
        [System.String] $CertificatePath,
        [System.String] $CertificateSubject,
        [System.String] $IPAddress,
        [System.UInt16] $Port
    )

    New-CimInstance -ClassName SEEK_cBinding -ClientOnly -Property @{
        CertificatePath = $CertificatePath
        CertificateSubject = $CertificateSubject
        IPAddress = $IPAddress
        Port = $Port
        Protocol = "https"
    }
}

function add-SslCertificateForHttpsCimBinding
{
    [CmdletBinding()]
    param($httpsCimBinding)

    $ip = get-HttpSysIp $httpsCimBinding.IPAddress
    $path = $httpsCimBinding.CertificatePath
    $port = $httpsCimBinding.Port
    $thumbprint = get-CertificateThumbprint $httpsCimBinding

    $sslBindingPath = "IIS:\SslBindings\${ip}!${port}"

    if (Test-Path $sslBindingPath) {
        Write-Verbose "SSL binding for endpoint ${ip}:${port} alerady exists."
        Write-Verbose "Clobbering with new SSL binding."
        Remove-Item $sslBindingPath
    }

    Get-Item "${path}\${thumbprint}" | New-Item $sslBindingPath
}

function compare-CimBindings {
    [CmdletBinding()]
    param
    (
        $cimBinding,
        $otherCimBinding
    )

    $matchingBindingInformation = $cimBinding.BindingInformation -eq $otherCimBinding.BindingInformation
    $matchingProtocol = $cimBinding.Protocol -eq $otherCimBinding.Protocol

    if (-not ($matchingBindingInformation -and $matchingProtocol)) { return $false }

    $true
}

function containsCimBinding {
    [CmdletBinding()]
    param($bindings, $binding)

    $result = $false
    $bindings | ForEach-Object { if(compare-CimBindings $_ $binding) { $result = $true } }
    $result
}

function get-BindingConfigElements
{
    [CmdletBinding()]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String] $Site
    )

    (Get-ItemProperty "IIS:\Sites\${Site}" -Name bindings)
}

function get-BindingInformation
{
    [CmdletBinding()]
    param($binding)

    if($binding.BindingInformation -ne $null) { return $binding.BindingInformation }

    switch ($binding.Protocol)
    {
        "http"
        { get-HttpBindingInformation $binding }
        "https"
        { get-HttpsBindingInformation $binding }
    }
}

function get-BindingsResource
{
    [CmdletBinding()]
    param($bindingConfigElements, $site)

    $result = @{
        Bindings = @()
        Ensure = "Absent"
        Site = $site
    }

    if($bindingConfigElements.count -ne 0) {
        $result.Bindings = new-CimBindingsFromConfigElements $bindingConfigElements
        $result.Ensure = "Present"
    }

    $result
}

function get-CertificateThumbprint
{
    [CmdletBinding()]
    param($httpsCimBinding)

    (Get-ChildItem -Path $httpsCimBinding.CertificatePath | Where Subject -eq $httpsCimBinding.CertificateSubject).Thumbprint
}

function get-CurrentCimBindings
{
    [CmdletBinding()]
    param($site)

    (Get-TargetResource -Site $site).Bindings
}

function get-HttpBindingInformation
{
    [CmdletBinding()]
    param($httpBinding)

    $hostName = $httpBinding.HostName
    $ipAddress = $httpBinding.IPAddress
    $port = $httpBinding.Port

    "${ipAddress}:${port}:${hostName}"
}

function get-HttpsBindingInformation
{
    [CmdletBinding()]
    param($httpsBinding)

    $ipAddress = $httpsBinding.IPAddress
    $port = $httpsBinding.Port

    "${ipAddress}:${port}:"
}

function get-HttpSysIp
{
    [CmdletBinding()]
    param($ip)

    if ($ip -eq "*") { return "0.0.0.0" }
    $ip
}

function new-CimBindingsForSite {
    [CmdletBinding()]
    param($ensure, $cimBindings, $site, $clear = $false)

    $currentCimBindings = @()

    if (!$clear) { $currentCimBindings = @(get-CurrentCimBindings $site) }

    if ($Ensure -eq "Absent") {
        return select-FromCimBindingsWithoutCimBindings -From $currentCimBindings -Without $cimBindings
    }

    $newBindings = $currentCimBindings
    $newBindings += $cimBindings
    return $newBindings
}

function new-BindingsValue
{
    [CmdletBinding()]
    param($bindings)

    (new-CimBindingsWithBindingInformation $bindings) | ForEach-Object {
        @{
            bindingInformation = $_.BindingInformation
            protocol = $_.Protocol
        }
    }
}

function new-CimBindingsWithBindingInformation
{
    [CmdletBinding()]
    param($cimBindings)

    $cimBindings | ForEach-Object {
        new-CimBindingFromHash @{
            BindingInformation = get-BindingInformation $_
            CertificatePath = $_.CertificatePath
            CertificateSubject = $_.CertificateSubject
            HostName = $_.HostName
            IPAddress = $_.IPAddress
            Port = $_.Port
            Protocol = $_.Protocol
        }
    }
}

function new-CimBindingFromConfigElement
{
    [CmdletBinding()]
    param($bindingConfigElement)

    $bindingHash = @{
        BindingInformation = $bindingConfigElement.bindingInformation
        Protocol = $bindingConfigElement.protocol
    }

    if ($bindingHash.Protocol -eq "https") {
        $bindingHash.CertificatePath = $bindingConfigElement.certificatePath
        $bindingHash.CertificateSubject = $bindingConfigElement.certificateSubject
    }

    new-CimBindingFromHash $bindingHash
}

function new-CimBindingsFromConfigElements
{
    [CmdletBinding()]
    param($bindingConfigElements)

    $bindingConfigElements.collection | ForEach-Object { new-CimBindingFromConfigElement $_ }
}

function new-CimBindingFromHash
{
    [CmdletBinding()]
    param($bindingHash)

    New-CimInstance -ClassName SEEK_cBinding -ClientOnly -Property (new-HashWithoutNullValues $bindingHash)
}

function new-HashWithoutNullValues
{
    [CmdletBinding()]
    param($hashtable)

    $result = @{}
    $hashtable.Keys | Where { $hashtable.$_ -ne $null } | ForEach { $result.$_ = ($hashtable.$_) }
    $result
}

function select-CommonCimBindings
{
    [CmdletBinding()]
    param($cimBindings, $otherCimBindings)

    $cimBindings | Where-Object { containsCimBinding $otherCimBindings $_ }
}

function select-FromCimBindingsWithoutCimBindings
{
    [CmdletBinding()]
    param($from, $without)

    $from | Where-Object { -not (containsCimBinding $without $_) }
}

function Stop-AppFabricApplicationServer
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$SiteName
    )

    Write-Debug "Checking whether App Fabric is installed."
    Get-Module -ListAvailable -Name ApplicationServer -OutVariable applicationServerModule 4>&1 | Out-Null
    if($applicationServerModule)
    {
        Import-Module ApplicationServer 4>&1 | Out-Null
        Stop-ASApplication -SiteName $SiteName
    }
}

function Start-AppFabricApplicationServer
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$SiteName
    )

    Write-Debug "Checking whether App Fabric is installed."
    Get-Module -ListAvailable -Name ApplicationServer -OutVariable applicationServerModule 4>&1 | Out-Null
    if($applicationServerModule)
    {
        Import-Module ApplicationServer 4>&1 | Out-Null
        Start-ASApplication -SiteName $SiteName
    }
}

function Confirm-Dependencies
{
    Write-Debug "Checking whether WebAdministration is there in the machine or not."
    Get-Module -ListAvailable -Name WebAdministration -OutVariable webAdministrationModule 4>&1 | Out-Null
    if(-not $webAdministrationModule)
    {
        Throw "Please ensure that the WebAdministration module is installed."
    }
    Import-Module WebAdministration 4>&1 | Out-Null
}

Export-ModuleMember -Function *-TargetResource

lib\cWebAdministration\DSCResources\SEEK_cWebAppAndPool\SEEK_cWebAppAndPool.psd1
#
# Module manifest for module 'SEEK_cWebAppAndPool'
#
# Generated by: wgodfrey
#
# Generated on: 27/05/2014
#

@{

# Script module or binary module file associated with this manifest.
RootModule = 'SEEK_cWebAppAndPool.schema.psm1'

# Version number of this module.
ModuleVersion = '1.0'

# ID used to uniquely identify this module
GUID = 'e539c622-7f70-455b-a0ea-c92c17559b3e'

# Author of this module
Author = 'wgodfrey'

# Company or vendor of this module
CompanyName = 'SEEK Ltd'

# Copyright statement for this module
Copyright = '(c) 2014 SEEK Ltd. All rights reserved.'

# Description of the functionality provided by this module
# Description = ''

# Minimum version of the Windows PowerShell engine required by this module
# PowerShellVersion = ''

# Name of the Windows PowerShell host required by this module
# PowerShellHostName = ''

# Minimum version of the Windows PowerShell host required by this module
# PowerShellHostVersion = ''

# Minimum version of Microsoft .NET Framework required by this module
# DotNetFrameworkVersion = ''

# Minimum version of the common language runtime (CLR) required by this module
# CLRVersion = ''

# Processor architecture (None, X86, Amd64) required by this module
# ProcessorArchitecture = ''

# Modules that must be imported into the global environment prior to importing this module
# RequiredModules = @()

# Assemblies that must be loaded prior to importing this module
# RequiredAssemblies = @()

# Script files (.ps1) that are run in the caller's environment prior to importing this module.
# ScriptsToProcess = @()

# Type files (.ps1xml) to be loaded when importing this module
# TypesToProcess = @()

# Format files (.ps1xml) to be loaded when importing this module
# FormatsToProcess = @()

# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
# NestedModules = @()

# Functions to export from this module
FunctionsToExport = '*'

# Cmdlets to export from this module
CmdletsToExport = '*'

# Variables to export from this module
VariablesToExport = '*'

# Aliases to export from this module
AliasesToExport = '*'

# List of all modules packaged with this module
# ModuleList = @()

# List of all files packaged with this module
# FileList = @()

# Private data to pass to the module specified in RootModule/ModuleToProcess
# PrivateData = ''

# HelpInfo URI of this module
# HelpInfoURI = ''

# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
# DefaultCommandPrefix = ''

}

lib\cWebAdministration\DSCResources\SEEK_cWebAppAndPool\SEEK_cWebAppAndPool.schema.psm1
Configuration cWebAppAndPool
{
    param
    (
        [String]$Name,
        [String[]]$WebSiteName,
        [String]$AppPoolName,
        [HashTable]$AppPoolCredentials,
        [String]$AppPoolManagedRuntimeVersion = "v4.0",
        [String]$AppPoolIdentityType = "SpecificUser",
        [String]$AppPoolManagedPipelineMode = "Integrated",
        [String]$AppPoolEnable32BitAppOnWin64 = "false",
        [HashTable]$AuthenticationInfo = @{Anonymous = "true"; Basic = "false"; Digest = "false"; Windows = "false"},
        [String]$PhysicalPath
    )

    Import-DscResource -Module cWebAdministration -Name SEEK_cWebAppPool, SEEK_cWebApplication

    cWebAppPool AppPool
    {
        Name = $AppPoolName
        ApplicationName = $Name
        UserName = $AppPoolCredentials.Username
        Password = $AppPoolCredentials.Password
        ManagedRuntimeVersion = $AppPoolManagedRuntimeVersion
        IdentityType = $AppPoolIdentityType
        ManagedPipelineMode = $AppPoolManagedPipelineMode
        Enable32BitAppOnWin64 = $AppPoolEnable32BitAppOnWin64
    }

    Foreach ($website in @($WebSiteName))
    {
        cWebApplication "${website}WebApplication"
        {
            Name = $Name
            Website = $website
            WebAppPool =  $AppPoolName
            PhysicalPath = $PhysicalPath
            AuthenticationInfo = SEEK_cWebApplicationAuthenticationInformation
                                {
                                    Anonymous = $AuthenticationInfo.Anonymous
                                    Basic = $AuthenticationInfo.Basic
                                    Digest = $AuthenticationInfo.Digest
                                    Windows = $AuthenticationInfo.Windows
                                }
            DependsOn = @("[cWebAppPool]AppPool")
        }
    }
}
lib\cWebAdministration\DSCResources\SEEK_cWebsite\SEEK_cWebsite.schema.mof
 
lib\cWebAdministration\DSCResources\SEEK_cWebsite\SEEK_cWebsite.psm1
data LocalizedData
{
    # culture="en-US"
    ConvertFrom-StringData @'
SetTargetResourceInstallwhatIfMessage=Trying to create website "{0}".
SetTargetResourceUnInstallwhatIfMessage=Trying to remove website "{0}".
WebsiteNotFoundError=The requested website "{0}" is not found on the target machine.
WebsiteDiscoveryFailureError=Failure to get the requested website "{0}" information from the target machine.
WebsiteCreationFailureError=Failure to successfully create the website "{0}".
WebsiteRemovalFailureError=Failure to successfully remove the website "{0}".
WebsiteUpdateFailureError=Failure to successfully update the properties for website "{0}".
WebsiteBindingUpdateFailureError=Failure to successfully update the binding "{0}" for website "{1}".
WebsiteBindingInputInvalidationError=Desired website bindings not valid for website "{0}".
WebsiteCompareFailureError=Failure to successfully compare properties for website "{0}".
WebBindingCertifcateError=Failure to add certificate to web binding. Please make sure that the certificate thumbprint "{0}" is valid.
WebsiteStateFailureError=Failure to successfully set the state of the website {0}.
WebsiteBindingConflictOnStartError = Website "{0}" could not be started due to binding conflict. Ensure that the binding information for this website does not conflict with any existing website's bindings before trying to start it.
'@
}

# The Get-TargetResource cmdlet is used to fetch the status of role or Website on the target machine.
# It gives the Website info of the requested role/feature on the target machine.
function Get-TargetResource
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$Name
    )

        Confirm-Dependencies

        $getTargetResourceResult = $null;

        $Website = Get-Website | where {$_.Name -eq $Name}

        if ($Website.count -eq 0) # No Website exists with this name.
        {
            $ensureResult = "Absent";
        }
        elseif ($Website.count -eq 1) # A single Website exists with this name.
        {
            $ensureResult = "Present"

            $SslFlags = Get-SslFlags -Location $Name

            [PSObject[]] $Bindings
            $Bindings = (Get-ItemProperty -path IIS:\Sites\$Name -Name Bindings).collection

            $CimBindings = foreach ($binding in $bindings)
            {
                $BindingObject = Get-WebBindingObject -Binding $binding

                if($BindingObject.Protocol -eq "http") {
                    New-CimInstance -ClassName SEEK_cWebBindingInformation -Property @{Port=[System.UInt16]$BindingObject.Port;Protocol=$BindingObject.Protocol;HostName=$BindingObject.HostName;IPAddress=$BindingObject.IPAddress} -ClientOnly
                }
                elseif($BindingObject.Protocol -eq "https") {
                    if (($BindingObject.CertificateThumbprint -eq $null) -or ($BindingObject.CertificateStoreName -eq $null)) {
                        New-CimInstance -ClassName SEEK_cWebBindingInformation -Property @{Port=[System.UInt16]$BindingObject.Port;Protocol=$BindingObject.Protocol;HostName=$BindingObject.HostName;IPAddress=$BindingObject.IPAddress} -ClientOnly
                    }
                    else {
                        New-CimInstance -ClassName SEEK_cWebBindingInformation -Property @{Port=[System.UInt16]$BindingObject.Port;Protocol=$BindingObject.Protocol;HostName=$BindingObject.HostName;IPAddress=$BindingObject.IPAddress;CertificateThumbprint=$BindingObject.CertificateThumbprint;CertificateStoreName=$BindingObject.CertificateStoreName} -ClientOnly
                    }
                }
                elseif($BindingObject.Protocol -eq "net.pipe") {
                    New-CimInstance -ClassName SEEK_cWebBindingInformation -Property @{Protocol=$BindingObject.Protocol;HostName=$BindingObject.HostName} -ClientOnly
                }
                elseif($BindingObject.Protocol -eq "net.tcp") {
                    New-CimInstance -ClassName SEEK_cWebBindingInformation -Property @{Port=[System.UInt16]$BindingObject.Port;Protocol=$BindingObject.Protocol;HostName=$BindingObject.HostName} -ClientOnly
                }
            }

            $CimAuthentication = Get-AuthenticationInfo -Website $Name

        }
        else # Multiple websites with the same name exist. This is not supported and is an error
        {
            ThrowTerminatingError `
                -ErrorId "WebsiteDiscoveryFailure" `
                -ErrorMessage  ($($LocalizedData.WebsiteDiscoveryFailure) -f ${Name}) `
                -ErrorCategory ([System.Management.Automation.ErrorCategory]::InvalidResult)

        }

        # Add all Website properties to the hash table
        $getTargetResourceResult = @{
                                        Name = $Name
                                        Ensure = $ensureResult
                                        PhysicalPath = $Website.physicalPath
                                        State = $Website.state
                                        ID = $Website.id
                                        SslFlags = $SslFlags
                                        ApplicationPool = $Website.applicationPool
                                        BindingInfo = $CimBindings
                                        AuthenticationInfo = $CimAuthentication
                                        HostFileInfo = $null
                                    }

        return $getTargetResourceResult
}


# The Set-TargetResource cmdlet is used to create, delete or configuure a website on the target machine.
function Set-TargetResource
{
    [CmdletBinding()]
    param
    (
        [ValidateSet("Present", "Absent")]
        [string]$Ensure = "Present",

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$Name,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$PhysicalPath,

        [ValidateSet("Started", "Stopped")]
        [string]$State = "Started",

        [string]$ApplicationPool,

        [ValidateNotNull()]
        [string]$SslFlags = "",

        [Microsoft.Management.Infrastructure.CimInstance[]]$BindingInfo,

        [Microsoft.Management.Infrastructure.CimInstance[]]$HostFileInfo,

        [Microsoft.Management.Infrastructure.CimInstance]$AuthenticationInfo
    )

    Confirm-Dependencies

    $getTargetResourceResult = $null;

    if($Ensure -eq "Present")
    {
        #Remove Ensure from parameters as it is not needed to create new website
        $Result = $psboundparameters.Remove("Ensure");
        #Remove State parameter form website. Will start the website after configuration is complete
        $Result = $psboundparameters.Remove("State");

        #Remove SslFlags parameter form website.
        #SslFlags will be added to site using separate cmdlet
        $Result = $psboundparameters.Remove("SslFlags");

        #Remove bindings from parameters if they exist
        #Bindings will be added to site using separate cmdlet
        $Result = $psboundparameters.Remove("BindingInfo");

        #Remove authentication settings from parameters if they exist
        #Authentication settings will be added to site using separate cmdlet
        $Result = $psboundparameters.Remove("AuthenticationInfo");

        #Remove host file settings from parameters if they exist
        #Host file settings will be added to site using separate cmdlet
        $Result = $psboundparameters.Remove("HostFileInfo");

        if(!(Test-BindingDoesNotConflictWithOtherSites -WebsiteName $Name -WebsiteBindingInfo $BindingInfo))
        {
            ThrowTerminatingError `
                -ErrorId "WebsiteBindingConflictOnStart" `
                -ErrorMessage  ($($LocalizedData.WebsiteBindingConflictOnStartError) -f ${Name}) `
                -ErrorCategory ([System.Management.Automation.ErrorCategory]::InvalidResult)
        }

        $website = Get-Website | where {$_.Name -eq $Name}

        if($website -ne $null)
        {
            Stop-AppFabricApplicationServer -SiteName $Name

            #update parameters as required

            $UpdateNotRequired = $true

            #Update Physical Path if required
            if(ValidateWebsitePath -Name $Name -PhysicalPath $PhysicalPath)
            {
                $UpdateNotRequired = $false
                Set-ItemProperty -Path "IIS:\Sites\${Name}" -Name physicalPath -Value $physicalPath
                Write-Verbose("Physical path for website $Name has been updated to $PhysicalPath");
            }

            #Update Bindings if required
            if ($BindingInfo -ne $null)
            {
                if(ValidateWebsiteBindings -Name $Name -BindingInfo $BindingInfo)
                {
                    $UpdateNotRequired = $false

                    #Update Bindings
                    UpdateBindings -Name $Name -BindingInfo $BindingInfo

                    Write-Verbose("Bindings for website $Name have been updated.");
                }
            }

            if (!(Test-AuthenticationInfo -Website $Name -AuthenticationInfo $AuthenticationInfo))
            {
                Set-AuthenticationInfo -Website $Name -AuthenticationInfo $AuthenticationInfo
                Write-Verbose ("Authentication information for website $Name has been updated.")
            }

            #Update host entry if required
            if ($HostFileInfo -ne $null)
            {
                if(ValidateHostFileEntry -HostFileInfo $HostFileInfo)
                {
                    UpdateHostFileEntry -HostFileInfo $HostFileInfo

                    Write-Verbose("Hostfile for website $Name has been updated.");
                }
            }

            #Update Application Pool if required
            if(($website.applicationPool -ne $ApplicationPool) -and ($ApplicationPool -ne ""))
            {
                $UpdateNotRequired = $false
                Set-ItemProperty -Path "IIS:\Sites\${Name}" -Name applicationPool -Value $applicationPool
                Write-Verbose("Application Pool for website $Name has been updated to $ApplicationPool")
            }

            Set-WebConfiguration -PSPath IIS:\Sites -Location $Name -Filter 'system.webserver/security/access' -Value $SslFlags

            #Update State if required
            if($website.state -ne $State -and $State -ne "")
            {
                $UpdateNotRequired = $false
                if($State -eq "Started")
                {

                    try
                    {

                    Start-Website -Name $Name

                    }
                    catch
                    {
                        ThrowTerminatingError `
                            -ErrorId "WebsiteStateFailure" `
                            -ErrorMessage  ($($LocalizedData.WebsiteStateFailureError) -f ${Name}) `
                            -ErrorCategory ([System.Management.Automation.ErrorCategory]::InvalidResult) `
                            -Exception ($_.exception)
                    }

                }
                else
                {
                    try
                    {

                    Stop-Website -Name $Name

                    }
                    catch
                    {
                        ThrowTerminatingError `
                            -ErrorId "WebsiteStateFailure" `
                            -ErrorMessage  ($($LocalizedData.WebsiteStateFailureError) -f ${Name}) `
                            -ErrorCategory ([System.Management.Automation.ErrorCategory]::InvalidResult) `
                            -Exception ($_.exception)
                    }
                }

                Write-Verbose("State for website $Name has been updated to $State");

            }

            if($UpdateNotRequired)
            {
                Write-Verbose("Website $Name already exists and properties do not need to be udpated.");
            }

            Start-AppFabricApplicationServer -SiteName $Name
        }
        else #Website doesn't exist so create new one
        {
            try
            {
                #Workaround for bug when there are no websites then New-Website fails
                if ((Get-Website).count -eq 0) {
                    $psboundparameters.Add("Id", 1)
                }
                $Website = New-Website @psboundparameters
                $Result = Stop-Website $Website.name -ErrorAction Stop

                Set-WebConfiguration -PSPath IIS:\Sites -Location $Name -Filter 'system.webserver/security/access' -Value $SslFlags

                #Clear default bindings if new bindings defined and are different
                if($BindingInfo -ne $null)
                {
                    if(ValidateWebsiteBindings -Name $Name -BindingInfo $BindingInfo)
                    {
                        UpdateBindings -Name $Name -BindingInfo $BindingInfo

                        Write-Verbose ("Binding information for website $Name added")
                    }
                }

                Write-Verbose ("Begin Authentication information update for website $Name, $AuthenticationInfo")

                Set-AuthenticationInfo -Website $Name -AuthenticationInfo $AuthenticationInfo

                #Update host entry if required
                if ($HostFileInfo -ne $null)
                {
                  UpdateHostFileEntry -HostFileInfo $HostFileInfo

                  Write-Verbose("Hostfile for website $Name has been updated.")
                }

                Write-Verbose("successfully created website $Name")

                #Start site if required
                if($State -eq "Started")
                {
                    #Wait 1 sec for bindings to take effect
                    #I have found that starting the website results in an error if it happens to quickly
                    Start-Sleep -s 1
                    Start-Website -Name $Name -ErrorAction Stop
                }

                Write-Verbose("successfully started website $Name")
            }
            catch
            {
                ThrowTerminatingError `
                    -ErrorId "WebsiteCreationFailure" `
                    -ErrorMessage  ($($LocalizedData.FeatureCreationFailureError) -f ${Name}) `
                    -ErrorCategory ([System.Management.Automation.ErrorCategory]::InvalidResult) `
                    -Exception ($_.exception)
            }
        }
    }
    else #Ensure is set to "Absent" so remove website
    {
        try
        {
            $website = Get-Website | where {$_.Name -eq $Name}
            if($website -ne $null)
            {
                Stop-AppFabricApplicationServer -SiteName $Name
                Remove-website -name $Name

                Write-Verbose("Successfully removed Website $Name.")
            }
            else
            {
                Write-Verbose("Website $Name does not exist.")
            }
        }
        catch
        {
            ThrowTerminatingError `
                -ErrorId "WebsiteRemovalFailure" `
                -ErrorMessage  ($($LocalizedData.WebsiteRemovalFailureError) -f ${Name}) `
                -ErrorCategory ([System.Management.Automation.ErrorCategory]::InvalidResult) `
                -Exception ($_.exception)
        }

    }
}

# Ensure that there are no other websites with binding information that will conflict with this site
function Test-BindingDoesNotConflictWithOtherSites {
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$WebsiteName,

        [Microsoft.Management.Infrastructure.CimInstance[]]
        $WebsiteBindingInfo
    )
    [array]$existingSites = Get-Website | Where Name -ne $WebsiteName | Select -ExpandProperty Name
    [array]$existingBindingInfo = $existingSites | Where-Object { $_ -ne $null } | ForEach-Object { (Get-TargetResource -Name $_).BindingInfo }
    [array]$proposedBindingInfo = $existingBindingInfo + (NormalizeIpAddressBinding -BindingInfo $WebsiteBindingInfo)
    [array]$uniqueBindingInfo = $proposedBindingInfo | Where-Object { $_ -ne $null } | Select -Property Port, IpAddress, HostName -Unique
    return ($proposedBindingInfo.Count -eq $uniqueBindingInfo.Count)
}


# The Test-TargetResource cmdlet is used to validate if the role or feature is in a state as expected in the instance document.
function Test-TargetResource
{
    [CmdletBinding()]
    param
    (
        [ValidateSet("Present", "Absent")]
        [string]$Ensure = "Present",

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$Name,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$PhysicalPath,

        [ValidateSet("Started", "Stopped")]
        [string]$State = "Started",

        [string]$ApplicationPool,

        [ValidateNotNull()]
        [string]$SslFlags = "",

        [Microsoft.Management.Infrastructure.CimInstance[]]$BindingInfo,

        [Microsoft.Management.Infrastructure.CimInstance[]]$HostFileInfo,

        [Microsoft.Management.Infrastructure.CimInstance]$AuthenticationInfo
    )

    Confirm-Dependencies

    $DesiredConfigurationMatch = $true;

    $website = Get-Website | where {$_.Name -eq $Name}
    $Stop = $true

    Do
    {
        #Check Ensure
        if(($Ensure -eq "Present" -and $website -eq $null) -or ($Ensure -eq "Absent" -and $website -ne $null))
        {
            $DesiredConfigurationMatch = $false
            Write-Verbose("The Ensure state for website $Name does not match the desired state.");
            break
        }

        # Only check properties if $website exists
        if ($website -ne $null)
        {
            #Check Physical Path property
            if(ValidateWebsitePath -Name $Name -PhysicalPath $PhysicalPath)
            {
                $DesiredConfigurationMatch = $false
                Write-Verbose("Physical Path of Website $Name does not match the desired state.");
                break
            }

            #Check State
            if($website.state -ne $State -and $State -ne $null)
            {
                $DesiredConfigurationMatch = $false
                Write-Verbose("The state of Website $Name does not match the desired state.");
                break
            }

            #Check Application Pool property
            if(($ApplicationPool -ne "") -and ($website.applicationPool -ne $ApplicationPool))
            {
                $DesiredConfigurationMatch = $false
                Write-Verbose("Application Pool for Website $Name does not match the desired state.");
                break
            }

            if((Get-SslFlags -Location $Name) -ne $SslFlags)
            {
                $DesiredConfigurationMatch = $false
                Write-Verbose("SSL Flags for Website $Name does not match the desired state.");
                break
            }

            #Check Binding properties
            if($BindingInfo -ne $null)
            {
                if(ValidateWebsiteBindings -Name $Name -BindingInfo $BindingInfo)
                {
                    $DesiredConfigurationMatch = $false
                    Write-Verbose("Bindings for website $Name do not mach the desired state.");
                    break
                }
            }

            if (!(Test-AuthenticationInfo -Website $Name -AuthenticationInfo $AuthenticationInfo))
            {
                $DesiredConfigurationMatch = $false
                Write-Verbose("Authentication for website $Name do not mach the desired state.");
                break
            }

            #Check Host file entry properties
            if($HostFileInfo -ne $null)
            {
                if(ValidateHostFileEntry -HostFileInfo $HostFileInfo)
                {
                    $DesiredConfigurationMatch = $false
                    Write-Verbose("Host file entries for website $Name do not mach the desired state.");
                    break
                }
            }
        }

        $Stop = $false
    }
    While($Stop)

    $DesiredConfigurationMatch;
}

#region HelperFunctions

#Normalize empty IPAddress to "*"
function NormalizeIpAddressBinding
{
    [CmdletBinding()]
    param
    (
        [parameter()]
        [Microsoft.Management.Infrastructure.CimInstance[]]
        $BindingInfo
    )

    return $BindingInfo | Where-Object { $_ -ne $null } | ForEach-Object {
        if($_.IPAddress -eq "" -or $_.IPAddress -eq $null)
        {
            return New-CimInstance -ClassName SEEK_cWebBindingInformation -Property @{Port=[System.UInt16]$_.Port;Protocol=$_.Protocol;HostName=$_.HostName;IPAddress="*"} -ClientOnly
        }
        return $_
    }
}

function ValidateHostFileEntry
{
    [CmdletBinding()]
    param
    (
        [parameter()]
        [Microsoft.Management.Infrastructure.CimInstance[]]
        $HostFileInfo
    )

    $result = $true

    $hostFile = [Environment]::SystemDirectory + "\drivers\etc\hosts"

    foreach($aHostFileInfo in $HostFileInfo)
    {
        $HostEntryIPAddress = $aHostFileInfo.CimInstanceProperties["HostIpAddress"].Value
        $HostEntryName = $aHostFileInfo.CimInstanceProperties["HostEntryName"].Value
        $RequireHostFileEntry = [bool]::Parse([string]$aHostFileInfo.CimInstanceProperties["RequireHostFileEntry"].Value)

        if ($RequireHostFileEntry)
        {
            if (-not (Select-String $hostFile -pattern "^${HostEntryIPAddress}\s+${HostEntryName}\s*$"))
            {
                $result = $true
            }
            else
            {
                $result = $false
            }
        }
        else
        {
            $result = $false
        }
    }

    return $result
}

function UpdateHostFileEntry
{
    [CmdletBinding()]
    param
    (
        [parameter()]
        [Microsoft.Management.Infrastructure.CimInstance[]]
        $HostFileInfo
    )

    $hostFile = Get-HostsFilePath

    foreach($aHostFileInfo in $HostFileInfo)
    {
        $HostEntryIPAddress = $aHostFileInfo.CimInstanceProperties["HostIpAddress"].Value
        $HostEntryName = $aHostFileInfo.CimInstanceProperties["HostEntryName"].Value
        $RequireHostFileEntry = [bool]::Parse([string]$aHostFileInfo.CimInstanceProperties["RequireHostFileEntry"].Value)

        try
        {
            if ($RequireHostFileEntry)
            {
                if ($HostEntryIPAddress -ne $null -and $HostEntryName -ne $null)
                {
                    if (-not (Select-String $hostFile -pattern "\s+${hostEntryName}\s*$"))
                    {
                        Add-Content $hostFile "`n$HostEntryIPAddress    $hostEntryName"
                    }
                    else {
                        (Get-Content($hostFile)) | ForEach-Object {$_ -replace "^\d+.\d+.\d+.\d+\s+${HostEntryName}\s*$", "$HostEntryIPAddress    $hostEntryName" } | Set-Content($hostFile)
                    }
                }
            }
        }
        Catch
        {
            ThrowTerminatingError `
                -ErrorId "HostEntryUpdateFailure" `
                -ErrorMessage  ($($LocalizedData.HostEntryUpdateFailure) -f ${HostEntryName, HostEntryIPAddress}) `
                -ErrorCategory ([System.Management.Automation.ErrorCategory]::InvalidResult) `
                -Exception ($_.exception)
        }
    }
}

# ValidateWebsite is a helper function used to validate the results
function ValidateWebsite
{
    [CmdletBinding()]
    param
    (
        [object] $Website,

        [string] $Name
    )

    # If a wildCard pattern is not supported by the website provider.
    # Hence we restrict user to request only one website information in a single request.
    if($Website.Count-gt 1)
    {
        ThrowTerminatingError `
                -ErrorId "WebsiteDiscoveryFailure" `
                -ErrorMessage  ($($LocalizedData.WebsiteDiscoveryFailureError) -f ${Name}) `
                -ErrorCategory ([System.Management.Automation.ErrorCategory]::InvalidResult)
    }
}

# Helper function used to validate website path
function ValidateWebsitePath
{
    [CmdletBinding()]
    param
    (
        [string] $Name,

        [string] $PhysicalPath
    )

    $PathNeedsUpdating = $false

    if((Get-ItemProperty "IIS:\Sites\$Name" -Name physicalPath) -ne $PhysicalPath)
    {
        $PathNeedsUpdating = $true
    }

    $PathNeedsUpdating

}

# Helper function used to validate website bindings
# Returns true if bindings are valid (ie. port, IPAddress & Hostname combinations are unique).

function ValidateWebsiteBindings
{
    [CmdletBinding()]
    Param
    (
        [parameter()]
        [string]
        $Name,

        [parameter()]
        [Microsoft.Management.Infrastructure.CimInstance[]]
        $BindingInfo
    )

    if (!(Test-UniqueBindings -BindingInfo $BindingInfo))
    {
        ThrowTerminatingError `
            -ErrorId "WebsiteBindingInputInvalidation" `
            -ErrorMessage  ($($LocalizedData.WebsiteBindingInputInvalidationError) -f ${Name}) `
            -ErrorCategory ([System.Management.Automation.ErrorCategory]::InvalidResult)
    }

    return compareWebsiteBindings -Name $Name -BindingInfo $BindingInfo
}

# return true if all bindings are unique, false otherwise
function Test-UniqueBindings
{
    [CmdletBinding()]
    Param
    (
        [parameter()]
        [Microsoft.Management.Infrastructure.CimInstance[]]
        $BindingInfo
    )

    [array]$uniqueBindingInfo = $BindingInfo | Select -Property IpAddress, Port, HostName -Unique
    return ($BindingInfo.Count -eq $uniqueBindingInfo.Count)
}

function Test-AuthenticationEnabled
{
    [CmdletBinding()]
    [OutputType([System.Boolean])]
    Param
    (
        [parameter(Mandatory = $true)]
        [System.String]$WebSite,

        [parameter(Mandatory = $true)]
        [ValidateSet("Anonymous","Basic","Digest","Windows")]
        [System.String]$Type
    )


    $prop = Get-WebConfigurationProperty `
        -Filter /system.WebServer/security/authentication/${Type}Authentication `
        -Name enabled `
        -Location $WebSite
    return $prop.Value
}

function Set-Authentication
{
    [CmdletBinding()]
    Param
    (
        [parameter(Mandatory = $true)]
        [System.String]$WebSite,

        [parameter(Mandatory = $true)]
        [ValidateSet("Anonymous","Basic","Digest","Windows")]
        [System.String]$Type,

        [System.Boolean]$Enabled
    )

    Set-WebConfigurationProperty -Filter /system.WebServer/security/authentication/${Type}Authentication `
        -Name enabled `
        -Value $Enabled `
        -Location $WebSite
}

function Get-AuthenticationInfo
{
    [CmdletBinding()]
    [OutputType([Microsoft.Management.Infrastructure.CimInstance])]
    Param
    (
        [parameter(Mandatory = $true)]
        [System.String]$WebSite
    )

    $authenticationProperties = @{}
    foreach ($type in @("Anonymous", "Basic", "Digest", "Windows"))
    {
        $authenticationProperties[$type] = [string](Test-AuthenticationEnabled -Website $Website -Type $type)
    }

    return New-CimInstance -ClassName SEEK_cWebAuthenticationInformation -ClientOnly -Property $authenticationProperties
}

function Test-AuthenticationInfo
{
    [CmdletBinding()]
    [OutputType([System.Boolean])]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String]$Website,

        [parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [Microsoft.Management.Infrastructure.CimInstance]$AuthenticationInfo
    )

    $result = $true

    foreach ($type in @("Anonymous", "Basic", "Digest", "Windows"))
    {
        $expected = $AuthenticationInfo.CimInstanceProperties[$type].Value
        $actual = Test-AuthenticationEnabled -Website $Website -Type $type
        if ($expected -ne $actual)
        {
            $result = $false
            break
        }
    }

    return $result
}

function Set-AuthenticationInfo
{
    [CmdletBinding()]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String]$WebSite,

        [parameter()]
        [ValidateNotNullOrEmpty()]
        [Microsoft.Management.Infrastructure.CimInstance]$AuthenticationInfo
    )

    foreach ($type in @("Anonymous", "Basic", "Digest", "Windows"))
    {
        $enabled = ($AuthenticationInfo.CimInstanceProperties[$type].Value -eq $true)
        Set-Authentication -Website $Website -Type $type -Enabled $enabled
    }
}

function Get-DefaultAuthenticationInfo
{
    New-CimInstance -ClassName SEEK_cWebAuthenticationInformation `
        -ClientOnly `
        -Property @{Anonymous="false";Basic="false";Digest="false";Windows="false"}
}

# Helper function used to compare website bindings of actual to desired
# Returns true if bindings need to be updated and false if not.
function compareWebsiteBindings
{
    [CmdletBinding()]
    param
    (
        [parameter()]
        [string]
        $Name,

        [parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [Microsoft.Management.Infrastructure.CimInstance[]]
        $BindingInfo
    )
    #Assume bindingsNeedUpdating
    $BindingNeedsUpdating = $false

    #check to see if actual settings have been passed in. If not get them from website
    if($ActualBindings -eq $null)
    {
        $ActualBindings = (Get-ItemProperty -path "IIS:\Sites\$Name" -Name Bindings).collection

        #Format Binding information: Split BindingInfo into individual Properties (IPAddress:Port:HostName)
        $ActualBindingObjects = @()
        foreach ($ActualBinding in $ActualBindings)
        {
            $ActualBindingObjects += Get-WebBindingObject -Binding $ActualBinding
        }
    }

    #Compare Actual Binding info ($FormatActualBindingInfo) to Desired($BindingInfo)
    try
    {
        if($BindingInfo.Count -le $ActualBindingObjects.Count)
        {
            foreach($Binding in $BindingInfo)
            {
                $ActualBinding = $ActualBindingObjects | ?{$_.Port -eq $Binding.CimInstanceProperties["Port"].Value}
                if ($ActualBinding -ne $null)
                {
                    if([string]$ActualBinding.Protocol -ne [string]$Binding.CimInstanceProperties["Protocol"].Value)
                    {
                        $BindingNeedsUpdating = $true
                        break
                    }

                    if([string]$ActualBinding.IPAddress -ne [string]$Binding.CimInstanceProperties["IPAddress"].Value)
                    {
                        # Special case where blank IPAddress is saved as "*" in the binding information.
                        if([string]$ActualBinding.IPAddress -eq "*" -AND [string]$Binding.CimInstanceProperties["IPAddress"].Value -eq "")
                        {
                            #Do nothing
                        }
                        else
                        {
                            $BindingNeedsUpdating = $true
                            break
                        }
                    }

                    if([string]$ActualBinding.HostName -ne [string]$Binding.CimInstanceProperties["HostName"].Value)
                    {
                        $BindingNeedsUpdating = $true
                        break
                    }

                    if([string]$ActualBinding.CertificateThumbprint -ne [string]$Binding.CimInstanceProperties["CertificateThumbprint"].Value)
                    {
                        $BindingNeedsUpdating = $true
                        break
                    }

                    if([string]$ActualBinding.CertificateStoreName -ne [string]$Binding.CimInstanceProperties["CertificateStoreName"].Value)
                    {
                        $BindingNeedsUpdating = $true
                        break
                    }
                }
                else
                {
                    {
                        $BindingNeedsUpdating = $true
                        break
                    }
                }
            }
        }
        else
        {
            $BindingNeedsUpdating = $true
        }

        $BindingNeedsUpdating

    }
    catch
    {
        ThrowTerminatingError `
                -ErrorId "WebsiteCompareFailure" `
                -ErrorMessage  ($($LocalizedData.WebsiteCompareFailureError) -f ${Name}) `
                -ErrorCategory ([System.Management.Automation.ErrorCategory]::InvalidResult) `
                -Exception ($_.exception)
    }
}

function UpdateBindings
{
    [CmdletBinding()]
    param
    (
        [parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Name,

        [parameter()]
        [Microsoft.Management.Infrastructure.CimInstance[]]
        $BindingInfo
    )

    #Enable all protocols specified in bindings
    $SiteEnabledProtocols = $BindingInfo  | Select-Object -ExpandProperty Protocol -Unique
    Set-ItemProperty -Path "IIS:\Sites\${Name}" -Name EnabledProtocols -Value ($SiteEnabledProtocols -join ',')

    $bindingParams = @()
    foreach($binding in $BindingInfo)
    {
        $Protocol = $Binding.CimInstanceProperties["Protocol"].Value
        if($Protocol -eq $null){$Protocol = 'http'} #Default to Http
        $IPAddress = $Binding.CimInstanceProperties["IPAddress"].Value
        if($IPAddress -eq $null){$IPAddress = '*'} # Default to any/all IP Addresses
        $Port = $Binding.CimInstanceProperties["Port"].Value
        $HostName = $Binding.CimInstanceProperties["HostName"].Value


        if ($Protocol -eq 'net.pipe')
        {
            $bindingInformation = "$HostName"
        }
        elseif ($Protocol -eq 'net.tcp')
        {
            $bindingInformation = "$($Port):$HostName"
        }
        else
        {
            $bindingInformation = "$($IPAddress):$($Port):$HostName"
        }

        $bindingParams += @{Protocol = $Protocol; BindingInformation = $bindingInformation}
    }

    try
    {
        Set-ItemProperty -Path "IIS:\Sites\${Name}" -Name bindings -value $bindingParams
    }
    Catch
    {
        ThrowTerminatingError `
            -ErrorId "WebsiteBindingUpdateFailure" `
            -ErrorMessage  ($($LocalizedData.WebsiteBindingUpdateFailureError) -f ${HostName}, ${Name}) `
            -ErrorCategory ([System.Management.Automation.ErrorCategory]::InvalidResult) `
            -Exception ($_.exception)
    }

    $HttpsBindingInfo = $BindingInfo | ? { $_.CimInstanceProperties["Protocol"].Value -eq "https" }
    foreach($binding in $HttpsBindingInfo)
    {
        $Port = $Binding.CimInstanceProperties["Port"].Value
        $IpAddress = $Binding.CimInstanceProperties["IPAddress"].Value
        $SslSubject = $Binding.CimInstanceProperties["SslSubject"].Value
        $SslCertPath = $Binding.CimInstanceProperties["SslCertPath"].Value

        try
        {
            if ($SslSubject -ne $null -and $SslCertPath -ne $null)
            {
                $theCert = Get-ChildItem -path $SslCertPath | Where-Object {$_.Subject -eq $SslSubject }

                Set-BindingCertificate `
                    -IpAddress $IpAddress `
                    -Port $Port `
                    -Certificate $theCert
            }
        }
        catch
        {
            throw $_
            ThrowTerminatingError `
                -ErrorId "WebBindingCertifcateError" `
                -ErrorMessage  ($($LocalizedData.WebBindingCertifcateError) -f ${CertificateThumbprint}) `
                -ErrorCategory ([System.Management.Automation.ErrorCategory]::InvalidResult) `
                -Exception ($_.exception)
        }
    }

}

function Set-BindingCertificate
{
    [CmdletBinding()]
    Param
    (
        [parameter(Mandatory=$true)]
        [System.Object]$Certificate,

        [System.String]$IpAddress = "0.0.0.0",

        [System.String]$Port = 443
    )
    $path = "IIS:\SslBindings\${IpAddress}!${Port}"

    if (Test-Path $path)
    {
        $thumbprint = (Get-Item $path).Thumbprint
        if ($Certificate.Thumbprint -eq $thumbprint)
        {
            return
        }
        else
        {
            Remove-Item $path
        }
    }

    New-Item -Path $path -Value $Certificate
}

function Get-WebBindingObject
{
    [CmdletBinding()]
    Param
    (
        [parameter(Mandatory=$true)]
        [System.Object]$Binding
    )

    $bindingProperties = @{Protocol = $Binding.protocol}

    switch -wildcard ($Binding.protocol)
    {
        "http*"
        {
            $Matches = $null
            if ($Binding.BindingInformation -match "^\[?(?<IPAddress>[\*\w\d\.:]*)\]?:(?<Port>[\*\d]+):(?<HostName>.*)$")
            {
                $bindingProperties["IPAddress"] = $Matches["IPAddress"]
                $bindingProperties["Port"] = $Matches["Port"]
                $bindingProperties["HostName"] = $Matches["HostName"]
            }
            else { throw "BindingInformation format is invalid for protocol ""$($Binding.protocol)"" {$($Binding.BindingInformation)}" }
        }
        "https"
        {
            $bindingProperties["CertificateThumbprint"] = $Binding.CertificateHash
            $bindingProperties["CertificateStoreName"] = $Binding.CertificateStoreName
        }
        "net.tcp"
        {
            $Matches = $null
            if ($Binding.BindingInformation -match "^(?<Port>[\*\d]+):(?<HostName>.*)$")
            {
                $bindingProperties["Port"] = $Matches["Port"]
                $bindingProperties["HostName"] = $Matches["HostName"]
            }
            else { throw "BindingInformation format is invalid for protocol ""$($Binding.protocol)"" {$($Binding.BindingInformation)}" }
        }
        "net.pipe"
        {
            $bindingProperties["HostName"] = $Binding.BindingInformation
        }
        "net.msmq"
        {
            $bindingProperties["HostName"] = $Binding.BindingInformation.Split("/")[0]
        }
        default { throw "Invalid protocol ""$($Binding.protocol)""" }
    }

    return (New-Object PSObject -Property $bindingProperties)
}

function Get-HostsFilePath
{
    return [Environment]::SystemDirectory + "\drivers\etc\hosts"
}

function ThrowTerminatingError
{
    [CmdletBinding()]
    param
    (
        [System.String]$ErrorId,
        [System.String]$ErrorMessage,
        [System.Management.Automation.ErrorCategory]$ErrorCategory,
        [System.Exception]$Exception = $null
    )

    $exception = New-Object System.InvalidOperationException $ErrorMessage, $Exception
    $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $ErrorId, $ErrorCategory, $null
    throw $errorRecord
}

function Get-SslFlags
{
    [CmdletBinding()]
    param
    (
        [System.String]$Location
    )

    $sslFlags = Get-WebConfiguration -PSPath IIS:\Sites -Location $Location -Filter 'system.webserver/security/access' | % { $_.sslFlags }
    $sslFlags = if ($sslFlags -eq $null) { "" } else { $sslFlags }
    return $sslFlags
}

function Stop-AppFabricApplicationServer
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$SiteName
    )

    Write-Debug "Checking whether App Fabric is installed."
    Get-Module -ListAvailable -Name ApplicationServer -OutVariable applicationServerModule 4>&1 | Out-Null
    if($applicationServerModule)
    {
        Import-Module ApplicationServer 4>&1 | Out-Null
        Stop-ASApplication -SiteName $SiteName
    }
}

function Start-AppFabricApplicationServer
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$SiteName
    )

    Write-Debug "Checking whether App Fabric is installed."
    Get-Module -ListAvailable -Name ApplicationServer -OutVariable applicationServerModule 4>&1 | Out-Null
    if($applicationServerModule)
    {
        Import-Module ApplicationServer 4>&1 | Out-Null
        Start-ASApplication -SiteName $SiteName
    }
}


function Confirm-Dependencies
{
    Write-Debug "Checking whether WebAdministration is there in the machine or not."
    Get-Module -ListAvailable -Name WebAdministration -OutVariable webAdministrationModule 4>&1 | Out-Null
    if(-not $webAdministrationModule)
    {
        Throw "Please ensure that the WebAdministration module is installed."
    }
    Import-Module WebAdministration 4>&1 | Out-Null
}

#endregion
lib\cWebAdministration\DSCResources\SEEK_cWebVirtualDirectory\SEEK_cWebVirtualDirectory.schema.mof
 
lib\cWebAdministration\DSCResources\SEEK_cWebVirtualDirectory\SEEK_cWebVirtualDirectory.psm1
$LogonMethodEnum = @("Batch","Interactive","Network","ClearText")

function Get-TargetResource
{
    [CmdletBinding()]
    [OutputType([System.Collections.Hashtable])]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String]
        $Website,

        [System.String]
        $WebApplication = $null,

        [parameter(Mandatory = $true)]
        [System.String]
        $Name
    )

    Confirm-Dependencies

    if (test-VirtualDirectoryExists $WebSite $Name $WebApplication)
    {
        $virtualDirectoryPath = Get-VirtualDirectoryPath -Site $Website -Name $Name -Application $WebApplication
        $virtualDirectory = Get-Item -Path $virtualDirectoryPath
        return @{
            Name = $Name
            Website = $Website
            WebApplication = $WebApplication
            PhysicalPath = $virtualDirectory.PhysicalPath
            LogonMethod = $virtualDirectory.logonMethod
            Username = $virtualDirectory.username
            Password = $virtualDirectory.password
            Ensure = "Present"
        }
    }

    return @{
        Name = $Name
        Website = $Website
        WebApplication = $WebApplication
        PhysicalPath = $null
        LogonMethod = $null
        Username = $null
        Password = $null
        Ensure = "Absent"
    }
}

function Set-TargetResource
{
    [CmdletBinding()]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String]
        $Website,

        [System.String]
        $WebApplication = $null,

        [parameter(Mandatory = $true)]
        [System.String]
        $Name,

        [parameter(Mandatory = $true)]
        [System.String]
        $PhysicalPath,

        [ValidateSet("Batch","Interactive","Network","ClearText")]
        [System.String]
        $LogonMethod = "ClearText",

        [System.String]
        $Username = "",

        [System.String]
        $Password = "",


        [ValidateSet("Present","Absent")]
        [System.String]
        $Ensure = "Present"
    )

    Confirm-Dependencies
    Stop-AppFabricApplicationServer -SiteName $Website

    try
    {
        $virtualDirectory = Get-TargetResource -Website $Website -Name $Name -WebApplication $WebApplication

        if ($Ensure -eq "Present")
        {
            $path = Get-VirtualDirectoryPath -Site $Website -Application $WebApplication -Name $Name

            if ($virtualDirectory.Ensure -eq "Absent")
            {
                Write-Verbose "Creating new Web Virtual Directory $Name."
                New-WebVirtualDirectory -Site $Website -Application $WebApplication -Name $Name -PhysicalPath $PhysicalPath
            }
            else
            {
                Write-Verbose "Updating physical path for web virtual directory $Name."
                Set-ItemProperty -Path $path -Name physicalPath -Value $PhysicalPath
            }

            Set-ItemProperty -Path $path -Name logonMethod -Value ($LogonMethodEnum.IndexOf($LogonMethod))

            Set-ItemProperty -Path $path -Name username -Value $Username
            Set-ItemProperty -Path $path -Name password -Value $Password
        }

        if ($virtualDirectory.Ensure -eq "Present" -and $Ensure -eq "Absent")
        {
            Write-Verbose "Removing existing Virtual Directory $Name."
            Remove-WebVirtualDirectory -Site $Website -Application $WebApplication -Name $Name
        }
    }
    finally
    {
        Start-AppFabricApplicationServer -SiteName $Website
    }
}

function Test-TargetResource
{
    [CmdletBinding()]
    [OutputType([System.Boolean])]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String]
        $Website,

        [System.String]
        $WebApplication = $null,

        [parameter(Mandatory = $true)]
        [System.String]
        $Name,

        [parameter(Mandatory = $true)]
        [System.String]
        $PhysicalPath,

        [ValidateSet("ClearText","Network","Interactive","Batch")]
        [System.String]
        $LogonMethod = "ClearText",

        [System.String]
        $Username = "",

        [System.String]
        $Password = "",

        [ValidateSet("Present","Absent")]
        [System.String]
        $Ensure = "Present"
    )

    Write-Verbose "Checking the virtual directories for the website."

    $virtualDirectory = Get-TargetResource -Website $Website -Name $Name -WebApplication $WebApplication

    if ($virtualDirectory.Ensure -eq "Absent" -and $Ensure -eq "Absent")
    {
        Write-Verbose "Web virtual direcotry $Name should be absent and is absent"
        return $true
    }

    if ($virtualDirectory.Ensure -eq "Present" `
        -and $Ensure -eq "Present" `
        -and $virtualDirectory.physicalPath -eq $PhysicalPath `
        -and $virtualDirectory.logonMethod -eq $LogonMethod `
        -and $virtualDirectory.username -eq $Username `
        -and $virtualDirectory.password -eq $Password)
    {
        Write-Verbose "Web virtual directory is in required state"
        return $true
    }

    Write-Verbose "Web virtual directory $Name does not match desired state."

    return $false
}

function Get-VirtualDirectoryPath
{
    param
    (
        [parameter(Mandatory = $true)]
        [System.String]
        $Name,

        [parameter(Mandatory = $true)]
        [System.String]
        $Site,

        [System.String]
        $Application = $null
    )

    if (-not $Application)
    {
        return "IIS:\Sites\${Site}\${Name}"
    }

    return "IIS:\Sites\${Site}\${Application}\${Name}"
}

function test-VirtualDirectoryExists
{
    param
    (
        [System.String] $Website,
        [System.String] $Name,
        [System.String] $WebApplication
    )

    $virtualDirectoryPath = Get-VirtualDirectoryPath -Site $Website -Name $Name -Application $WebApplication

    if(-not (Test-Path $virtualDirectoryPath)) { return $false}

    $virtualDirectory = Get-Item -Path $virtualDirectoryPath

    $virtualDirectory.PhysicalPath -ne $null
}

function Stop-AppFabricApplicationServer
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$SiteName
    )

    Write-Debug "Checking whether App Fabric is installed."
    Get-Module -ListAvailable -Name ApplicationServer -OutVariable applicationServerModule 4>&1 | Out-Null
    if($applicationServerModule)
    {
        Import-Module ApplicationServer 4>&1 | Out-Null
        Stop-ASApplication -SiteName $SiteName
    }
}

function Start-AppFabricApplicationServer
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$SiteName
    )

    Write-Debug "Checking whether App Fabric is installed."
    Get-Module -ListAvailable -Name ApplicationServer -OutVariable applicationServerModule 4>&1 | Out-Null
    if($applicationServerModule)
    {
        Import-Module ApplicationServer 4>&1 | Out-Null
        Start-ASApplication -SiteName $SiteName
    }
}

function Confirm-Dependencies
{
    Write-Debug "Checking whether WebAdministration is there in the machine or not."
    Get-Module -ListAvailable -Name WebAdministration -OutVariable webAdministrationModule 4>&1 | Out-Null
    if(-not $webAdministrationModule)
    {
        Throw "Please ensure that the WebAdministration module is installed."
    }
    Import-Module WebAdministration 4>&1 | Out-Null
}

Export-ModuleMember -Function *-TargetResource

lib\cWebAdministration\DSCResources\SEEK_cWebApplication\SEEK_cWebApplication.psm1
function Get-TargetResource
{
    [CmdletBinding()]
    [OutputType([System.Collections.Hashtable])]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String]$Website,

        [parameter(Mandatory = $true)]
        [System.String]$Name
    )

    Confirm-Dependencies

    $webApplication = Find-UniqueWebApplication -Site $Website -Name $Name
    if ($webApplication -ne $null)
    {
        return @{
            Website = $Website
            Name = $Name
            WebAppPool = $webApplication.ApplicationPool
            PhysicalPath = $webApplication.PhysicalPath
            Ensure = "Present"
            AuthenticationInfo = Get-AuthenticationInfo -Website $Website -ApplicationName $Name
            SslFlags = (Get-SslFlags -Location "${Website}/${Name}")
            EnabledProtocols = (Get-ItemProperty "IIS:\Sites\${Website}\${Name}" -Name "EnabledProtocols").Value
        }
    }

    return @{
        Website = $Website
        Name = $Name
        WebAppPool = $null
        PhysicalPath = $null
        Ensure = "Absent"
        AuthenticationInfo = $null
        SslFlags = $null
        EnabledProtocols = $null
    }
}


function Set-TargetResource
{
    [CmdletBinding()]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String]$Website,

        [parameter(Mandatory = $true)]
        [System.String]$Name,

        [parameter(Mandatory = $true)]
        [System.String]$WebAppPool,

        [parameter(Mandatory = $true)]
        [System.String]$PhysicalPath,

        [ValidateNotNull()]
        [string]$SslFlags = "",

        [ValidateSet("Present","Absent")]
        [System.String]$Ensure = "Present",

        [System.String] $EnabledProtocols,

        [Parameter(Mandatory=$false, HelpMessage="Obsolete")]
        [System.String] $AutoStartMode,

        [Microsoft.Management.Infrastructure.CimInstance]$AuthenticationInfo
    )

    Confirm-Dependencies
    Stop-AppFabricApplicationServer -SiteName $Website

    try
    {
        if ($AuthenticationInfo -eq $null) { $AuthenticationInfo = Get-DefaultAuthenticationInfo }

        $webApplication = Find-UniqueWebApplication -Site $Website -Name $Name
        $webappPath = "IIS:\Sites\${Website}\${Name}"
        if ($Ensure -eq "Present")
        {

            if ($webApplication -eq $null)
            {
                Write-Verbose "Creating new Web application $Name."
                New-WebApplication -Site $Website -Name $Name -PhysicalPath $PhysicalPath -ApplicationPool $WebAppPool
            }
            else
            {
                if ($webApplication.physicalPath -ne $PhysicalPath)
                {
                    Write-Verbose "Updating physical path for Web application $Name."
                    Set-ItemProperty -Path $webappPath -Name physicalPath -Value $physicalPath
                }
                if ($webApplication.applicationPool -ne $ApplicationPool)
                {
                    Write-Verbose "Updating physical path for Web application $Name."
                    Set-ItemProperty -Path $webappPath -Name applicationPool -Value $WebAppPool
                }
            }

            Set-AuthenticationInfo -Website $Website -ApplicationName $Name -AuthenticationInfo $AuthenticationInfo -ErrorAction Stop
            Set-WebConfiguration -Location "${Website}/${Name}" -Filter 'system.webserver/security/access' -Value $SslFlags

            if ($EnabledProtocols) {
                Set-ItemProperty -Path $webappPath -Name enabledProtocols -Value $EnabledProtocols
            }
        }
        elseif (($Ensure -eq "Absent") -and ($webApplication -ne $null))
        {
            Write-Verbose "Removing existing Web Application $Name."
            Remove-WebApplication -Site $Website -Name $Name
        }
    }
    finally
    {
        Start-AppFabricApplicationServer -SiteName $Website
    }

}


function Test-TargetResource
{
    [CmdletBinding()]
    [OutputType([System.Boolean])]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String]$Website,

        [parameter(Mandatory = $true)]
        [System.String]$Name,

        [parameter(Mandatory = $true)]
        [System.String]$WebAppPool,

        [parameter(Mandatory = $true)]
        [System.String]$PhysicalPath,

        [ValidateNotNull()]
        [string]$SslFlags = "",

        [ValidateSet("Present","Absent")]
        [System.String]$Ensure = "Present",

        [System.String] $EnabledProtocols,

        [Parameter(Mandatory=$false, HelpMessage="Obsolete")]
        [System.String] $AutoStartMode,

        [Microsoft.Management.Infrastructure.CimInstance]$AuthenticationInfo
    )

    Confirm-Dependencies

    if ($AuthenticationInfo -eq $null) { $AuthenticationInfo = Get-DefaultAuthenticationInfo }

    $webApplication = Get-TargetResource -Website $Website -Name $Name

    if($Ensure -eq "Present")
    {
        $enabledProtocolsMatch = if ($EnabledProtocols) { $webApplication.EnabledProtocols -eq $EnabledProtocols } else { $true }

        if(($webApplication.Ensure -eq $Ensure) `
            -and ($webApplication.PhysicalPath -eq $PhysicalPath) `
            -and ($webApplication.WebAppPool -eq $WebAppPool) `
            -and ((Get-SslFlags -Location "${Website}/${Name}") -eq $SslFlags) `
            -and (Test-AuthenticationInfo -Website $Website -ApplicationName $Name -AuthenticationInfo $AuthenticationInfo) `
            -and $enabledProtocolsMatch)
        {
            return $true
        }
    }
    elseif($webApplication.Ensure -eq $Ensure)
    {
        return $true
    }

    return $false
}

function Find-UniqueWebApplication
{
    Param
    (
        [parameter(Mandatory = $true)]
        [System.String]$Site,

        [parameter(Mandatory = $true)]
        [System.String]$Name
    )

    $webApplications = @(Get-WebApplication -Site $Site -Name $Name)

    if ($webApplications.Count -gt 1)
    {
        throw "Multiple web applications found for ""${Site}/${Name}"""
    }

    return $webApplications[0]
}

function Test-AuthenticationEnabled
{
    [OutputType([System.Boolean])]
    Param
    (
        [parameter(Mandatory = $true)]
        [System.String]$WebSite,

        [parameter(Mandatory = $true)]
        [System.String]$ApplicationName,

        [parameter(Mandatory = $true)]
        [ValidateSet("Anonymous","Basic","Digest","Windows")]
        [System.String]$Type
    )


    $prop = Get-WebConfigurationProperty `
        -Filter /system.WebServer/security/authentication/${Type}Authentication `
        -Name enabled `
        -Location "${WebSite}/${ApplicationName}"
    return $prop.Value
}

function Set-Authentication
{
    Param
    (
        [parameter(Mandatory = $true)]
        [System.String]$WebSite,

        [parameter(Mandatory = $true)]
        [System.String]$ApplicationName,

        [parameter(Mandatory = $true)]
        [ValidateSet("Anonymous","Basic","Digest","Windows")]
        [System.String]$Type,

        [System.Boolean]$Enabled
    )

    Set-WebConfigurationProperty -Filter /system.WebServer/security/authentication/${Type}Authentication `
        -Name enabled `
        -Value $Enabled `
        -Location "${WebSite}/${Name}"
}

function Get-AuthenticationInfo
{
    [OutputType([Microsoft.Management.Infrastructure.CimInstance])]
    Param
    (
        [parameter(Mandatory = $true)]
        [System.String]$WebSite,

        [parameter(Mandatory = $true)]
        [System.String]$ApplicationName
    )

    $authenticationProperties = @{}
    foreach ($type in @("Anonymous", "Basic", "Digest", "Windows"))
    {
        $authenticationProperties[$type] = [string](Test-AuthenticationEnabled -Website $Website -ApplicationName $Name -Type $type)
    }

    return New-CimInstance -ClassName SEEK_cWebApplicationAuthenticationInformation -ClientOnly -Property $authenticationProperties
}

function Test-AuthenticationInfo
{
    [OutputType([System.Boolean])]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String]$Website,

        [parameter(Mandatory = $true)]
        [System.String]$ApplicationName,

        [parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [Microsoft.Management.Infrastructure.CimInstance]$AuthenticationInfo
    )

    $result = $true

    foreach ($type in @("Anonymous", "Basic", "Digest", "Windows"))
    {

        $expected = $AuthenticationInfo.CimInstanceProperties[$type].Value
        $actual = Test-AuthenticationEnabled -Website $Website -ApplicationName $ApplicationName -Type $type
        if ($expected -ne $actual)
        {
            $result = $false
            break
        }
    }

    return $result
}

function Set-AuthenticationInfo
{
    param
    (
        [parameter(Mandatory = $true)]
        [System.String]$WebSite,

        [parameter(Mandatory = $true)]
        [System.String]$ApplicationName,

        [parameter()]
        [ValidateNotNullOrEmpty()]
        [Microsoft.Management.Infrastructure.CimInstance]$AuthenticationInfo
    )

    foreach ($type in @("Anonymous", "Basic", "Digest", "Windows"))
    {
        $enabled = ($AuthenticationInfo.CimInstanceProperties[$type].Value -eq $true)
        Set-Authentication -Website $Website -ApplicationName $ApplicationName -Type $type -Enabled $enabled
    }
}

function Get-DefaultAuthenticationInfo
{
    New-CimInstance -ClassName SEEK_cWebApplicationAuthenticationInformation `
        -ClientOnly `
        -Property @{Anonymous="false";Basic="false";Digest="false";Windows="false"}
}

function Get-SslFlags
{
    [CmdletBinding()]
    param
    (
        [System.String]$Location
    )

    $sslFlags = Get-WebConfiguration -PSPath IIS:\Sites -Location $Location -Filter 'system.webserver/security/access' | % { $_.sslFlags }
    $sslFlags = if ($sslFlags -eq $null) { "" } else { $sslFlags }
    return $sslFlags
}

function Stop-AppFabricApplicationServer
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$SiteName
    )

    Write-Debug "Checking whether App Fabric is installed."
    Get-Module -ListAvailable -Name ApplicationServer -OutVariable applicationServerModule 4>&1 | Out-Null
    if($applicationServerModule)
    {
        Import-Module ApplicationServer 4>&1 | Out-Null
        Stop-ASApplication -SiteName $SiteName
    }
}

function Start-AppFabricApplicationServer
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$SiteName
    )

    Write-Debug "Checking whether App Fabric is installed."
    Get-Module -ListAvailable -Name ApplicationServer -OutVariable applicationServerModule 4>&1 | Out-Null
    if($applicationServerModule)
    {
        Import-Module ApplicationServer 4>&1 | Out-Null
        Start-ASApplication -SiteName $SiteName
    }
}

function Confirm-Dependencies
{
    Write-Debug "Checking whether WebAdministration is there in the machine or not."
    Get-Module -ListAvailable -Name WebAdministration -OutVariable webAdministrationModule 4>&1 | Out-Null
    if(-not $webAdministrationModule)
    {
        Throw "Please ensure that the WebAdministration module is installed."
    }
    Import-Module WebAdministration 4>&1 | Out-Null
}


Export-ModuleMember -Function *-TargetResource

lib\cWebAdministration\DSCResources\SEEK_cWebApplication\SEEK_cWebApplication.schema.mof
 
lib\cWebAdministration\DSCResources\SEEK_cFeatureDelegation\SEEK_cFeatureDelegation.psm1
function Get-TargetResource
{
    [CmdletBinding()]
    [OutputType([System.Collections.Hashtable])]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String]$Section
    )

    Confirm-Dependencies

    $configuration = Get-WebConfiguration -Filter $Section -PSPath "IIS:"

    if($configuration -ne $null -and $configuration.OverrideMode -eq "Allow") {
        return @{
            Ensure = "Present"
            Section = $Section
        }
    }

    return @{Ensure = "Absent"}
}

function Test-TargetResource
{
    [CmdletBinding()]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String]
        $Section,

        [ValidateSet("Present","Absent")]
        [System.String]
        $Ensure  = "Present"
    )

    Confirm-Dependencies

    $actualState = Get-TargetResource -Section $Section

    if ($Ensure -eq $actualState.Ensure) { return $true }

    return $false
}

function Set-TargetResource
{
    [CmdletBinding()]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String]
        $Section,

        [ValidateSet("Present","Absent")]
        [System.String]
        $Ensure  = "Present"
    )

    Confirm-Dependencies

    if($Ensure -eq "Absent") {
        $overrideMode = "Deny"
    }
    else {
        $overrideMode = "Allow"
    }

    Set-WebConfiguration -Filter $Section -PSPath "IIS:" -MetaData "overrideMode" -Value $overrideMode
}

function Confirm-Dependencies
{
    Write-Debug "Checking whether WebAdministration is there in the machine or not."
    Get-Module -ListAvailable -Name WebAdministration -OutVariable webAdministrationModule 4>&1 | Out-Null
    if(-not $webAdministrationModule)
    {
        Throw "Please ensure that the WebAdministration module is installed."
    }
    Import-Module WebAdministration 4>&1 | Out-Null
}


Export-ModuleMember -Function *-TargetResource
lib\cWebAdministration\DSCResources\SEEK_cFeatureDelegation\SEEK_cFeatureDelegation.schema.mof
 

Log in or click on link to see number of positives.

In cases where actual malware is found, the packages are subject to removal. Software sometimes has false positives. Moderators do not necessarily validate the safety of the underlying software, only that a package retrieves software from the official distribution point and/or validate embedded software against official distribution point (where distribution rights allow redistribution).

Chocolatey Pro provides runtime protection from possible malware.

Add to Builder Version Downloads Last Updated Status
SEEK DSC WebAdministration 2.0.0.20230301-alpha9 83 Tuesday, January 3, 2023 Exempted
SEEK DSC WebAdministration 2.0.0-alpha9 586 Thursday, July 30, 2015 Approved
SEEK DSC WebAdministration 2.0.0-alpha7 503 Friday, May 1, 2015 Approved
SEEK DSC WebAdministration 2.0.0-alpha6 477 Wednesday, April 22, 2015 Approved
SEEK DSC WebAdministration 2.0.0-alpha5 468 Tuesday, April 21, 2015 Approved
SEEK DSC WebAdministration 2.0.0-alpha4 482 Tuesday, April 21, 2015 Approved
SEEK DSC WebAdministration 2.0.0-alpha2 457 Tuesday, February 24, 2015 Approved
SEEK DSC WebAdministration 2.0.0-alpha1 444 Monday, February 23, 2015 Approved
SEEK DSC WebAdministration 1.0.9-alpha6 416 Tuesday, June 9, 2015 Approved
SEEK DSC WebAdministration 1.0.9-alpha5 434 Tuesday, June 9, 2015 Approved
SEEK DSC WebAdministration 1.0.9-alpha4 415 Tuesday, June 9, 2015 Approved
SEEK DSC WebAdministration 1.0.9-alpha3 441 Tuesday, May 26, 2015 Approved
SEEK DSC WebAdministration 1.0.9-alpha2 460 Tuesday, May 26, 2015 Approved
SEEK DSC WebAdministration 1.0.9-alpha1 432 Friday, May 22, 2015 Approved
SEEK DSC WebAdministration 1.0.4 533 Friday, May 1, 2015 Approved
SEEK DSC WebAdministration 1.0.3 467 Wednesday, April 22, 2015 Approved
SEEK DSC WebAdministration 1.0.2 435 Tuesday, April 21, 2015 Approved
SEEK DSC WebAdministration 1.0.0.87 642 Sunday, February 22, 2015 Approved
SEEK DSC WebAdministration 1.0.0.77 471 Sunday, January 25, 2015 Approved
SEEK DSC WebAdministration 1.0.0.76 438 Wednesday, January 14, 2015 Approved
SEEK DSC WebAdministration 1.0.0.75 710 Tuesday, December 2, 2014 Approved
SEEK DSC WebAdministration 1.0.0.74 535 Sunday, November 9, 2014 Approved
SEEK DSC WebAdministration 1.0.0.73 428 Friday, November 7, 2014 Approved
SEEK DSC WebAdministration 1.0.0.72 481 Thursday, November 6, 2014 Approved
SEEK DSC WebAdministration 1.0.0.71 429 Thursday, November 6, 2014 Approved
SEEK DSC WebAdministration 1.0.0.70 425 Thursday, November 6, 2014 Approved
SEEK DSC WebAdministration 1.0.0.69 448 Monday, November 3, 2014 Approved
SEEK DSC WebAdministration 1.0.0.68 418 Monday, November 3, 2014 Approved
SEEK DSC WebAdministration 1.0.0.67 416 Monday, November 3, 2014 Approved
SEEK DSC WebAdministration 1.0.0.64 461 Thursday, October 30, 2014 Approved
SEEK DSC WebAdministration 1.0.0.63 442 Thursday, October 30, 2014 Approved
SEEK DSC WebAdministration 1.0.0.62 439 Monday, October 27, 2014 Approved
SEEK DSC WebAdministration 1.0.0.61 397 Friday, October 24, 2014 Approved
SEEK DSC WebAdministration 1.0.0.60 436 Friday, October 24, 2014 Approved
SEEK DSC WebAdministration 1.0.0.59 414 Friday, October 24, 2014 Approved
SEEK DSC WebAdministration 1.0.0.58 385 Friday, October 24, 2014 Approved
SEEK DSC WebAdministration 1.0.0.55 426 Friday, October 24, 2014 Approved
SEEK DSC WebAdministration 1.0.0.54 436 Wednesday, October 15, 2014 Approved
SEEK DSC WebAdministration 1.0.0.53 449 Wednesday, October 15, 2014 Approved
SEEK DSC WebAdministration 1.0.0.52 460 Wednesday, October 15, 2014 Approved
SEEK DSC WebAdministration 1.0.0.51 423 Wednesday, October 15, 2014 Approved
SEEK DSC WebAdministration 1.0.0.50 439 Sunday, October 12, 2014 Approved
SEEK DSC WebAdministration 1.0.0.48 421 Friday, October 10, 2014 Approved
SEEK DSC WebAdministration 1.0.0.47 404 Friday, October 10, 2014 Approved
SEEK DSC WebAdministration 1.0.0.46 389 Friday, October 10, 2014 Approved
SEEK DSC WebAdministration 1.0.0.45 404 Thursday, October 9, 2014 Approved
SEEK DSC WebAdministration 1.0.0.43 390 Wednesday, October 8, 2014 Approved
SEEK DSC WebAdministration 1.0.0.42 401 Wednesday, October 8, 2014 Approved
SEEK DSC WebAdministration 1.0.0.41 385 Thursday, October 2, 2014 Approved
SEEK DSC WebAdministration 1.0.0.40 405 Thursday, September 25, 2014 Approved
SEEK DSC WebAdministration 1.0.0.39 371 Thursday, September 25, 2014 Approved
SEEK DSC WebAdministration 1.0.0.37 385 Wednesday, September 24, 2014 Approved
SEEK DSC WebAdministration 1.0.0.36 378 Monday, September 22, 2014 Approved
SEEK DSC WebAdministration 1.0.0.35 366 Monday, September 15, 2014 Approved
SEEK DSC WebAdministration 1.0.0.34 396 Monday, September 15, 2014 Approved
SEEK DSC WebAdministration 1.0.0.33 389 Monday, September 15, 2014 Approved
SEEK DSC WebAdministration 1.0.0.32 377 Thursday, September 11, 2014 Approved
SEEK DSC WebAdministration 1.0.0.31 369 Wednesday, September 10, 2014 Approved
SEEK DSC WebAdministration 1.0.0.30 403 Wednesday, September 10, 2014 Approved
SEEK DSC WebAdministration 1.0.0.29 419 Wednesday, September 10, 2014 Approved
SEEK DSC WebAdministration 1.0.0.28 422 Tuesday, September 9, 2014 Approved
SEEK DSC WebAdministration 1.0.0.27 374 Tuesday, September 9, 2014 Approved
SEEK DSC WebAdministration 1.0.0.20 403 Tuesday, September 9, 2014 Approved
SEEK DSC WebAdministration 1.0.0.19 397 Tuesday, September 9, 2014 Approved
SEEK DSC WebAdministration 1.0.0.18 426 Tuesday, September 9, 2014 Approved
SEEK DSC WebAdministration 1.0.0.17 396 Tuesday, September 9, 2014 Approved
SEEK DSC WebAdministration 1.0.0.13 407 Friday, September 5, 2014 Approved
SEEK DSC WebAdministration 1.0.0.11 403 Friday, September 5, 2014 Approved
SEEK DSC WebAdministration 1.0.0 409 Tuesday, September 9, 2014 Approved
SEEK DSC WebAdministration 0.0.0.1 354 Tuesday, May 5, 2015 Approved

This package has no dependencies.

Discussion for the SEEK DSC WebAdministration Package

Ground Rules:

  • This discussion is only about SEEK DSC WebAdministration and the SEEK DSC WebAdministration package. If you have feedback for Chocolatey, please contact the Google Group.
  • This discussion will carry over multiple versions. If you have a comment about a particular version, please note that in your comments.
  • The maintainers of this Chocolatey Package will be notified about new comments that are posted to this Disqus thread, however, it is NOT a guarantee that you will get a response. If you do not hear back from the maintainers after posting a message below, please follow up by using the link on the left side of this page or follow this link to contact maintainers. If you still hear nothing back, please follow the package triage process.
  • Tell us what you love about the package or SEEK DSC WebAdministration, or tell us what needs improvement.
  • Share your experiences with the package, or extra configuration or gotchas that you've found.
  • If you use a url, the comment will be flagged for moderation until you've been whitelisted. Disqus moderated comments are approved on a weekly schedule if not sooner. It could take between 1-5 days for your comment to show up.
comments powered by Disqus