Private/WebUtil.ps1

Function Get-FreeWebPort {
    <#
    .Synopsis
    Find a free port for web application.
 
    .Description
    Find a free port for web application, starting from a given port, and increment if needed.
 
    .Parameter startingPort
    The port to start with.
 
    .Example
    # find a free port starting with 8090
    Get-FreeWebPort 8090
    #>
    
    [cmdletbinding()]
    [OutputType([int])]
    param( 
        [int] $startingPort
    )
    Process
    {        
        $usedPorts = @()
        Import-Module WebAdministration
        
        foreach ($bind in (Get-WebBinding).bindingInformation) {
            $port = Get-BindingPort $bind
            $usedPorts += $port 
        }
        
        $choosenPort = $startingPort
        while ($usedPorts.contains($choosenPort)) {
            $choosenPort += 10
        }
        
        return $choosenPort
    }
}

function Get-BindingPort($bind) {
    $startIndex = $bind.indexof(':')+1
    $endIndex = $bind.lastindexof(':')
    $port = $bind.Substring($startIndex, ($endIndex-$startIndex))
    return [int] $port
}

function Find-WebSite($Port) {
    $sites = Get-WebSite
    foreach ($site in $sites) {
        $matchSite = Find-SiteMatchPort $site $Port
        if ($matchSite) {
            return $site
        }
    }

    return $null
}

function Find-SiteMatchPort($Site, $Port) {
   $bindings = $Site.bindings.Collection
   foreach ($binding in $bindings.bindingInformation) {
       $sitePort = Get-BindingPort $binding
       $siteName = $Site.Name
       Write-Verbose "Comparing site $sitePort with $Port"
       if ($sitePort -eq $Port) {
           Write-Verbose "Site $siteName match port $Port"
           return $true
       }
   }

   return $false
}

function Get-Path($Site, $WebApplication) {
    return "$Site/$WebApplication"
}

function Set-WebAuthentication($Tenant, $WebSite, $AppName, $Value) {
    $Path = Get-Path $WebSite $AppName
    Write-Verbose "Path is $Path"
    if ($Value -eq "Windows") {
        Set-WebConfigurationProperty -filter /system.webServer/security/authentication/windowsAuthentication -name enabled -value $true -PSPath IIS:\ -location "$Path"
        Set-WebConfigurationProperty -filter /system.webServer/security/authentication/AnonymousAuthentication -name enabled -value $false -PSPath IIS:\ -location "$Path"
        $config = (Get-WebConfiguration system.web/authentication "IIS:Sites\$Website\$AppName")
        $config.mode = "Windows"
        $config | Set-WebConfiguration system.web/authentication
    }

    if ($Value -eq "Formular") {
        Set-WebConfigurationProperty -filter /system.webServer/security/authentication/windowsAuthentication -name enabled -value $false -PSPath IIS:\ -location "$Path"
        Set-WebConfigurationProperty -filter /system.webServer/security/authentication/AnonymousAuthentication -name enabled -value $true -PSPath IIS:\ -location "$Path"
        $config = (Get-WebConfiguration system.web/authentication "IIS:Sites\$Website\$AppName")
        $config.mode = "Forms"
        $config | Set-WebConfiguration system.web/authentication
    }

    Store-WebConf $Tenant "Authentication" $Value

    Write-Verbose "Configuration saved"
}

function Store-WebConf($Tenant, $Key, $Value) {
    $path = Get-WebConfigPathFromTenant $Tenant
    if (!(Test-Path $path)) {
        md $path | Out-Null
    }

    $filePath = "$path$Key"
    Write-Verbose "Writing $Value to $filePath"
    Set-Content $filePath $Value
}

function Get-WebConf($Tenant, $Key) {
    $path = Get-WebConfigPathFromTenant $Tenant
    $filePath = "$path$Key"
    if (!(Test-Path $filePath)) {
        Write-Verbose "Path $filePath does not exist"
        return $null
    }

    Write-Verbose "Reading $filePath"
    $value = Get-Content $filePath
    Write-Verbose "$Key : $value"
    return $value
}

function Get-SSLConf($Tenant) {
    return Get-WebConf $Tenant "SSL"
}

function Get-AuthenticationConf($Tenant) {
    return Get-WebConf $Tenant "Authentication"
}

function Apply-WebConfOnWebServices($webPath) {
    $ssl = Get-SSLConf $Tenant
    if ($ssl -eq $null) {
        $ssl = "true"
    }

    $authentication = Get-AuthenticationConf $Tenant
    if ($authentication -eq $null) {
        $authentication = "Windows"
    }

    Write-Output "Web configuration - SSL: $ssl, Authentication: $authentication"
    $servicePath = "$webPath\services2.config"
    $backupPath = "$webPath\services.backup"

    Backup-ServiceConfig $servicePath $backupPath
    Write-ServiceInit $servicePath
    Write-ServicesHeader $servicePath
    Write-Services $servicePath $authentication $ssl
    Write-ServicesFooter $servicePath
}

