List all my Azure websites using an Azure Powershell Function - powershell

Im testing the new Azure Functions, and would like to write a function that return all my Azure Websites. But needless to say I run into some problems, and documantation is still minimal.
run.ps1
# Get the input request
$in = Get-Content $req -Raw | ConvertFrom-Json
Write-Output "Loading..."
Get-AzureRmSubscription -SubscriptionId $in.SubscriptionId | Select-AzureRmSubscription
$Result = Get-AzureWebsite
Write $Result
This function take the subscription id as a parameter, and is supposed to list the available websites. But I get this exception.
2017-06-13T12:43:57.763 Get-AzureRmSubscription : Run Login-AzureRmAccount to login.
So I tried to add Login-AzureRmAccount but then I get.
2017-06-13T12:45:04.959 Login-AzureRmAccount : Error HRESULT E_FAIL has been returned from a call to a COM component.
And that is where I stand now.
Update
After help from #4c74356b41 I now am able to login. My code for logging in looks like this.
$subscriptionId = "<SubscriptionId>"
$tenantid = "<TenantId>"
$clientid = "<ApplicationId>"
$password = "<Password>"
$userPassword = ConvertTo-SecureString -String $password -AsPlainText -Force
$userCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $clientid, $userPassword
Add-AzureRmAccount -TenantId $tenantid -ServicePrincipal -SubscriptionId $subscriptionId -Credential $userCredential
I can see that this work when I test the code. But as soon as I add this line.
Select-AzureSubscription -Current -SubscriptionId $subscriptionId
I get this exception.
Select-AzureSubscription : The subscription id <SubscriptionId> doesn't exist.
Parameternavn: id
At line:11 char:1
+ Select-AzureSubscription -Current -SubscriptionId $subscriptionId
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Select-AzureSubscription], ArgumentException
+ FullyQualifiedErrorId : Microsoft.WindowsAzure.Commands.Profile.SelectAzureSubscriptionCommand
I also tried to add this line.
Get-AzureRmSubscription –SubscriptionId $subscriptionId | Select-AzureRmSubscription
Which look like is working, it only thows a warning WARNING: Unable to acquire token for tenant 'Common' but still list the correct subscription details without any exceptions.
Then when I try
Get-AzureWebsite
I get this exception.
Get-AzureWebsite : No default subscription has been designated. Use Select-AzureSubscription -Default <subscriptionName> to set the default subscription.
At line:15 char:1
+ Get-AzureWebsite
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Get-AzureWebsite], ApplicationException
+ FullyQualifiedErrorId : Microsoft.WindowsAzure.Commands.Websites.GetAzureWebsiteCommand

