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 = "coadmin@myenterprise.onmicrosoft.com" $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 juneb@sapien.com or follow her on Twitter at @juneb_get_help.
RT @juneb_get_help: Great news in #Azure #PowerShell: Add-AzureAccount -Credential parameter allows non-interactive use in scripts. http:/…
RT @juneb_get_help: Great news in #Azure #PowerShell: Add-AzureAccount -Credential parameter allows non-interactive use in scripts. http:/…