function Backup-ServiceConfig($Path, $Backup) {
    Write-Verbose "Creating backup of $Path to $Backup"
    Copy-Item $Path $Backup -force | Out-Null
}

function Write-ServiceInit($Path) {
    Write-Verbose "Initializing $Path"
    New-Item $Path -force | Out-Null
}

function Write-ServicesHeader($Path) {
    Add-Content $Path "<services>"
}

function Write-ServicesFooter($Path) {
    Add-Content $Path "</services>"
}

function Write-Services($Path, $Authentication, $SSL) {
    foreach($pair in $services.GetEnumerator()) {
        $service = $($pair.Name)
        $behavior = $($pair.Value)
        Write-Verbose "Registering service $service"
        Write-ServiceHeader $Path $service
        $binding = Get-Binding $Authentication "false"
        Write-EndPoint $Path $behavior $binding
        if ($SSL -eq "true") {
            $binding = Get-Binding $Authentication "true"
            Write-EndPoint $Path $behavior $binding
        }

        Write-ServiceFooter $Path
    }
}

function Get-Binding($Authentication, $SSL) {
    if ($Authentication -eq "Windows") {
        if ($SSL -eq "true") {
            return "securedWebBinding"
        } else {
            return "defaultWebBinding"
        }
    } else {
        if ($SSL -eq "true") {
            return "anoSecuredWebBinding"
        } else {
            return "anoWebBinding"
        }
    }
}

function Write-ServiceHeader($Path, $Service) {
    $header = "`t" + $serviceHeaderTemplate.Replace("[SERVICE]", $Service)
    Add-Content $Path $header
}

function Write-EndPoint($Path, $Behavior, $Binding) {
    $endpoint = "`t`t" + $endPointTemplate.Replace("[BEHAVIOR]", $Behavior).Replace("[BINDING]", $Binding)
    Add-Content $Path $endpoint
}

function Write-ServiceFooter($Path) {
    Add-Content $Path "`t</service>"
}

$serviceHeaderTemplate = "<service behaviorConfiguration=`"httpGetEnablingBehavior`" name=`"[SERVICE]`">"
$endPointTemplate = "<endpoint address=`"`" behaviorConfiguration=`"[BEHAVIOR]`" binding=`"webHttpBinding`" bindingConfiguration=`"[BINDING]`" contract=`"Ortems.PlannerOne.Web.UserControl.CalendarExceptions.CalendarException`"/>"

$services = @{
        "Ortems.PlannerOne.Web.UserControl.CalendarExceptions.CalendarException" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.UserControl.Indicators.IndicatorsService" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.UserControl.Scheduling.ConfirmationLoader" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.UserControl.Sequencing.SequencingService" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.UserControl.Display.Custom.TaskColorService" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.UserControl.Filter.FilterService" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.Views.ResourceSequence.ResourceSequenceService" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.UserControl.DetailsPanel.InfoService" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.UserControl.Utilities.UtilitiesService" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.UserControl.Display.RefreshService" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.UserControl.Display.ViewsService" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.UserControl.Display.Custom.RowService" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.UserControl.Display.Custom.Task" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.UserControl.Robots.RobotsService" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.UserControl.Search.SearchService" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.UserControl.Action.ManageTask.TaskManagerService" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.Views.Calendar.Service" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.UserControl.ActivityComputation.ActivityComputationService" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.Service.SelectionService" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.Views.JobOverview.JobOverviewService" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.UserControl.Display.Total.TotalService" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.Service.ViewsService" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.UserControl.SwitchPlanning.SwitchPlanningService" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.UserControl.MoveTasks.MoveTasksService" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.Api.PlanningProduction" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.Api.PlanningProject" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.UserControl.WebGantt.Gantt" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.Admin.PerformanceService" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.Admin.PerformanceSessionService" = "webHttp";
        "Ortems.PlannerOne.Web.Admin.WebSecurityService" = "webHttp";
        "Ortems.PlannerOne.Web.UserControl.Action.Assignment.ChooseResource" = "webScriptEnablingBehavior";
        "Ortems.PlannerOne.Web.Configure.ConfigurationService" = "webHttp";
        "Ortems.PlannerOne.Web.Admin.ICalConfigurationService" = "webHttp";
        "Ortems.PlannerOne.Web.UserControl.PinTasks.PinTasksService" = "webScriptEnablingBehavior";
}