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