Last active
February 1, 2022 23:14
-
-
Save craiglandis/adfd9be097d02b19bfb623420ed952f0 to your computer and use it in GitHub Desktop.
Misc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if ($enableWinRM) | |
{ | |
if ($certUrl -and $vaultResourceId) | |
{ | |
Write-Output "Using cert URL $certUrl" | |
} | |
else | |
{ | |
if (!$vaultName) | |
{ | |
$vaultName = "$($resourceGroupName)vault1" | |
} | |
$vault = Get-AzKeyVault -VaultName $vaultName -ResourceGroupName $resourceGroupName | |
if ($vault) | |
{ | |
Write-Output "Using existing vault $vaultName for WinRM cert" | |
} | |
else | |
{ | |
# https://docs.microsoft.com/en-us/azure/key-vault/general/key-vault-recovery?tabs=azure-powershell#key-vault-powershell | |
$vaultInRemovedState = Get-AzKeyVault -VaultName $vaultName -Location $location -InRemovedState | Where-Object {$_.ResourceId.StartsWith("/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName")} | |
if ($vaultInRemovedState) | |
{ | |
Write-Output "Purging vault in removed state: $($vaultInRemovedState.ResourceId)" | |
$vaultInRemovedState | Remove-AzKeyVault -InRemovedState -Force -ErrorAction Stop | |
} | |
Write-Output "Creating vault $vaultName to store WinRM cert" | |
$vault = New-AzKeyVault -VaultName $vaultName -ResourceGroupName $resourceGroupName -Location $location -EnabledForDeployment -EnabledForTemplateDeployment -ErrorAction Stop | |
} | |
$vaultResourceId = $vault.ResourceId | |
Write-Output "Vault ID: $vaultResourceId" | |
$certName = $vmName | |
$certStoreLocation = 'Cert:\CurrentUser\My' | |
$pfxFilePath = "$env:TEMP\$certName.pfx" | |
$context = Get-AzContext -ErrorAction Stop | |
if ($context.Account.Type -eq 'ServicePrincipal') | |
{ | |
$servicePrincipalName = $context.Account.Id | |
Write-Output "Updating vault access policy to allow access by currently logged in service principal $servicePrincipalName" | |
$permissionsToKeys = @('decrypt', 'encrypt', 'unwrapKey', 'wrapKey', 'verify', 'sign', 'get', 'list', 'update', 'create', 'import', 'delete', 'backup', 'restore', 'recover', 'purge') | |
$permissionsToSecrets = @('get', 'list', 'set', 'delete', 'backup', 'restore', 'recover', 'purge') | |
# Had superset of these without using -PermissionsToCertificates $permissionsToCertificates so ¯\_(ツ)_/¯ | |
# $permissionsToCertificates = @('get', 'list', 'update', 'create') | |
# Set-AzKeyVaultAccessPolicy -VaultName $vaultName -ServicePrincipalName $servicePrincipalName -PermissionsToCertificates $permissionsToCertificates -PermissionsToKeys $permissionsToKeys -PermissionsToSecrets $permissionsToSecrets | |
Set-AzKeyVaultAccessPolicy -VaultName $vaultName -ServicePrincipalName $servicePrincipalName -PermissionsToKeys $permissionsToKeys -PermissionsToSecrets $permissionsToSecrets | |
} | |
if ($createCertInVault) | |
{ | |
# https://docs.microsoft.com/en-us/azure/key-vault/certificates/quick-create-powershell#add-a-certificate-to-key-vault | |
Write-Output "Creating self-signed cert in vault $vaultName then importing to $certStoreLocation" | |
$subjectName = "CN=$($certName)" | |
$certPolicy = New-AzKeyVaultCertificatePolicy -SecretContentType 'application/x-pkcs12' -SubjectName $subjectName -IssuerName 'Self' -ValidityInMonths 12 -ReuseKeyOnRenewal | |
$cert = Add-AzKeyVaultCertificate -VaultName $vaultName -Name $certName -CertificatePolicy $certPolicy | |
while ($cert.Status -eq 'inProgress') | |
{ | |
Start-Sleep -Seconds 5 | |
$cert = Get-AzKeyVaultCertificateOperation -VaultName $vaultName -Name $certName | |
} | |
if ($cert.Status -ne 'completed') | |
{ | |
Write-Output "Key vault cert creation failed: $($cert.Status)" | |
exit 3 | |
} | |
$cert = Get-AzKeyVaultCertificate -VaultName $vaultName -Name $certName | |
$thumbprint = $cert.Thumbprint | |
$certUrl = $cert.SecretId | |
Write-Output "Created cert: $certName, thumbprint: $thumbprint" | |
Write-Output "Exporting cert: $certName, thumbprint: $thumbprint to $pfxFilePath" | |
$secret = Get-AzKeyVaultSecret -VaultName $vaultName -Name $certName -AsPlainText | |
$secretByte = [Convert]::FromBase64String($secret) | |
$x509Cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($secretByte, $null, 'Exportable,PersistKeySet') | |
$type = [System.Security.Cryptography.X509Certificates.X509ContentType]::Pfx | |
$pfxFileByte = $x509Cert.Export($type, $password) | |
[System.IO.File]::WriteAllBytes($pfxFilePath, $pfxFileByte) | |
Write-Output "Exported cert: $certName, thumbprint: $thumbprint to $pfxFilePath" | |
Write-Output "Importing cert: $certName, thumbprint: $thumbprint from $pfxFilePath to $certStoreLocation" | |
Import-PfxCertificate -FilePath $pfxFilePath -CertStoreLocation $certStoreLocation -Password $passwordSecureString -ErrorAction Stop | Out-Null | |
if (Test-Path -Path "$certStoreLocation\$thumbprint" -PathType Leaf) | |
{ | |
Write-Output "Imported cert: $certName, thumbprint: $thumbprint from $pfxFilePath to $certStoreLocation" | |
} | |
} | |
else | |
{ | |
Write-Output "Creating self-signed cert in $certStoreLocation then copying to vault $vaultName" | |
$command = "New-SelfSignedCertificate -DnsName $certName -CertStoreLocation $certStoreLocation -KeySpec KeyExchange -KeyExportPolicy Exportable -ErrorAction Stop" | |
Write-Output $command | |
$cert = Invoke-Expression -Command $command | |
$thumbprint = $cert.Thumbprint | |
Write-Output "Created cert: $certName, thumbprint: $thumbprint in $certStoreLocation" | |
Write-Output "Exporting cert: $certName, thumbprint: $thumbprint to $pfxFilePath" | |
Export-PfxCertificate -Cert $cert -FilePath $pfxFilePath -Password $passwordSecureString -ErrorAction Stop | |
if (Test-Path -Path $pfxFilePath -PathType Leaf) | |
{ | |
Write-Output "Exported cert: $certName, thumbprint: $thumbprint to $pfxFilePath" | |
Write-Output "Copying cert: $certName, thumbprint: $thumbprint to vault $vaultName" | |
$fileContentBytes = Get-Content $pfxFilePath -AsByteStream -ReadCount 0 -ErrorAction Stop | |
$fileContentEncoded = [System.Convert]::ToBase64String($fileContentBytes) | |
$jsonObject = [pscustomobject][ordered]@{data = $fileContentEncoded; dataType = 'pfx'; password = $password} | ConvertTo-Json | |
$jsonObjectBytes = [System.Text.Encoding]::UTF8.GetBytes($jsonObject) | |
$jsonEncoded = [System.Convert]::ToBase64String($jsonObjectBytes) | |
$secretName = $certName | |
$secret = ConvertTo-SecureString -String $jsonEncoded -AsPlainText -Force -ErrorAction Stop | |
$certUrl = (Set-AzKeyVaultSecret -VaultName $vaultName -Name $secretName -SecretValue $secret -ErrorAction Stop).Id | |
Write-Output "Copied cert: $certName, thumbprint: $thumbprint to vault $vaultName" | |
} | |
} | |
$uri = $certUrl -as [System.Uri] | |
if ($uri.IsAbsoluteUri -and $uri.Scheme -eq 'https') | |
{ | |
Write-Output "WinRM cert URL: $certUrl" | |
if (Test-Path -Path $pfxFilePath -PathType Leaf) | |
{ | |
Write-Output "Removing $pfxFilePath" | |
Remove-Item -Path $pfxFilePath -Force | |
Write-Output "Removed $pfxFilePath" | |
} | |
} | |
else | |
{ | |
$enableWinRM = $false | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment