Tuesday 21 July 2020

MS Azure : Use PowerShell ISE to Run Azure Automation Runbooks

We can Manage and Run Azure Automation Runbooks using PowerShell ISE. This way it helps to test the Powershell script in local Powershell console and then can be published to Azure Automation Runbooks.
To use that we have to install the module Azure Automation Runbook ToolKit on to local machine


Install the PowerShell Module using the below cmdlet:
You can install the ISE add-on module from PowerShell Gallery with:
Install-Module AzureAutomationAuthoringToolkit -Scope CurrentUser
Then, if PowerShell ISE to always automatically load the add-on, run:
Install-AzureAutomationIseAddOn
Otherwise, whenever you want to load the add-on, just run the following in the PowerShell ISE:
Import-Module AzureAutomationAuthoringToolkit


Here is How it looks like in Powershell after Importing and Signing in:




Wednesday 15 July 2020

MS Azure : Run Login-AzureRmAccount to Login Silently in Azure Automation Runbooks

How to Run Login-AzureRmAccount to Login Silently when working with PowerShell script in azure Automation Runbooks to get data from Azure Subscription

Issue: This blogpost is to fix the below error message:
Get-AzureRmResourceGroup : Run Login-AzureRmAccount to login.
At line:35 char:19
+ $ResourceGroups = Get-AzureRmResourceGroup
+                   ~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:)PSInvalidOperationException
    + FullyQualifiedErrorId : InvalidOperation,Microsoft.Azure.Commands.Resources

When executing any AzureRM [i.e. Azure Resource Manager] PowerShell command first requires Azure authentication at Azure subscription level.
So if executing AzureRM command without Login-AzureRMAccount, we will get an error message as above.

Solution:
Use Azure AD Service Principal to resolve this issue. So what is Service Principal?
Service principal means running an application as a user and giving full access to it so now it can perform any action against azure subscription level. As Azure subscription is always present in the Azure Active Directory tenant; must add the information of application in Azure AD tenant and this is nothing but the service principal.
So how do we create a Service principal? Well you don’t have to create because it is already exists when we have an Azure ARM automation account created.
Open Assets -> Connections -> AzureRunAsConection
This shows type as Azure service principal and there are many Ids present.

Application Id is the one by which your Automation account is identified as Service principal in Azure AD. Tenant id is nothing but Azure AD id under which your subscription exists. Subscription Id is the actual Azure subscription Id.

Let’s verify this exist in your Azure AD as well. For the same, on Azure portal open
Azure Active Directory -> App Registrations
You will see an Application Id same as what we have observed under automation account connection.

This means AzureRunAsConection of automation account is acting as Service principal. Hence it can be used for authentication against the subscription and also to perform operations against our azure subscription. With this let’s write some PowerShell code to perform authentication using service principal.

Authenticating using Service principal

Code for authenticating Azure Automation account runbook using Automation connection as Service principal is shown below:
Add above code segment in any runbook you wish to in Azure Automation account and you will never receive error of “Run Login-AzureRMAccount to login”.
Thats it!! :-)
$connectionName = "AzureRunAsConnection"
try
{
    # Get the connection "AzureRunAsConnection "
    $servicePrincipalConnection = Get-AutomationConnection -Name $connectionName      
    "Logging in to Azure..."
    $account = Add-AzureRmAccount `
        -ServicePrincipal `
        -TenantId $servicePrincipalConnection.TenantId `
        -ApplicationId $servicePrincipalConnection.ApplicationId `
        -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint 
}
catch {
    if (!$servicePrincipalConnection)
    {
        $ErrorMessage = "Connection $connectionName not found."
        throw $ErrorMessage
    } else{
        Write-Error -Message $_.Exception
        throw $_.Exception
    }
}
Write-Output $account