The command

CommandStatus
m365g governance inspect external-accessPublished, tenant-verified

The inspection reaches no tenant, so no tenant can verify it: it stands on the collections it reads, and its label is theirs. Its earlier name is m365g inspect external-access; inspect arrived in 1.0.0b10.

CollectionCollected byStatus
sites-sharingm365g spo sharing listPublished, tenant-verified
tenant-sharingm365g spo tenant sharing getPublished, tenant-verified
guestsm365g entra guest listPublished, tenant-verified
sites-guestsm365g spo site guestsPublished, tenant-verified

What a composed inspection is

A collector reads one surface. An inspection relates what several collectors read:

Text
collector -> dataset -> join -> inspection

It makes no call to a tenant, so the same evidence always gives the same inspection. It brings no reading of a Microsoft surface of its own: every value it shows is a fact some collector published, with that collector's state. And it is not an assessment. It relates what was observed and names what it could not establish; it counts nothing as good or bad and reaches no outcome. Rules do that.

The commands that feed it

  • m365g spo sharing list contributes what each enumerated site permits: sharing.capability, read site by site.
  • m365g spo tenant sharing get contributes what the organisation permits: tenant_sharing.capability.
  • m365g entra guest list contributes the guest accounts in the directory, when its evidence is present.
  • m365g spo site guests contributes which guest accounts each site has met, when its evidence is present.
  • m365g spo site list contributes no value. A site that was enumerated and has no sharing read still gets a row, which says the setting was not read.

The first four are the collections the inspection declares it reads, and it runs with any of them missing. The fifth is not required: the inspection gives a row to every SharePoint site document it finds under the directory, so an enumeration kept beside the others makes unread sites visible instead of absent.

PowerShell
m365g spo sharing list --tenant-url https://contoso-admin.sharepoint.com --evidence-out ./evidence/sharing
m365g spo tenant sharing get --tenant-url https://contoso-admin.sharepoint.com --evidence-out ./evidence/tenant
m365g governance inspect external-access --evidence ./evidence

--evidence is searched recursively. The first two commands reach a tenant; the third does not. With only these two collections kept, every row says guests met [not-collected]: the read that would answer it is not in the evidence.

What it prints

Text
Which SharePoint sites permit sharing outside the organisation, and how far?

