Azure.ps1

<#
    .SYNOPSIS
        Ensures a new Azure Resource Group
    .DESCRIPTION
        Ensures a new Azure Resource Group. Must already be logged to an Azure RM Account
    .LINK
        Nexus Innovations : http://www.nexusinno.com
    --------------------------------------------------------------------------------------
    Module 'Nexus.PSToolkit'
    by: Nexus Innovations.
    --------------------------------------------------------------------------------------
#>

function global:Add-AzureResourceGroup () {
    Param (
        [Parameter(Mandatory=$true)]
        [string]$ResourceGroupName,

        [Parameter(Mandatory=$true)]
        [string]$Location,
        
        [switch]$Force
    )

    $resourceGroup = Get-AzureRmResourceGroup -Name $ResourceGroupName -ErrorAction SilentlyContinue
    if($resourceGroup) {
        if($Force) {
            Write-Host "Recreating $ResourceGroupName..."
            Remove-AzureRmResourceGroup -ResourceGroupName $ResourceGroupName -Force
            $resourceGroup = New-AzureRmResourceGroup -Name $ResourceGroupName -Location $Location
        } else {
            Write-Warning "Azure Resource Group already exists! Use the Force Switch to recreate the resource group."
        }
    } else {
        Write-Host "Creating $ResourceGroupName..."
        $resourceGroup = New-AzureRmResourceGroup -Name $ResourceGroupName -Location $Location
    }

    return $resourceGroup
}

<#
    .SYNOPSIS
        Ensures a new Azure Storage
    .DESCRIPTION
        Ensures a new Azure Storage within an existing Resource Group.
        An account prefix is used in pair with unique guid to prevent name conflicts
 
        Must already be logged to an Azure RM Account
    .LINK
        Nexus Innovations : http://www.nexusinno.com
    --------------------------------------------------------------------------------------
    Module 'Nexus.PSToolkit'
    by: Nexus Innovations.
    --------------------------------------------------------------------------------------
#>

function global:Add-AzureStorage() {
    Param (
        [Parameter(Mandatory=$true)]
        [string]$ResourceGroupName,

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

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

        [switch]$Force
    )

    $storageAccount = Get-AzureRmStorageAccount -ResourceGroupName $ResourceGroupName | Where-Object {$_.StorageAccountName.StartsWith($StorageAccountPrefix)} -ErrorAction SilentlyContinue
    if($storageAccount) {
        if($Force) {
            Write-Host "Recreating $StorageAccountPrefix..."
            $storageAccount | Remove-AzureRmStorageAccount -Force
            $storageAccount = New-AzureStorage -ResourceGroupName $ResourceGroupName -Location $Location -StorageAccountPrefix $StorageAccountPrefix
        } else {
            Write-Warning "Azure Storage Account already exists! Use the Force Switch to recreate the storage account."
        }
    } else {
        Write-Host "Creating $StorageAccountPrefix..."
        $storageAccount = New-AzureStorage -ResourceGroupName $ResourceGroupName -Location $Location -StorageAccountPrefix $StorageAccountPrefix
    }

    return $storageAccount
}

<#
    .SYNOPSIS
        Ensures a new Azure Cdn
    .DESCRIPTION
        Ensures a new Azure Cdn within an existing Resource Group.
        See the New-AzureCdnInfo cmdlet for how to supply the parameter for this function
 
        Must already be logged to an Azure RM Account
    .LINK
        Nexus Innovations : http://www.nexusinno.com
    --------------------------------------------------------------------------------------
    Module 'Nexus.PSToolkit'
    by: Nexus Innovations.
    --------------------------------------------------------------------------------------
#>

