Azure.ps1

function Connect-Azure {
  param(
    [Parameter(mandatory = $True)]
    [string] $Name,
    [switch] $Key
  )

  # TODO test resource exists

  $address = (Get-AzPublicIpAddress -Name "${name}-ip" -ResourceGroupName $Name).IpAddress

  # TODO fix ips, if not first 10.1.1.4 i.e. 10.1.1.101

  # TODO use ssh-connect
  if ($Key) {
    $keyPath = Get-SshKey -Type "rsa"
    scp -i "$($env:USERPROFILE)\.ssh\id_rsa_box" -o UserKnownHostsFile=\\.\NUL -o StrictHostKeyChecking=no $keyPath box@${address}:/home/box/.ssh/id_rsa
    ssh -i "$($env:USERPROFILE)\.ssh\id_rsa_box" -o UserKnownHostsFile=\\.\NUL -o StrictHostKeyChecking=no box@$($address) 'chmod 600 /home/box/.ssh/id_rsa'
  }

  ssh -i "$($env:USERPROFILE)\.ssh\id_rsa_box" -o UserKnownHostsFile=\\.\NUL -o StrictHostKeyChecking=no box@$($address)
}

function Connect-AzureAccount {
  # TODO 'InteractiveBrowserCredential authentication failed: Connect-AzAccount -DeviceCode

  if ( -not (Get-AzContext -errorAction SilentlyContinue)) {
    Write-Host("Connecting Azure account ...")
    Connect-AzAccount
  }

  if (!(Get-AzAccessToken -ErrorAction SilentlyContinue)) {
    Write-Host("Azure credentials have expired, connecting Azure account ...")
    Connect-AzAccount
  }
}

function Initialize-Azure {

  # Set-PSRepository -Name 'PSGallery' -InstallationPolicy Trusted

  # Install NuGet -MinimumVersion 2.8.5.201
  if ((Get-PackageProvider -Name NuGet).version -lt 2.8.5.201 ) {
    Write-Host("Installing NuGet Package Provider ...")
    Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 
  }

  # get_SerializationSettings' error: Az.Accounts max version: 2.9.1
  # TODO downgrade if needed
  Install-AzureModule Az.Network -RequiredVersion 4.8.0 # Az.Accounts 2.9.1
  Install-AzureModule Az.Resources -RequiredVersion 5.6.0 
  
  Install-AzureBicep
}

function Install-AzureBicep {
  if (-Not (Get-Command bicep -errorAction SilentlyContinue)) {
    Write-Host("Installing Bicep")
    $installPath = "$env:USERPROFILE\.bicep"
    $installDir = New-Item -ItemType Directory -Path $installPath -Force
    $installDir.Attributes += 'Hidden'
    # Fetch the latest Bicep CLI binary
    (New-Object Net.WebClient).DownloadFile("https://github.com/Azure/bicep/releases/latest/download/bicep-win-x64.exe", "$installPath\bicep.exe")
    # Add bicep to your PATH
    $currentPath = (Get-Item -path "HKCU:\Environment" ).GetValue('Path', '', 'DoNotExpandEnvironmentNames')
    if (-not $currentPath.Contains("%USERPROFILE%\.bicep")) { setx PATH ($currentPath + ";%USERPROFILE%\.bicep") }
    if (-not $env:path.Contains($installPath)) { $env:path += ";$installPath" }
  }
}

function Install-AzureModule {
  param(
    [string] $Name,
    [string] $RequiredVersion
  )

  $module = Get-InstalledModule $Name -errorAction SilentlyContinue
  if (-Not($module)) {
    Write-Host "Intalling module ${Name} ..."
    Install-Module -Name $Name -Scope CurrentUser -AllowClobber -Repository PSGallery -Force -RequiredVersion $RequiredVersion

  }
}

function New-Azure {
  param(
    [Parameter(mandatory = $True)]
    [string] $Name,
    [string] $Location = "westeurope",
    [ValidateSet(1, 2, 4)]
    [int] $Size = 1
  )

  Initialize-Azure
  Connect-AzureAccount

  if (-not(Get-AzResourceGroup -Name $Name -ErrorAction SilentlyContinue)) {
    Write-Host("Creating resource group ${Name}")
    New-AzResourceGroup -Name $Name -Location $Location
  }

  # The key needs to be at least 2048-bit and in ssh-rsa format.
  $keyPath = Get-SshKey -Type "rsa" -Public
  $publicKey = Get-Content $keyPath

  $vmSize = Switch ($Size) {
    1 { "Standard_B1s"}
    2 { "Standard_B2s"}
    4 { "Standard_B4ms"}
  }

  Write-Host "Deploying virtual machine ..."

  New-AzResourceGroupDeployment -ResourceGroupName $Name -TemplateFile (Join-Path $PSScriptRoot Azure.json) -TemplateParameterObject @{"name" = $Name; "location" = $Location; "size" = $vmSize; "publicKey" = $publicKey}
}

function Remove-Azure {
  param(
    [Parameter(mandatory = $True)]
    [string] $Name
  )

  Remove-AzResourceGroup -Name $Name

}