Grant Permissions to All Communication Sites Associated with a Hub Site

This isn’t rocket science, but it’s something I do often enough that I want to lodge the PowerShell in a post instead of continuing to rewrite it.

When we are building an Intranet, we often want to grant permissions for all the Communication Sites to a small set of people during the testing process. This script will do that for one user.

Here is a quick overview of what is happening:

  • Everything before line 12 is just set up. I define a few variables pointing to the Admin Site and Hub Site. I connect to the Admin Site in line 9, and then I have a token which is reusable for all the other connections.
  • In line 12, I get all the sites which are associated with the Hub Site. In this case, it is the root site in the tenant and also a Home Site. This is the most common setup for an Intranet.
  • Next I loop through all the associated sites. The first step is to connect to each site.
  • I’m finding both the Owners and Members groups in lines 16-17. We may want to make some people Owners and other People Members, and we can use the appropriate group in line 18.
  • Communication Sites don’t have backing Microsoft 365 Groups, so I can use the Add-PnPGroupMember cmdlet, which just adds the user(s) to the correct SharePoint group.
  • You could duplicate line 18 to grant permissions to more than one person.
# Import modules
Import-Module PnP.PowerShell

# Base variables
$adminUrl = "https://tenant-admin.sharepoint.com/"
$HubSiteURL = "https://tenant.sharepoint.com/"

# Connect to the tenant
Connect-PnPOnline -Url $adminUrl -Interactive

# Get the sites associated with the Intranet Hub Site
$associatedSites = Get-PnPHubSiteChild -Identity $HubSiteURL | Sort-Object 

foreach ($site in $associatedSites) {
    Connect-PnPOnline -Url $site -Interactive
    $ownerGroup = (Get-PnPSiteGroup | Where-Object { $_.LoginName -like "*Owner*" })[0]
    $memberGroup = (Get-PnPSiteGroup | Where-Object { $_.LoginName -like "*Member*" })[0]
    Add-PnPGroupMember -LoginName "[email protected]" -Group $ownerGroup.LoginName

}

I know the best way to do this is by using a Microsoft 365 Group, but this down and dirty approach makes sense in a limited way. When we launch the Intranet, we’ll clean out all the Members and Visitors to start fresh, so it doesn’t matter that much if we are a bit messy for now. Plus, we may be granting temporary Member permissions to someone just during the build phase.


Eagle-eyed reader Brian McCullough (@bpmccullough) pointed out I was working too hard to get the Member and Owner groups.

Rather than these two lines:

$ownerGroup = (Get-PnPSiteGroup | Where-Object { $_.LoginName -like "*Owner*" })[0]
$memberGroup = (Get-PnPSiteGroup | Where-Object { $_.LoginName -like "*Member*" })[0]

We can do this:

$ownerGroup = Get-PnPGroup -AssociatedOwnerGroup
$memberGroup = Get-PnPGroup -AssociatedMemberGroup

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.