function global:Add-AzureCdn () {
    Param (
        [string]$ResourceGroupName,
        [PSObject]$CdnInfo,
        [switch]$Force
    )

    $cdnProfile = Get-AzureRmCdnProfile -ProfileName $CdnInfo.ProfileName
    if($cdnProfile) {
        if($Force) {
            Write-Host "Recreating CDN $CdnInfo ..."
            Remove-AzureRmCdnEndpoint -ResourceGroupName $ResourceGroupName -ProfileName $CdnInfo.ProfileName -EndpointName $CdnInfo.EndPointName -Force
            Remove-AzureRmCdnProfile -ResourceGroupName $ResourceGroupName -ProfileName $CdnInfo.ProfileName -Force
            $newCdn = New-AzureCdn -ResourceGroupName $ResourceGroupName -CdnInfo $CdnInfo
        } else {
            Write-Warning "Azure CDN already exists! Use the Force Switch to recreate the CDN."
        }
    } else {
        Write-Host "Creating CDN $CdnInfo ..."
        $newCdn = New-AzureCdn -ResourceGroupName $ResourceGroupName -CdnInfo $CdnInfo
    }

    return $newCdn
}

<#
    .SYNOPSIS
        Creates a new Azure CDN Info custom object
    .DESCRIPTION
        Creates a new Azure CDN Info custom object that hold the information
        regarding needed to initialize the CDN deployment.
 
        Must already be logged to an Azure RM Account
    .LINK
        Nexus Innovations : http://www.nexusinno.com
    --------------------------------------------------------------------------------------
    Module 'Nexus.PSToolkit'
    by: Nexus Innovations.
    --------------------------------------------------------------------------------------
#>

function global:New-AzureCdnInfo() {
    Param (
        [string]$ProfileName,
        [string]$Location,
        [string]$EndPointName,
        [string]$OriginName
    )

    $properties = @{ProfileName = $ProfileName; 
                    Location = $Location; 
                    EndPointName = $EndPointName; 
                    OriginName = $OriginName; 
                    OriginHostHeader = "$OriginName.blob.core.windows.net"}
    
    return New-Object PSObject -Property $properties
}

function script:New-AzureStorage {
    Param (
        [string]$ResourceGroupName,
        [string]$StorageAccountPrefix,
        [string]$Location
    )

    $name = New-UniqueStorageAccountName -StorageAccountPrefix $StorageAccountPrefix
    $storageAccount = New-AzureRmStorageAccount -ResourceGroupName $ResourceGroupName -Name $name -SkuName Standard_LRS -Location $Location
    $storageKeys = Get-AzureRmStorageAccountKey -ResourceGroupName $ResourceGroupName -Name $storageAccount.StorageAccountName

    $storageCtx = New-AzureStorageContext -StorageAccountName $storageAccount.StorageAccountName -StorageAccountKey $storageKeys[0].Value

    Write-Host "Creating Storage Blob Container..."
    New-AzureStorageContainer -Context $storageCtx -Name "nexus-spfx-webpart"

    return $storageAccount
}

function script:New-AzureCdn {
    Param (
        [string]$ResourceGroupName,
        [PSObject]$CdnInfo
    )

    $cdnProfile = New-AzureRmCdnProfile -ResourceGroupName $resourceGroupName -ProfileName $CdnInfo.ProfileName -Location $CdnInfo.Location -Sku Standard_Akamai

    $isAvailable = Get-AzureRmCdnEndpointNameAvailability -EndpointName "nexusspfx" | Select-Object -Property NameAvailable
    if($isAvailable) {
        New-AzureRmCdnEndpoint -ProfileName $cdnProfile.Name -ResourceGroupName $resourceGroupName -Location $CdnInfo.Location `
                               -EndpointName $CdnInfo.EndPointName -OriginName $CdnInfo.OriginName -OriginHostHeader $CdnInfo.OriginHostHeader -OriginHostName $CdnInfo.OriginHostHeader
    } else {
        Write-Warning "Endpoint name is not available! Skipping endpoint creation..."
    }

    return $cdnProfile
}

function script:New-UniqueStorageAccountName {
    Param (
        [Parameter(Mandatory=$true)]
        [string]$StorageAccountPrefix
    )

    if([string]::IsNullOrEmpty($StorageAccountPrefix)) {
        throw "Specify storage account prefix!"
    }

    $pattern = "$StorageAccountPrefix{0}"
    $uid = [Guid]::NewGuid().ToString().Split('-') | Select-Object -First 1
    return [string]::Format($pattern, $uid)
}