Update Automation Run As account using PowerShell

You can use PowerShell to update your existing Automation account if:

  • You create an Automation account but decline to create the Run As account.
  • You already use an Automation account to manage Resource Manager resources and you want to update the account to include the Run As account for runbook authentication.
  • You already use an Automation account to manage classic resources and you want to update it to use the Classic Run As account instead of creating a new account and migrating your runbooks and assets to it.
  • You want to create a Run As and a Classic Run As account by using a certificate issued by your enterprise certification authority (CA).

Prerequisites

  • The script can be run only on Windows 10 and Windows Server 2016 with Azure Resource Manager modules 2.01 and later. It is not supported on earlier versions of Windows.
  • Azure PowerShell 1.0 and later. For information about the PowerShell 1.0 release, see How to install and configure Azure PowerShell.
  • An Automation account, which is referenced as the value for the –AutomationAccountName and -ApplicationDisplayName parameters in the following PowerShell script.

To get the values for SubscriptionID, ResourceGroup, and AutomationAccountName, which are required parameters for the scripts, do the following:

  1. In the Azure portal, select your Automation account on the Automation account blade, and then select All settings.
  2. On the All settings blade, under Account Settings, select Properties.
  3. Note the values on the Properties blade.

The Automation account "Properties" blade

Create Run As Account PowerShell script

This PowerShell script includes support for the following configurations:

  • Create a Run As account by using a self-signed certificate.
  • Create a Run As account and a Classic Run As account by using a self-signed certificate.
  • Create a Run As account and a Classic Run As account by using an enterprise certificate.
  • Create a Run As account and a Classic Run As account by using a self-signed certificate in the Azure Government cloud.

Depending on the configuration option you select, the script creates the following items.

For Run As accounts:

  • Creates an Azure AD application to be exported with either the self-signed or enterprise certificate public key, creates a service principal account for the application in Azure AD, and assigns the Contributor role for the account in your current subscription. You can change this setting to Owner or any other role. For more information, see Role-based access control in Azure Automation.
  • Creates an Automation certificate asset named AzureRunAsCertificate in the specified Automation account. The certificate asset holds the certificate private key that's used by the Azure AD application.
  • Creates an Automation connection asset named AzureRunAsConnection in the specified Automation account. The connection asset holds the applicationId, tenantId, subscriptionId, and certificate thumbprint.

For Classic Run As accounts:

  • Creates an Automation certificate asset named AzureClassicRunAsCertificate in the specified Automation account. The certificate asset holds the certificate private key used by the management certificate.
  • Creates an Automation connection asset named AzureClassicRunAsConnection in the specified Automation account. The connection asset holds the subscription name, subscriptionId, and certificate asset name.
Note

If you select either option for creating a Classic Run As account, after the script is executed, upload the public certificate (.cer file name extension) to the management store for the subscription that the Automation account was created in.

  1. Save the following script on your computer. In this example, save it with the filename New-RunAsAccount.ps1.

     #Requires -RunAsAdministrator
      Param (
     [Parameter(Mandatory=$true)]
     [String] $ResourceGroup,
    
     [Parameter(Mandatory=$true)]
     [String] $AutomationAccountName,
    
     [Parameter(Mandatory=$true)]
     [String] $ApplicationDisplayName,
    
     [Parameter(Mandatory=$true)]
     [String] $SubscriptionId,
    
     [Parameter(Mandatory=$true)]
     [Boolean] $CreateClassicRunAsAccount,
    
     [Parameter(Mandatory=$true)]
     [String] $SelfSignedCertPlainPassword,
    
     [Parameter(Mandatory=$false)]
     [String] $EnterpriseCertPathForRunAsAccount,
    
     [Parameter(Mandatory=$false)]
     [String] $EnterpriseCertPlainPasswordForRunAsAccount,
    
     [Parameter(Mandatory=$false)]
     [String] $EnterpriseCertPathForClassicRunAsAccount,
    
     [Parameter(Mandatory=$false)]
     [String] $EnterpriseCertPlainPasswordForClassicRunAsAccount,
    
     [Parameter(Mandatory=$false)]
     [ValidateSet("AzureCloud","AzureUSGovernment")]
     [string]$EnvironmentName="AzureCloud",
    
     [Parameter(Mandatory=$false)]
     [int] $SelfSignedCertNoOfMonthsUntilExpired = 12
     )
    
     function CreateSelfSignedCertificate([string] $keyVaultName, [string] $certificateName, [string] $selfSignedCertPlainPassword,
                                   [string] $certPath, [string] $certPathCer, [string] $selfSignedCertNoOfMonthsUntilExpired ) {
     $Cert = New-SelfSignedCertificate -DnsName $certificateName -CertStoreLocation cert:\LocalMachine\My `
        -KeyExportPolicy Exportable -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" `
        -NotAfter (Get-Date).AddMonths($selfSignedCertNoOfMonthsUntilExpired)
    
     $CertPassword = ConvertTo-SecureString $selfSignedCertPlainPassword -AsPlainText -Force
     Export-PfxCertificate -Cert ("Cert:\localmachine\my\" + $Cert.Thumbprint) -FilePath $certPath -Password $CertPassword -Force | Write-Verbose
     Export-Certificate -Cert ("Cert:\localmachine\my\" + $Cert.Thumbprint) -FilePath $certPathCer -Type CERT | Write-Verbose
     }
    
     function CreateServicePrincipal([System.Security.Cryptography.X509Certificates.X509Certificate2] $PfxCert, [string] $applicationDisplayName) {  
     $CurrentDate = Get-Date
     $keyValue = [System.Convert]::ToBase64String($PfxCert.GetRawCertData())
     $KeyId = (New-Guid).Guid
    
     $KeyCredential = New-Object  Microsoft.Azure.Commands.Resources.Models.ActiveDirectory.PSADKeyCredential
     $KeyCredential.StartDate = $CurrentDate
     $KeyCredential.EndDate= [DateTime]$PfxCert.GetExpirationDateString()
     $KeyCredential.EndDate = $KeyCredential.EndDate.AddDays(-1)
     $KeyCredential.KeyId = $KeyId
     $KeyCredential.CertValue  = $keyValue
    
     # Use key credentials and create an Azure AD application
     $Application = New-AzureRmADApplication -DisplayName $ApplicationDisplayName -HomePage ("http://" + $applicationDisplayName) -IdentifierUris ("http://" + $KeyId) -KeyCredentials $KeyCredential
     $ServicePrincipal = New-AzureRMADServicePrincipal -ApplicationId $Application.ApplicationId
     $GetServicePrincipal = Get-AzureRmADServicePrincipal -ObjectId $ServicePrincipal.Id
    
     # Sleep here for a few seconds to allow the service principal application to become active (ordinarily takes a few seconds)
     Sleep -s 15
     $NewRole = New-AzureRMRoleAssignment -RoleDefinitionName Contributor -ServicePrincipalName $Application.ApplicationId -ErrorAction SilentlyContinue
     $Retries = 0;
     While ($NewRole -eq $null -and $Retries -le 6)
     {
        Sleep -s 10
        New-AzureRMRoleAssignment -RoleDefinitionName Contributor -ServicePrincipalName $Application.ApplicationId | Write-Verbose -ErrorAction SilentlyContinue
        $NewRole = Get-AzureRMRoleAssignment -ServicePrincipalName $Application.ApplicationId -ErrorAction SilentlyContinue
        $Retries++;
     }
        return $Application.ApplicationId.ToString();
     }
    
     function CreateAutomationCertificateAsset ([string] $resourceGroup, [string] $automationAccountName, [string] $certifcateAssetName,[string] $certPath, [string] $certPlainPassword, [Boolean] $Exportable) {
     $CertPassword = ConvertTo-SecureString $certPlainPassword -AsPlainText -Force   
     Remove-AzureRmAutomationCertificate -ResourceGroupName $resourceGroup -AutomationAccountName $automationAccountName -Name $certifcateAssetName -ErrorAction SilentlyContinue
     New-AzureRmAutomationCertificate -ResourceGroupName $resourceGroup -AutomationAccountName $automationAccountName -Path $certPath -Name $certifcateAssetName -Password $CertPassword -Exportable:$Exportable  | write-verbose
     }
    
     function CreateAutomationConnectionAsset ([string] $resourceGroup, [string] $automationAccountName, [string] $connectionAssetName, [string] $connectionTypeName, [System.Collections.Hashtable] $connectionFieldValues ) {
     Remove-AzureRmAutomationConnection -ResourceGroupName $resourceGroup -AutomationAccountName $automationAccountName -Name $connectionAssetName -Force -ErrorAction SilentlyContinue
     New-AzureRmAutomationConnection -ResourceGroupName $ResourceGroup -AutomationAccountName $automationAccountName -Name $connectionAssetName -ConnectionTypeName $connectionTypeName -ConnectionFieldValues $connectionFieldValues
     }
    
     Import-Module AzureRM.Profile
     Import-Module AzureRM.Resources
    
     $AzureRMProfileVersion= (Get-Module AzureRM.Profile).Version
     if (!(($AzureRMProfileVersion.Major -ge 2 -and $AzureRMProfileVersion.Minor -ge 1) -or ($AzureRMProfileVersion.Major -gt 2)))
     {
        Write-Error -Message "Please install the latest Azure PowerShell and retry. Relevant doc url : https://docs.microsoft.com/powershell/azureps-cmdlets-docs/ "
        return
     }
    
     Login-AzureRmAccount -EnvironmentName $EnvironmentName
     $Subscription = Select-AzureRmSubscription -SubscriptionId $SubscriptionId
    
     # Create a Run As account by using a service principal
     $CertifcateAssetName = "AzureRunAsCertificate"
     $ConnectionAssetName = "AzureRunAsConnection"
     $ConnectionTypeName = "AzureServicePrincipal"
    
     if ($EnterpriseCertPathForRunAsAccount -and $EnterpriseCertPlainPasswordForRunAsAccount) {
     $PfxCertPathForRunAsAccount = $EnterpriseCertPathForRunAsAccount
     $PfxCertPlainPasswordForRunAsAccount = $EnterpriseCertPlainPasswordForRunAsAccount
     } else {
       $CertificateName = $AutomationAccountName+$CertifcateAssetName
       $PfxCertPathForRunAsAccount = Join-Path $env:TEMP ($CertificateName + ".pfx")
       $PfxCertPlainPasswordForRunAsAccount = $SelfSignedCertPlainPassword
       $CerCertPathForRunAsAccount = Join-Path $env:TEMP ($CertificateName + ".cer")
       CreateSelfSignedCertificate $KeyVaultName $CertificateName $PfxCertPlainPasswordForRunAsAccount $PfxCertPathForRunAsAccount $CerCertPathForRunAsAccount $SelfSignedCertNoOfMonthsUntilExpired
     }
    
     # Create a service principal
     $PfxCert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2 -ArgumentList @($PfxCertPathForRunAsAccount, $PfxCertPlainPasswordForRunAsAccount)
     $ApplicationId=CreateServicePrincipal $PfxCert $ApplicationDisplayName
    
     # Create the Automation certificate asset
     CreateAutomationCertificateAsset $ResourceGroup $AutomationAccountName $CertifcateAssetName $PfxCertPathForRunAsAccount $PfxCertPlainPasswordForRunAsAccount $true
    
     # Populate the ConnectionFieldValues
     $SubscriptionInfo = Get-AzureRmSubscription -SubscriptionId $SubscriptionId
     $TenantID = $SubscriptionInfo | Select TenantId -First 1
     $Thumbprint = $PfxCert.Thumbprint
     $ConnectionFieldValues = @{"ApplicationId" = $ApplicationId; "TenantId" = $TenantID.TenantId; "CertificateThumbprint" = $Thumbprint; "SubscriptionId" = $SubscriptionId}
    
     # Create an Automation connection asset named AzureRunAsConnection in the Automation account. This connection uses the service principal.
     CreateAutomationConnectionAsset $ResourceGroup $AutomationAccountName $ConnectionAssetName $ConnectionTypeName $ConnectionFieldValues
    
     if ($CreateClassicRunAsAccount) {
         # Create a Run As account by using a service principal
         $ClassicRunAsAccountCertifcateAssetName = "AzureClassicRunAsCertificate"
         $ClassicRunAsAccountConnectionAssetName = "AzureClassicRunAsConnection"
         $ClassicRunAsAccountConnectionTypeName = "AzureClassicCertificate "
         $UploadMessage = "Please upload the .cer format of #CERT# to the Management store by following the steps below." + [Environment]::NewLine +
                 "Log in to the Microsoft Azure Management portal (https://manage.windowsazure.com) and select Settings -> Management Certificates." + [Environment]::NewLine +
                 "Then click Upload and upload the .cer format of #CERT#"
    
          if ($EnterpriseCertPathForClassicRunAsAccount -and $EnterpriseCertPlainPasswordForClassicRunAsAccount ) {
          $PfxCertPathForClassicRunAsAccount = $EnterpriseCertPathForClassicRunAsAccount
          $PfxCertPlainPasswordForClassicRunAsAccount = $EnterpriseCertPlainPasswordForClassicRunAsAccount
          $UploadMessage = $UploadMessage.Replace("#CERT#", $PfxCertPathForClassicRunAsAccount)
     } else {
          $ClassicRunAsAccountCertificateName = $AutomationAccountName+$ClassicRunAsAccountCertifcateAssetName
          $PfxCertPathForClassicRunAsAccount = Join-Path $env:TEMP ($ClassicRunAsAccountCertificateName + ".pfx")
          $PfxCertPlainPasswordForClassicRunAsAccount = $SelfSignedCertPlainPassword
          $CerCertPathForClassicRunAsAccount = Join-Path $env:TEMP ($ClassicRunAsAccountCertificateName + ".cer")
          $UploadMessage = $UploadMessage.Replace("#CERT#", $CerCertPathForClassicRunAsAccount)
          CreateSelfSignedCertificate $KeyVaultName $ClassicRunAsAccountCertificateName $PfxCertPlainPasswordForClassicRunAsAccount $PfxCertPathForClassicRunAsAccount $CerCertPathForClassicRunAsAccount $SelfSignedCertNoOfMonthsUntilExpired
     }
    
     # Create the Automation certificate asset
     CreateAutomationCertificateAsset $ResourceGroup $AutomationAccountName $ClassicRunAsAccountCertifcateAssetName $PfxCertPathForClassicRunAsAccount $PfxCertPlainPasswordForClassicRunAsAccount $false
    
     # Populate the ConnectionFieldValues
     $SubscriptionName = $subscription.Subscription.SubscriptionName
     $ClassicRunAsAccountConnectionFieldValues = @{"SubscriptionName" = $SubscriptionName; "SubscriptionId" = $SubscriptionId; "CertificateAssetName" = $ClassicRunAsAccountCertifcateAssetName}
    
     # Create an Automation connection asset named AzureRunAsConnection in the Automation account. This connection uses the service principal.
     CreateAutomationConnectionAsset $ResourceGroup $AutomationAccountName $ClassicRunAsAccountConnectionAssetName $ClassicRunAsAccountConnectionTypeName $ClassicRunAsAccountConnectionFieldValues
    
     Write-Host -ForegroundColor red $UploadMessage
     }
    
  2. On your computer, start Windows PowerShell from the Start screen with elevated user rights.

  3. From the elevated command-line shell, go to the folder that contains the script you created in step 1.
  4. Execute the script by using the parameter values for the configuration you require.

    Create a Run As account by using a self-signed certificate
    .\New-RunAsAccount.ps1 -ResourceGroup <ResourceGroupName> -AutomationAccountName <NameofAutomationAccount> -SubscriptionId <SubscriptionId> -ApplicationDisplayName <DisplayNameofAADApplication> -SelfSignedCertPlainPassword <StrongPassword> -CreateClassicRunAsAccount $false

    Create a Run As account and a Classic Run As account by using a self-signed certificate
    .\New-RunAsAccount.ps1 -ResourceGroup <ResourceGroupName> -AutomationAccountName <NameofAutomationAccount> -SubscriptionId <SubscriptionId> -ApplicationDisplayName <DisplayNameofAADApplication> -SelfSignedCertPlainPassword <StrongPassword> -CreateClassicRunAsAccount $true

    Create a Run As account and a Classic Run As account by using an enterprise certificate
    .\New-RunAsAccount.ps1 -ResourceGroup <ResourceGroupName> -AutomationAccountName <NameofAutomationAccount> -SubscriptionId <SubscriptionId> -ApplicationDisplayName <DisplayNameofAADApplication> -SelfSignedCertPlainPassword <StrongPassword> -CreateClassicRunAsAccount $true -EnterpriseCertPathForRunAsAccount <EnterpriseCertPfxPathForRunAsAccount> -EnterpriseCertPlainPasswordForRunAsAccount <StrongPassword> -EnterpriseCertPathForClassicRunAsAccount <EnterpriseCertPfxPathForClassicRunAsAccount> -EnterpriseCertPlainPasswordForClassicRunAsAccount <StrongPassword>

    Create a Run As account and a Classic Run As account by using a self-signed certificate in the Azure Government cloud
    .\New-RunAsAccount.ps1 -ResourceGroup <ResourceGroupName> -AutomationAccountName <NameofAutomationAccount> -SubscriptionId <SubscriptionId> -ApplicationDisplayName <DisplayNameofAADApplication> -SelfSignedCertPlainPassword <StrongPassword> -CreateClassicRunAsAccount $true -EnvironmentName AzureUSGovernment

    Note

    After the script has executed, you will be prompted to authenticate with Azure. Sign in with an account that is a member of the subscription administrators role and co-administrator of the subscription.

After the script has executed successfully, note the following:

Next steps