How to Change the Default Azure RM subscription - azure

ASM had the ability to change the default subscription with the -Default (and now deprecated) parameter
Select-AzureSubscription -Default
but the ARM version
Select-AzureRMSubscription
does not have the -Default parameter.
How can I change the default ARM subscription? It is very annoying that my default is a subscription that I never use.
Edit for clarification: When I say change default subscription I mean the default subscription that you are connected to with each new PowerShell session.

Step 1: Get-AzureRmSubscription
It will List all your subscriptions.
Step 2: Select-AzureRmSubscription -SubscriptionId xxxxx-xxxxx-xxxxxx-xxxx
The SubscriptionID can be found in the output of the Get-AzureRmSubscription. You can also use the SubscriptionName.
Step 3: (Get-AzureRmContext).Subscription
Confirm that you have selected the right subscription.

I don't think there is a way, but for me I've added the following to my powershell profile:
Login-AzureRmAccount -SubscriptionName "My Subscription"
How to customize PowerShell profile

According to your requirement, I tested the following command to change my subscription on my side and I could change the subscription.
Get-AzureRmSubscription –SubscriptionName "your subscription" | Select-AzureRmSubscription
Here is my test, you could refer to it.
Note: You could find the command in this official document about Azure Resource Manager Cmdlets.

This is now resolved with Azure PowerShell version 5.
Enable-AzureRmContextAutosave
Once you run this command, every new Azure PowerShell session will default to the last context set with the
Set-AzureRMContext
command

Add-AzureRmAccount -Environment [If Needed] -Subscription "[Add Yours]" -ContextName "Default"

I have the same challenge - there does not seem to be any Cmdlet in the AzureRM module for it [version 4.2.0]:
Get-Command set-*subscription* -Module AzureRM
Subscription objects returned by Get-AzureSubscription (Azure module) are obviously different from those returned by the GetAzureRmSubscription - ie there's not a IsDefault property on the ARM-ones.
Following the mindset of 4c74356b41 you could add a less "disturbing" line in your profile:
$PSDefaultParameterValues["Login-AzureRmAccount:SubscriptionName"] = "my subscriptionName"

Two scenarios not covered is if you already have a PowerShell profile that you want to edit and if you want to change the PowerShell profile for PowerShell ISE.
The easiest way to set your subscription in ARM is to use your PowerShell profile as 4c74356b41 points out.
To find the path to your PowerShell profiles use $Profile | Format-List.
The Windows PowerShell profile is typically in ..\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
The PowerShell ISE profile is typically in ..\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1
If either are missing use New-Item -path $profile -type file –force from the ISE or PowerShell window to create an empty file.
If you want to list all PowerShell profile files with their path add the -Force switch $Profile | Format-List -Force.
If you are using a Microsoft account, such as me#outlook.com, then add this to the .ps1 file Login-AzureRmAccount -TenantId "Tenant ID" -SubscriptionId "Subscription ID". You can get a list of all Subscription and Tenant IDs using
Get-AzureRmSubscription | Format-List.
You could use APowerShell's answer also, I prefer not to use the Subscription Name parameter. It isn't uncommon for the sub name to change when you have multiple subs, the SubID and TenantID will not change.
If you are logging in using a work account like user#domain.com then you can automate the entire login and subscription selection using something like this.
$AzureAcct = "user#contoso.com"
$AzurePwd = ConvertTo-SecureString "P#s$w0rd" -AsPlainText -Force
$AzureCreds = New-Object System.Management.Automation.PSCredential($AzureAcct, $AzurePwd)
$Login-AzureRmAccount -Credential $AzureCreds -TenantId "Tenant ID" -SubscriptionId "Subscription ID"
If you only use the parameter -SubscriptionId you can get login errors if the account has been added to multiple Azure subscriptions, so it is important to use -TenantId as well.

You will hav eto use context like this Set-AzureRmContext -SubscriptionName for every session

Related

Is there any Poweshell Script or az command to get the list of Products and its Subscription IDs for API Management?

We are using the Azure API Management Product subscription id in our Front End applications and there is no track on which frontend application is using which id as the product is having multiple subscription id and the one API has multiple products attached to it.
Sometimes we need to add the header policies where the front-end developer will give us the subscription id they are using and it becomes difficult to check in the portal UI to get the name of the product from the subscription id.
Looking for a Powershell script or az command which can give the list of products with subscription id so that it will be easy and useful.
Thanks
List products: https://learn.microsoft.com/en-us/powershell/module/az.apimanagement/get-azapimanagementproduct?view=azps-5.5.0
List subscriptions: https://learn.microsoft.com/en-us/powershell/module/az.apimanagement/get-azapimanagementsubscription?view=azps-5.5.0
Get subscription key: https://learn.microsoft.com/en-us/powershell/module/az.apimanagement/get-azapimanagementsubscriptionkey?view=azps-5.5.0
APIM az reference: https://learn.microsoft.com/en-us/cli/azure/apim?view=azure-cli-latest
I do it like this. Unfortunately, I don't know yet how to extract the secret keys of the apim subscriptions, which do not appear here:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force
Connect-AzAccount
Select-AzSubscription -SubscriptionName 'my-playground'
$apimContext = New-AzApiManagementContext -ResourceGroupName "my-
playground" -ServiceName "my-apim-playground"
Get-AzApiManagementSubscription -Context $apimContext | Format-Table -
Property Name, SubscriptionId

