Category Archives: Microsoft 365

OneDrive Site Lifecycle – 93-Day Unlicensed Archiving vs Standard Retention

If you are trying to access somebody’s OneDrive site and it says “The site is archived” – here is what you need to know. Microsoft recently implemented a new feature (process) of mandatory archiving OneDrive sites after 93 days since account becomes unlicensed.

So now it two processes that applied to OneDrive sites of the off-boarding personnal:

  • Unlicensed OneDrive enforcement (93‑day process) — operational lifecycle that places the OneDrive into read‑only and then archives it after a set number of days unlicensed. [learn.microsoft.com]
  • Standard retention controls — compliance mechanisms (OneDrive retention period, Purview retention policies, legal holds) that govern how long content is preserved and when it can be deleted. [learn.microsoft.com]

This KBA describes how these mechanisms interact, and provides a decision matrix for common offboarding scenarios.


Key Concepts

A) “Unlicensed OneDrive enforcement” (the 93‑day process)

When a user’s Microsoft 365 license is removed, the OneDrive becomes unlicensed. Microsoft’s enforcement (began Jan 27, 2025) introduces these behaviors: [learn.microsoft.com]

  • Day 60 unlicensed: OneDrive is placed into read‑only mode. [learn.microsoft.com]
  • Day 93 unlicensed: OneDrive is archived (or begins deletion flow depending on configuration). [learn.microsoft.com]
  • Once archived, neither admins nor end users can access content until an admin takes action (for example, enabling billing or restoring licensing where applicable). [learn.microsoft.com]
  • Enforcement does not change your retention timelines or the standard deletion process; it changes access state and may change whether/when the site enters deprovisioning. [learn.microsoft.com]

Note: Microsoft’s guidance indicates exceptions for certain clouds/segments (e.g., EDU, GCC, DoD). [learn.microsoft.com]


B) “Standard retention” (compliance & lifecycle retention)

When OneDrive content is being deleted, Microsoft honors retention mechanisms in the following order: [learn.microsoft.com]

  1. OneDrive retention period (tenant/OneDrive setting for deleted users) [learn.microsoft.com]
  2. Purview retention policies (retain content for X years, etc.) [learn.microsoft.com]
  3. Legal holds (eDiscovery holds, litigation hold/in-place hold) [learn.microsoft.com]

After those are satisfied, the account/site is recycled and then permanently deleted. [learn.microsoft.com]


The Critical Point: Archival and Retention run in parallel

Think of it this way:

  • Unlicensed enforcement controls access state (active → read-only → archived) and can trigger entry into the standard deletion pipeline. [learn.microsoft.com]
  • Retention controls how long the data must remain preserved before permanent deletion is allowed. [learn.microsoft.com]

So you can have a OneDrive that is:

  • Archived but retained for years (compliance requires preservation), OR
  • Archived and then deleted (no retention/hold and billing not enabled), OR
  • Archived indefinitely (billing enabled prevents deletion for non-deleted users). [learn.microsoft.com]

Decision Matrix (Most Common Scenarios)

Step 1 — Determine the identity state in Entra ID

There are two major branches in Microsoft’s guidance: [learn.microsoft.com]

  1. User deleted in Entra ID
  2. User NOT deleted in Entra ID (account still exists but unlicensed)

Scenario Group 1: User deleted in Entra ID

When the user is deleted in Entra ID, the OneDrive is removed following the standard OneDrive deletion process, honoring retention in this order: OneDrive retention period → retention policies → legal holds. [learn.microsoft.com]

What the 93-day rule changes here:
Microsoft states enforcement does not change retention timelines or the deletion process for this branch. [learn.microsoft.com]

Result patterns

  • If retention/hold exists → preserved until retention ends, then recycled/deleted. [learn.microsoft.com]
  • If no retention/hold → deleted per standard lifecycle after retention period (if configured) and recycle bin stages. [learn.microsoft.com]

Scenario Group 2: User NOT deleted in Entra ID (unlicensed)

These accounts are archived on their 93rd unlicensed day.
What happens next depends mainly on billing for unlicensed OneDrive accounts: [learn.microsoft.com]

2A) Billing enabled

  • The OneDrive remains archived and is not deleted (while billing remains enabled). [learn.microsoft.com]
  • Admins must take action to regain access (billing/reactivation workflows), otherwise content stays inaccessible. [learn.microsoft.com]