Well, how do you expect to work with your subscription without authenticating? would you like anybody to be able to modify your resources without any validation at all? so you need to authenticate before doing anything.
Working with powershell in Azure Function is no different from working with powershell on your machine (except module management).
To login you could use service principal auth ang login with something like:
Add-AzureRmAccount -TenantId $tenantid -ServicePrincipal -SubscriptionName $name `
-Credential ([pscredential]::new($clientid,(ConvertTo-SecureString -String $password -AsPlainText -Force)))
you can replace variables (hardcoded in the code) with environment variables.

Add 4c74356b41's answer, Get-AzureWebsite is an Azure Classic mode cmdlet. Now, you login your ARM subscription, so, it requires you login classic subscription. Select-AzureSubscription is a classic cmdlet that use to select classic subscription.
In Azure ARM mode, website is renamed Webapp, you could check Azure App Service announcement.
So, if you want to list your all webapp, you should use cmdlet Get-AzureRmWebApp.
More information please refer to this link: Using Azure Resource Manager-Based PowerShell to Manage Azure Web Apps.

Related

Set-AzureRmContext error when executed within an Azure Automation Runbook

Update:
Seems like someone else had the same issue and reported it.
I am facing an issue with a simple PowerShell script when invoking it from an Azure Automation Runbook. The same piece of code works flawless when running it locally.
I have added a Service Principal in an Azure Active Directory (hosted in Azure German Cloud) with password credential and grant it contributor access to a subscription (also hosted in Azure German Cloud).
The Azure Automation service is hosted in North Europe since it's currently not available in the Azure German Cloud.
All I try to do is to login to my subscription with the above mentioned principal using the Add-AzureRmAccount cmdlet. After that I try to set the current context using the Set-AzureRmContext and getting the following error message:
Set-AzureRmContext : Please provide a valid tenant or a valid subscription.
At line:26 char:1
+ Set-AzureRmContext -TenantId $TenantId -Su ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Set-AzureRmContext], ArgumentException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Profile.SetAzureRMContextCommand
Here is the script I try to run (left the configuration blank):
$TenantId = ""
$ApplicationId = ""
$ClientSecret = ""
$SubscriptionId = ""
$secpasswd = ConvertTo-SecureString $ClientSecret -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ($ApplicationId , $secpasswd)
Add-AzureRmAccount -ServicePrincipal -Environment 'AzureGermanCloud' -Credential $mycreds -TenantId $TenantId
Set-AzureRmContext -TenantId $TenantId -SubscriptionId $SubscriptionId
I also tried to use Login-AzureRmAccount without success. Also I am able to use the Get-AzureRmResourceGroup cmdlet to retrieve the resource groups so the login seems to work.
All Azure modules are updated to the latest version.
TLTR:
My main goal is to start a SQL export job using the New-AzureRmSqlDatabaseExport from the runnbook but it seems like the above mentioned error causes the cmdlet to fail with the following message:
New-AzureRmSqlDatabaseExport : Your Azure credentials have not been set up or have expired, please run
Login-AzureRMAccount to set up your Azure credentials.
At line:77 char:18
+ ... rtRequest = New-AzureRmSqlDatabaseExport -ResourceGroupName $Resource
I had the same issue a few weeks ago and what worked was to first login to Azure account (which I think you already did) using:
Login-AzureRmAccount
Then get the subscription ID from Azure and use select the subscription using the ID instead of the name as follows:
Select-AzureRmSubscription -SubscriptionId {insert-subscription-id}
Below is the code that worked for me (regular dc regions). If it doesn't work, go to the Automation Account >> Modules >> Update Azure Modules.
$ClientSecret = ""
$ApplicationId = ""
$SubscriptionId = ""
#New PSCredential Object
$secpasswd = ConvertTo-SecureString $ClientSecret -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ($ApplicationId , $secpasswd)
#Login to subscription
Login-AzureRmAccount -Credential $mycreds -SubscriptionId $SubscriptionId
#Export Database
New-AzureRmSqlDatabaseExport -ResourceGroupName "<RG>" -ServerName "<SQLSERVERNAME>" -DatabaseName "<DATABASENAME>" -StorageKeyType "StorageAccessKey" -StorageKey "<STRKEY>" -StorageUri "<URITOFILE>" -AdministratorLogin "<DBLOGIN>" -AdministratorLoginPassword "<DBPASS>"
Update
Maybe running with a Run As Account can be a workaround for the issue. Create one by navigating to the Azure Automation Account >> Account Settings >> Run As Accounts. Here's an example code.
# Authenticate to Azure with service principal and certificate, and set subscription
$connectionAssetName = "AzureRunAsConnection"
$conn = Get-AutomationConnection -Name $ConnectionAssetName
Add-AzureRmAccount -ServicePrincipal -Tenant $conn.TenantID -ApplicationId $conn.ApplicationId -CertificateThumbprint $conn.CertificateThumbprint -ErrorAction Stop | Write-Verbose
Set-AzureRmContext -SubscriptionId $conn.SubscriptionId -ErrorAction Stop | Write-Verbose
It looks like this is a known issue and I wasn't able to find a fix for that. But there are two workarounds:
Using a Hybrid Runnbook Worker (mentioned by Walter - MSFT)
Using a RunAsAccount with certificate credentials (mentioned by Bruno Faria)
It is important to specify the -Environment parameter. Otherwise I got the following exception:
Login-AzureRmAccount : AADSTS90038: Confidential Client is not
supported in Cross Cloud request.
Here is the code I am using to login to AzureGermanCloud (MCD) from an Azure Runbook hosted in NorthEurope:
$connectionAssetName = "AzureRunAsConnection"
$conn = Get-AutomationConnection -Name $ConnectionAssetName
Login-AzureRmAccount `
-ServicePrincipal `
-CertificateThumbprint $conn.CertificateThumbprint `
-ApplicationId $conn.ApplicationId `
-TenantId $conn.TenantID `
-Environment AzureGermanCloud
When you login your Azure account, you could use specified subscription id. You could try following script.
$subscriptionId=""
$tenantid=""
$clientid=""
$password=""
$userPassword = ConvertTo-SecureString -String $password -AsPlainText -Force
$userCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $clientid, $userPassword
Add-AzureRmAccount -TenantId $tenantid -ServicePrincipal -SubscriptionId $subscriptionId -Credential $userCredential -Environment 'AzureGermanCloud'

