Let say you administer Microsoft 365 SharePoint Online and you want to get a list of new SharePoint sites (e.g. sites created during last week/month).
With GUI it’s done easily: SharePoint Admin Center -> Active Sites -> sort based on “Date Created” – done.
With PowerShell – not so simple. “Get-PnPTenantSite” cmdlet returns site objects but the object does not have “Created” field. You have to connect separately to each site and get root web object where you can check when the web was created. For small environments it is possible, for large environments it can take days… And still not nice. -Filter option would help, but “…Currently, you can filter by these properties: Owner, Template, LockState, Url.”
Get-SPOSite – similar experience.
Microsoft Graph API helps. It returns result in seconds. There are some pros and cons for each method though.
Microsoft Graph Search API allows KQL in queries. So we can form a query with something like “created>=1/1/2021” and use entity type = ‘[“site”]’. Search should return only sites created after Jan 01, 2021.
This option is also based on Microsoft Graph API, but sites entry point, which allows search too and sort results by property “createdDateTime”. So we will just search for everything and select how many results we need based on createdDateTime property.
Scenario: you administer SharePoint Online Microsoft 365 tenant business asks you to remove mobile phone numbers from SharePoint User Profiles:
As a SharePoint administrator, you can do it: 1. Start Microsoft 365 SharePoint Admin Center 2. Navigate to More Features -> User Profiles -> Manage User Properties
3. Under “Contact Information” -> Mobile phone -> Edit
4. Uncheck “Replicable”, Save, wait a minute or two 5. – Select “Default Privacy Settings”: “Only Me” – Uncheck “User can override” – Uncheck “Allow users to edit values for this property” – Uncheck “Show in the profile properties section of the user’s profile page” – Uncheck “Indexed”
Other combination of authentication options ( -interactive, -clientId, -Token, -SPOManagementShell, -PnPManagementShell ) – worked well, but only for /_api endpoints, and gave me “401 UNAUTHORIZED” against system/site pages. Unattended authentication (with clientId, clientSecret and certificate) – same.
Legacy PnP module SharePointPnPPowerShellOnline did not work at all: “EXCEPTION,PnP.PowerShell.Commands.Admin.InvokeSPRestMethod”.
I tested it with – SharePointPnPPowerShellOnline v 3.29.2101.0 (under Windows PowerShell 5.1) and – PnP.PowerShell 1.8.0. (both Windows PowerShell 5.1 and .net core PowerShell 7.1.5)
The error “The term ‘Search-UnifiedAuditLog’ is not recognized”:
Search-UnifiedAuditLog: C:\scripts\PowerShell.auth\Search-AuditLog-w-App.ps1:16:12 Line | 16 | $results = Search-UnifiedAuditLog -StartDate $start -EndDate $end -Re … | ~~~~~~ | The term 'Search-UnifiedAuditLog' is not recognized as a name of a cmdlet, function, script file, or executable | program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
means a proper administrative role (e.g. “Exchange administrator”) is not assigned to the app.
PowerShell is our best friend when it comes to ad-hoc and/or scheduled reports in Microsoft 365. PnP team is doing great job providing more and more functionality with PnP PowerShell module for Office 365 SharePoint and Teams.
Small and medium business organizations are mostly good, but for large companies it might be a problem due to just huge amount of data stored in SharePoint. PowerShell reports on all users or all sites might run days… which is probably OK if you run this report once, but totally not acceptable if you need this report e.g. daily/weekly or on-demand.
How can we make heavy PowerShell scripts run faster?
Of course, you start with logic (algorithm) and leveraging full PowerShell functionality (e.g. PowerShell 7 parallelism or PnP batching).
What if you did everything, but it still takes too long? You need something like brute force – the closer your code runs to your tenant – the better. What are the option? – Automation account runbook (+workflow) – Azure Function Apps – Azure VM in the region closest to your Tenant
Automation account runbook (+workflow)
Seemed like a good option, but not something Microsoft promotes. Even opposite – automation accounts support only PowerShell 5 (not 7), no plug-ins for VS Code and recently there were messages on some retirement or smth.
Meantime, I tested it – and did not find any significant increasing in speed. In a nutshell, what is behind this service? Same windows machines running somewhere in Azure .
Quick answer: spin-up a few VMs in different Azure regions, then ping your SharePoint tenant. The moment you see 1ms ping you know the tenant exact location.
Microsoft says: “Customers should view tenant specific data location information in your Microsoft 365 Admin Center in Settings | Org settings | Organization Profile | Data location.” And it might look like:
That’s accurate to the geography (e.g. US, UE, AP), but not to the region (for instance – “Central US”, “UK West” or “Australia Southeast”). In other words, If you know your data are in the US, you do not know where exactly – East/West/Central or South US. Meantime when you create an Azure resource (e.g. Virtual Machine) – you can select specific region.
How do I know – where is my Microsoft 365 tenant actually located?
Can we just ping the tenant, analyze result and find Office 365 tenant region? Luckily, SharePoint tenant is pinging with just PS>ping tenantName.SharePoint.com I have tested 5 regions and 4 different tenants:
ping from/to (ms)
tenant 1 (US)
tenant 2 (EU)
tenant 3 (US)
tenant 4 (US)
South Central US
So I figured it out: My o365 tenants #3 and #4 regions are South Central US (Texas, San Antonio), tenant #1 resides in East US.
Why do I need this?
Imagine you are running heavy reports against your tenant. So probably you want your code running as close as possible to your tenant. For this, you can spin-up a VM in Azure or use Azure Functions – just select proper region 🙂 (please check also “Long-running PowerShell reports optimization in Office 365“)
Update: Microsoft is deploying an updated version of “Disable Subsites” feature:
This update makes the setting options for new subsite creation easier to understand and prevents users from being able to create subsites using alternate paths when the subsite setting is disabled.
Admins in the SharePoint admin center can choose to either enable or disable subsite creation across sites or enable for classic sites only. Now, when disabling subsite creation, not only will the subsite option be hidden from the command bar including classic but also users will not be able to create new subsites directly through an URL or API.
The option: Hide the Subsite command has been renamed to Disable subsite creation for all sites and will also hide the subsite creation command (including classic) and disable users from being able to create new subsites through a URL or API. The option: Show the Subsite command only for classic sites, has been renamed to Enable subsite creation for classic sites only. The option: Show the Subsite command for all sites, has been renamed to Enable subsite creation for all sites.
Update is applied. What’s Next?
After this update is applied, if you have “Subsite Creation” set to “Disable subsite creation for all sites”, then if any attempt to create a subsite – you’ll get an error message “Sorry, something went wrong. New subsites are not available for your organization. Create a new site instead.”
Site is a new folder
Microsoft recommend “flat structure”, i.e. no subsites. So SPO admins are disabling subsites creation at tenant level. Did you know that you still can create subsite? Let me explain how it is done.
If creation subsites is allowed, you should be able to see it like this:
But actually subsites are not always best practice. Microsoft recommend “flat structure”, i.e. instead of subsite you should have a separate site collection, and if you need a hierarchy and navigation – use Hub sites. So, in Office 365 SharePoint admins usually “disable” SubSites creation:
Now, you see, SubSites are not really disabled, but only the button to create subsites is hidden: “This controls whether the Subsite command appears on the New menu on the Site contents page”.
Anyway, the result is: you are not able to create a SubSite (web) in SharePoint Online:
Actually there are at least 3 options to create a SubSite:
Quick and simple answer: use SharePoint Search center or Microsoft Search, (or Bing if it is integrated).
Detailed explanation on how to find a public Team
In Microsoft Office 365, under MS Teams, there are 3 team types:
Private team: you can only join the team if you are invited or know the team code. SharePoint site behind the private team is shared only to members – not for everyone. You cannot see team name or description or content until you are team member (details). You are not able to search for the team name or content.
Public team: you can join the public team if you wish. The site behind the public team is shared with everyone except external users, so you can see public team name and description, but from MS Teams (desktop or web application) you cannot see public team content until you are team member.
Org-wide team: you are joined the team automatically (details)
From Teams – you can click on “Join or create a team” and you should be able to see some publicteams (but not all):
There is a “Search teams” box at the top right, so what if you are looking for a specific public team (not in the list) …
You know exact team name or at least some first letters. Solution: You are lucky. Just start typing team name in search bar at top right and hit “enter”- you will see shortened list of public teams matching your search criteria:
NB: do not use wildcards, it will not work:
NB: do not use top search bar, it will not work:
You want to join a public team, but you do not know exact team name. You know (or guess) something about the team, like
part of the team name
part of the team description
some keywords from team content files
Unfortunately, in this case both great Microsoft technologies – Search and Team – fail. You will not be able to find a public team:
Solution: use SharePoint search SharePoint site is created once a team is created.
For public teams – SharePoint site has “Everyone except external users” by default in “Members” group:
which means literally “Everyone except external users” has access to the site with “Edit” permissions.
SharePoint search is security-trimmed, i.e. you will see the site content in search results only if you do have access to the site. So just go to the SharePoint or SharePoint search center and search for what you know or guess about the team:
You can use all the power of SharePoint search (wildcards, refiners, keyword query language KQL etc)
Once you found something – you can go to the SharePoint site:
Now from the site – look at the site name and hover the mouse over the site name – you’ll see pop-up window. Now you know exact team name – and you can search for the team under Teams, or, if you are so lucky you see “Join” button – just join the team.click site title or hove over the site title:
One moment – you cannot see team’s chat messages in SharePoint, as chats are kept in Azure. But you can search for chat content after you joint the team.
Somehow both – SharePoint Search and Teams Search are not working against site/team description. Hopefully this bug will be addressed.
You can also search for site Url in teams. When you create a team – Office 365 generates a short team name (removes spaces and adds numbers if the team name is not unique; e.g. if the team name “Test” you might have “test381” as a short name, but if the team name is “This Is My Unique Team” – short name might be “ThisIsMyUniqueTeam”). After you can change team name and/or SharePoint site name. Team search under MS teams work for both names – short name initially assigned (kept as site specific Url) and new team name. But only starting with the beginning of the string.