How to manage multiple M365 tenants using inbuilt Microsoft tools

image

Okay, let’s break down how to effectively and securely manage multiple Microsoft 365 (M365) tenants using Microsoft’s integrated and add-on tools, especially when multiple employees need access.

The cornerstone solution for this scenario is Azure Lighthouse. It’s specifically designed for service providers (like MSPs) or enterprise IT teams managing multiple tenants.

Here’s a breakdown of the tools and strategies:

1. Azure Lighthouse (The Foundation)

  • What it is: Azure Lighthouse allows you to manage customer (or subsidiary) Azure and M365 resources from within your own management tenant. It uses Azure Delegated Resource Management.

  • How it works:
    • You (the managing organization) define access roles and permissions for your employees (organized into Microsoft Entra ID groups) within your tenant.

    • You create an “offer” (either a Managed Service offer in the Azure Marketplace or an ARM template deployment) that specifies these roles and the scope (subscriptions, resource groups, or entire tenant for some M365 workloads).

    • The customer/managed tenant accepts this offer, delegating the defined permissions to your specified groups/users in your tenant.
  • Key Benefits:
    • Centralized Management: Your employees log in only to your primary management tenant. They don’t need separate accounts or guest accounts in each customer tenant.

    • Enhanced Security:
      • Reduces credential sprawl (fewer accounts to manage/compromise).

      • Enables consistent application of security policies (like MFA, Conditional Access) from your tenant for your employees accessing customer resources.

      • Uses least privilege principles by assigning specific Azure built-in roles with appropriate permissions.

      • Activity logs in the customer tenant clearly show actions performed by users from your managing tenant.
    • Scalability: Easily onboard new customer tenants and assign permissions to your employee groups.

    • Cross-Tenant Visibility: View resources and alerts across multiple delegated tenants in unified dashboards (e.g., Azure Portal, Microsoft Sentinel).

2. Key Integrated Tools Leveraged with Lighthouse:

  • Azure Portal (portal.azure.com):

    • Directory + Subscription Filter: Your employees can easily switch context between different customer directories/subscriptions they have delegated access to.

    • Azure Resource Management: Manage Azure resources (VMs, networking, storage, etc.) within delegated subscriptions.

    • Microsoft Entra ID Management: Perform delegated Entra ID tasks in customer tenants (user management, group management, etc., depending on assigned roles like User Administrator, Helpdesk Administrator).

    • Service Health: Monitor the health of Azure services across delegated subscriptions.
  • Microsoft 365 Admin Centers (Accessed via Delegation):

    • While Lighthouse primarily delegates Azure roles, many M365 services are managed via Azure RBAC or have corresponding Azure AD roles that grant access.

    • Your employees, using their single login, can often access customer M365 admin centers (like admin.microsoft.com, Exchange Admin Center, SharePoint Admin Center, Teams Admin Center, security.microsoft.com, compliance.microsoft.com) if they have been assigned appropriate delegated Entra ID roles (e.g., Global Reader, Exchange Administrator, Teams Administrator, Security Administrator). The context switching happens within the respective admin portals.
  • Microsoft Sentinel:

    • Cross-Workspace Incident Viewing: If you deploy Sentinel workspaces in customer tenants, Lighthouse allows you to view and manage incidents across multiple workspaces from your managing tenant’s Sentinel instance.

    • Centralized SIEM: You can configure data connectors in each managed tenant to forward logs (Entra ID, M365 Defender, etc.) to a central Sentinel workspace in your management tenant for unified threat detection and response. This often requires specific permissions or configurations within the managed tenant.
  • Microsoft Defender Portals (security.microsoft.com / Microsoft 365 Defender & compliance.microsoft.com / Microsoft Purview):

    • Lighthouse delegation (with appropriate roles like Security Administrator/Reader, Compliance Administrator) allows your employees to access these portals for managed tenants.

    • While full cross-tenant unified views within these specific portals are still evolving, delegation significantly simplifies access compared to managing separate accounts. Some multi-tenant views are emerging, particularly for MSPs using Defender for Endpoint.
  • Microsoft Defender for Cloud:

    • Assess the security posture of Azure resources across delegated subscriptions.

    • Manage security policies and recommendations centrally.

