Nickname (or alias or moniker or hypocorism etc.) is some another name – usually shorter than original name and widely used in maybe all countries in the world. E.g. Bob is a nickname for Robert in the US and GB, Checo is the other name for Sergio in Mexico. There might be personal names also – e.g. Bapu (father) is an word that is usually associated with Mohandas Karamchand Gandhi, also known as the Mahatma Gandhi. More examples: David “Noodles” Aaronson, Roger Keith “Syd” Barrett etc.
In Microsoft 365 we want to search for a person’s name we know – and in many cases it’s a nickname – e.g. Beth (Bethany) or Alex (Alexander). Can m365 search do that?
It takes a few steps to implement search by nickname:
create a custom property under SharePoint Online User Profiles service
fill this property with values
configure Search Schema – map crawled property to managed property
Step-by-Step
Create a custom property under SharePoint Online User Profiles service
Ensure you have a SharePoint Administrator role activated
Navigate to SharePoint Admin Center – more features – User Profiles – Manage user properties – New Property
Configure custom property according to your needs, – ensure “Policy Settings” “Default Privacy Setting:” Everyone is selected – ensure “Search Settings” “Indexed” is selected
Fill SharePoint Online User Profile Properties with values
That would be a custom solution – e.g. manual work from SPO Admin Center GUI or PowerShell script ( e.g. with some dictionary). This is required for search to pick it up, crawl the property and create crawled property – so you could proceed with search schema mapping.
Configure Search Schema – map crawled property to managed property
For the nickname to be generally available in full-text-search – i.e. user simply enter value in a search bar and gets results – here are the steps:
Ensure you have a SharePoint Administrator role activated
Navigate to SharePoint Admin Center – More features – Search – Manage Search Schema
Select Crawled Properties and ensure search picked up your custom property and crawled it – check your crawled property name under Category: People.
Under Managed Properties – create a new managed property
select “Searchable”
under Advanced searchable settings – select Full-text index: PeopleIdx
What is the Microsoft Search KQL query field limits for a verticals? Is there limited number of characters or lines?
You know what is Microsoft 365 Search Vertical and what is KQL query in vertical configuration, right?
Under Microsoft 365 admin center Search and intelligence you can configure search verticals. There are some out-of-the-box verticals – like All, Files, Sites, People and you can configure custom one.
As a part of vertical configuration – you can specify KQL query – if you want e.g. limit search with some sites or content types etc.
The question is – how many sites I can specify in this query field? E.g. can I specify 1000 sites? 10k sites?
And the answer is: It does not matter, because the limit is not in number of characters or lines.
In my dev environment I was able to save 50,000 lines (~3M characters). But attempt to save 100K lines (6M symbols) has failed (due to timeout, I believe:
Again, as I said the problem is not here.
The problem is time required for search to apply query. I.e. when you ask search to bring you something – after it gets results from index and before display results to you it applies KQL query configured for the vertical. And this time is the bottleneck.
Here is what I got measuring search response time depending on query size:
Search
response time, seconds
KQL query # of lines
KQL query size, # of symbols
works
1
500
28,000
works
5
1000
59,000
works
9
2000
120,000
works
25
3000
180,000
works/fails
30
3500
208,000
fails
35
3600
214,000
fails
35
50,000
3,000,000
n/a
n/a
100,000 (can’t save KQL query
6,000,000 (can’t save KQL query)
Which means that after ~ 1000 lines (50,000 characters) KQL query size – query becomes too slow, and after ~3000 lines (180k chars) – can fail (due to timeout I’d say).
DepartmentId
If your sites are organized in hierarchy under Hub site – you can use DepartmentId managed property to significantly decrease number of lines in query, as you can cover all sites under the hub with
If you configure Verticals Query at the tenant level – i.e., Microsoft 365 Administration -> Settings -> Search and intelligence -> Customizations -> Verticals then search results will be trimmed everywhere – SharePoint Landing Page, Office landing page (Office.com), Office App, Bing search (but not other sites).
Teams search will not be affected as from Teams you only search for teams content. Same for Onedrive and Yammer. Sites with site or hub search scope will not be affected too.
If you configure verticals at site level: Site Settings -> Microsoft Search -> Configure search settings -> Verticals and want this be in effect – ensure site search scope is set to site or hub scope. But in this case you will loose answers functionality.
Global search settings – like acronyms, bookmarks and verticals – works only at tenant level search or at site leve if the site search scope is set to tenant. If site search scope is site or hub – then site-level search verticals will apply (and no answers functionality will be possible).
Published: May 1, 2022 Update from Mar 5, 2023: Microsoft confirmed this as valid solution. Update from May 20, 2024: still true Update from June 12, 2024: I have just found “ABP in Exchange Online“… Looking into it…
Scenario
You want specific users do not appear in Microsoft 365 SharePoint, Teams or Outlook search results. For instance, when user left company and the account is not deleted, but just disabled in Entra Id (Azure AD), so account is present and searchable. Or there are two accounts of the same person – main one and a secondary one – so you want secondary account is removed from org structure and search. Etc.
Solution
Set “ShowInAddressList” Azure AD User object property to false. It’s done using Az module, e.g. with PowerShell:
In many cases we do not need some accounts to appear in Microsoft 365 Search. Examples are:
a) secondary or admin accounts e.g. a person have several roles and several accounts under the same name, e.g. regular user: John Smith John.Smith@contoso.com administrative account: John Smith John.Smith.Admin@contoso.com b) role, shared or service accounts: marketing@contoso.com c) non-mail-enabled objects d) disabled accounts
Getting multiple search results for the same person might confuse users and even lead to miscommunication and broken processes.
There is a good article by Tania Menice (Microsoft): Exclude Users From Delve and SharePoint Online People Search with the latest updates explaining how it is done for classic search and stating that currently it is not possible for modern search, but Microsoft is working on it.
In short, the article says:
Set the profiles AD property msExchHideFromAddressLists to True or Yes,
Sync/wait, so finally SharePoint UPA service SPS-HideFromAddressLists property will be updated (as it is mapped to msExchHideFromAddressLists AD property)
Under SharePoint classic search – update query to: {searchboxquery} -“SPS-HideFromAddressLists”:1
It works perfect for classic search. The problem is it does not work as expected in modern Microsoft Search.
“People” vertical is not customizable so far. So we cannot change query in Microsoft 365 search to do the same trick. But… it seems like Microsoft is working on it so finally it should be done by some kind of ootb config.
Here is how different services or search entry points respect SPS-HideFromAddressLists SharePoint UPA property:
So only “People” vertical in Microsoft search does not respect SPS-HideFromAddressLists (msExchHideFromAddressLists).
(Modern) Microsoft 365 Search
What about cloud-based accounts (not synchronized from local AD)?
There is a configuration setting “Show in global address list” that does the same job. It’s under Microsoft 365 admin center -> Active Users -> User – Edit -> Mail -> Show in global address list:
And another configuration settings “Hide from global address list (GAL)” under Exchange Admin Center:
I tested behavior for different kind of accounts and here are results:
User Account
#1
#2
#3
#4
#5
Enabled
Yes
No
Yes
Yes
Yes
Licensed (E5)
No
Yes
Yes
Yes
Yes
m365 Admin Center: Show in Global Address List
n/a
No
No
Yes
No
Exchange Admin Center: Hide from global address list (GAL)
n/a
Yes
Yes
No
Yes
ShowInAddressList Entra Id property value
null
null
null
null
False
SPO UPA ‘SPS-HideFromAddressLists‘ value
False
False
False
False
True
Outlook Address List “All Users”
Shown
Office.com Search: Vertical “All”
Shown
Office.com Search: Vertical “People”
Shown
Shown
Shown
Shown
Bing Work Search: All/People verticals
Shown
Shown
Teams Search: “All” Vertical
Shown
Shown
Teams Search: “People” vertical
Shown
Shown
Shown
Shown
Microsoft 365 Profile card – Organization
Shown
Shown
Teams Profile card – Organization
Shown
Shown
Shown
Shown
Teams People Picker
Shown
Shown
Shown
Shown
SharePoint People Picker
Shown
Outlook People Picker:
Shown
* – some users can see changes after hours, for some it takes days
It seems confusing we have 4 properties responsible for the same:
“Show in Global Address List” under m365 Admin Center
“Hide from global address list (GAL)” under Exchange Admin Center
“ShowInAddressList” Azure AD User object property
“SPS-HideFromAddressLists” SharePoint User Profile property
Are these properties related to each other?
Let’s test it:
Action-Consequences (immediate reaction – minutes if not other mentioned)
“Show in Global Address List” under m365 Admin Center
“Hide from global address list (GAL)” under Exchange Admin Center
ShowInAddressList Azure AD User object property
SPS-HideFromAddressLists SharePoint User Profile property
New user created, license assigned
Yes
Off
null
False
Uncheck “Show in my organization address list” under Microsoft 365 admin center
No
On
after one minute: null after 24 hours: null
after one minute: False after 24 hours: False
Set “ShowInAddressList” Azure AD User object property to “True”
Yes
Off
True
False
Set “ShowInAddressList” Azure AD User object property to “False”
“Show in Global Address List” under m365 Admin Center and “Hide from global address list (GAL)” under Exchange Admin Center – same switch, i.e. if you change one – another is updated automatically Neither of them affect “ShowInAddressList” Azure AD User object property or “SPS-HideFromAddressLists” SharePoint User Profile property
“SPS-HideFromAddressLists” SharePoint User Profile property is not changeable. If you try to change the property value you get an error message: “Set-PnPUserProfileProperty : Property Not Editable: This property can not be modified.“
“ShowInAddressList” Azure AD User object property is editable and synchronized to “Show in Global Address List” under m365 Admin Center and “Hide from global address list (GAL)” under Exchange Admin Center, and also with “SPS-HideFromAddressLists” SharePoint User Profile property (takes minutes), but then search crawler must pick this change up (takes hours) to hide/show the user (this was tested and validated for cloud-born accounts only)
here Microsoft says: regarding showInAddressList – Do not use in Microsoft Graph. Manage this property through the Microsoft 365 admin center instead. Represents whether the user should be included in the Outlook global address list. See Known issue.
Known issue (Microsoft): showInAddressList property is out of sync with Microsoft Exchange. When querying users through Microsoft Graph, the showInAddressList property may not indicate the same status shown in Microsoft Exchange. We recommend you manage this functionality directly with Microsoft Exchange through the Microsoft 365 admin center and not to use this property in Microsoft Graph.
Disclaimer
I used and tested all cloud-born accounts only. I do not have on-prem AD, so If your users are synchronized from local AD – do your own research – is this property synced from some local AD property, and if so – set AD property instead.
Microsoft is constantly changing the product. So what I found out here now might differ with what you work with.
It’s a good idea to test/validate this solution in your non-prod environment and against test users in your prod environment.
Bottom line
Setting “ShowInAddressList” Azure AD User object property to “false” is the most effective way to hide user account from search, but it could be changed only with PowerShell:
There are scenarios when you need to pull only newly created SharePoint sites, e.g. get sites created since yesterday or get last 100 created sites. Usually other articles and existing PowerShell scripts solve this by pulling all sites from tenant and then iterating through sites to get only new sites. That approach is not nice and simply does not work in large environments. How can we get only sites created recently, not all sites? Here is how I use Microsoft Graph API to get only new sites.
Update (6/28/2024): Microsoft announced updates to it’s delta API for SharePoint, so I added option 3 – see below.
Scenario
Let say you administer Teams, OneDrive and SharePoint Online in a Microsoft 365 tenant. You have a pretty big environment – ~10k or more sites and you want to quickly find just new SharePoint sites or teams (e.g. sites created recently – during last hour/day/week/month). This might be required for ad-hoc reports and for automation scenarios – like applying required configurations or assign some property value to all newly created sites.
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 a site object but the object does not have “Created” field. It’s a web property (not site property). But to get a web object – you have to connect separately to each site and get root web object to check when the web was created. For small environments it is possible, for large environments it can take days… And still not nice. “Get-PnPTenantSite” with “-Filter” option would help, but “…Currently, you can filter by these properties: Owner, Template, LockState, Url.”
but… 1) it’ll give you group-based sites only 2) it is not easy to automate 3) this might take long for large environments. I know much better solution:
Solution
Microsoft Graph API helps. It returns result in seconds and you can sort or filter results based on created date . Below are two methods: Option 1 is based on Search and filtering and Option 2 is based on Sites Search and sorting. So there are some pros and cons for each method.
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.
You can use “Get delta” under SharePoint Graph API – check for details here. It says “Get newly created, updated, or deleted sites without having to perform a full read of the entire sites collection”. I’ll do my own testing, but for now check this: Video: Microsoft Graph Delta Capabilities in SharePoint API
Your organization use Microsoft 365. You are implementing or configuring an Intranet Portal (Home Site). Search plays an important role here – you want search be relevant to the context – i.e.
Official Results – if a user searches something on a company’s intranet portal – user expect “official” results, not a something from somebody’s OneDrive or Yammer chat
Promoted Results – so information management team can adjust search with search answers – Bookmarks, Acronyms and Q&As
Problem
Microsoft Bookmarks are working only at tenant level search – i.e. if you want bookmarks work on site level search – you need to set up site search scope as tenant.
So if you configure the Intranet Portal site (Home site) search scope to “site” or “hub” to limit results with site/hub content – you will loose “answers” functionality.
Solution
The solution is very simple:
Keep site search scope as tenant-wide to use answers (boormarks), and
Configure search verticals and query to limit results to “official” sites only
Update Query field with KQL – e.g., with something like
(path:http//contoso.sharepoint.com/sites/IntranetPortal/ OR path:http//contoso.sharepoint.com/sites/CompanyNews/ OR path:http//contoso.sharepoint.com/sites/Onboarding)/)
to get results only from “Intranet Portal” and “Company News” sites.
Keep in mind that this will affect all other SharePoint search entry points – SharePoint landing page, Office.com etc. – so although you can configure All (and Files) verticals, but it’s not recommended. It will confuse users – they expect to search for everything under “All” vertical. Instead, consider custom vertical – e.g. “Official” scope.
After configuring – It might take 1-24 hours for the change to take effect, depending on tenant size.
Service vs Site search
If you configure that at the tenant level – i.e., Microsoft 365 Administration -> Settings -> Search and intelligence -> Customizations -> Verticals then search results will be trimmed everywhere – SharePoint Landing Page, Office landing page (Office.com), Office App, Bing search. Teams search will not be affected as from Teams you only search for teams content. Same for Onedrive and Yammer.
If you want the “official” search results only under Intranet Portal and leave other search entry points unaffected – then you need to configure the same at Home (Intranet Portal) site level: Site Settings -> Microsoft Search -> Configure search settings -> Verticals and configure site search scope to site or hub scope. But in this case you will loose answers functionality.
Global search settings – like acronyms, bookmarks and verticals – works only if site search scope is tenant. If site search scope is site or hub – then site-level search verticals will apply (and no answers functionality will be possible).
Home site is a root site
There might be two problems with that:
if a home site configured as a root site – you KQL will look like(path:http//contoso.sharepoint.com/ OR path:http//contoso.sharepoint.com/sites/CompanyNews)and that query will not work as any site Url will match the root site Url.
if you need to mention many sites in KQL – like 50 sites with an Official Information – you might hit the “number of allowed character” limit
The solution is DepartmentId property:
DepartmentId
Use DepartmentId={<Hub Site ID>} in the KQL qury and your search results will be limited to your hub content while answers will still be working too. You can even combine DepartmentId with other conditions to add more sites (that are not in hub) to search scope:
(DepartmentId={4965d9be-929b-411a-9281-5662f5e09d49} OR path:http//contoso.sharepoint.com/sites/Onboarding OR path:http//contoso.sharepoint.com/sites/CompanyNews)
It worth to mention, that DepartmentId is the property that propagated from the root of the hub site to all associated sites and their content – list items, documents and pages.
Site Property Bag
Another possible option would be – site property bag… The ultimate goal is to provide users with “Official” results only. But official sites might not be all part of one Home site hub. We can include in All search vertical query 10, 50, 100 sites, but what if we have 10k official sites in enterprise – e.g. operated by different departments – and all of them might want to be present in search results. So, how about – if the site is considered official – we create an indexed site property, e.g. “SiteIsOfficial” with a value “Yes”. Then we map the crawled property to a managed property – e.g. RefinableString89 – and use this managed search property in query – e.g. (SiteIsOfficial=Yes).
This is actually clever idea, but this does not work… This query would only return sites, not sites content. E.g. what was indexed as site object – will be included (including home page). But site items – i.a. documents, lists, other pages – all site content – will not be included…
So let’s get back to DepartmentId…
Rename All Vertical
Again – the ultimate goal is to give users option to have “Official” results. But they still might want to be able to search through all content. What if we rename the default “All” vertical to “Home Site” and configure query for official results only. Then we can create a custom vertical called “Everything” or “All” with no query limitations to give users all reasults
Update: not a good idea either… If the home site search scope is tenant – so verticals are configured and be visible at tenant level – i.e. everywhere…
Separate Official Vertical
My personal preference is to keep All vertical as real All, and create a custom Vertical “Official” for official results only where we would use query trick.
There is a new feature in Microsoft 365 SharePoint Online – “Restricted SharePoint Search“. With Restricted SharePoint Search you can restrict organization-wide search to a curated set of “allowed” SharePoint sites – sites that you have checked the permissions and applied data governance for.
Office graph = codename for collective set of services and insights we generate on top of the infrastructure that fast office graph group developed = social Intel concepts (SharePoint home, Delve, OneDrive Discoverview) are derivatives of Office graph
Microsoft Search API provides one unified search endpoint that you can use to query data in the Microsoft cloud – messages and events in Outlook mailboxes, and files on OneDrive and SharePoint – that Microsoft Search already indexes.
Turing technology – understands you, answers your question e.g. hover over doc -> doc summary (based on “deep speed” AI model) announcement at Ignite Spring, more on Ignite Fall 2021
Modern Search: MS nailed the fundamentals, now start bringing it everywhere – to Teams first, then SharePoint (said Nov 2020).
Modern Search Customizations – we’ll take the best from Classic SharePoint Search, a lot will retire – investing in more flexibility
Bill Baer: “People use search in a different ways 1) you have organisations who have a well-established intranet built around set of governance controls, a very clean architecture and they want to build a search into that intranet scenario; that’s why a lot of SharePoint capabilities are going to come along with Microsoft search for that particular endpoint 2) then you have other people who live their day in teams“
Updates
Shared search engine results page (developed once – transitioned everywhere) Ctrl-F to search through teams (chats?) (contextual search) Natural language search (starting from Outlook) Image search (before eoy), +
Metadata content type search Syntex customers will be able to use content type to search in the advanced search flyout in document libraries that contain content types beyond the default types. Syntex only.
Conversations: teams chats, outlook groups conversations, yammer conversation can be found under Conversations vertical in Bing search. Later – in Office.com and SharePoint landing page. E-mail messages are added to Conversations vertical in Bing search
Bookmarks (new promoted results), acronyms, Q&A – all under “Answers”
BookmarksTargeting – for the specific audience based on device/OS, Country/Region, security groups…
SharePoint Search Admin Center -> will be migrated from SharePoint admin center to to Microsoft Search Admin Center transitioning (Search and Intelligence Admin Center) – long-running project custom dictionaries, spelling suggestions – will retire, (move to a graph-driven speller)
+ Viva Topics – based search capabilities
Create Topic Answers with Microsoft Viva Topics to bring together people, content, and information (including synonyms and acronyms)
Knowledge answers provide a direct answer to questions authoritative information in an organization across SharePoint and OneDrive content
Files/Calendars/Links answers
Graph Connectors Graph Connectors are generally available (ADLS – Azure Data Lake Storage Gen2, Azure DevOps, Azure SQL and Microsoft SQL Server, Enterprise websites, MediaWiki, File share, Oracle SQL, Salesforce, Jira, Confluence, ServiceNow + 100+ from partners; New connectors coming to Microsoft Search: Jira Graph connector, Confluence Graph connector).
Graph Connector allows to connect external source of information to Microsoft 365 and makes that data available across all m365 apps and services so you can find what you need wherever you’re working, whether in one of your favorite productivity apps or one of the many Microsoft 365 services such as SharePoint or Office.com
Graph Connectors roadmap:
Actionable experiences Search results on select Graph connectors will soon support actions that will allow users to interact with the result and perform changes to the Connector content within the Search application.
Results clusters The results shown in a result cluster are grouped together based on the search vertical configuration.
Profile Query variables Define any attribute from the user’s Profile, as a query variable and it would be resolved during query evaluation (This feature is currently in preview)
Profile enrichment with Graph connectors …you will soon be able to enrich Microsoft 365 profile properties like Job title, Phone numbers, Skills etc. with data from HRMS systems using graph connectors. …then surface this rich profile information on people experiences like profile cards.
Search Federation federation capabilities will allow enterprises build and integrate their custom LOB search experiences, customized search providers, into the overall Microsoft Search. With federated search, you can make information from systems where the data cannot leave the systems boundaries available to search across in Microsoft 365 productivity apps and services, without indexing its data with Microsoft Search.
Standalone Search – AAD identity – Graph connector – Ingest your data – use Search = in Windows 10, Office.com ( e.g. for those who have their data in other productivity suite, have no intent to use m365, but want to search)
There is a known problem in SharePoint (and Teams*) – complicated permissions system. Site owners/administrators provide access, site contributors upload documents and at any moment nobody knows – who has access to which files. As a result – sometimes sensitive documents become overshared (over-exposed). The biggest concern is when sites content is shared with “Everyone”. How do we know which content is shared with “Everyone”? Is there a report?
Obviously, only data owner knows who should have access to site documents, so we (SharePoint admins) do not fix permissions automatically (until there is a policy), but at least we can help site owners with reports and maybe initiate permissions review for “nasty” sites?
Below I’m sharing 4 possible solutions:
Solution #0 – Out-of-the-box EEEU report, but it comes with Premium license only
Solution #1 – also OotB report that comes with some 3-rd party tools
Solution #2 – PowerShell “Brute force” – free but require advanced skills and efforts
Solution #3 – Search-based – also free, and require less skills and efforts
(*) Microsoft with the introduction of Teams had to simplify permissions in SharePoint – since there should only be 3 types of access levels – owner, member and visitor. It was… in some ways, but in other ways it made things worse.
You are lucky if you can use 3-rd party tools (e.g. ShareGate, SysKit Point, AvePoint, Metalogix etc.), with the ability to get full permissions report. Though – if your m365 environment is not small – there might be a problem to get full permissions report for all tenant sites. Some tools allow you to get tenant-wide permissions report for specific Ids – this option should work better for large environments.
Still there might be another problem. Consider the following. When I say “shared with Everyone” – I actually mean at least 3 possible “everyone” system logins:
Everyone
Everyone except external users
All users
– those are system id’s, but what if there are other ids – e.g. migrated from on-prem or cloud-born custom security groups in tenant that also includes everyone or many users (e.g. dynamic security group that includes all org accounts)?
What if your Identity management operates security groups “All employee” or “Contractors” or “All licensed users”? Do you think these groups can be identified as “Everyone” groups? Do you think it’d be a good idea to check if content is shared with other large groups (not only system Everyone…)? Would you like to run permissions report separately for all groups that include “all” or “almost all” users?
Also, knowing that full reports heavily load the system, 3-rd party tools might by default limit “how deep report is” to the root site and lists/libraries, not including e.g. folders and items. So you might need go to settings and turn on “full deep” option Keep it in mind.
Obviously this option #1 is not free, as it requires licenses to be obtained. And still it worth to consider option 3.
Solution #2 (PowerShell “Brute force”)
You can get full permissions report per site or for entire tenant with PowerShell, which if free… The only you need is to write a script yourself or find existing one. Sounds easy?
Well, first problem is it takes a decent amount of time and competences to write such script. If if you find one – it would require some skills to adopt and run it. Frankly say, I have not seen so far scripts that were out-of-the-box ready to do that job. And it is not a good idea to run scripts you got from internet against your production environment until you understand it tested it and fully confident with.
Another possible problem – size of environment. The script I designed and use to get comprehensive permissions report might run hours against a good site – if I need full details on site/subsites, lists/libraries, folders and list items levels. So if you have less than 1000 sites – probably this approach can fly. But if your environment is 10K+ sites – it will take forever. So the approach might not work for large enterprise environments.
One might say – we can limit report with only root web permissions to get it faster. But this would be not accurate. And what is not accurate in the IT security – leads to even bigger risks. So, we need check permissions up to every item level deep, as even one file with sensitive info shared inappropriately can cause security issue. (Btw, 3-rd party tools usually by default limit reports to libraries level, so check reporting options…)
The other issue with this approach… Let say you got full permissions report… It would look like “resource -> group -> permissions”… How do you know for each group – what is the group in terms of membership?
Ok, if this solution is not easy to get working – what are other options?
Solution #3 (Search-based)
This solution is based on simple but clever idea: why do we need to iterate through all the tenant documents/items if all the content is already crawled by search? Search is also respect permissions. Can we just use search to get files shared with Everyone? Let us see.
What if we use some dummy user account with no specific permissions provided and no group memberships and try to search content on behalf of that account. The idea is if this user can see some data – then these data is open to everyone.
With this option we would use search query “*” and all 5 possible SharePoint entities – driveItem’,’listItem’,’list’,’drive’,’site’ to find everything that is shared with everyone. We’d pull results with paging (we’d use “from” option in a loop to pull all results). After we get all results – we’d select only unique site collections. But! We might have some problems here.
Problem #1. Again, for small environments or if there are not much “Open” sites – it would work. But for large enterprise environments the problem is the same as in “brute force”. Search would returns too many results – and it might take weeks (exact time is unpredictable) to get all of them. (Surely there are sites “legally” shared with everyone, public Office 365 group based sites, communication sites… So your search will be flooded with content from sites you already know are shared with all).
Problem #2. We are getting results with paging. But recently Microsoft started limiting number of returning results. E.g. your search request result might say like “there are 3659735 total hits” but after result number 1000 it just stops returning anything, even with paging.
Solution#3 Option #2 – loop sites
The idea is: why do we need to get all search results if even one result from a site would be enough to put the site to the list of “open” sites. In other words, we do not need all results from the site, we only need to know if there are any results from the site, at least one – so we know if the site is open for everyone or not.
So, consider the following approach:
You get list of all sites in tenant.
You run search request against each site in the loop (e.g. consider KQL option “Site: https://yourTenant.SharePoint.com/sites/YourSite”. If at least something found in the site – add the site to the “Open Sites” list. With this approach you will get list of sites shared with “Everyone…” in a predictable time.
Solution#3 Option #3 – exclude known “open” sites
There are sites “legally” shared with everyone – e.g. corporate portal, department communication sites, public teams, public Viva Engage communities etc. If it is know that these sites are public – you can exclude them from all sites list – so in the “Solution#3 Option #2 – loop sites” – you’d loop only through sites that are not supposed to be public. I know – percentage of “legally public” sites in tenant to all sites is a relatively small number, so should not significantly decrease elapsed time… but still.
Pros and cons of the Solution # 3
Pro 1: the only fast enough (at least predictable time to complete) and accurate enough to rely on solution.
Pro 2: There might be custom security groups intended to hold all or part of the enterprise (e.g. “All employee” or “all contractors”). If the enterprise comprises from several businesses or regions – it might be “All Business 1” or “All EMEA”… you got the idea. So you can tweak this search-based solution by adding your dummy account you are running search on behalf of to some of theses groups to find out if there are resources shared maybe not with everyone but with all “North America based” users or with “all employees”, which might make sense also.
Con 1 : crawling and indexing takes time, so search-based reports can miss recent changes in data and permissions
Con 2: this approach cannot be automated (since we need an interactive authentication). I.e. we need to run it manually every time.
Con 3: After we get all sites shared with everyone – we do not know – at what level permissions are broken and provided to everyone. It might be entire site or one file. It does not really help if you try to get all search results from the site. If you want to know what exactly is shared with everyone – on the site – run permissions report against this site (shortlist of sites).
Notes
Note 1: consider there are resources like “Styles Library” shared with everyone by default, especially on migrated sites
Note 2: this is a separate topic, but consider implementing/using sensitivity labels. At least you can start with high-sensitive sites. With sensitivity labels – site owners/member would know – what kind of site they are working on.
What’s next
Ok, we know list of SharePoint resources shared with everyone, but what would be the next step? Should we communicate to site owners – if so how to let site owners know that there are resources shared with Everyone… on their sites. To be continued…