Azure / azure-powershell

Microsoft Azure PowerShell
Other
4.25k stars 3.84k forks source link

Make it easier to work across all subscriptions a logged in user has access to under the user context #6550

Open kilasuit opened 6 years ago

kilasuit commented 6 years ago

With having more than a small handful of subscriptions you soon have requirements to be able to work across all of them at ease. In the portal we are able to just see all things and not have to log into the subscription to be able to work with it.

Can the login/subscription management be overhauled to be based in the same manner as the portal as per #6549 when you have multiple subscriptions changing subscription context is not only time consuming but adds excess required code and looping within Subscriptions to be able to do some of the same tasks that you can do in the Portal.

Ideally using a context that has access to 2+ subscriptions should be able to call back all resources in those subsciptions without needing to explictly change the subscription individually.

However there should be logic implemented that would allow to be able to choose subscriptions to include/exclude under a context, something that I can manage to do very easily in the portal by choosing which subscriptions I want to query against and which ones I don't want to. This could be inplemented simple -ExcludeSubscription or -IncludeSubcription parameter.

cormacpayne commented 6 years ago

@kilasuit Hey Ryan, thanks for the feedback 😀 we will need to have some internal discussions about how to properly implement this, and then roll out some experimental modules with the change to get additional feedback.

A couple of questions for you:

kilasuit commented 6 years ago

Hey @cormacpayne

I some how missed this response but having a switch parameter to include all subscriptions would be good, however it would also be good to be able to just sign into azure at the tenant level, not subscription level like this is currently set to be, and be able to run commands from tenant down as opposed to being forced into a subscription.

My reason for this is that I currently manage an estate where we separate all our regions into subscriptions and regularly need to get an overview across the whole estate which is sometimes easier to do things in the portal, and suffer the lag of it, than pull it back via PowerShell, which seems backwards to me.

However I do also think that this would be still useful to keep the ability to switch into a subscription when you want to manage just that subscription as well, so that's not something that I think should change.

Hopefully the additional info helps :-)

lanrongwen commented 6 years ago

The current paradigm of having to switch sub contexts is very slow and clunky when you're working with multiple subs. Our scans/updates take much longer than they should. We do the equivalent in rest much faster because it doesn't care about the context.

I would recommend making all the cmdlets accept either a -subscription/id/name. Then one could get a list of subs they want to look at, and pass them in to the cmdlets without having to track/switching context. If subscription isn't passed in, they should query all available subs to that user.