Add-AzureRmAccount : Sequence contains no element (Not working for Gmail accounts too)

I have created a 'Free Trial' account with my personal email ID which is a Gmail ID. I'm getting the error :
Add-AzureRmAccount : Sequence contains no elements At line:1 char:1
+ Add-AzureRmAccount -Credential $cred
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Add-AzureRmAccount], AadAuthenticationFailedException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Profile.AddAzureRMAccountCommand
The code I'm running is
$username = "abc#gmail.com"
$password = "something"
$secpass = $password | ConvertTo-SecureString -AsPlainText -Force
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $secpass
Add-AzureRmAccount -Credential $cred
Are there certain type of accounts/subscriptions for which logging in like this is supposed to work?
Windows Live ID credentials cannot be used for a non-interactive login. This error message is described as part of this issue which has been raised because it needs improving.
I think you either need to use Login-AzureRmAccount to login interactively or create a Service Principal for login, per this guide: https://learn.microsoft.com/en-us/powershell/azure/authenticate-azureps?view=azurermps-4.2.0
Log in with a service principal
Service principals provide a way for you to create non-interactive
accounts that you can use to manipulate resources. Service principals
are like user accounts to which you can apply rules using Azure Active
Directory. By granting the minimum permissions needed to a service
principal, you can ensure your automation scripts are even more
secure.
If you don't already have a service principal, create one.
Log in with the service principal:
Login-AzureRmAccount -ServicePrincipal -ApplicationId "http://my-app" -Credential $pscredential -TenantId $tenantid

Why does Azure Powershell script think I'm not logged-in?

I'm building an Azure Powershell script to add a DB firewall rule.
I first of all login using Add-AzureRmAccount:
$userName = "j---#s---.--"
$securePassword = ConvertTo-SecureString -String "---------" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($userName, $securePassword)
Add-AzureRmAccount -Credential $cred
This returns the following, which I assume means that I have successfully logged-in:
Environment : AzureCloud
Account : j---#s---.--
TenantId : [GUID]
SubscriptionId : [GUID]
SubscriptionName : Visual Studio Ultimate mit MSDN
CurrentStorageAccount :
At this stage I can query for my subscription:
Get-AzureRmSubscription –SubscriptionName "Visual Studio Ultimate mit MSDN" | Select-AzureRmSubscription
Which returns
Account : j---#s---.--
Environment : AzureCloud
Subscription : [GUID]
Tenant : [GUID]
So far, so good.
However, whenever the script calls anything at the resource-group level, such as
Find-AzureRmResource -ResourceNameContains "-----NorthEurope"
then it responds with
Run Login-AzureRmAccount to login.
The exception detail is
+ CategoryInfo : InvalidOperation: (:) [Find-AzureRmResource], PSInvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.FindAzureResourceCmdlet
Which doesn't help me at all.
I've even explicitly called
Login-AzureRmAccount $cred
prior to the Find-AzureRmResource call, but this makes no difference.
Of course, what I'm ultimately looking to do is call
New-AzureRmSqlServerFirewallRule -ResourceGroupName "-----NorthEurope" `
-ServerName "-----.database.windows.net" `
-FirewallRuleName "test1" `
-StartIpAddress "-.-.-.-" `
-EndIpAddress "-.-.-.-"
But that encounters the same exception.
Can anyone explain why I keep getting asked to run Login-AzureRmAccount after I've apparently successfully added the account?
Solution
What got it working for me, as #Tomer alluded to in the comments, was to forcefully re-get all AzureRm modules.

