Public/Install-Sitecore.ps1

#Requires -Modules SitecoreInstallFramework, SitecoreFundamentals, WebAdministration
#Requires -RunAsAdministrator

$sifDefaultsExist = Get-Variable SifHelperDefaults -Scope global -verbose -ErrorAction SilentlyContinue
if (!$sifDefaultsExist) {
    $global:SifHelperDefaults = @{}
}

Function Install-Sitecore {
    <#
    .Synopsis
        Splats a hashtable on a function in a safer way than the built-in
        mechanism.
    .Example
        Install-Sitecore Get-XYZ $PSBoundParameters
    #>

    [CmdletBinding(SupportsShouldProcess = $true, DefaultParameterSetName = "__all")]
    param(
        [Parameter(ParameterSetName = "__all", ValueFromPipeline = $true, Mandatory = $true, Position = 0)]
        [Parameter(ParameterSetName = "__defaults", ValueFromPipeline = $true, Mandatory = $true, Position = 1)]
        [hashtable] $parameters,

        [Parameter(ParameterSetName = "__all", ValueFromPipeline = $true, Mandatory = $true, Position = 1)]
        [string] $detail,

        [Parameter(ParameterSetName = "__defaults", ValueFromPipeline = $true, Mandatory = $true, Position = 0)]
        [hashtable] $defaultParameters,

        [Parameter(ParameterSetName = "__setDefaults", ValueFromPipeline = $true, Mandatory = $true, Position = 0)]
        [hashtable] $setDefaults,

        [Parameter(ParameterSetName = "__getDefaults", ValueFromPipeline = $true, Position = 0)]
        [switch] $getDefaults = $false,

        [Parameter(ValueFromRemainingArguments = $true)]
        [PSCustomObject] $moreParameters
    )


    begin {

        function GetSection {
            param(
                [Parameter(Mandatory = $true)]
                [PSCustomObject]$InputObject,
                [Parameter(Mandatory = $true)]
                [string]$Section
            )
    
            if ($InputObject.HasMember($Section)) {
                return $InputObject.$section
            }
    
            $null
        }
    
        Function Join-Hashtable {
            #comment based help is here
            [CmdletBinding()]
            Param (
                [hashtable]$First,
                [hashtable]$Second
            )
    
            #create clones of hashtables so originals are not modified
            $Primary = $First.Clone()
            $Secondary = $Second.Clone()
    
            #check for any duplicate keys
            $duplicates = $Primary.keys | Where-Object {$Secondary.ContainsKey($_)}
            if ($duplicates) {
                foreach ($item in $duplicates) {
                    $primary.Remove($item)
                }
            }
    
            #join the two hash tables
            $Primary + $Secondary
        } #end Join-Hashtable
    
        Function WriteDetail {
            param (
                [string] $detail,
                [hashtable] $params
            )

            Write-Emphatic -TaskName 'Install-Sitecore' -TaskType "[$detail]" -Info "Path = '$($params.Path)'"
        }

        [hashtable]$all = @{}
        
        switch ($PSCmdlet.ParameterSetName) {
            '__all' {
                $all = Join-Hashtable -First $global:SifHelperDefaults -Second $parameters
                $all = Join-Hashtable -First $all -Second $PSBoundParameters

                Write-Detail -detail $detail -params $all
                Write-Progress -Activity $detail
            }
            '__defaults' {
                $global:SifHelperDefaults = $defaultParameters
                $all = Join-Hashtable -First $global:SifHelperDefaults -Second $parameters
                $all = Join-Hashtable -First $all -Second $PSBoundParameters
            }
            '__setDefaults' {
                $global:SifHelperDefaults = $setDefaults
                return
            }
            '__getDefaults' {
                return $global:SifHelperDefaults
            }
        }

        $finalHash = @{}
    }

    process {


        if ($moreParameters -and $moreParameters.Count -gt 0) {
            for ($i = 0; $i -lt $moreParameters.Count; $i += 2) {
                $moreParameterKey = ($moreParameters[$i] -replace '^-+')
                $moreParameterValue = $moreParameters[$i + 1]

                if ($moreParameterKey) {
                    $all.$moreParameterKey = $moreParameterValue
                }
            }
        }

        $path = $all.Path
        $pathJson = Invoke-ReadJsonConfigFunction -Path $path
        $allowedParameters = GetSection -Section 'Parameters' -InputObject $pathJson

        if ($allowedParameters) {
            foreach ($allowedParameter in $allowedParameters.GetMembers()) {
                $allowedParameterKey = $allowedParameter.Name
                if ($all.ContainsKey($allowedParameterKey)) {
                    $allowedParameterValue = $all.$allowedParameterKey
                    Write-Debug "Adding parameter $allowedParameterKey`: $allowedParameterValue"
                    $finalHash.$allowedParameterKey = $allowedparameterValue
                }
            }
        }

        $FunctionName = "Install-SitecoreConfiguration"
        $command = Get-Command -Name $FunctionName
        $namedParameters = ($command).Parameters.Keys

        foreach ($namedParameter in $namedParameters) {
            if ($all.ContainsKey($namedParameter)) {
                $newParameterValue = $all.$namedParameter
                Write-Debug "Adding parameter $namedParameter`: $newParameterValue"
                $finalHash.$namedParameter = $newParameterValue
            }
        }

        $finalHashOutput = $finalHash | Out-String
        Write-Verbose "Executing [Install-Sitecore] with parameters $finalHashOutput" -Verbose


        if ($finalHash.Count -eq 0) {
            "$FunctionName" | Invoke-Expression
        }
        else {
            "$FunctionName @finalHash" | Invoke-Expression
        }

    }

    end {
        switch ($PSCmdlet.ParameterSetName) {
            '__all' {
                Write-Progress -Activity $detail -Completed
            }
        }
    }
}