I would also recommend they all must accept an optional -resourceid. That way a user can jump straight to the resource directly. I'm surprised how often we know the exact resource id but can't work on it directly because we have to first "get-" the resource using select-azureadsubscription, then a get with the resource group and resource name... (For instance, getting a NIC from a VM, as the vm list the id, but get-azurermnetworkinterface doesn't accept the ID as input.)

For Backwards compatibility, let a user optionally set a context. Otherwise got to the all sub model.

These two changes together I think would make a much easier/faster experience for users, especially those with multiple subscriptions.

lanrongwen commented 6 years ago

I would also say, adding it to get alone helps but doesn't fix the problem. Most the time we are looking so we can actively make changes, and context switching in the middle of a scan would still be a lot of extra work...

kilasuit commented 6 years ago

Hey @cormacpayne, do you know if there is any update on this at all?

cormacpayne commented 6 years ago

@kilasuit Hey Ryan, we haven't made any progress on this item yet -- our focus since May has been on engineering tasks and preparing the new Az module built for .NET Standard. Once this module is out (and fine-tuned 😀), we will turn our attention to items in the backlog (such as this) and prioritizing them. We'll make sure to update this issue appropriately during our upcoming planning.

kilasuit commented 5 years ago

@cormacpayne / @sphibbs - any updates on this at all?

sphibbs commented 5 years ago

We have begun design discussions for how we'd handle running cmds across multiple subscriptions. We will also be adding subscriptionid and resourceid parameters to cmds where it makes sense.

kilasuit commented 5 years ago

@sphibbs that sounds like a good start but would this be possible to move these calls to being tenant level by default and then allowing subscriptionID & SubscriptionName as parameters so I could do a series of PowerShell commands like the below

Get all Vm's with APP* in the name across all subscriptions in the tenant

Get-AzVM *APP

or

Get all Vm's with APP* in the name in the Dev Subscription

Get-AzVM *APP -SubscriptionName Dev
markcowl commented 5 years ago

I think that by default, at least for Get-* cmdlets, -Subscription should take a list of subscriptions. This would enable users to use PSDefaultParameterValues to define a default subscription set.

Get-AzVM -Subscription "Sub1", "Sub2", "Sub3" *App

or

$PSDefaultParameterValues= @{"Get-Az*:Subscription"={@('Sub1', 'Sub2', 'Sub3')}}
Get-AzVM *App

We would then need to consider the default behavior when subscription isn't provided. For example, whether to continue defaulting to the current context and allow selecting multiple subscriptions in a context

Select-AzContext -Subscription 'sub1', 'sub2', 'sub3' 

and then whether the selected context after login should allow access to all available subscriptions in the tenant by default (which would be a big breaking change, but would make us parallel with the portal), or just have this as an option (for example, allowing the -Subscription parameter in login to take a list, or providing a -AllSubscriptions switch)

Connect-AzAccount -Subscription 'Sub1', 'Sub2', 'Sub3'
Connect-AzAccount -AllSubscriptions

I think I favor just selecting all subscriptions by default, because for new users, it is the most like the thing that is most familiar to them (the portal).

In any case, I think we would still need a 'default' subscription for modification cmdlets - it would be surprising to create a resource group across multiple subscriptions, for example, unless I explicitly specified which ones.

I also wonder whether, for cmdlets that make modifications if we need the ability to specify multiple subscriptions, or if accepting resources from the pipeline takes care of this, as long as Gets allow returning resources across subscriptions. In some cases (role assignment, policy assignments), it would be a use case to apply subscription-wide policies across multiple subscriptions.

markcowl commented 5 years ago

Generally, we like using -Subscription which can accept either names or IDs, rather than explicitly using SubscriptionName and SubscriptionId as separate parameters, but I wonder if you find being explicit about this helpful, or at least providing parameter aliases from SubscriptionName -> Subscription and SubscriptionId -> Subscription to point users in the right direction.

markcowl commented 5 years ago

BTW, right now, this can be done somewhat awkwardly using the -DefaultProfile parameter

Get-AzContext -ListAvailable | %{Get-AzVM -DefaultProfile $_}
kilasuit commented 5 years ago

@markcowl - if we got Connect-AzAccount -AllSubscriptions and could choose between this and Connect-AzAccount -Subscription 'Sub1', 'Sub2', 'Sub3' & Connect-AzAccount -DefaultSubscription that would offer a good experience that allows me as a user the most flexibily and also aligns close to the current experience in the Portal too, as I can choose a default subscription to view, I just used SubscriptionName and SubscriptionID for familiarity reasons but having a single parameter would be preferential.

I am a big believer that the User Experience should be as similar in PowerShell to the Portal as it mitigates any possible confusion when switching between the two so with this in mind and when you say (which would be a big breaking change, but would make us parallel with the portal), how big a change do you think this would be in engineering effort? and more importantly do you think its not only feasible but the right way to go? I know I do, hence raising this issue, but what's your thoughts?

markcowl commented 5 years ago

@kilasuit Yes, agreed, I am just wondering if 'all subscriptions in tenant' should be the default -this is a breaking change, but a simplifying one and for most users this would be the same as current behavior. Then users can opt out of this behavior using -subscription [string[]] to filter the subscriptions (and potentially -DefaultSubscription [string] to set the 'modification' subscription)

Doing this change in the current code base would be a big change in user experience AND a fairly large implementation change. This is because SDKs across languages use Subscription as a client property rather than a method parameter. However, as part of moving to generated cmdlets, we are using a new lightweight SDK that would make this quite a bit simpler, so the biggest change would be in documentation.

Also, we are in the middle of developing shared authentication with some other tools (VS, and CLI to start) which would work quite a bit more seamlessly with a tenant-centric view of subscriptions like this suggests.

kilasuit commented 5 years ago

To come back to this I find myself writing a shed load of wrapper code when I need to do anything that makes sure of cross subscription items like Keyvault's Log Analytic Workspaces and even archive Storage accounts in my scripts that looks often like this (for deploying a new policy to a new VM Subscription


Import-AzContext - Path $contextPath
Select-AzSubscription -Subscription $managementSubID
# Here I need to Pipe the output of Get-AzOperationalInsightsWorkspace to Where-Object because of the incessant need for the Resource Group Name being passed to all calls to commands like Get-AzOperationalInsightsWorkspace & many other commands
$LAWorkspace = Get-AzOperationalInsightsWorkspace | Where-Object Name -Match $WorkspaceName | Select-Object ResourceId

Select-AzSubscription -Subscription $NewVMSubID

New-AzDeployment -Name PolicyDeployment -TemplateFile $PSScriptRoot\LogAnalyticsPolicyDeploy.json -Location uksouth -PolicyName $PolicyName -ResourceId $LAWorkspace

This is messy, prone to error and a huge waste of additional code that woudl be 100% redundant if you could just query across the tenant for all resource types by default like you can in the Portal.

The sooner this change comes about the better

& yes - all subscriptions in tenant' should be the default for the user that has signed in, unless explicitly opted out to XYZ Subscription or XZY & 123 Subscriptions etc

kilasuit commented 5 years ago

Glad to see this getting some traction in as per the RFC's added in #10045

ChristopherGLewis commented 4 years ago

Couple of comments:

1) Contexts are the the bane of scripting. You typically set your context at the beginning of your script and go. Having the context switched out from under your script (always self inflicted) is just painful.