Board Papers  https://contoso.sharepoint.com/sites/board-papers
  in force         not-established  (this site's sharing setting was not read)
  site / org       [permission-denied] / ExternalUserSharingOnly
  external sharing not-established · new guests not-established · anonymous links not-established
  guests met       [not-collected]

Finance Close  https://contoso.sharepoint.com/sites/finance-close
  in force         Disabled  (the site's own setting)
  site / org       Disabled / ExternalUserSharingOnly
  external sharing not-permitted · new guests not-permitted · anonymous links not-permitted
  guests met       [not-collected]

Project Falcon  https://contoso.sharepoint.com/sites/project-falcon
  in force         ExternalUserSharingOnly  (bounded by what the organisation permits)
  site / org       ExternalUserAndGuestSharing / ExternalUserSharingOnly
  external sharing permitted · new guests permitted · anonymous links not-permitted
  guests met       [not-collected]

Supplier Portal  https://contoso.sharepoint.com/sites/supplier-portal
  in force         ExternalUserSharingOnly  (the site's own setting)
  site / org       ExternalUserSharingOnly / ExternalUserSharingOnly
  external sharing permitted · new guests permitted · anonymous links not-permitted
  guests met       [not-collected]

4 SharePoint sites in the evidence:
  external sharing not-established: 1
  external sharing not-permitted: 1
  external sharing permitted: 2

Not established by this inspection:
  - which guests exist in the directory: no guest collection is in this evidence
  - whether anything on a site is in fact shared: a setting says what is permitted, and neither sharing links nor site membership were read
  - which person outside the organisation can reach which site: that needs site membership or sharing links joined to a guest's object id, and neither was read
  - sites the collecting identity could not enumerate: they are absent from the evidence and their number is not knowable from it

From 5 evidence documents, sha256:60e81480dac2…, collected 2026-11-10T09:21:40Z to 2026-11-10T09:23:05Z.

The counts at the end are the number of rows in each state, named for the state they count. They are not added into anything.

--output csv and --output md give one row per site, with the columns name, url, site_capability, organisation_capability, in_force, external_sharing, new_guests, anonymous_links, guests_met and because:

Text
name,url,site_capability,organisation_capability,in_force,external_sharing,new_guests,anonymous_links,guests_met,because
Board Papers,https://contoso.sharepoint.com/sites/board-papers,[permission-denied],ExternalUserSharingOnly,not-established,not-established,not-established,not-established,[not-collected],this site's sharing setting was not read
Finance Close,https://contoso.sharepoint.com/sites/finance-close,Disabled,ExternalUserSharingOnly,Disabled,not-permitted,not-permitted,not-permitted,[not-collected],the site's own setting
Project Falcon,https://contoso.sharepoint.com/sites/project-falcon,ExternalUserAndGuestSharing,ExternalUserSharingOnly,ExternalUserSharingOnly,permitted,permitted,not-permitted,[not-collected],bounded by what the organisation permits
Supplier Portal,https://contoso.sharepoint.com/sites/supplier-portal,ExternalUserSharingOnly,ExternalUserSharingOnly,ExternalUserSharingOnly,permitted,permitted,not-permitted,[not-collected],the site's own setting

--out FILE also writes the inspection as JSON, with the digest of the evidence it was made from, so that somebody else can check it was made from the same documents.

What is in force

SharePoint does not let a site permit more than its organisation. So what is in force for a site is the less permissive of two settings: the site's own, and the organisation's. Each row says which of the two decided, in its because.

In the output above the organisation is set to ExternalUserSharingOnly:

  • Project Falcon is set to ExternalUserAndGuestSharing, which is more than the organisation permits. In force: ExternalUserSharingOnly, bounded by what the organisation permits.
  • Supplier Portal is set to ExternalUserSharingOnly, the same as the organisation. In force: ExternalUserSharingOnly, the site's own setting.
  • Finance Close is set to Disabled, which is less than the organisation permits. In force: Disabled, the site's own setting.
  • Board Papers was not read: [permission-denied]. In force: not-established, because this site's sharing setting was not read.

Two cases never borrow a value. When the site's setting was not read, nothing is in force that the inspection can name, and the row is not-established: it is not given the organisation's value and not given its neighbours'. When the organisation's setting was not read, the row carries the site's own value and says that the bound was not established.

The four values, and what each permits

The values are SharePoint's own names for the SharingCapability setting of a site and of an organisation, in Microsoft's order from the most restrictive to the least. Each permits what the one before it permits, and one thing more.

  • Disabled: external sharing not-permitted, new guests not-permitted, anonymous links not-permitted.
  • ExistingExternalUserSharingOnly: external sharing permitted, new guests not-permitted, anonymous links not-permitted.
  • ExternalUserSharingOnly: external sharing permitted, new guests permitted, anonymous links not-permitted.
  • ExternalUserAndGuestSharing: external sharing permitted, new guests permitted, anonymous links permitted.

A value outside these four is reported as not-established, with the value named, and is not guessed at.

Guest accounts, beside the sites and joined to nothing

When evidence from m365g entra guest list is among the evidence it is given, the inspection reports the guest accounts by condition.

Published, tenant-verified

This part stands on a read that has read one directory, a population of one account. The Engine's record says the inspection then reported that account without joining it to any site. Neither a pending invitation nor a disabled account was observed there, so the lines that count those conditions are proved on documents shaped like the read's output, as the example below is.

The end of the same inspection, with a guest collection of four accounts kept beside the other two:

Text
4 SharePoint sites in the evidence:
  external sharing not-established: 1
  external sharing not-permitted: 1
  external sharing permitted: 2

Guest accounts in the directory (read: observed):
  accounts read 4 · enabled 3 · disabled 1
  invitations accepted 3 · pending 1
  These accounts exist. Which sites any of them can reach was not read.

Not established by this inspection:
  - whether anything on a site is in fact shared: a setting says what is permitted, and neither sharing links nor site membership were read
  - which person outside the organisation can reach which site: that needs site membership or sharing links joined to a guest's object id, and neither was read
  - sites the collecting identity could not enumerate: they are absent from the evidence and their number is not knowable from it

From 10 evidence documents, sha256:481b73f9568c…, collected 2026-11-10T09:21:40Z to 2026-11-10T09:40:00Z.

Each number counts guest accounts in one stated condition: read, enabled, disabled, invitation accepted, invitation pending. They are not added to anything and nothing is concluded from them.

With only the directory's guests in the evidence, the relation guest to site is not joined. The inspection states it among its relations, in these words: guest -> site: NOT JOINED. A guest account existing and a site permitting guests are two facts side by side, and nothing read connects one to the other.

With a guest collection present, the line about which guests exist leaves the list of what is not established. When the guest read ended in any state other than observed, the line stays and says that what was read is a lower bound.

Which guests each site has met

Published, tenant-verified

This read has read one directory. That is what the label above stands on, and the Engine's record of the read lists what it did not cover. The two sides of the comparison with the directory's guests did not overlap there, so a guest that is both listed and met has not been observed against a directory: that branch is proved by a test only. What an account is that a site has met and the directory does not list as a guest was not read. The sites that refused were recorded under an earlier classification in that run; the corrected one is proved by a test over the same messages. Being in a site's list of users is not having access, and nothing in the read is about access. And it was one directory at one moment, which establishes nothing about how another answers.

When evidence from m365g spo site guests is also present, each row gains guests met, and the inspection joins a site's list of users to the directory's guests on the object identifier both carry. The same inspection again, with that collection kept beside the others:

Text
Board Papers  https://contoso.sharepoint.com/sites/board-papers
  in force         not-established  (this site's sharing setting was not read)
  site / org       [permission-denied] / ExternalUserSharingOnly
  external sharing not-established · new guests not-established · anonymous links not-established
  guests met       [permission-denied]

Project Falcon  https://contoso.sharepoint.com/sites/project-falcon
  in force         ExternalUserSharingOnly  (bounded by what the organisation permits)
  site / org       ExternalUserAndGuestSharing / ExternalUserSharingOnly
  external sharing permitted · new guests permitted · anonymous links not-permitted
  guests met       3

4 SharePoint sites in the evidence:
  external sharing not-established: 1
  external sharing not-permitted: 1
  external sharing permitted: 2

Guest accounts in the directory (read: observed):
  accounts read 4 · enabled 3 · disabled 1
  invitations accepted 3 · pending 1
  These accounts exist. Which sites any of them can reach was not read.

Guest accounts the sites have met, by directory object id:
  distinct accounts 3
  also listed as guests in the directory 2 · not listed as guests 1
  listed as guests and met by no site 2
  A site having met an account is not that account having access.

Not established by this inspection:
  - whether anything on a site is in fact shared: a setting says what is permitted, and neither sharing links nor site membership were read
  - which person outside the organisation can open which site today: a site's list of users says the site has met an account, an entry stays after a permission is removed, and a guest reached through a group may have access with no entry of their own
  - what an account is that a site has met and the directory does not list as a guest: it may have been removed from the directory, or be an external account whose type is not Guest. Neither was read
  - sites the collecting identity could not enumerate: they are absent from the evidence and their number is not knowable from it

From 14 evidence documents, sha256:6ce78af5ef04…, collected 2026-11-10T09:21:40Z to 2026-11-10T09:40:00Z.

It says met, and never access. The relation the inspection states is that the site HAS MET the account, which is not the account having access, and the block ends on the same sentence. An entry in a site's list of users stays after a permission is removed, and a guest reached through a group may have access with no entry of their own.

The block counts accounts, on each side of the join and on neither side more than once.

  • distinct accounts: the accounts the sites have met, each counted once however many sites met it.
  • also listed as guests in the directory and not listed as guests: where each of those accounts was found in the directory's guests. An account a site has met and the directory does not list may have been removed from the directory, or be an external account whose type is not Guest. Neither was read, and the inspection does not decide.
  • listed as guests and met by no site: the directory's guests that no site's list holds.

Without a guest collection in the evidence the three comparison lines are not printed, and only the distinct accounts are.

Board Papers shows guests met [permission-denied]: the site refused that read. [not-collected] on a row means the site has no such read in the evidence. Neither is a site that has met no guest; that is 0.

Two inspections, compared

An inspection kept with --out can be compared with a later one of the same question.

PowerShell
m365g governance inspect-diff external-access-november.json external-access-december.json
Text
What changed: Which SharePoint sites permit sharing outside the organisation, and how far?

  before 5 documents, collected 2026-11-10T09:21:40Z to 2026-11-10T09:23:05Z
  after  4 documents, collected 2026-12-10T09:30:00Z to 2026-12-10T09:30:00Z

Entered the evidence: 0
Left the evidence: 1
  Supplier Portal
Changed: 3
  Board Papers
    site_capability: [permission-denied] -> Disabled
    organisation_capability: ExternalUserSharingOnly -> ExternalUserAndGuestSharing
    in_force: not-established -> Disabled
    external_sharing: not-established -> not-permitted
    new_guests: not-established -> not-permitted
    anonymous_links: not-established -> not-permitted
  Finance Close
    organisation_capability: ExternalUserSharingOnly -> ExternalUserAndGuestSharing
  Project Falcon
    organisation_capability: ExternalUserSharingOnly -> ExternalUserAndGuestSharing
    in_force: ExternalUserSharingOnly -> ExternalUserAndGuestSharing
    anonymous_links: not-permitted -> permitted
Unchanged: 0

Not established by this comparison:
  - why a row left: it is not in the later evidence, which is not the same as the resource no longer existing
  - what happened between the two collections: two readings are two moments, and a value that changed and changed back is not seen
  - when anything changed: only that it differs between the two collection times recorded above

Between the two collections the organisation's setting changed, and with it what is in force for Project Falcon, whose own setting did not move. Finance Close shows the organisation's value changing beside it and nothing in force changing. Supplier Portal left the evidence.

The comparison reaches no tenant and reads two files and nothing else. It is m365g governance inspect-diff, which the Engine's reference names without a validation state: Published

Only like is compared with like. The two inspections must be the same scenario with the same parameters. Anything else is refused with exit 2, because the difference in the question would be reported as a change in the tenant:

Text
refusing to compare: the two inspections differ in scenario: 'external-access' and 'ownership'. Comparing them would report the difference in the question as a change in the tenant.

A row that left is not a resource that was deleted. It is a resource that is not in the later evidence: removed, or no longer shown to the identity that collected, or not collected that time. The comparison prints what it does not establish, and that is the first line of it.

What it does not establish

The inspection prints this list itself, on every run, and it is the part to read first. A setting says what is permitted. It does not say what happened.

  • Which guests exist in the directory, when no guest collection is in the evidence.
  • Whether anything on a site is in fact shared. Neither sharing links nor site membership were read.
  • Which person outside the organisation can open which site. Without the guests each site has met, nothing joins a person to a site. With them, the site has met an account and no more: an entry stays after a permission is removed, and a guest reached through a group may have access with no entry of their own.
  • What an account is that a site has met and the directory does not list as a guest.
  • Sites the collecting identity could not enumerate. They are absent from the evidence, and their number is not knowable from it.

So external sharing permitted on a row is a statement about a setting. It is not a statement that the site is shared, that it has guests, or that anybody outside has opened it.

What is planned beside it

ReadStatus
Delegated permission grantsPlanned, not implemented

The Engine's permission notes prepare it and request nothing.