3. Essential Supporting Tools & Practices:

  • PowerShell (Microsoft Graph SDK, Azure Az, Exchange Online, etc.):
    • Automation: Crucial for performing tasks at scale across multiple tenants (e.g., applying a standard configuration, running reports, user management).

    • Authentication: Use your managing tenant credentials combined with the delegated tenant ID to connect and manage resources programmatically. Service Principals in your managing tenant can also be granted delegated permissions via Lighthouse for automated tasks. Use secure authentication methods (certificates, managed identities where applicable) instead of interactive logins or stored credentials for scripts.
  • Microsoft Graph API:
    • The underlying API for Azure and M365. Use it directly or via SDKs (like the PowerShell SDK) for complex automation and integration scenarios across tenants. Again, authentication leverages the Lighthouse delegation.
  • Microsoft Entra ID Features (in your Managing Tenant):
    • Security Groups: Create groups for different support tiers or roles (e.g., “Tier 1 Support”, “Exchange Admins”, “Security Analysts”). Assign Lighthouse delegated permissions to these groups, not individual users. Managing group membership is easier than managing individual permissions across many tenants.

    • Conditional Access Policies: Enforce MFA, device compliance, location restrictions, etc., for your employees when they access any resources, including delegated customer tenants. This is a major security benefit.

    • Privileged Identity Management (PIM): Use PIM in your managing tenant to provide just-in-time (JIT) access to the Azure AD groups that hold the delegated Lighthouse permissions. This further enhances security by ensuring elevated privileges are only active when needed and for a limited time.

    • Access Reviews: Regularly review who has access to the delegated permission groups in your tenant.

4. Implementation Strategy:

  1. Design Your Management Structure: Define roles and responsibilities for your employees. Create corresponding Microsoft Entra ID security groups in your management tenant.

  2. Define Lighthouse Offers: Determine the necessary Azure built-in roles (e.g., Reader, Contributor, User Access Administrator, specific service admin roles) needed for each employee group. Create ARM templates or Managed Service offers for delegation.

  3. Onboard Customer Tenants: Deploy the ARM templates to or have customers accept the Managed Service offers in their respective tenants. This establishes the delegation.

  4. Configure Security in Your Tenant: Implement robust Conditional Access policies and PIM for the groups assigned delegated permissions.

  5. Train Your Staff: Ensure employees understand how to use the Azure Portal directory switcher, how delegated permissions work, and the security protocols (MFA, PIM activation).

  6. Leverage Automation: Identify repetitive tasks and automate them using PowerShell/Graph API with delegated credentials or service principals.

  7. Utilize Centralized Monitoring: Configure Sentinel or other monitoring tools to gain cross-tenant visibility.

In Summary:

Azure Lighthouse is the core Microsoft technology enabling secure and efficient multi-tenant management. By combining it with the Azure Portal, M365 admin centers, Sentinel, Defender, PowerShell, and robust Microsoft Entra ID security features (Groups, CA, PIM) within your managing tenant, you can provide your employees with streamlined, secure access to manage multiple customer environments effectively.

PowerShell script to report EntraID signin update

One the things that I have tasked myself with is to go back through my scripts and using AI (aka Github Copilot) to improve my code.

Screenshot 2025-04-18 095201

The latest script to get this treatment is:

https://github.com/directorcia/Office365/blob/master/graph-signins-get.ps1

which now has greater flexibility and speed. I also used Copilot to produce documentation for the script which is here:

https://github.com/directorcia/Office365/wiki/Get-tenant-signins

In my Visual Studio Code editor what I did was simply to open up the script.

Screenshot 2025-04-18 100356

I then set Copilot to operate in ‘agent’ mode, as shown above. I also selected an AI model to use. I have the default choices of:

Screenshot 2025-04-18 100555

I can also configure others like Gemini if I want. This time I selected Claude 3.7 and then basically told Copilot to ‘improve’ my code. After that I asked it to provide options for using paging to get more results as well as ensuring the output was in local time.

After one update to the time format it produced an error when it ran but I simply told Copilot to fix that error and it did so. The code once again executed.

Thus, the updated script and documentation is now available via the links above and I am amazed at how easy it was to make all these changes to get the result that I wanted without having to type any additional code myself into the script! I suppose he downside is that the code is more complex and I don’t intrinsically understand it as well as if I had written every line, but I have Copilot to help explain any part of the code to me if needed and the time savings getting to a result speak for themselves.

The functionality that AI provided for me via Github Copilot is enormous and should make short work of any PowerShell automation I do in the future. If you are using PowerShell (or any code) then you really need to be looking at the benefits AI will provide you.

SharePoint Agents PAYG costs

image

To get a better idea of the costs of using SharePoint Agents, I’d suggest you have a look at:

https://techcommunity.microsoft.com/blog/spblog/consumption-based-pricing-for-sharepoint-agents/4389591

with the highlight being:

Under the PAYGO model, customers are billed $0.01 per message. Each interaction with a SharePoint agent uses thirty-two (32) messages, so customers are billed at $0.32 per interaction with SharePoint agents. The PAYGO meter uses your Azure subscription as the payment instrument, ensuring seamless integration with existing billing processes. This meter is available worldwide.

and

There are no in-product feature differences between the PAYGO meter, and the SharePoint agent included in the Microsoft 365 Copilot license. Users have the same capabilities and benefits, regardless of the billing model they choose.

Thus, with each interaction being $0.32, let say that typically a user will interact with SharePoint agents three times during any inquiry. That makes it about $1 per enquiry. If we now say that an average user will make 20 inquiries per day, that is $20 per user per day. Multiply that across all the users in an organisation and you can see how it could get very expensive very quickly.

Clearly then, pay as you go SharePoint agents is for very low volume of usage across the organisation, typically one enquiry per day. Otherwise, it make more sense to buy a full license of Microsoft 365 Copilot for the user in question because they effectively get unlimited SharePoint agent enquiries as well as a personal AI assistant plus more.

If you combine any other pay as go usage of Copilot, such as with Copilot Studio as I have outlined before, then it make far more sense to get a full Microsoft 365 Copilot for those who need to use any AI tools. However, pay as you go billing does provide you the flexibility to mix and match with full Microsoft 365 Copilot licenses. If you have a business with 5 major users and 20 casual users then teh starting point is for those 5 users to have full Microsoft 365 Copilot license, while the rest simply use an Azure subscription to cover any incidental costs until the point when another person in the business needs a full license.

To keep control of any SharePoint or Copilot pay as you go, you shoudl always set up a budget in Azure as I have outlined before with Security Copilot

Pay as you SharePoint agents do provide a degree of flexibility of quickly and easily enabling AI across your SharePoint information for your whole organisation but if usage of AI starts to grow then so too will the costs, and potentially quite dramatically if appropriate limits are not configured. The best option with pay as you go SharePoint agents then is its use in combination with full Microsoft 365 Copilot licenses for users who need to use AI extensively in their jobs, while casual users can remain on the pay as you go option. The good news is that you do have the flexibility to mix and match with the two types of licenses as needed and Azure does give you the added benefit of being able to turn off immediately where Microsoft 365 Copilot licenses are typically an annual commitment.

Copilot Studio PAYG costs

Now that I have set up pay as you go (PAYG) Copilot Studio via an Azure subscription, the next big question is what are the costs likely to be? These are somewhat hard to quantify exactly because it ‘depends’ on a lot of factors.

Start with:

Copilot Studio licensing here:

https://learn.microsoft.com/en-us/microsoft-copilot-studio/billing-licensing

which says:

  • Pay-as-you-go: $0.01 per message

but then it isn’t a simple ratio of 1 question = 1 message, oh no. You need to look at this:

Message scenarios

which gives you this table:

Screenshot 2025-03-13 140428

The example Microsoft provides is:

Diagram illustrating various Copilot Studio events and their corresponding billing events.

Each interaction with an agent might utilize multiple message types simultaneously. For example, an agent grounded in a tenant Microsoft Graph could use 32 messages (30 messages for the Microsoft Graph grounding, and two for generative answers) to respond to a single complex prompt from a user.

Agent costs depend on an agent’s complexity and its usage.

Inside the Power Platform admin center, under licensing and Copilot Studio I see this:

Screenshot 2025-03-13 141042

if I drill into this a little more I find:

Screenshot 2025-03-13 141024

Ok, so 2,040 messages is the usage.

I then waited and checked my Azure billing for the period and it reports:

Screenshot 2025-03-13 134801

which is AU$20.30 for Copilot Studio usage across those 2,040 messages I suggest. If you divide the cost by the messages you come out to around that suggested $0.01 per message as expected.

How does that relate to usage? Again, hard to exactly quantify as I was the only user and I was building and testing an autonomous agent with Copilot Studio for around 8 hours roughly. Thus, that means an average of 255 AI message per hour or 4.25 messages per minute.

Based on that, the best estimate (rule of thumb) I could give you would be, based on ‘average use’ across a typical day (8 hours), for a single user using Copilot regularly throughout the day the cost is going you around AU$20 per user for that 8 hours of sustained usage.

I fully appreciate this is nowhere near exact but, so far it is the best average I can come up with for sustained daily usage.

If we assume that a ‘normal’ user is not going to using AI in the sustained manner across the whole day we could then apply say a 50% usage discount and settle on around AU$10 per user per day for an ‘average’ user using Copilot resources in an ‘average’ way per day. More intensive usage would be considered around AU$20 per user per day I suggest.

In summary then, via my imperfect observations and calculations I would suggest to you that if you do indeed implement Copilot service via Pay As You Go (PAYG) then the ‘typical’ costs you can expect would be around AU$10 per user per day up to AU$20 per user per day. If this was sustained across a full month then you would be looking at $300 per average user per month which is way above the cost of a full license of Microsoft 365 Copilot whih which would be a flat fee of around AU$45 per user per month.

This is the best estimate I can give you and your costs and usage will vary but I think $10 per user per day for average Copilot use on a PAYG plan is as good as any place to start.

Clearly then, if your users are planning on sustained Microsoft 365 Copilot usage a paid license of Microsoft 365 Copilot is a much more effective investment from what I can determine.

Need to Know podcast–Episode 341

In this episode I provide the benefits that become available once you add and Azure subscription to your Microsoft environment. From pay as you go options with Copilot and SharePoint all the way through adding more security to your environment, Azure contain a range of features that you should consider. I’ll also bring you up to date with all the latest news from the Microsoft Cloud, so listen along and enjoy.

Brought to you by www.ciaopspatron.com

you can listen directly to this episode at:

https://ciaops.podbean.com/e/episode-341-why-add-azure/

Subscribe via iTunes at:

https://itunes.apple.com/au/podcast/ciaops-need-to-know-podcasts/id406891445?mt=2

or Spotify:

https://open.spotify.com/show/7ejj00cOuw8977GnnE2lPb

Don’t forget to give the show a rating as well as send me any feedback or suggestions you may have for the show.

Resources

@directorcia

Join my shared channel

CIAOPS merch store

Become a CIAOPS Patron

CIAOPS Blog

CIAOPS Brief

CIAOPSLabs

Support CIAOPS

Microsoft 365 E5 Security is now available as an add-on to Microsoft 365 Business Premium

Microsoft Technical Takeoff: Windows + Intune

Azure Lighthouse support for MSSP use of Security Copilot Sentinel scenarios in Public Preview

Get the most out of OneNote with these little-known features

Edit your name in Teams meetings

Rethinking remote assistance security in a Zero Trust world

Introducing Exchange Online Tenant Outbound Email Limits

Can’t swap Azure subscriptions

Screenshot 2025-03-07 153419

So I have a situation where an Azure subscription expired and was then disabled (through no fault of my own I might add).

Screenshot 2025-03-07 154142

The status shows as disabled. Problem is now a new valid subscription has been added but I can’t move the resource groups from the old (and disabled) subscription to the new one because:

Error type

The subscription '8a6d2938-80eb-43bf-XXXX-142XXXX1ab90' is disabled and therefore marked as read only. You cannot perform any write actions on this subscription until it is re-enabled. (Code: ReadOnlyDisabledSubscription)
(Code: ReadOnlyDisabledSubscription)

In a nutshell the disabled subscription is now read only and I can’t shift resources if it is read write. That means I’d have to somehow re-enable it (typically converting it to PAYG), just to move to a new subscription.

So, the moral of this story seems to be, don’t let an Azure subscription expire and become disabled because migrating stuff out of it may not be possible!


A better KQL Query to report failed login by country

SigninLogs
| where ResultType != 0  // Non-successful sign-ins
| where TimeGenerated >= ago(30d)  // Last 30 days
| extend Country = tostring(LocationDetails.countryOrRegion)
| where Country != “AU”  // Exclude Australia
| summarize FailedLogins = count() by Country
| order by FailedLogins desc

The above is an improved version of a KQL query you can use to report on failed logins to Entra ID over the past 30 days. It also excludes a country (here Australia) if desired.

image

image

The country codes are here:

https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2

Note: if you copy and paste directly from here you will probably have the change the “ when you paste into your own environment as the wrong “ gets taken across!