2) The subscription "scope" should be as similar as possible to the Portal's global filter (in fact managing and using the Portal's global filter from PS would be excellent). At the same time, I'm in full support of a -Subscription parameter on all cmdlets.

3) This feature should NOT be limited to GETs - there are many scripts that I've written that are working on one sub and updating items on another. There are also many times that I'll run scripts in parallel processes where subscription context switches cause all sorts of mayhem, so having a -Subscription 'sub1' or -Subscription @(sub1,sub2,sub3) parameter on every cmdlet would allow for much better threading/parallelism.

markcowl commented 4 years ago

@ChristopherGLewis Note sure if you mean that a Subscription parameter is necessary on every cmdlet (which is the plan), or that you are able to specify multiple subscriptions in modification cmdlets.

Generally for modification cmdlets, the subscription parameter is only used when you specify other identity parameters (rg, name, etc.), and not when you supply a resource ID or an object (through piping). Is there a scenario for providing multiple subscription ids with a name and resource group name, or would this be ,more properly handled through piping, or through specifyign multiple resource IDs?

kilasuit commented 3 years ago

Any update on this at all?

JustinGrote commented 2 years ago

I usually just use a ForEach-Subscription utility function I made that finds all subscriptions that match the same account as the current az context, and then runs the provided script block after setting the context each time. It's not great but it works.

shareonline commented 2 years ago

I usually just use a ForEach-Subscription utility function I made that finds all subscriptions that match the same account as the current az context, and then runs the provided script block after setting the context each time. It's not great but it works.

Well yes it works, but the awful performance of this is really not great.. To improve performance (by alot), i also use the rest api where possible. But this requires a lot of extra code, and then i could just as well write it in C# instead..

Powershell should be easy, quick and forgiving. C#/.NET directly when you want something more..

JustinGrote commented 2 years ago

Definitely seems like a -Subscription parameter for all command would be the easiest way to go, since batch API queries support specifying an array of subscription GUIDs image

shareonline commented 2 years ago

Definitely seems like a -Subscription parameter for all command would be the easiest way to go, since batch API queries support specifying an array of subscription GUIDs

Yeah if batch requests could somehow be included as options where they exist in the Api's this would be alot of help..

danpousson commented 2 years ago

hello any updates on allowing context to see multiple/all subscriptions?

mcdonamw commented 2 years ago

Is this still being investigated? I'm new to Azure and I am now finding this issue with managing my multiple subscriptions. Coming from raw PoSH, it really made me wonder why I couldn't just Get-AzSubscription | Get-Az* for simple tasks across all subs.

kilasuit commented 1 year ago

Coming back to this I would want this to be isolated at the tenant level when I log in so that I or others like me are not able to query across tenants unnecessarily, but could do if needed

shareonline commented 1 year ago

4½ years after.. 😲

mcdonamw commented 9 months ago

Welp, another year and no updates on this? 😞