I love Azure and I love PowerShell. They are a perfect marriage. It’s amazing how much automation you can do inside of Azure with some PowerShell scripting. In fact, you hardly see me using the Azure Portal these days.
Automation is great until manual processes are required. I have been able to automate a lot of things in Azure. One thing I struggled with was automating the process of logging into Azure. Well, I have figured it out so I wanted to share it with everyone.
Let me explain, for every single script I have I need to login to Azure in order to run them. This requires us to execute “Login-AzureRmAccount.” While this seems trivial by default it forces the following popup screen shown below.
For me, the goal of automation is the ability to have things run without human intervention. Therefore, this popup is a huge pain in the butt. I thought I had to live with this until my friend Shawn Weisfeld at SQL Saturday Houston mentioned to me that he thought this was possible to automate. We exchanged a few emails and this blog post is the result of them.
What is Azure Resource Manager?
Let’s take a step back, what is Azure Resource Manager and why should you care about it? Azure Resource Manager is the new recommended way of interacting with Azure. You can deploy, manage and monitor all of the resources for a solution inside of a resource group. This makes life so much easier than having to implement and configure each piece of your infrastructure for a deployment separately. Also, for testing purposes when you are done just delete your resource group and you will remove everything. Resource Manager is the future, and it makes our lives in Azure better. This is our hub where most of our automation will reside.
Now back to automation of the login. Azure has implemented Active Directory services. Could it be possible for us to create a user or something similar to a group-managed service to allow us to automate authentication without human intervention? This got me thinking we might be able to leverage it for automating the login process.
Let The Games Begin
Step one starts with logging in. Yes, were going to do this manually by running the code below and providing our login and password credentials. Hopefully, this will be your last time 😉
We are going to want to grab our TenatId. You should see something similar to the screenshot below with the actual values. The TenantId will be used in our final step.
Now that we are logged into the Azure Resource Manager (RM) we will start by creating our Azure RM Active Directory application. This will allow us to create a relationship that identifies an application with Active Directory.
Here we will also provide your password and display name you will use for the application entity in Active Directory. The IdentiferUris parameter is how you find this application entry as well.
$password = "<Your Password>" $azureAdApplication = New-AzureRmADApplication -DisplayName "<Your App Name>" -HomePage "https://www.contoso.org" -IdentifierUris "https://www.contoso.org/example" -Password $Password
Next, we will create a service principal for our application. This will end up being an instance of the application that needs to access other resources. We will utilize the application identifier established by our previous step.
New-AzureRmADServicePrincipal -ApplicationId $azureAdApplication.ApplicationId
Now that we have a service principal we are going to assign a role to our service principal. You can see more details on roles, in our case we are going to configure owner.
New-AzureRmRoleAssignment -RoleDefinitionName Owner -ServicePrincipalName $azureAdApplication.ApplicationId.Guid
Hopefully, by now you might be wondering some of the following things. How the heck am I using Active Directory? I have never set one up in Azure so how would I connect? What is the domain name?
Your account that you use to connect to the Azure Portal is pulled into an azure active directory when you create it. Humor me, go log in to the Azure Portal. Now take your mouse over your login in the top right corner. This should be over your login name (john.sterrett@linchpin…) in the screen shot below.
If you look at the last line it will say Domain: firstname.lastname@example.org. That is your domain name and it will be used as part of your login in our final step.
Time to pull everything together so we can now automate the process of logging in with Login-AzureRmAccount command.
First, we will need to create our credential which will consist of a login and a password. The login will be the ApplicationId unique identifier and the domain name combined together like “email@example.com” The application Id could be found in step three. We also show it if you run all the scripts together in the script below. Our password comes from step two above. We will talk about securing it a little later.
Finally, in step one when we originally connected by manually typing our username and password PowerShell outputted our tenantId. We will need this as well in as its required for us using credentials with Login-AzureRmAccount.
$azureAdApplication.ApplicationId.Guid $accountId = "<ApplicationId.Guid>" $tenantId = "<TenantId>" $login = $AccountId.ToString()+ "@<YourDomainName>.onmicrosoft.com" #Create Credentials $pass = ConvertTo-SecureString $password -AsPlainText –Force $cred = New-Object -TypeName pscredential –ArgumentList $login, $pass #Automate Future Logins Login-AzureRmAccount -Credential $cred -ServicePrincipal –TenantId $tenantId
Automating the process of logging in was difficult for me to understand at first. I know of some others who have given up. I hope this blog post makes it easier for everyone who wants to automate the process of logging into Azure Resource Manager with PowerShell.
In the process, your password is in plain text and not secured. I wanted to use Azure Key Vault as I thought it would be perfect for this. Unfortunately, you have to be logged into Azure Key Vault so it is not ideal for storing the password you need to login to Azure Resource Manager. Shawn came up with a good solution to encrypt and decrypt your password locally.