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 = "__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
    )

    Install-SifPreReqs

    function GetSection {
        param(
            [Parameter(Mandatory = $true)]
            [PSCustomObject]$InputObject,
            [Parameter(Mandatory = $true)]
            [string]$Section
        )

        if ($InputObject.HasMember($Section)) {
            return $InputObject.$section
        }

        $null
    }

    [hashtable]$all = @{}

    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

    switch ($PSCmdlet.ParameterSetName) {
        '__all' {
            $all = Join-Hashtable -First $global:SifHelperDefaults -Second $parameters
            $all = Join-Hashtable -First $all -Second $PSBoundParameters
        }
        '__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 = @{}

    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"
    if ($finalHash.Count -eq 0) {
        "$FunctionName" | Invoke-Expression
    }
    else {
        "$FunctionName @finalHash" | Invoke-Expression
    }
}