Running Set-AzureRmAppServicePlan from Automation script (RunBook)

I'm trying to run Set-AzureRmAppServicePlan from automation runbook but getting
Set-AzureRmAppServicePlan : Run Login-AzureRmAccount to login. At
line:20 char:1
+ Set-AzureRmAppServicePlan -ResourceGroupName "...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Set-AzureRMAppServicePlan], PSInvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.Azure.Commands.WebApps.Cmdlets.AppServicePlans.SetAzureAppServicePlanCmdlet
Note that actual runbook authentication using Automation Credential is successful.
And I can run this script from local powershell using
Login-AzureRmAccount
Add-AzureRmAccount
Set-AzureRmAppServicePlan...
Is it possible at all to run this from automation without interactive login?
Thanks
Pavel
figure it out.. pretty simple instead of
Add-AzureAccount - which is used in sample runbook Get-AzureVMTutorial created automatically
need to use
Add-AzureRmAccount
for use with Azure Resource Manager cmdlet requests like
Set-AzureRmAppServicePlan
Leaving question / answer here.. might still help someone
If you are not using MFA, pls see the following cmds, replace 'yourPassword', 'yourUserName', 'yourEnvironment', 'yourSubscriptionId', 'yourTenantId' with your own message and put it to your script then you can login without interactive page.
$userPassword = ConvertTo-SecureString -String "yourPassword" -AsPlainText -Force
$psCred = new-object -typename System.Management.Automation.PSCredential -argumentlist 'yourUserName', $userPassword
$credential = Get-Credential -Credential $psCred
add-azureRmAccount -EnvironmentName 'yourEnvironment' -credential $credential -subscriptionId 'yourSubscriptionId' -tenant 'yourTenantId'

Azure PowerShell automation "no default subscritpion has been designated"

I am getting the following error. I am in fact setting the default subscription name.
4/27/2015 10:28:28 AM, Error: Get-AzureVM : No default subscription
has been designated. Use Select-AzureSubscription -Default
to set the default subscription. At test:9 char:9
+
+ CategoryInfo : CloseError: (:) [Get-AzureVM], ApplicationException
+ FullyQualifiedErrorId : Microsoft.WindowsAzure.Commands.ServiceManagement.IaaS.GetAzureVMCommand
Here is my code:
workflow test
{
# Initial set up
$Cred = Get-AutomationPSCredential -Name "******"
Add-AzureAccount -Credential $Cred
Select-AzureSubscription -Default -SubscriptionName 'Beebunny'
$vmName = "MyMachineName"
Get-AzureVM -servicename $vmName
Write-output "All done."
}
If I try Select-AzureSubscription -Default 'SubscriptionName' it throws an error saying the syntax is invalid.
Edit: I have also tried Select-AzureSubscription -SubscriptionName 'SubscriptionName' without the Default flag.
Funny thing is that if I run this in AzurePS directly from Windows, it runs just fine. I am about 95% sure this is an Azure bug but wanted to get a second opinion first.
What version of the Azure module do you have loaded? Are you using the default module provided by the Automation service? Also, have you imported any other modules to this subscription?
Try creating a clean runbook with the following code, replacing the credential and subscription with the proper names. Can you get the credential and authenticate successfully?
workflow Test-GetVM
{
$Cred = Get-AutomationPSCredential -Name 'AdAzureCred'
if(!$Cred) {
Throw "Could not find an Automation Credential Asset named. Make sure you have created one in this Automation Account."
}
$Account = Add-AzureAccount -Credential $Cred
if(!$Account) {
Throw "Could not authenticate to Azure. Make sure the user name and password are correct."
}
Select-AzureSubscription -SubscriptionName "Visual Studio Ultimate with MSDN"
Get-AzureVM
}
UPDATE: Do you have the Resource Manager module loaded to the subscription as well?
I had the same problem and the solution was execute Add-AzureAccount, do the login process requested and once done all was working.