Combine with retention policies / holds:
Retention can still apply for compliance, but in practice this path commonly results in “archived but preserved” behavior. Microsoft also clarifies Purview mechanisms still apply and retention order remains relevant. [learn.microsoft.com]

2B) Billing NOT enabled

  • On Day 93, the OneDrive is archived and begins the standard deletion process. [learn.microsoft.com]
  • That deletion process still honors retention mechanisms in order: OneDrive retention period → retention policies → legal holds. [learn.microsoft.com]

What this means in practice

  • With retention policy / legal hold: the OneDrive can remain preserved until retention ends, even if it is archived/inaccessible during that time. [learn.microsoft.com]
  • Without retention/hold: it proceeds through recycle bin and permanent deletion after retention mechanisms (if any) are satisfied. [learn.microsoft.com]

Practical “Combination” Cases (Cheat Sheet)

Case 1 — “We remove the license but keep the user object (typical offboarding)”

Best practice: If business requires access to the files later, plan either (a) content migration/transfer before Day 93, or (b) enable billing and document cost/ownership.


Case 2 — “We delete the user in Entra ID (hard offboarding)”

Best practice: If you need long-term preservation, ensure Purview retention/holds are correctly scoped before deletion.


Case 3 — “Retention policy applied to OneDrive (e.g., retain 7 years), user becomes unlicensed”

Important operational impact: Retention does not guarantee admin access to content at all times—archival can restrict access even while content is preserved. [learn.microsoft.com]


Case 4 — “No retention policy / no hold; license removed”


Admin Actions and Where to Look

Identify impacted OneDrives

Microsoft provides admin reporting for unlicensed OneDrive accounts and guidance for identification/monitoring and management actions. [learn.microsoft.com]

Remediation options (high level)

Depending on business need:

  • Restore/maintain access (e.g., re-license user, or enable unlicensed account billing where applicable) [learn.microsoft.com]
  • Preserve for compliance (apply/confirm Purview retention policies or legal hold scope) [learn.microsoft.com]
  • Remove (allow deletion lifecycle to complete if no retention requirements) [learn.microsoft.com]

Recommended Offboarding Playbook (Operational)

  1. Classify the user: deleted vs not deleted in Entra ID. [learn.microsoft.com]
  2. Check retention requirements: is the user/site in scope of retention policy or legal hold? [learn.microsoft.com]
  3. Decide access strategy before Day 93:
  • If the business needs files: migrate/transfer, or plan billing/licensing route.
  • If only compliance needs preservation: ensure retention/hold is applied and documented. [learn.microsoft.com]
  1. Monitor Day 60/Day 93 milestones (read-only then archived) to avoid surprises. [learn.microsoft.com]

FAQ (Quick Clarifications)

Q1: Does the 93‑day enforcement override retention policies?

No. Microsoft states the standard deletion process still honors retention mechanisms (OneDrive retention period → retention policies → legal holds) and enforcement does not change retention timelines. [learn.microsoft.com]

Q2: If a OneDrive is retained by policy, will admins always be able to open it?

Not necessarily. The OneDrive can be archived and inaccessible until admins take specific actions. Retention can preserve data, while archival can restrict access. [learn.microsoft.com]

Q3: What’s the biggest “gotcha”?

Assuming “retention == access.” Retention ensures preservation rules, but enforcement can still move unlicensed OneDrives into an archived state where access is blocked unless admins take action. [learn.microsoft.com]


Source / References

How to run Get-PnPUser correctly for large sites

Get-PnPUser PowerShell cmdlet is to get the list of site user. For small sites it work OK, but for sites with a large number of site users the cmdlet fails throwing a warning/error “Get-PnPUser: the request was canceled due to the configured HttpClient.Timeout of 100 seconds elapsing.”. Typically suggested fixes like to increase timeout do not work. Here is how to solve the issue.

Fixes do not work

  • Increase the Global Connection Timeout
  • Handle Transient API Throttling

Solution

If you need a list of site users – just get the hidden “User Information List” and get all it’s items:

# Target the hidden list object specifically by its internal title
Get-PnPList -Identity "User Information List"
# Extract the list rows and select the relevant columns
Get-PnPListItem -List "User Information List" -PageSize 1000