Assign Key Vault Secrets to an Azure Function using Azure PowerShell

I am trying to automate the creation of certain azure resources via an Azure PowerShell script that is triggered from an Azure DevOps release pipeline. I want to create a function app, and automatically integrate reading right access to secrets in an already existing Key Vault. This Key Vault is in the same Azure subscription.
While I can create most resources following the documentation, there seems to be a lack of documentation regarding the creation of certain resources using Azure PowerShell (or I can't find it).
If I follow the sample from this link, I can accomplish it without a problem by using the UI in the Azure Portal, but I can't find any documentation on Microsoft Docs to do it using PowerShell.
Write-Host "Creating Function App..."
$fnApp = New-AzFunctionApp -Name $functionAppName `
-ResourceGroupName $emailFunctionRg `
-Location "$(AzureRegion)" `
-StorageAccount $storageName `
-Runtime dotnet `
-FunctionsVersion '3' `
-IdentityType SystemAssigned
Write-Host "Function App created!"
Write-Host "Assigning Key Vault access..."
$appId = Get-AzADServicePrincipal -DisplayName $functionAppName
Set-AzKeyVaultAccessPolicy -VaultName EmailSettings -ServicePrincipalName $appId -PermissionsToSecrets Get,List
Write-Host "Key Vault access granted!"
Running Set-AzKeyVaultAccessPolicy fails with "Insufficient privileges to complete the operation.". But I am not sure if this is the right path to follow, it was just a guess, based on the available functions in the documentation.
Any ideas?
Two potential issues to check out here:
your app creation assigns the result to $fnApp. perhaps $fnApp or as commented above, $fnApp.ApplicationId is what you should be using for the -ServicePrincipalName parameter on the access policy grant.
you don't have privileges to assign RBAC roles. Go to the Key Vault, choose Access Control, then click the Role Assignments tab and verify that your user appears in the list as an Administrator, User Access Administrator, or Owner.
Edit: With respect to the RBAC privilege, since this is running in Azure Powershell from Azure DevOps, you need to check the role assignment for the Service Connection's service principal - under Azure Active Directory in the Azure Portal, look up the principal used to create the service connection, and make sure THAT gets the correct Role on the key vault.
After a little of trial and error I just came to the conclusion I was not using the right parameter for the Set-AzKeyVaultAccessPolicy cmdlet.
The following script will work (if the service principle running it has the appropriate role, like WaitingForGuacamole mentioned in his/her answer):
Write-Host "Creating Function App..."
$fnApp = New-AzFunctionApp -Name <FnAppName> `
-ResourceGroupName <ResourceGroupName> `
-Location <AzureRegion> `
-StorageAccount <StorageAccount> `
-Runtime dotnet `
-FunctionsVersion '3' `
-IdentityType SystemAssigned
Write-Host "Function App created!"
Write-Host "Assigning Key Vault access..."
Set-AzKeyVaultAccessPolicy -VaultName <NameOfTheKeyVault> -ObjectId (Get-AzADServicePrincipal -DisplayName <FnAppName>).Id -PermissionsToSecrets <Get, List, etc...>
Write-Host "Key Vault access granted!"

Azure storage account key updation using RM module

I am trying to setup a powershell code which would update the storage account credentials every once in a while and below is the script that I have come across and it works perfectly fine.
function setupContext(){
Add-AzureRmAccount
Save-AzureRmContext -Path “path\to\json\file”
}
#setupContext
Import-AzureRmContext -Path “path\to\json\file”
$subscriptionId='***********************************'
Select-AzureRMSubscription -SubscriptionId $subscriptionId -WarningAction SilentlyContinue
$resourceGroup="**************"
$storageAccountName="******************"
$BLOBKey= New-AzureRmStorageAccountKey -ResourceGroupName $resourceGroup -Name $storageAccountName -KeyName key2
Write-Host "BLOB Key:"$BLOBKey.Keys[0]
The above code does the required work, however it requires us to login to the azure-rm account which basically defeats the idea of automating this process since I would need keep updating this generated profile.
Note: I am not allowed to use az module as of now since the environment in which I work has some .NET version limitations.
So if there any other solution which could overcome the azure rm login issue, please suggest.
Use Azure Automation. This automatically sets up something called RunAs account. Which simply said is just Azure AD Service Principal.
Then assign this principal privileges on the storage account just like any other user and you are done.
And in the Automation Runbook do
$connection = Get-AutomationConnection -Name AzureRunAsConnection
Connect-AzureRmAccount `
-ServicePrincipal `
-Tenant $connection.TenantID `
-ApplicationID $connection.ApplicationID `
-CertificateThumbprint $connection.CertificateThumbprint
$AzureContext = Select-AzureRmSubscription -SubscriptionId $connection.SubscriptionID
... run rest of the code ...
If you want to run this from outside of Azure like on-prem server then set up manually service principal. Here is guide
https://learn.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal
And just log into this app from powershell instead of the user.
Looks you want to use a non-interactive way to do that automatically. To access the azure resource with a non-interactive way, your best option currently is to use the service principal(AD App).
An Azure service principal is an identity created for use with applications, hosted services, and automated tools to access Azure resources.
The other reply is for azure automation runbook, you could follow my steps to automate it in other places else.
1.Create an Azure Active Directory application and create a secret for the app, save the secret and get values for signing in.
2.Navigate to the storage account(or the subscription which the storage account located) in the portal -> Access control (IAM) -> Add -> Add role assignment -> search your service principal(AD App) with name and add it as a role(e.g. Owner/Contributor) -> Save.
Note: To give the role, you need to use an account which is an Owner of the specific scope(storage account/subscription).
3.Then use the script as below, replace the specific properties with the values in step 1.
function setupContext(){
$azureAplicationId ="<application id>"
$azureTenantId= "<tenant id>"
$azurePassword = ConvertTo-SecureString "<client secret>" -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($azureAplicationId , $azurePassword)
Add-AzureRmAccount -Credential $psCred -TenantId $azureTenantId -ServicePrincipal
Save-AzureRmContext -Path “path\to\json\file”
}
#setupContext
Import-AzureRmContext -Path “path\to\json\file”
$subscriptionId='***********************************'
Select-AzureRMSubscription -SubscriptionId $subscriptionId -WarningAction SilentlyContinue
$resourceGroup="**************"
$storageAccountName="******************"
$BLOBKey= New-AzureRmStorageAccountKey -ResourceGroupName $resourceGroup -Name $storageAccountName -KeyName key2
Write-Host "BLOB Key:"$BLOBKey.Keys[0]
Besides, if you want to learn more about the service principal, you could take a look at this link - Application and service principal objects in Azure Active Directory

Set-AzContext works in Azure Cloud Shell but doesn't in Azure PowerShell

When i execute following command
Clear-AzureProfile
Connect-AzAccount -TenantID xxxxxxxxxxxxxxxxxxx
Set-AzContext -SubscriptionId xxxxxxxxxxxxxxxxxxx
in Azure PowerShell i get this error.
Set-AzContext : Please provide a valid tenant or a valid subscription.
At line:6 char:1
+ Set-AzContext -SubscriptionId xxxxxxxxxxxxxxxxxxx
and if i run the same command in Azure Cloud Shell it works
Name Account SubscriptionName Environment TenantId
xxxx xxxxxxx xxxx xxxx xxxx
I switched from free-trial to pay-as-you-go subscription and using credentials for pay-as-you-go in both environment but it doesn't work. can anyone help
Close your powershell and open a new one, or use Clear-AzContext, not Clear-AzureProfile. Then use Connect-AzAccount -Tenant xxxxx -Subscription xxxxx, it should work.
If you are cycling through subscriptions in the same tenant and don't want to have to sign in with Connect-AzAccount multiple times, the following worked for me to switch between subscriptions:
Remove-AzContext -InputObject (Get-AzContext) -Force | Out-Null;
$sub = Set-AzContext -Subscription $_.SubscriptionName;
Before adding the Remove-AzContext statement I was seeing that Set-AzContext was not actually switching the context to another subscription for some reason.
I used to have this problem too, and my solution was different that one provided on top of this.
Apparently, in our Azure Cloud Shell, we have several contexts available, so, we don't have to set the context (using Set-AzContext), but to switch to one or other context, using Select-AzContext)
I can list the contexts using
Get-AzContext -ListAvailable
Then choose one using the
Select-AzContext -Name ...
For-example, in scripts, I use this one-line command to switch to the subscription having ID $SubscriptionID :
Select-AzContext -name ((Get-AzContext -ListAvailable).Name -match $SubscriptionId)[0]
Not elegant, but efficient
I don't know why we are in such situation. Maybe because we are administrating using invited accounts from another tenant.
Hope this help someone in same situation than us.

How to find the current Azure RM Subscription

In Azure Classic / Service Management, Get-AzureSubscription would give a list of subscriptions in the Tenant with an indicator of which was current.
There was also a Get-AzureSubscription -Current flag that would give you just the current subscription.
Is there a way to find the current subscription in AzureRM.Profile?
Get-AzureRmContext gives you info about the selected subscription, default storage account, etc.
(Get-AzureRmContext).Subscription gives you the current subscription.
Now you can use the new Az commands
Get-AzContext
You can also use Get-AzureRmSubscription
$sub = Get-AzureRmSubscription
$sub.SubscriptionId
This will give you the SubscriptionId

Resources