{"id":7994,"date":"2014-10-23T06:00:00","date_gmt":"2014-10-23T13:00:00","guid":{"rendered":"http:\/\/www.sapien.com\/blog\/?p=7994"},"modified":"2015-12-01T18:13:00","modified_gmt":"2015-12-02T02:13:00","slug":"saving-passwords-for-add-azureaccount","status":"publish","type":"post","link":"https:\/\/dev.sapien.com\/blog\/2014\/10\/23\/saving-passwords-for-add-azureaccount\/","title":{"rendered":"Saving Passwords for Add-AzureAccount"},"content":{"rendered":"<p>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. <\/p>\n<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- <\/p>\n<p>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 (<a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=397622\" target=\"_blank\">Get-AzurePublishSettingsFile<\/a>) and import (<a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=397624\" target=\"_blank\">Import-AzurePublishSettingsFile<\/a>) a PublishSettings file. This technique uses a management certificate with security credentials and, while it\u2019s a bit more complex, once the certificate is on the machine, you can access your Azure account in Windows PowerShell. <\/p>\n<p>You can also use Azure Active Directory (Azure AD). The <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=397618\" target=\"_blank\">Add-AzureAccount<\/a> 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. <\/p>\n<p>Until now. <\/p>\n<p>Beginning in Azure PowerShell 0.8.9, you can use the <strong>Credential <\/strong>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\u2019s easy to create an organizational ID for any account. More on that below). <\/p>\n<p>Here\u2019s the snippet for adding an Azure account to Windows PowerShell in a script. As an alternative to the equally interactive <a href=\"http:\/\/go.microsoft.com\/fwlink\/p\/?linkid=293936\" target=\"_blank\">Get-Credential<\/a> cmdlet, you use the <a href=\"http:\/\/go.microsoft.com\/fwlink\/p\/?linkid=293993\" target=\"_blank\">New-Object<\/a> 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.<\/p>\n<pre lang=\"PowerShell\">$cred = New-Object -TypeName System.Management.Automation.PSCredential ($userName, $securePassword)\r\nAdd-AzureAccount -Credential $cred<\/pre>\n<p>This is a great solution, but the instructions in <a name=\"how-to-install-and-configure-azure-powershell\"><\/a><a href=\"http:\/\/azure.microsoft.com\/en-us\/documentation\/articles\/install-configure-powershell\">How to install and configure Azure PowerShell<\/a> tell you to use plain text for both the user name and password.<\/p>\n<pre lang=\"PowerShell\">$username = \"<your_organizational_account_user_name>\"\r\n$securePassword = ConvertTo-SecureString `\r\n        -String \"<your_organizational_account_password>\" -AsPlainText -Force\r\n$cred = New-Object System.Management.Automation.PSCredential ($username, $securePassword)\r\nAdd-AzureAccount -Credential $cred<\/pre>\n<p>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. <\/p>\n<p>It\u2019s easy to do. In this code, we use the <a href=\"http:\/\/go.microsoft.com\/fwlink\/p\/?linkid=294000\" target=\"_blank\">Read-Host<\/a> cmdlet to prompt you for the password (just once). The <strong>AsSecureString<\/strong> parameter is equivalent to piping the password string that you type to the <a href=\"http:\/\/go.microsoft.com\/fwlink\/p\/?linkid=293933\" target=\"_blank\">ConvertTo-SecureString<\/a> cmdlet. The result is a secure string.<\/p>\n<pre lang=\"PowerShell\">$secure = Read-Host -AsSecureString -Prompt \"Enter your Azure organization ID password.\"<\/pre>\n<p>Next, use the <a href=\"http:\/\/go.microsoft.com\/fwlink\/p\/?linkid=293932\" target=\"_blank\">ConvertFrom-SecureString<\/a> cmdlet to convert the secure string to an encrypted string and then save it to disk.<\/p>\n<pre lang=\"PowerShell\">ConvertFrom-SecureString -SecureString $secure | Out-File -FilePath $FilePath<\/pre>\n<p>If anyone happened to peek in that file, they\u2019d see something that looks like this. <\/p>\n<blockquote>\n<pre>01000000d08c9ddf0115d1118c7a00c04fc297eb010000009b2299cb1e643949ae2af8e01153829c00000\r\n00001000000d08c9ddf0115d1118c7a00c04fc297eb010000009b2299cb1e643949ae2af8e01153829c00\r\n000000020000000000106600000001000020000000e5e552e0bc6def08bf715a2511ad26cef2a41211f28\r\n35cba161944b4f17fc017000000000e80000000020000200000008b267e1ac697b27b381925dc4cc43db6\r\na06c6f5524442e340e7b456fb9005a42200000007c829e84ebd387a803b10ca08d0c43c0df7abbc2e1067\r\n07ad21178d0b1f215084000000093ae66ef19b086d52da13b76308ee7f4910d7b70c5af1c8366db5f8be1\r\nc746c301eb88c11e4609ad4ef90a638adba7c571b739978952c165626075282e58eec6<\/pre>\n<\/blockquote>\n<p>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.<\/p>\n<pre lang=\"PowerShell\">$username = \"coadmin@myenterprise.onmicrosoft.com\"\r\n$securePassword = ConvertTo-SecureString (Get-Content -Path $FilePath)\r\n$cred = New-Object -TypeName System.Management.Automation.PSCredential ($username, $securePassword)\r\n$result = Add-AzureAccount -Credential $cred<\/pre>\n<p>This is easy and much more secure. Here\u2019s a little function that saves any password to disk as an encrypted string.<\/p>\n<pre>    <span style=\"color: #0000ff;\">function<\/span> <span style=\"color: #008080;\">Save-Password<\/span><span style=\"color: #000000;\">\r\n    {\r\n        <\/span><span style=\"color: #0000ff;\">Param<\/span><span style=\"color: #000000;\">\r\n        (\r\n            [<\/span><span style=\"color: #4682b4;\">parameter<\/span><span style=\"color: #000000;\">(Mandatory <\/span><span style=\"color: #0000ff;\">=<\/span> <span style=\"color: #8b0000;\">$true<\/span><span style=\"color: #000000;\">)]\r\n            [<\/span><span style=\"color: #0000cd;\">String<\/span><span style=\"color: #000000;\">]\r\n            <\/span><span style=\"color: #8b0000;\">$FilePath<\/span><span style=\"color: #000000;\">,\r\n            \r\n            [<\/span><span style=\"color: #4682b4;\">parameter<\/span><span style=\"color: #000000;\">(Mandatory <\/span><span style=\"color: #0000ff;\">=<\/span> <span style=\"color: #8b0000;\">$true<\/span><span style=\"color: #000000;\">)]\r\n            [<\/span><span style=\"color: #0000cd;\">Switch<\/span><span style=\"color: #000000;\">]\r\n            <\/span><span style=\"color: #8b0000;\">$PassThru<\/span><span style=\"color: #000000;\">\r\n        )\r\n        \r\n        <\/span><span style=\"color: #8b0000;\">$secure<\/span> <span style=\"color: #0000ff;\">=<\/span> <span style=\"font-weight: bold; color: #0000ff;\">Read-Host<\/span> <span style=\"color: #3399ff;\">-AsSecureString<\/span> <span style=\"color: #ff0000;\">\"Enter your Azure organization ID password.\"<\/span>\r\n        <span style=\"color: #8b0000;\">$encrypted<\/span> <span style=\"color: #0000ff;\">=<\/span> <span style=\"font-weight: bold; color: #0000ff;\">ConvertFrom-SecureString<\/span> <span style=\"color: #3399ff;\">-SecureString<\/span> <span style=\"color: #8b0000;\">$secure<\/span>\r\n        <span style=\"color: #8b0000;\">$result<\/span> <span style=\"color: #0000ff;\">=<\/span> <span style=\"font-weight: bold; color: #0000ff;\">Set-Content<\/span> <span style=\"color: #3399ff;\">-Path<\/span> <span style=\"color: #8b0000;\">$FilePath<\/span> <span style=\"color: #3399ff;\">-Value<\/span> <span style=\"color: #8b0000;\">$encrypted<\/span> <span style=\"color: #3399ff;\">-PassThru<\/span>\r\n        \r\n        <span style=\"color: #0000ff;\">if<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #0000ff;\">!<\/span><span style=\"color: #8b0000;\">$result<\/span><span style=\"color: #000000;\">)\r\n        {\r\n            <\/span><span style=\"color: #0000ff;\">throw<\/span> <span style=\"color: #ff0000;\">\"Failed to store encrypted string at $FilePath.\"<\/span><span style=\"color: #000000;\">\r\n        }\r\n        <\/span><span style=\"color: #0000ff;\">if<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #8b0000;\">$PassThru<\/span><span style=\"color: #000000;\">)\r\n        {\r\n            <\/span><span style=\"font-weight: bold; color: #c00000;\">dir<\/span> <span style=\"color: #8b0000;\">$FilePath<\/span><span style=\"color: #000000;\">\r\n        }\r\n    }<\/span><\/pre>\n<p>&nbsp;<\/p>\n<p>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 <a name=\"use-the-azure-ad-method\"><\/a>\u201cUse the Azure AD method\u201d section of <a name=\"how-to-install-and-configure-azure-powershell\"><\/a><a href=\"http:\/\/azure.microsoft.com\/en-us\/documentation\/articles\/install-configure-powershell\">How to install and configure Azure PowerShell<\/a>.<\/p>\n<p>I still haven\u2019t 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.<\/p>\n<p><i>June Blender is a technology evangelist at SAPIEN Technologies, Inc. You can reach her at <a href=\"mailto:juneb@sapien.com\">juneb@sapien.com<\/a> or follow her on Twitter at <a href=\"https:\/\/twitter.com\/juneb_get_help\">@juneb_get_help<\/a>.<\/i><\/p>\n","protected":false},"excerpt":{"rendered":"<p>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. &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- As users of Azure PowerShell know well, there [&hellip;]<\/p>\n","protected":false},"author":31,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[25],"tags":[934,28],"class_list":["post-7994","post","type-post","status-publish","format-standard","hentry","category-windows-powershell","tag-juneb","tag-powershell"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/7994","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/users\/31"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/comments?post=7994"}],"version-history":[{"count":16,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/7994\/revisions"}],"predecessor-version":[{"id":10598,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/7994\/revisions\/10598"}],"wp:attachment":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/media?parent=7994"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/categories?post=7994"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/tags?post=7994"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}