Surely you’d get a different object type, but still you’ll be able to find properties you need via something like $user[“Name”] for Get-PnPListItem object versus $user.LoginName for Get-PnPUser object. But if you need a Get-PnPUserObject – you always can do something like

Get-PnPUser -Identity $listItem["Name"] 

That is it. You’ll figure out the rest.

P.S. If you need to get all SharePoint site users via Microsoft Graph API – use the same trick – get items from the UIL (as there is no dedicated API entry point to get site users). Here is the “Get SharePoint Site Users via Graph API” KBA.

Microsoft 365 Ownership Report by Manager Hierarchy

In large Microsoft 365 environments, leadership and governance teams often need visibility into collaboration resources owned by a specific organization unit – typically defined by a manager and their reporting chain. Native tools make it easy to inspect a single Team or site, but not to answer a simple question at scale: “What Teams and SharePoint sites are owned by anyone under this leader?” This PowerShell script builds that inventory by expanding a manager’s hierarchy and correlating owners to Microsoft 365 Groups/Teams and their associated SharePoint sites.

Here are the scripts (beta):

https://github.com/VladilenK/m365-PowerShell/tree/main/Solutions/HierarchyReports

Update: Added Get-Hierarchy.ps1 script
The script retrieves the hierarchy of all subordinates for a given manager in Entra Id

Update: Added Get-Sites.ps1 script
The script pulls all group-based sites owned by anyone from the hierarchy

Handling Large Lists in PowerShell

There is a known problem in SharePoint: 5,000 Items List View Threshold. Actually any SharePoint list can have up to 30 million items and a library can have up to 30 million files and folders. See more SharePoint capabilities and limits. The important moment is you cannot have more than 5k items in a single view (explained here). So obviously you’d need to create a custom view with a filter that would show less than 5,000 items and you are good (here Microsoft explains how it works and provide more options to manage large lists). But there are scenarios where we have to use PowerShell to deal with large lists.

Scenario 1 (most frequent): List is close to 5k items view threshold, and business wants you to remove items based on some criteria and keep the list (e.g. remove older items, or completed items etc.). Optionally business wants you to archive older items into another list, and keep original list short. It is too

Scenario 2: users did not create a smaller views in advance and now stuck with the list not functioning without ability to edit/create a custom view. This could happen with a regular list or library, or

Scenario 3: overflow of the access request list. This is a particular case of the scenario 2. In SharePoint site we have an “access request” functionality. If a user have no permissions to a site, and tries to open this site – he/she will get “Access denied” page with an ability to request access to a resource. These requests are saved in a special hidden list. Sometimes when you have too many requests – this list grows to 5,000 requests and you cannot go to the list to approve/decline new requests.

All these scenarios require us to use PowerShell. Here is the technique.

Install PowerShell and configure your PowerShell environment

In this article I’ll guide you through how to get PowerShell and configure your environment for PowerShell scripting against Microsoft 365. For those who do not need detailed instructions:

  • Install PowerShell 7 (cross-platform one)
  • Install Visual Studio Code
    • find and install PowerShell plugin for VSCode
    • install MgGraph (Microsoft Graph) module
    • install PnP.PowerShell module
  • Get and configure Azure App Registration
    • registration a new Azure App
    • configure API permissions and get admin consent
    • configure authentication

Windows PowerShell

Every Windows computer comes with PowerShell pre-installed. So if you are on a Windows machine – try the following: Start -> Windows PowerShell. You’ll see:

So you can type something like “Get-Date” or “Get-ComputerInfo” or “Get-Disk” or “Get-Random” and see results right away, e.g.:

But, hold on! This is not the PowerShell we need. This is so-called PowerShell 5 (classic, legacy one, nowadays called “Windows PowerShell”). Though you can use Windows PowerShell OotB, we will use new, modern, cross-platform PowerShell (for Windows, Linux, and macOS).

PowerShell

