Last active
March 24, 2022 21:56
-
-
Save davoodharun/7b914fbbe572bb7b7ccae7f3c557e3aa to your computer and use it in GitHub Desktop.
Create a service principal for Automation Account in Azure
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
#Requires -RunAsAdministrator | |
Param ( | |
[Parameter(Mandatory=$true)] | |
[String] $SubscriptionId, | |
[Parameter(Mandatory=$true)] | |
[String] $ResourceGroup, | |
[Parameter(Mandatory=$true)] | |
[String] $AutomationAccountName, | |
[Parameter(Mandatory=$true)] | |
[String] $ApplicationDisplayName, | |
[Parameter(Mandatory=$true)] | |
[SecureString] $CertPassword, | |
[Parameter(Mandatory=$false)] | |
[int] $NoOfMonthsUntilExpired = 12, | |
[string]$backupCertVaultName | |
) | |
#Uncomment for authentication if running independently | |
#Add-AzureRmAccount -EnvironmentName "AzureUSGovernment" | |
#Select-AzureRmSubscription -SubscriptionId $SubscriptionId | |
$CurrentDate = Get-Date | |
$KeyId = (New-Guid).Guid | |
$CertPath = Join-Path $env:TEMP ($ApplicationDisplayName + ".pfx") | |
Write-Verbose "Create a new certificate for authentication of server (automation run as) service principal" | |
$Cert = Get-ChildItem -Path cert:\LocalMachine\My | Where-Object { ( $PSItem.Subject -eq "CN=SDTestAutomationUserRunAs") -and ($PSItem.NotAfter -gt (Get-Date).AddDays(90)) } | |
if( -not $Cert) { | |
$Cert = New-SelfSignedCertificate -DnsName $ApplicationDisplayName -CertStoreLocation cert:\LocalMachine\My -KeyExportPolicy Exportable -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" | |
} | |
Write-Verbose "Exporting authentication certificate" | |
Export-PfxCertificate -Cert ("Cert:\localmachine\my\" + $Cert.Thumbprint) -FilePath $CertPath -Password $CertPassword -Force | Write-Verbose | |
$PFXCert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate -ArgumentList @($CertPath, ([PSCredential]::new('fakeCred',$CertPassword).GetNetworkCredential().Password)) | |
$KeyValue = [System.Convert]::ToBase64String($PFXCert.GetRawCertData()) | |
Write-Verbose "Create Azure PSADKeyCredential" | |
$KeyCredential = New-Object Microsoft.Azure.Commands.Resources.Models.ActiveDirectory.PSADKeyCredential | |
$KeyCredential.StartDate = $CurrentDate | |
$KeyCredential.EndDate= $PFXCert.GetExpirationDateString() | |
$KeyCredential.KeyId = $KeyId | |
$KeyCredential.CertValue = $KeyValue | |
Write-Verbose "Checking for existing AzureRmADApplication $($ApplicationDisplayName)." | |
$Application = Get-AzureRmADApplication -DisplayNameStartWith $ApplicationDisplayName -ErrorAction SilentlyContinue | |
if ($null -eq $Application) { | |
Write-Verbose "Creating Azure AD application $($ApplicationDisplayName)." | |
# Create the Azure AD application - use newly create certificate for key credentials | |
$Application = New-AzureRmADApplication -DisplayName $ApplicationDisplayName -HomePage ("http://" + $ApplicationDisplayName) -IdentifierUris ("http://" + $KeyId) -KeyCredentials $keyCredential | |
} | |
$newApp = Get-AzureRmADApplication -ApplicationId "$($Application.ApplicationId)" -ErrorAction SilentlyContinue | |
$AppRetries = 0; | |
While ($newApp -eq $null -and $AppRetries -le 6) | |
{ | |
sleep 5 | |
$newApp = Get-AzureRmADApplication -ApplicationId "$($Application.ApplicationId)" -ErrorAction SilentlyContinue | |
$AppRetries++; | |
} | |
# Create the child service principal for the Azure AD application | |
if (-not (Get-AzureRmADServicePrincipal | Where {$_.ApplicationId -eq $Application.ApplicationId})) { | |
New-AzureRMADServicePrincipal -ApplicationId $Application.ApplicationId | Write-Verbose | |
} | |
Get-AzureRmADServicePrincipal | Where {$_.ApplicationId -eq $Application.ApplicationId} | Write-Verbose | |
#When the service principal becomes active, create the appropriate role assignments | |
$Retries = 0; | |
$NewRole = Get-AzureRMRoleAssignment -ServicePrincipalName $Application.ApplicationId -ErrorAction SilentlyContinue | |
While ($NewRole -eq $null -and $Retries -le 6) | |
{ | |
# Sleep here for a few seconds to allow the service principal application to become active (should only take a couple of seconds normally) | |
Sleep 5 | |
Try { | |
New-AzureRMRoleAssignment -RoleDefinitionName "Contributor" -ServicePrincipalName $Application.ApplicationId | Write-Verbose -ErrorAction SilentlyContinue | |
New-AzureRMRoleAssignment -RoleDefinitionName "User Access Administrator" -ServicePrincipalName $Application.ApplicationId | Write-Verbose -ErrorAction SilentlyContinue | |
} | |
Catch { | |
Write-Verbose "Service Principal not yet active, delay before adding the the role assignment." | |
} | |
Sleep 10 | |
$NewRole = Get-AzureRMRoleAssignment -ServicePrincipalName $Application.ApplicationId -ErrorAction SilentlyContinue | |
$Retries++; | |
} | |
Write-Verbose "Azure AD application - $($ApplicationDisplayName) - and service principal with role assignment(s) created." | |
# Get the tenant id for this subscription | |
$SubscriptionInfo = Get-AzureRmSubscription -SubscriptionId $SubscriptionId | |
$TenantID = $SubscriptionInfo | Select TenantId -First 1 | |
# Create the automation resources | |
Write-Verbose "Create the Azure automation certificate object" | |
if (-not ( get-AzureRmAutomationCertificate -ResourceGroupName $ResourceGroup -AutomationAccountName $AutomationAccountName -Name "AzureRunAsCertificate" -ErrorAction SilentlyContinue)) { | |
New-AzureRmAutomationCertificate -ResourceGroupName $ResourceGroup -AutomationAccountName $AutomationAccountName -Path $CertPath -Name "AzureRunAsCertificate" -Password $CertPassword -Exportable | write-verbose | |
Write-Verbose "Azure automation certificate created - AzureRunAsCertificate - in Azure automation account: $($AutomationAccountName)." | |
} | |
# Create a Automation connection asset named AzureRunAsConnection in the Automation account. This connection uses the service principal, with the newly uploaded certificate. | |
$ConnectionAssetName = "AzureRunAsConnection" | |
Remove-AzureRmAutomationConnection -ResourceGroupName $ResourceGroup -AutomationAccountName $AutomationAccountName -Name $ConnectionAssetName -Force -ErrorAction SilentlyContinue | |
$ConnectionFieldValues = @{"ApplicationId" = $Application.ApplicationId; "TenantId" = $TenantID.TenantId; "CertificateThumbprint" = $Cert.Thumbprint; "SubscriptionId" = $SubscriptionId} | |
New-AzureRmAutomationConnection -ResourceGroupName $ResourceGroup -AutomationAccountName $AutomationAccountName -Name $ConnectionAssetName -ConnectionTypeName AzureServicePrincipal -ConnectionFieldValues $ConnectionFieldValues | |
Write-Output "Azure automation connection created - $($ConnectionAssetName) - in Azure automation account: $($AutomationAccountName)." | |
if($backupCertVaultName){ | |
$secret = ConvertTo-SecureString -String $KeyValue -AsPlainText -Force | |
$secretContentType = 'application/x-pkcs12' | |
Set-AzureKeyVaultSecret -VaultName $backupCertVaultName -Name "$($ApplicationDisplayName)Cert" -SecretValue $secret -ContentType $secretContentType | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment