Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save craiglandis/adfd9be097d02b19bfb623420ed952f0 to your computer and use it in GitHub Desktop.
Save craiglandis/adfd9be097d02b19bfb623420ed952f0 to your computer and use it in GitHub Desktop.
Misc
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