This is how nowadays called a new cross-platform PowerShell. Just “PowerShell” (or PowerShell 7, as 7 is it’s current/latest major version. Here is the Microsoft’s official guide “Install PowerShell on Windows, Linux, and macOS“. There are multiple options to install PowerShell 7 – just choose your one (you are Power User, you should figure it out). E.g. you can use your Windows PowerShell window to install PowerShell 7:

Once modern PowerShell, your Start->PowerShell experience should look like:

Notice that you have both – PowerShell 5 (for Windows) and PowerShell 7 (cross-platform).

Start PowerShell 7 and try something like “Get-Command” or “Get-Help”. Congratulations! Let go to the next step.

IDE – Integrated Development Environment

So far what you did – you used PowerShell cmdlets in command-line window. It is ok to use plain PowerShell window to quickly run one or a few PowerShell commands, but usually we work with scripts. A PowerShell script is a program written in PowerShell – composed of a sequence of PowerShell cmdlets, structured with logic to perform specific tasks. So we would need some kind of editor for PowerShell programs. Actually you can use any universal text editor – like Notepad, Notepad++ to create your code, you’d save it as .ps1 file (e.g. myFirstScript.ps1) and than run you script with PowerShell. But there is a better way – using IDE. IDE stands for “Integrated Development Environment” – a developer-oriented text editor equipped with a bunch of goodies that help creating and debugging code.

Visual Studio Code

One of the most popular IDE is Visual Studio Code (or vscode) – a free open-source IDE from Microsoft. You can get it from code.visualstudio.com – just download it and install it.

I’d recommend you to take some brief vscode introduction lessons – like this one from Microsoft. VScode can be used to code in many programming languages – Python, C#, Javascript etc. We will be using it to code in PowerShell. I’d recommend to create a new folder for your PowerShell scripts, and from VSCode open a folder. After you trust yourself – you’ll see something like:

Using “New file” icon – create a new file, name it e.g. “my-first-script.ps1” (.ps1 extension is required).

PowerShell plugin

VSCode will realize that you are coding in PowerShell and suggest you to install a PowerShell plugin (or you can install it manually):

PowerShell plugin is the last piece we need to start scripting in PowerShell.

PowerShell Modules

Technically, what we already installed – enough to start coding for SharePoint (e.g. calling Microsoft Graph API via built-in Invoke-RestMethod), but there are some much more convenient ways – using modules.

PowerShell is built around modules. Every command you use is provided by a module. PowerShell includes built-in modules out of the box that offer essential cmdlets (such as Get-Host). However, to work with Microsoft 365 services, you’ll need additional modules that contain cmdlets specifically designed for interacting with Microsoft 365. There are modules to work with Teams, Exchange, SharePoint, Entra Id etc. Below are the most popular modules.

Microsoft Graph

Microsoft Graph is a unified API endpoint developed by Microsoft that allows developers and IT professionals to access and interact with a wide range of Microsoft 365 services and data. It acts as a gateway to data stored across Microsoft services. Utilizing Microsoft Graph from PowerShell code is better done with Microsoft Graph PowerShell SDK. So check it out and install.

PnP.PowerShell

The other very popular and useful module is PnP.PowerShell. PnP is an open source community backed by Microsoft (but PnP products are not officially supported by Microsoft). The PnP team does an excellent job of developing and providing a wide range of tools, SDKs, documentation, learning videos, and other resources to help developers work with Microsoft 365 efficiently. For PowerShell developers they maintain PnP.PowerShell module. So please go ahead and install it as well.

Authentication and Authorization

To work with Microsoft 365, the first step is authentication – essentially proving that you are actually who you claim to be (via providing login name and password or fingerprint etc.). Once you authenticated to Microsoft – you can access resources if you have permissions and cannot access others because you do not have permissions provided. This is called authorization.

This is true for your interactive experience with Microsoft 365 via browser, or Teams app etc. The same is true when you access Microsoft 365 programmatically – via PowerShell code. You need to authenticate and being authorized.

For smooth authentication and authorization to Microsoft 365 from your PowerShell code you’d need so called App Registration properly configured. App Registration is where API permissions and authentication methods are specified.

There are two authentication methods most commonly used in programming – interactive and non-interactive. Interactive authentication – is when a program acts on behalf of a user (e.g. you as a current user). The other method is used when your program needs to work unattended (without user presence) – on behalf of an application itself with it’s own permissions. You’d need separate app registration for each of these methods.

Interactive Applications

Interactive programs is what we will mostly use in this “PowerShell for Power Users” series of tutorials. Interactive login require delegated API permissions configured in the App Registration and proper authentication configuration Authentication blade. When your interactive program works – it’s effective permissions are the intersection of your personal permissions and permissions specified in the app registration.

Here is how to get an app registration, configure delegated API and authentication.

Non-Interactive Applications

Non-Interactive programs (also called daemon apps or background services or scheduled jobs etc.) are used mostly used by admins for tenant-level automation. But it is possible to automate something for a specific site, e.g. one of the common scenarios – data analytics can automate pulling some data from SharePoint site into e.g. Azure Data factory via pipeline. Non-Interactive authentication require application API permissions configured in the App registration and a secret generated or certificate uploaded. When a non-interactive program works – it’s effective permissions are the permissions specified in the app registration.

Here is how to get unattended access for a specific SharePoint site with Sites.Selected.

PowerShell for Power Users: Introduction

Are you ready to elevate your Microsoft 365 experience? Whether you’re a SharePoint site owner, Teams channel manager, or a power user working across OneDrive, Exchange, and other services, PowerShell can be the game changer you didn’t know you needed. This blog series, “PowerShell for Power Users, Unlocking the Full Potential of Your Microsoft 365 Workflow” introduces you to Microsoft’s powerful command-line shell and scripting language—and shows you how it can transform your productivity, automate repetitive actions, and give you deeper control across your Microsoft 365 workspace.

Why PowerShell in Microsoft 365?

Traditionally seen as a tool for IT professionals, PowerShell is now essential for power users who want to automate tasks, customize environments, and solve problems efficiently across Microsoft 365. PowerShell empowers you to:

  • Automate routine operations in SharePoint, Teams, OneDrive, and Exchange
  • Pull reports on usage, structure, and compliance that are not available out-of-the-box
  • Manage site collections, lists, libraries, Teams channels, and mailbox settings
  • Perform bulk operations that would be tedious through the UI
  • Audit and troubleshoot environments with precision
  • Integrate with Microsoft Search, Copilot, and Power Platform for intelligent workflows

What Can You Expect from This Series?

We’ll start with the basics—demystifying the PowerShell interface, understanding cmdlets, and connecting to services like SharePoint Online, Teams, and Exchange. Then we’ll dive into real-world scenarios. Each article will include clear explanations, sample scripts, and best practices—making PowerShell approachable even if you have no prior scripting experience.

Who Should Follow This Series?

This blog is for any Microsoft 365 user who wants to:

  • Move beyond manual, repetitive tasks
  • Learn scripting at their own pace, with practical examples
  • Boost productivity and efficiency across Microsoft 365
  • Bridge the gap between business needs and IT solutions

Getting Started

If you’re curious but feel intimidated by scripting, don’t worry—PowerShell is more user-friendly than you might think, and this series is designed with beginners in mind. All you need is a willingness to learn and experiment. In the next articles, we’ll cover how to set up your environment, write your first simple script, and start automating tasks you do every day across Microsoft 365. Your journey toward becoming a PowerShell power user starts here!

  • Install PowerShell and configure your PowerShell environment
  • Introduction to Graph API for Teams, SharePoint, Copilot
  • Get all alerts for all users (alerts are scheduled for retirement)
  • Deal with large lists – 5,000 items problem
  • Search programmatically across all your data
  • Get the oldest or newest documents from your Teams channel or SharePoint library
  • Fix the Access Requests List Overflow issue
  • Fix the User Id Mismatch issue
  • Create a new Team, SharePoint site, Viva Engage community
  • Manage team membership (bulk upload/delete team members)
  • Update library/list items metadata (documents’ properties) in bulk
  • Generating reports on usage, structure, and compliance

‎Microsoft 365‎ Backup is turned on for your organization. What is next?

WIP…

In all cloud models – IaaS, PaaS, SaaS, user is always responsible for data. Microsoft is responsible for service, but data is something that client should take care of. Microsoft says “Microsoft 365‎ Backup helps your organization recover from data corruption events like ransomware attacks or accidental deletions”. That is exactly the point… Backup is a part of disaster recovery and business continuity concepts and should always be taken seriously. So let us go deeper in Microsoft’s “Microsoft 365‎ Backup ” offering.

Usually I do not retell what is already documented and explained by Microsoft itself or by other Microsoft 365 MVPs and gurus. What I do is I go beyond and share some insights from researches and real-world practices or at least highlight what seemed to me interesting or important.

SharePoint backup

What to backup

At the step 1 “Choose selection method” of the SharePoint backup policy creation, we have a choice:
“How do you want to select sites to back up?” and our options are:

  • Upload a list of sites in a CSV file
  • Using filters
  • Select sites individually

First option – “Upload a list of sites in a CSV file” – you’d create a list of up to 50,000 ‎sites as CSV file (example provided, but it’s just one column with sites Urls no header) and upload it.

Third option – “Select sites individually” is also straightforward . Good news – you can search (filter) sites by name or url.

Second option – “Using filters” seemed like the most promising, but
a) you can only use “Site name or URL contains” and “Site last modified”, and
b) Only existing sites that match these filters will be added to this policy. If new sites are created that match these filters, they won’t be added to the policy automatically. You can add or remove sites by setting the policy scope again later.

Thinking that first and third options are static by definition, that means the policy is not actually a policy, it’s just a master that produces a static SharePoint backup configuration.

Worth to highlight:

  • Literally we can modify only what to include, we cannot modify “Retention”, i.e. how exactly sites are backed up. Microsoft says: “Backups are initially kept for 14 days. After 14 days, the latest backup from each week will be kept for one year after it was created.”
  • Some sites within the scope might already be included in other policies. If so, they will not be added to this policy again.
  • Each policy is a static backup configuration that includes static list of sites selected during the policy setup.

SharePoint backup limitations:

  • CSV list cannot have more than 50,000 ‎sites (but you can have more than one policy)

References

Restoring Connection to Teams for a SharePoint Site

Sometimes a restored SharePoint site looks like it’s connected to a Microsoft 365 group (and Teams), but it’s actually a standalone site. So just restoring a deleted SharePoint site that was previously connected to team is not enough, there is some more work to be done. This article explains (from SharePoint admin standpoint) how that could happen and how to fix the broken SharePoint site to restore it’s lost connection to group and teams (the right way).

Scenario

A Teams-connected SharePoint site was deleted by one of the team owners during a cleanup. They didn’t see any useful content in Teams channels or files, so they deleted the team—along with the connected SharePoint site.

However, some team members had been using the SharePoint site directly (not through Teams). Two months later, they tried to access the site and received a 404 error. They contacted IT support to ask what happened and whether the data could be restored.

IT support found that the team was deleted by someone who had already left the company. Fortunately, the SharePoint site was still in the recycle bin (retained for 90 days), so it could be restored. But the Microsoft 365 group and the team (with chat messages, etc.) were already permanently deleted (retention is only 30 days).

After restoring the site, it appeared to be group-connected, but the group no longer existed.

Symptoms of a Broken Connection

  • Site permissions show ownership by a group, but clicking the group name does nothing.
  • Searching for the group in Microsoft 365 returns no results.
  • PowerShell shows a RelatedGroupId, but that group ID doesn’t exist in Entra ID.
  • The site behaves like it’s group-connected but lacks full functionality.

Normal Teams-Connected Site vs. Standalone Site

Let us test it from scratch. I will create a new team called “Test-Broken-Team-Site”.

Here is how the normal teams-connected SharePoint site looks like. When you hover your mouse over the site name, a pop-up window appears showing team details.

When you go to the site permissions – you can see that the site is owned by group “SiteName Owners”:

If you click the group name, another pop-up window appears with more information, including group members:

Let us get site object with PnP PowerShell:

$pnpTenantSite = Get-PnPTenantSite -Connection $connectionAdmin -Identity $siteUrl -Detailed
$pnpTenantSite | select Url, Template, IsTeamsConnected, GroupId, RelatedGroupId,  Owner | fl

Results:

You can see that IsTeamsConnected property is true and GroupId and RelatedGroupId are specified and the site owner is the same group Id with “_o” suffix.

Compare this with the same request against a standalone site:

IsTeamsConnected property is false, Group id is “00000000-0000-0000-0000-000000000000” and the site owner is the real user id.

Deleting the team and the site

I also posted some messages in the general team channel and created some test documents. Now let me delete the team. Any team owner can do this via:

What users will see after the team deletion:

“404 FILE NOT FOUND” error upon any attempt to go to the SharePoint site via browser:

The deleted group under “https://myaccount.microsoft.com/groups/deleted-groups”:

From the admin standpoint the deleted resource looks like.

The group appears under “Deleted Groups” in Entra ID and Microsoft 365 Admin Center (note that the group can be restored within 30 days):

The site appears under “Deleted Sites” in SharePoint Admin Center (retained for 93 days and marked as group-connected with a team), and the site is marked as Microsoft 365 group connected and with a team:

