|
[CmdletBinding()] |
|
Param( |
|
[Parameter()] |
|
[string]$SubscriptionId = $null |
|
, |
|
[Parameter()] |
|
[string]$CertificatePassword = "secret" |
|
, |
|
[Parameter()] |
|
[ValidateScript({ Test-Path $_ -IsValid })] |
|
[string]$CertificateStoreLocation = "Cert:\CurrentUser\My" |
|
, |
|
[Parameter()] |
|
[string]$CertificateThumbprint = $null |
|
) |
|
Begin { |
|
$__eap = $ErrorActionPreference |
|
$ErrorActionPreference = "Stop" |
|
} |
|
Process { |
|
Write-Host "Checking for AZ Module..." -NoNewline |
|
If ($null -eq (Get-InstalledModule "Az" -ErrorAction "SilentlyContinue")) { |
|
Write-Host "Not found, installing..." -NoNewline |
|
Install-Module -Name "Az" -AllowClobber -Scope "CurrentUser" -SkipPublisherCheck -Force | Out-Null |
|
Write-Host "Done." |
|
} Else { |
|
Write-Host "Found." |
|
} |
|
|
|
Write-Host "Connecting to azure..." -NoNewline |
|
$azCtx = Get-AzContext -ErrorAction "SilentlyContinue" |
|
If ($null -eq $azCtx) { |
|
$azCtx = Connect-AzAccount |
|
} |
|
Write-Host "Done. $($azCtx.Name)" |
|
|
|
If (!([string]::IsNullOrWhitespace($SubscriptionId))) { |
|
Write-Host "Confirming subscription..." -NoNewline |
|
If ($azCtx.Subscription.Id -ne $SubscriptionId) { |
|
$azSub = Get-AzSubscription -SubscriptionId $SubscriptionId -ErrorAction "SilentlyContinue" |
|
If ($null -ne $azSub) { |
|
$azSub | Set-AzContext |
|
$SubscriptionId = $azCtx.Subscription.Id |
|
Write-Host "Changed to ${SubscriptionId}." |
|
} Else { |
|
Write-Error "Failed. Unknown subscription '${SubscriptionId}'" |
|
} |
|
} Else { |
|
Write-Host "Found as ${SubscriptionId}." |
|
} |
|
} Else { |
|
Write-Host "Getting current subscription..." -NoNewline |
|
$azSub = Get-AzSubscription -SubscriptionId $azCtx.Subscription.Id |
|
$SubscriptionId = $azCtx.Subscription.Id |
|
Write-Host "Found as {$SubscriptionId}." |
|
} |
|
|
|
Write-Host "Getting tenant id..." -NoNewline |
|
$tenantId = $azSub.TenantId |
|
Write-Host "Found: ${tenantId}." |
|
|
|
If ([string]::IsNullOrWhitespace($CertificateThumbprint)) { |
|
Write-Host "Creating certificate..." -NoNewline |
|
$certSubject = "CN=${env:USERNAME}AzureServicePrincipal" |
|
$cert = Get-ChildItem $CertificateStoreLocation | Where-Object { $_.Subject -eq $certSubject } |
|
If ($null -eq $cert) { |
|
$cert = New-SelfSignedCertificate -CertStoreLocation $CertificateStoreLocation -Subject $certSubject -KeySpec "KeyExchange" |
|
$CertificateThumbprint = $cert.Thumbprint |
|
Write-Host "Done (thumbprint: ${CertificateThumbprint})" |
|
} Else { |
|
$CertificateThumbprint = $cert.Thumbprint |
|
Write-Host "Found (thumbprint: ${CertificateThumbprint})" |
|
} |
|
} Else { |
|
Write-Host "Locating certificate..." -NoNewline |
|
$cert = Get-Item "${CertificateStoreLocation}\${CertificateThumbprint}" -ErrorAction "SilentlyContinue" |
|
If ($null -eq $cert) { |
|
Write-Error "Provided thumbprint not found in certificate store" |
|
} Else { |
|
$CertificateThumbprint = $cert.Thumbprint |
|
Write-Host "Found (thumbprint: ${CertificateThumbprint})" |
|
} |
|
} |
|
|
|
$certValue = [System.Convert]::ToBase64String($cert.GetRawCertData()) |
|
|
|
Write-Host "Exporting certificate..." -NoNewline |
|
$certFile = "${env:USERNAME}AzureServicePrincipal.pfx" |
|
If (!(Test-Path $certFile)) { |
|
$certPassword = $CertificatePassword | ConvertTo-SecureString -AsPlainText -Force |
|
$cert | Export-PfxCertificate -Password $certPassword -FilePath $certFile |
|
Write-Host "Done." |
|
} Else { |
|
Write-Host "Found." |
|
} |
|
|
|
Write-Host "Creating service principal..." -NoNewline |
|
$displayName = "${env:USERNAME}AzureApp" |
|
$azADServicePrincipal = Get-AzADServicePrincipal -DisplayName $displayName |
|
If ($null -eq $azADServicePrincipal) { |
|
$azADServicePrincipal = New-AzADServicePrincipal -DisplayName $displayName -CertValue $certValue -StartDate $cert.NotBefore -EndDate $cert.NotAfter |
|
$applicationId = $azADServicePrincipal.ApplicationId |
|
Write-Host "Done (appId: ${applicationId})." |
|
} Else { |
|
$applicationId = $azADServicePrincipal.ApplicationId |
|
Write-Host "Found (appId: ${applicationId})." |
|
} |
|
|
|
Write-Host "Assinging role..." -NoNewline |
|
$azRoleAssignment = Get-AzRoleAssignment -RoleDefinitionName "Contributor" -ServicePrincipalName $applicationId |
|
If ($null -eq $azRoleAssignment) { |
|
Write-Host "Waiting for Azure to propagate changes..." -NoNewline |
|
Start-Sleep -Seconds 30 |
|
$azRoleAssignment = New-AzRoleAssignment -RoleDefinitionName "Contributor" -ServicePrincipalName $applicationId |
|
Write-Host "Done." |
|
} Else { |
|
Write-Host "Found." |
|
} |
|
|
|
Write-Host "Building docker base image..." -NoNewline |
|
$Dockerfile = @" |
|
# escape=`` |
|
FROM mcr.microsoft.com/windows/servercore:1803 |
|
SHELL ["powershell.exe", "-Command", "`$ErrorActionPreference='Stop';"] |
|
|
|
RUN Get-PackageProvider -Name 'NuGet' -ForceBootstrap ; `` |
|
Install-Module 'Az' -SkipPublisherCheck -Force |
|
|
|
COPY ${certFile} . |
|
RUN `$certPassword = '${CertificatePassword}' | ConvertTo-SecureString -AsPlainText -Force ; `` |
|
Import-PfxCertificate -Password `$certPassword -certStoreLocation '${CertificateStoreLocation}' -FilePath '${certFile}' |
|
|
|
RUN Connect-AzAccount -CertificateThumbprint '${CertificateThumbprint}' -ApplicationId '${applicationId}' -ServicePrincipal -Tenant '${tenantId}' |
|
"@ |
|
$tag = $azSub.Name.ToLower() |
|
$Dockerfile | & docker build --tag "az:${tag}" --file - . |
|
If ($LASTEXITCODE -eq 0) { |
|
Write-Host "Done. (image: ${tag})" |
|
} Else { |
|
Write-Host "Failed." |
|
} |
|
|
|
Write-Host "Cleaning up..." -NoNewline |
|
Remove-Item $certFile |
|
$cert | Remove-Item |
|
Write-Host "Done." |
|
} |
|
End { |
|
$ErrorActionPreference = $__eap |
|
} |