FIX: Get-AzContext missing ‘subscription’ Az.Accounts PowerShell

Get-AzContext missing a ‘subscription’ while using Set-AzContext

We use the command below as standard in our scripts, but I have also discovered that this is not entirely useful.

$null = Get-AzContext -ListAvailable | Where-Object {$_.Name -match $SubscriptionName} | Set-AzContext

But for more about that you should go to another section on this blog (see the Table of Contents).

You probably found this blog cause of an error message:

Set-AzContext: Please provide a valid tenant or a valid subscription.

$SubscriptionName = 'MSDN_2'
Set-AzContext -SubscriptionName $SubscriptionName

Set-AzContext: Please provide a valid tenant or a valid subscription.

I have selected the Azure contexts that I tried to select via Set-AzContext more than once, so it is strange that I suddenly couldn’t do this anymore and that the Context itself disappeared from the list that you can see via Get-AzContext.

You can add it again via the steps below.


Let’s re-add the subscription to your AzContext!

To return to the Set-AzContext that cannot find a tenant or subscription, the subscription is no longer listed in my Get-AzContext -ListAvailable.

Get-AzContext -ListAvailable

Name                                     Account                                                               
-------                                  -------       
MSDN (00000000-0000-0000-0000-0000000) [email protected]

But Get-AzSubscription still showed the subscription I need:

Get-AzSubscription

Name   Id                                  
----   --                                  
MSDN   00000000-0000-0000-0000-000000000000
MSDN_2 00000000-0000-0000-0000-000000000000

By selecting a subscription in the current context with Select-AzSubscription, you remain in the context you are logged in and the subscription is adjusted based on the context itself.

By running the command below:

Select-AzSubscription -SubscriptionName $SubscriptionName

Unfortunately, there is not much documentation about Select-AzSubscription and it looks like as if Set-AzContext is the new cmdlet you should use.
We used Select-AzureSubscription from the previous Azure module version which is legacy nowadays.

A context is shown again with the subscription:

Get-AzContext -ListAvailable

Name                                     Account                                                               
-------                                  -------       
MSDN (00000000-0000-0000-0000-0000000) [email protected]
MSDN_2 (00000000-0000-0000-0000-000... [email protected]

Yup, that should be it!


Difference between Set-AzSubscription and Set-AzContext

In Azure PowerShell, both Set-AzContext and Set-AzSubscription are used to set the current context or subscription, but they serve different purposes:

  1. Set-AzContext:
  • Purpose: Changes the current context in Azure PowerShell.
  • Context: In Azure, a context is a combination of a subscription, tenant, and environment. It represents the identity and environment under which Azure PowerShell commands are executed.
  • Usage:
    powershell Set-AzContext -SubscriptionId <SubscriptionName>
  • Note: This cmdlet allows you to set the entire context, including the subscription, tenant, and environment.
  1. Select-AzSubscription:
  • Purpose: Changes the current subscription.
  • Subscription: In Azure, a subscription is a logical container used to provision and manage resources. Each subscription can have its own billing, resource limits, and policies.
  • Usage:
    powershell Select-AzSubscription -SubscriptionName <SubscriptionName>
  • Note: This cmdlet specifically sets the active subscription without changing the other aspects of the context.

In summary:

  • If you want to change the entire context, including the subscription, tenant, and environment, you use Set-AzContext.
  • If you only want to switch the active subscription within the current context, you use Select-AzSubscription.

It’s worth noting that if you set the subscription using Select-AzSubscription, it does not change the Azure environment or tenant associated with the context; it only changes the active subscription within the current context.

If you need to switch the entire context, including the environment and tenant, you should use Set-AzContext.

For more about Azure Contexts, I’d like to refer you to:
Azure contexts and sign-in credentials | Microsoft Learn


Why I didn’t get an error using Set-AzContext after pipeline output

We mainly used the cmdlet below in our runbooks.

We first check whether there is an existing context, and if so, whether it matches the subscription we need and then select the correct Context via Set-AzContext.

$null = Get-AzContext -ListAvailable | Where-Object {$_.Name -match $SubscriptionName} | Set-AzContext

When we analyze the above, it becomes clear to me why this is not correct.

What we do first is check if there are any existing contexts. A context is created when logging in for the first time via Connect-AzAccount because it simply selects the first subscription with the default settings.

As a result, there is always 1 context.

The Azure Automation environments we use only have access to the subscription they are in, so the subscription name always matches the context that selects the first one.

But why doesn’t this work on our local devices (development), but it seems to work, causing you to get strange error messages in your scripts? Why does it not error out to: Set-AzContext: Please provide a valid tenant or a valid subscription. or Set-AzContext: Cannot bind argument to parameter ‘context’ because it is null?

The Where-Object contains no output, but it does create a PSObject:

$WhereObject = (Get-AzContext -ListAvailable | Where-Object {$_.Name -eq $SubscriptionName})
$WhereObject.PSObject

Members             : {ToString, GetType, Equals, GetHashCode}
Properties          : {}
Methods             : {ToString, GetType, Equals, GetHashCode}
ImmediateBaseObject : 
BaseObject          : 
TypeNames           : {System.Management.Automation.PSCustomObject, System.Object}

Instead of using Get-AzContext -ListAvailable we could use $null and it would still work.

So, why we do not get an error I’m not 100% sure, but it has something to do with the Where-Object as things like this also ‘work’ even without an error message:

$null | Where-Object {$_.Name -eq "MyName"} | Set-Service -ErrorAction Stop

So, never use a Where-Object with things like this as you do not know if it did something.
Another reason not to use pipelines in commands.

Use cases I can think of are more of the type ‘if not all of them are $true, then set them $true‘.


Cmdlet Resources

Published by

Bas Wijdenes

My name is Bas Wijdenes and I work as a PowerShell DevOps Engineer. In my spare time I write about interesting stuff that I encounter during my work.

Leave a Reply

Your email address will not be published. Required fields are marked *