Restoring SharePoint site

After 30 days the group is deleted permanently, including teams stuff, but SharePoint site is still retained. So we can go ahead and restore SharePoint site from the SharePoint admin center. It warns us that “We couldn’t find the Microsoft 365 group connected to this site. Restoring the site will not restore the group.”:

Ok, for the restored site – let us look at the site memberships. You’ll see the site is still owned by the Microsoft 365 group—but the group no longer exists. 🙁

That is the reason that users (team members) will not get access to the site automatically once the SharePoint site is restored. But let us get the SharePoint site PowerShell object:

GroupId is zeroes, which is good, IsTeamsConnected if false, which is correct, but the RelatedGroupId is still the same (as if it is a channel site) and the owner is the same.

Note: the site’s status described above is not always lake that. I’m not sure why, but in my practice so far some sites are getting restored with GroupId specified (and running ahead, in such cases this solution does not work).

User experience

(I provided access for myself to this site as admin).

The home page (site root) looks like something in between a Teams-connected and standalone site. There is no Teams icon and no pop-up window when hovering over the site title. But there is a “Conversation” menu we usually have on group-based sites (by the way, it fails if you click on it, because it’s supposed to send you to the group in Outlook… so you’ll get “Sorry, something went wrong” – “Invalid group ID or group alias.”)

"Sorry, something went wrong" - "Invalid group id or group alias."

Site settings page looks like the group-based site settings page. Compare standalone site settings page:

and broken teams connection site settings page… Specifically, you still do not have the “Users and Permissions” section (as it is supposed to be handled via Teams and group membership).:

And here is one more difference. On a regular standalone site when you are clicking on a gearbox – you can see “Connect to new Microsoft 365 Group” link which would allow user to convert this standalone site to a teams-connected site. Unfortunately, there is no such option on the broken site.

So what should we do? Can we re-connect this site to teams or make it true standalone site? Would this broken site stay as broken forever?

Is there a fix for broken teams connection in SharePoint site

First of all, you can’t change GroupId or RelatedGroupId directly—they’re read-only.

Let us try to change site primary site owner (remember it was a group) and see what has changed:

Set-PnPTenantSite -Identity $siteUrl -PrimarySiteCollectionAdmin $adminUPN

Hmm… primary site owner is a user, but SharePoint admin center still thinks the site is owned by non-existing group:

Changing the site owner from a group Id to a user id doesn’t help. SharePoint admin center still shows the deleted group as owner.

Let us try “Add-PnPMicrosoft365GroupToSite” to connect site to a new group via PowerShell.
Hooray! This did work!!!

The command worked perfectly:

Add-PnPMicrosoft365GroupToSite -Url $SiteURL -Alias "newM365GroupForBrokenSite" -DisplayName "New Team/Group for a broken site"  -KeepOldHomePage

Note: sometimes this does not work. The PowerShell cmdlet says “The site is already connected to group”…

Group was created in Entra Id and connected to SharePoint site:

SharePoint site is owned by a new group (the old one we will delete):

PnP PowerShell object contains correct information:

The only 🙂 problem: it says the site is team-connected, but it’s not.

If you click on a Teams icon near to the site title – it’ll give you “We’re still setting up the Microsoft Team for this group” “Please come back in a few minutes”. This message might last forever…

Ok, we have a m365 group and a group-based site without a team. Can we create a team from an existing group? Yes. Let us try it.

When you create a team – there is a link “More create team options”. It leads us to the list of options and one of them – create a team from group. There will be a list of groups and one of them would be our “New Team/Group for a broken site”. Select it. It say OK, a new team created.

Now let us see what we got.

It seems like it worked! Now we have a consistent full-functioning group-based site connected to team.

At the SharePoint site – teams icon redirects us to a team channel.
In the teams app – the team is listed among other teams.
Entra Id displays all the services correctly.
Teams admin center can see the team and all the settings look good.
SharePoint admin center also displays a team correctly. You might want to update “Don’t show team email address in Outlook”.

Standard Channels Confusion

One thing that might confuse users is channels. Long ago when you create a team – a channel named “General” was created by default. Not far ago Microsoft changed creating team experience – now you need to provide a name for channel. As you know – channel is a folder in the default document library. So our “broken” site has a folder “Test-Broken-Team-Site” that used to be a sole channel. When we created a team from an existing group (group with site) – a new default main channel was created named “General”, so under SharePoint we can see two folders, and under teams we can see only “General” channel.

