Deploy.ps1

<#
    .SYNOPSIS
        Creates and properly copy a valid Valo deployment folder with integrated customisation
    .DESCRIPTION
        This method acted as a controller to coordinate all methods to create a Valo Intranet
        from the information contained in client repository.
    .LINK
        Nexus Innovations : http://www.nexusinno.com
#>

function global:Initialize-GenesisFolder {
    Param (
        [Parameter(Mandatory=$true, ValueFromPipeline=$true)]
        [PSCustomObject]$InstallationConfig,

        [Parameter(ParameterSetName="Azure")]
        [switch]$AzureValoRepository,

        [Parameter(ParameterSetName="Local")]
        [switch]$LocalValoRepository,

        [Parameter(ParameterSetName="Local")]
        [ValidateScript({Test-Path $_})]
        [string]$ValoPath,

        [string]$DeploymentFolderName = "Deployment"
    )

    # Check if a directory containing the past deployments already exists
    if(Test-Path(".\$DeploymentFolderName")) {
        Write-Warning "Deployment folder already exists... removing!"
        Remove-Item $DeploymentFolderName -Force -Recurse
    }

    Write-Output "Creating deployment folder -> $DeploymentFolderName"
    $deploymentFolder = New-Item $DeploymentFolderName -ItemType Directory

    $valoArchivePath = $ValoPath
    if($PSCmdlet.ParameterSetName -eq "Azure") {
        Write-Output "Fetching Valo Archive from Azure repository..."
        
        # Login to Azure and select the subscription containing
        Connect-AzureRmAccount
        Set-AzureRmContext -Subscription $InstallationConfig.Azure.SubscriptionId

        # Fetch Valo starter pack from the Blob Storage
        Write-Verbose "Connection established to Azure, downloading the Valo partner pack archive"
        $valoArchivePath = Get-ValoFromAzureStorage `
                            -ValoVersion $InstallationConfig.Valo.Version `
                            -ResourceGroupName $InstallationConfig.Azure.ResourceGroupName `
                            -StorageAccountName $InstallationConfig.Azure.StorageAccountName `
                            -DestinationPath $deploymentFolder.FullName

        # For some weird reasons, even though the underlaying function returns the path to
        # the acquired Valo archive, some garbage data gets injected within the variable
        # and transforms it to an array. The desired data is on the second index.
        $valoArchivePath = $valoArchivePath[1].ToString()
    }

    # Unzip the Valo partner pack and the content import scripts
    Write-Verbose "Extracting the Valo Partner Pack"
    Expand-ValoPartnerPack `
        -ValoFolderPath $valoArchivePath `
        -DestinationPath $deploymentFolder.FullName `
        -ValoVersion $InstallationConfig.Valo.Version

    # Copy all client specific files to the Extracted valo folder
    $mergedGenesis = Join-Path $deploymentFolder.FullName "Genesis"
    Get-ChildItem  "genesis" | ForEach-Object {
        Write-Verbose "Copying $($_.FullName) to $valoPartnerPackFolderPath"
        Copy-Item $_.FullName -Recurse -Destination $mergedGenesis -Force
    }

    # Clean up any unwanted directory
    Get-ChildItem -Path $deploymentFolder.FullName | `
        Where-Object {$_.Name -like "Valo Modern*"} | `
        ForEach-Object {
        Remove-Item $_.FullName -Recurse -Force
    }

    Write-Output "Deployment folder is ready!"
    return $mergedGenesis
}

<#
    .SYNOPSIS
        This method return the file path of where the folder has been downloaded.
    .DESCRIPTION
        From the Azure storage account and the resource group name and the valo version,
        this method retrieve the original partner pack from the blob storage and download it.
    .LINK
        Nexus Innovations : http://www.nexusinno.com
#>

function script:Get-ValoFromAzureStorage {
    Param(
        [Parameter(Mandatory=$true)]
        [string]$ValoVersion,

        [Parameter(Mandatory=$true)]
        [string]$ResourceGroupName,

        [Parameter(Mandatory=$true)]
        [string]$StorageAccountName,

        [Parameter(Mandatory=$false)]
        [ValidateScript({Test-Path $_})]
        [string]$DestinationPath = (Get-Location)
    )

    # Obtain storage account context
    $storageKeys = Get-AzureRmStorageAccountKey -ResourceGroupName $ResourceGroupName -Name $StorageAccountName
    $storageContext = New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $storageKeys[0].Value

    # Obtain reference to blob partner pack based on the desired version of Valo
    $container = Get-AzureStorageContainer -Context $storageContext
    $blob = Get-AzureStorageBlob -Container $container.Name -Context $storageContext | Where-Object {$_.Name -like "*Modern*$ValoVersion*"}

    if($null -eq $blob) {
        throw "Valo version not found!"
    }

    # Download the partner pack localy
    Get-AzureStorageBlobContent -Blob $blob.Name -Container $container.Name -Context $storageContext -Destination $DestinationPath

    $valoFilePath = Join-Path $DestinationPath $blob.Name
    return $valoFilePath
}

<#
    .SYNOPSIS
        This method create, by unziping, the valo partner pack and return is folder path.
    .DESCRIPTION
        From the downloaded zip valo package and the client configuration,
        this method generate a folder ready to launch the genesis valo generator.
    .LINK
        Nexus Innovations : http://www.nexusinno.com
#>

function script:Expand-ValoPartnerPack {
    Param (
        [Parameter(Mandatory=$true)]
        [ValidateScript({Test-Path $_})]
        [string]$ValoFolderPath,

        [Parameter(Mandatory=$true)]
        [string]$ValoVersion,

        [ValidateScript({Test-Path $_})]
        [string]$DestinationPath = (Get-Location)
    )

    try {
        # Unzip the valo package
        Expand-Archive -Path $ValoFolderPath -DestinationPath $DestinationPath -Force

        # Move inside the unzipped Valo folder
        Push-Location -Path $ValoFolderPath.TrimEnd('.zip')

        # Retrieve the Installation packages path
        $partnerPackName = [string]::Format("PartnerPack-Modern-ReleaseO365.{0}.zip", $ValoVersion)
        $partnerPackPath = (Get-ChildItem -Recurse -Filter $partnerPackName).FullName

        if (-not ([string]::IsNullOrEmpty($partnerPackPath))) {
            Set-Location -Path $DestinationPath
            
            # Unzip the PartnerPack
            Expand-Archive -Path $partnerPackPath -DestinationPath $DestinationPath -Force
        } else {
            throw " An error occurred, the valo version is invalid!"
        }
    } finally {
        Pop-Location
    }
}