User Rating: 5 / 5

Star ActiveStar ActiveStar ActiveStar ActiveStar Active
 

One of the great features of the recent versions of Azure PowerShell is a non-interactive option for the Add-AzureAccount cmdlet. Unfortunately, the instructions tell you to save your Azure password in plain text, but there are much more secure alternatives. I explain one in this post.

——————-

As users of Azure PowerShell know well, there have always been two distinct ways of making your Azure account available to Windows PowerShell. You can download (Get-AzurePublishSettingsFile) and import (Import-AzurePublishSettingsFile) a PublishSettings file. This technique uses a management certificate with security credentials and, while it’s a bit more complex, once the certificate is on the machine, you can access your Azure account in Windows PowerShell.

You can also use Azure Active Directory (Azure AD). The Add-AzureAccount cmdlet prompts you to sign into your Azure account by popping up a sign-in window. When sign-in succeeds, information about your Azure account is saved in a subscription data file in your roaming user profile and Windows PowerShell gets an access token that it can use to access your Azure account on your behalf. This is a great strategy, except that the token expires (in about 12 hours) and the interactive sign-in prompt prevents you from using it in a script.

Until now.

Beginning in Azure PowerShell 0.8.9, you can use the Credential parameter of Add-AzureAccount to suppress the sign-in pop-up. It works only with an organizational ID (not with a Microsoft account), but it’s easy to create an organizational ID for any account. More on that below).

Here’s the snippet for adding an Azure account to Windows PowerShell in a script. As an alternative to the equally interactive Get-Credential cmdlet, you use the New-Object cmdlet to create a PSCredential object. Then, you pass it the username and a secure string form of the password of your Azure account. When you call Add-AzureAccount with the PSCredential object, it uses the credentials to sign you in so you are not prompted.

$cred = New-Object -TypeName System.Management.Automation.PSCredential ($userName, $securePassword)
Add-AzureAccount -Credential $cred

This is a great solution, but the instructions in How to install and configure Azure PowerShell tell you to use plain text for both the user name and password.

$username = "<your_organizational_account_user_name>"
$securePassword = ConvertTo-SecureString `
        -String "<your_organizational_account_password>" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ($username, $securePassword)
Add-AzureAccount -Credential $cred

This is neither secure nor necessary. Although no method is completely secure, storing a password in plain text in a text/script file on disk is downright scary. If you need to save a password on disk, at least save it in an encrypted string.

It’s easy to do. In this code, we use the Read-Host cmdlet to prompt you for the password (just once). The AsSecureString parameter is equivalent to piping the password string that you type to the ConvertTo-SecureString cmdlet. The result is a secure string.

$secure = Read-Host -AsSecureString -Prompt "Enter your Azure organization ID password."

Next, use the ConvertFrom-SecureString cmdlet to convert the secure string to an encrypted string and then save it to disk.

ConvertFrom-SecureString -SecureString $secure | Out-File -FilePath $FilePath

If anyone happened to peek in that file, they’d see something that looks like this.

01000000d08c9ddf0115d1118c7a00c04fc297eb010000009b2299cb1e643949ae2af8e01153829c00000
00001000000d08c9ddf0115d1118c7a00c04fc297eb010000009b2299cb1e643949ae2af8e01153829c00
000000020000000000106600000001000020000000e5e552e0bc6def08bf715a2511ad26cef2a41211f28
35cba161944b4f17fc017000000000e80000000020000200000008b267e1ac697b27b381925dc4cc43db6
a06c6f5524442e340e7b456fb9005a42200000007c829e84ebd387a803b10ca08d0c43c0df7abbc2e1067
07ad21178d0b1f215084000000093ae66ef19b086d52da13b76308ee7f4910d7b70c5af1c8366db5f8be1
c746c301eb88c11e4609ad4ef90a638adba7c571b739978952c165626075282e58eec6

Then, in Azure PowerShell scripts, you use almost the same code for your Add-AzureAccount command, except that you add a Get-Content command to get the encrypted string from its file.

$username = "This email address is being protected from spambots. You need JavaScript enabled to view it."
$securePassword = ConvertTo-SecureString (Get-Content -Path $FilePath)
$cred = New-Object -TypeName System.Management.Automation.PSCredential ($username, $securePassword)
$result = Add-AzureAccount -Credential $cred

This is easy and much more secure. Here’s a little function that saves any password to disk as an encrypted string.

    function Save-Password
    {
        Param
        (
            [parameter(Mandatory = $true)]
            [String]
            $FilePath,
            
            [parameter(Mandatory = $true)]
            [Switch]
            $PassThru
        )
        
        $secure = Read-Host -AsSecureString "Enter your Azure organization ID password."
        $encrypted = ConvertFrom-SecureString -SecureString $secure
        $result = Set-Content -Path $FilePath -Value $encrypted -PassThru
        
        if (!$result)
        {
            throw "Failed to store encrypted string at $FilePath."
        }
        if ($PassThru)
        {
            dir $FilePath
        }
    }

 

Now, about that organizational ID. You can create at least one organizational ID for any Azure account, even one that is secured with a Microsoft account, such as an Outlook.com account. You can find the instructions in the “Use the Azure AD method” section of How to install and configure Azure PowerShell.

I still haven’t figured out a workaround for the expiring Azure AD token, so I include an Add-AzureAccount command that gets a new token in every script. But the password is saved as an encrypted string and the user of the script is not interrupted.

June Blender is a technology evangelist at SAPIEN Technologies, Inc. You can reach her at This email address is being protected from spambots. You need JavaScript enabled to view it. or follow her on Twitter at @juneb_get_help.

If you have questions about our products, please post in our support forum.
For licensed customers, use the forum associated with your product in our Product Support Forums for Registered Customers.
For users of trial versions, please post in our Trial Software Questions forum.
Copyright © 2017 SAPIEN Technologies, Inc.