But all our data was under the old folder. Can we fix it? I think of two options.

Option 1 – add a tab to the channel – so we can see the existing folder under the main channel:

Option 2 – moving content of the “old” folder to a “new” folder, then you can delete the old folder and rename channel to the original name.

Private and Shared channels

The other thing that went wrong is private and shared channels. As you know, these channels are created as standalone sites related to team (site object has GroupId as zeroes, but RelatedGroupId would be an Id of the main site’s group id.). These sites are not getting restored automatically when a main site is restored. Moreover, in the SharePoint admin center those site are not visible under deleted sites.

The good news is these sites are visible with PowerShell. And you can restore the site with PowerShell:

Get-PnPTenantDeletedSite | ft SiiteId, Url, Title, DeletionTime, DaysRemaining
$siteUrl = "https://contoso.sharepoint.com/teams/Team-PrivateChannel"
Restore-PnPTenantSite -Identity $siteUrl 

The site will be restored, but, again, with broken connection to team. And I’m afraid it cannot be re-connected to a team, so it has to stay broken standalone site (or converted to a new-group-based which is a preferred option and if you like – with a team.

Summary

Quick Step-by-Step Recovery Guide

  • Restore the site via SharePoint Admin Center
  • Verify that the site connection is broken
    Check properties IsTeamsConnected, GroupId, and RelatedGroupId. Ensure group is permanently deleted.
  • Set yourself as a new primary site collection admin
  • Connect to a New Microsoft 365 Group via PowerShell “Add-PnPMicrosoft365GroupToSite”
  • Create a New Team from the Group.
    In Teams, go to Create Team > More Options > Create from Existing Group. Verify Everything Works.
  • Handle Folder/Channel Conflicts.
    • Option 1: Add it as a tab in the new “General” channel.
    • Option 2: Move content to “General” folder, delete old folder, and rename channel.
  • Channel sites (private channel, shared channel) are not restored and connected automatically.

References

Proactive SharePoint: Essential Initial Configurations for Every New Microsoft 365 Tenant

In this article I will share what I would recommend to configure on every new Microsoft 365 Tenant.

The Challenge: Why Many Microsoft 365 Tenants Become Unmanageable and Inefficient Over Time

Many organizations adopting Microsoft 365 quickly discover that while the platform offers immense power, its default configuration often leaves crucial features disabled. These “dormant” functionalities, designed to enhance data governance, search capabilities, content management, and user experience, remain untapped. The real problem arises when a tenant matures: as users populate SharePoint sites and OneDrive accounts with vast amounts of information, and as collaboration intensifies, attempts to enable these critical features become incredibly complex, disruptive, and even risky. Retrofitting governance, re-indexing content, or restructuring information architecture on an existing, data-rich tenant can lead to compliance headaches, data inconsistencies, user frustration, and significant administrative overhead. SharePoint administrators frequently struggle with the technical debt accrued from these missed initial configurations, spending countless hours trying to bring order to an environment that could have been optimally set up from day one.

Consider the following.

Ownerless resources

Having an owner for every Microsoft 365 resource should be enforced from day one.

Sensitivity labels

This step is an essential prerequisite for the other governance features. I have an article explaining ownerless Microsoft 365 groups policy in details and more KBAs regarding ownerless SharePoint resources.

Oversharing in SharePoint

Oversharing in SharePoint is a serious problem. The earlier you start addressing it – the easier you life as SharePoint engineer. Here are some thought: Control Oversharing in SharePoint Online: Smarter Access Management in Microsoft 365

User profiles to Term Store mapping

There is an OotB misconfiguration in Microsoft 365 User Profiles mapping to Term Store Metadata. Here is the KBA how to configure User Profiles correctly.


WIP


Why this approach?

  • Relatability: It immediately speaks to the pain points experienced by many SharePoint admins (“unmanageable,” “inefficient,” “struggling with it,” “technical debt”).
  • Highlights the “Why”: It explains why these features are off and why it’s a problem to turn them on later.
  • Emphasizes Proactivity: It sets the stage for your solution, which is about proactive setup.
  • Strong Call to Action (Implied): It makes the reader understand that your KBA will provide the solution to avoid these common pitfalls.