Private/NewInstanceHelperFunctions.ps1

function CreateService ([string]$InstanceName, [string]$BinaryPath, [string]$ConfigPath, [string]$ConfigArgument)
{
    $ServiceSplat = @{
        Name           = "IntelliSearch-{0}" -f $InstanceName
        BinaryPathName = $ConfigArgument -f $BinaryPath, $ConfigPath
        DisplayName    = "IntelliSearch {0}" -f $InstanceName
        StartupType    = "Automatic"
    }

    try
    {
        $Service = Get-Service -Name $ServiceSplat.Name -ErrorAction:Stop
    }
    catch [Microsoft.PowerShell.Commands.ServiceCommandException]
    {
        if (-not ($_.CategoryInfo.Category -eq "ObjectNotFound"))
        {
            Throw "Something went wrong looking for the services. ServiceName: $($ServiceSplat.Name)"
        }
    }

    if ($Service)
    {
        Throw "Services must have unique names. The name $($ServiceSplat.Name) already exists."
    }
    
    Write-Verbose "Creating service: $($ServiceSplat.Name)"
    New-Service @ServiceSplat

}

function CreateShortcut ([string]$Target, [string]$Destination, [string]$Arguments = $null)
{
    if (!(Test-Path $Destination -IsValid))
    {
        Throw "Shortcut destination path is not valid. Got $($Destination)"
    }

    if (Test-Path $Destination)
    {
        Remove-Item $Destination -ErrorAction:SilentlyContinue | Out-Null
    }

    Write-Verbose "Creating shortcut: $($Destination)"
    $WshShell = New-Object -comObject WScript.Shell
    $Shortcut = $WshShell.CreateShortcut($Destination)
    $Shortcut.TargetPath = $Target

    if (($Arguments -ne $null) -and ($Destination -match '.+\.lnk$'))
    {
        $Shortcut.Arguments = $Arguments
    }

    $Shortcut.Save()
}

function CreateWebAppPool ([string]$Name, [switch]$Classic)
{
    $AppPool = New-WebAppPool -Name $Name -Force
    
    if ($Classic)
    {
        $AppPool.managedPipelineMode = "Classic"
    }

    # Set any changes done to the pool before returning
    $AppPool | Set-Item -PassThru
}

function CreateWebApplication ($Node, [string]$Name, [string]$ComponentDirectory, [string]$InstanceDirectory)
{
    $InstallWebSitePath = Join-Path $ComponentDirectory $Node.WebRoot
    Copy-Item -Path ($InstallWebSitePath + "\*") -Destination $InstanceDirectory -PassThru -Recurse | Out-Null

    $AppPool = CreateWebAppPool -Name $Name -Classic:([System.convert]::ToBoolean($Node.Classic))
    $WebSite = New-WebSite -Name $Name -PhysicalPath $InstanceDirectory -ApplicationPool $AppPool.Name -Force

    # Splat to simplify changes to security modes
    $WebConfSplat = New-Object -TypeName System.Collections.Hashtable
    $WebConfSplat.Filter = "/system.webServer/security/authentication/*"
    $WebConfSplat.Name = "Enabled"
    $WebConfSplat.PSPath = "IIS:\"
    $WebConfSplat.Location = "{0}" -f $Name
    
    if ($Node.SecurityModes.DisableUnspecified)
    {
        $AuthenticationTypes = Get-WebConfigurationProperty @WebConfSplat

        $WebConfSplat.ErrorAction = "SilentlyContinue"
        $WebConfSplat.Value = $False
        foreach ($AuthType in $AuthenticationTypes)
        {
            $WebConfSplat.Filter = $AuthType.ItemXPath
            Set-WebConfigurationProperty @WebConfSplat | Out-Null
        }
    }

    $WebConfSplat.ErrorAction = "Stop"
    foreach ($SecurityMode in $Node.SelectNodes("//SecurityModes/*"))
    {
        $WebConfSplat.Filter = "/system.webServer/security/authentication/{0}" -f $SecurityMode.Name
        $WebConfSplat.Value = $SecurityMode.Enabled

        Write-Verbose ("Setting security mode for {0}" -f $SecurityMode.Name)
        Set-WebConfigurationProperty @WebConfSplat | Out-Null
    }

    # Return the website info
    $WebSite
}