WIP wrapper module for PnP PowerShell SharePoint permissions
This commit is contained in:
parent
ab2740394a
commit
030730448d
234
m365/PnPFolderAcl/PnPFolderAcl.psm1
Normal file
234
m365/PnPFolderAcl/PnPFolderAcl.psm1
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
|
||||||
|
#region Private Helpers
|
||||||
|
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Tests if a PnP Group exists.
|
||||||
|
.DESCRIPTION
|
||||||
|
This function tests if a PnP Group exists in the current SharePoint site.
|
||||||
|
.PARAMETER Identity
|
||||||
|
The identity of the group to test.
|
||||||
|
.EXAMPLE
|
||||||
|
Test-PnPGroup -Identity "MyGroup"
|
||||||
|
#>
|
||||||
|
function Test-PnPGroup {
|
||||||
|
param(
|
||||||
|
[string]$Identity
|
||||||
|
)
|
||||||
|
|
||||||
|
try {
|
||||||
|
Get-PnPGroup -Identity $Identity -ErrorAction Stop | Out-Null
|
||||||
|
return $true
|
||||||
|
} catch {
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Tests if an Entra ID Group exists and PnP can resolve it.
|
||||||
|
.DESCRIPTION
|
||||||
|
This function tests if a Entra ID Group exists and can be resolved by PnP.
|
||||||
|
.PARAMETER Identity
|
||||||
|
The identity of the group to test.
|
||||||
|
.EXAMPLE
|
||||||
|
Test-EntraIdGroup -Identity "MyGroup"
|
||||||
|
#>
|
||||||
|
function Test-EntraIdGroup {
|
||||||
|
param(
|
||||||
|
[string]$Identity
|
||||||
|
)
|
||||||
|
|
||||||
|
try {
|
||||||
|
Get-PnPEntraIdGroup -Identity $Identity -ErrorAction Stop | Out-Null
|
||||||
|
return $true
|
||||||
|
} catch {
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Functions
|
||||||
|
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Sets permissions on a folder in a SharePoint document library.
|
||||||
|
.DESCRIPTION
|
||||||
|
This script breaks permission inheritance on a specified folder in a SharePoint document library and assigns permissions to a specified owner group and additional groups defined in the ACL parameter.
|
||||||
|
.PARAMETER Name
|
||||||
|
The name of the folder to set permissions on.
|
||||||
|
.PARAMETER List
|
||||||
|
The name of the document library containing the folder. Default is 'Shared Documents'.
|
||||||
|
.PARAMETER Owner
|
||||||
|
The name of the SharePoint group to assign as the owner of the folder with 'Full Control' permissions.
|
||||||
|
.PARAMETER Acl
|
||||||
|
An array of objects defining additional groups and their permissions to assign to the folder. Each object should have a 'DisplayName' property for the group name and a 'Role' property for the permission level (e.g., 'Read', 'Edit').
|
||||||
|
.EXAMPLE
|
||||||
|
$Acl = @(
|
||||||
|
@{ DisplayName = "SG-ADMIN-AdvocateFloats-Dynamic"; Role = "Edit" },
|
||||||
|
@{ DisplayName = "SG-ADMIN-AdvocateManagers-Dynamic"; Role = "Edit" }
|
||||||
|
)
|
||||||
|
.\Set-PnPFolderAcl.ps1 -Name "ProjectX" -List "Shared Documents" -Owner "Project Owners" -Acl $Acl
|
||||||
|
#>
|
||||||
|
function Set-PnPFolderAcl {
|
||||||
|
[CmdletBinding(
|
||||||
|
SupportsShouldProcess = $true,
|
||||||
|
ConfirmImpact = 'High'
|
||||||
|
)]
|
||||||
|
param(
|
||||||
|
[Parameter(
|
||||||
|
Mandatory,
|
||||||
|
ValueFromPipeline,
|
||||||
|
ValueFromPipelineByPropertyName
|
||||||
|
)]
|
||||||
|
[string]$FolderName,
|
||||||
|
|
||||||
|
[Parameter()]
|
||||||
|
[string]$List = 'Shared Documents',
|
||||||
|
|
||||||
|
[Parameter(Mandatory)]
|
||||||
|
[string]$Owner,
|
||||||
|
|
||||||
|
[Parameter(Mandatory)]
|
||||||
|
[pscustomobject[]]$Acl
|
||||||
|
)
|
||||||
|
|
||||||
|
begin {
|
||||||
|
if (-not (Get-PnPContext)) {
|
||||||
|
Throw "Not connected to a SharePoint site. Run Connect-PnPOnline first."
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not (Get-PnPList -Identity $List -ErrorAction SilentlyContinue)) {
|
||||||
|
Throw "The specified list '$List' does not exist."
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not (Test-PnPGroup -Identity $Owner)) {
|
||||||
|
Throw "The specified owner group '$Owner' does not exist."
|
||||||
|
}
|
||||||
|
|
||||||
|
$ValidRoles = Get-PnPRoleDefinition | Select-Object -ExpandProperty Name
|
||||||
|
|
||||||
|
if (-not $ValidRoles) {
|
||||||
|
throw "Unable to retrieve SharePoint role definitions."
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
foreach ($entry in $Acl) {
|
||||||
|
if (-not ($entry.PSObject.Properties.Name -contains 'Group' -and
|
||||||
|
$entry.PSObject.Properties.Name -contains 'Role')) {
|
||||||
|
Throw "Each ACL entry must contain 'Group' and 'Role' properties."
|
||||||
|
}
|
||||||
|
if (-not (Test-PnPGroup -Identity $entry.Group) -and
|
||||||
|
-not (Test-EntraIdGroup -Identity $entry.Group)) {
|
||||||
|
Throw "The specified group '$($entry.Group)' does not exist as a PnP Group or Entra ID Group."
|
||||||
|
}
|
||||||
|
if ($entry.Role -notin $ValidRoles) {
|
||||||
|
Throw "Invalid role '$($entry.Role)' specified for group '$($entry.Group)'. Valid roles are: $($ValidRoles -join ', ')."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
process {
|
||||||
|
$FolderPath = "$List/$FolderName"
|
||||||
|
|
||||||
|
# Retrieve folder and current permissions
|
||||||
|
$FolderItem = Get-PnPFolder -Url $FolderPath -ErrorAction Stop
|
||||||
|
$ListItem = Get-PnPListItem -List $List -Id $FolderItem.ListItemAllFields.Id
|
||||||
|
|
||||||
|
|
||||||
|
# Break inheritance ONLY IF the folder doesn't already have unique permissions
|
||||||
|
if (-not $ListItem.HasUniqueRoleAssignments) {
|
||||||
|
|
||||||
|
if ($PSCmdlet.ShouldProcess(
|
||||||
|
$FolderPath,
|
||||||
|
"Break inheritance and grant Full Control to '$Owner' on '$FolderPath'."
|
||||||
|
)) {
|
||||||
|
|
||||||
|
Write-Verbose "Breaking inheritance for '$FolderPath'."
|
||||||
|
Write-Verbose "Granting 'Full Control' to '$Owner' on '$FolderPath'."
|
||||||
|
|
||||||
|
Set-PnPFolderPermission `
|
||||||
|
-List $List `
|
||||||
|
-Identity $FolderPath `
|
||||||
|
-Group $Owner `
|
||||||
|
-AddRole 'Full Control' `
|
||||||
|
-ClearExisting
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get existing role assignments
|
||||||
|
$RoleAssignments = Get-PnPProperty -ClientObject $ListItem -Property RoleAssignments
|
||||||
|
|
||||||
|
$CurrentAcl = foreach ($ra in $RoleAssignments) {
|
||||||
|
$principal = Get-PnPProperty -ClientObject $ra -Property Member
|
||||||
|
$bindings = Get-PnPProperty -ClientObject $ra -Property RoleDefinitionBindings
|
||||||
|
|
||||||
|
foreach ($binding in $bindings) {
|
||||||
|
[pscustomobject]@{
|
||||||
|
Principal = $principal.Title
|
||||||
|
Role = $binding.Name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# foreach ($entry in $CurrentAcl) {
|
||||||
|
|
||||||
|
# if ($entry.Principal -eq $Owner) {
|
||||||
|
# continue
|
||||||
|
# }
|
||||||
|
|
||||||
|
# if
|
||||||
|
# }
|
||||||
|
|
||||||
|
foreach ($entry in $Acl) {
|
||||||
|
|
||||||
|
$GroupName = $entry.Group
|
||||||
|
$Role = $entry.Role
|
||||||
|
|
||||||
|
$AlreadyAssigned = $ResolvedRoles | Where-Object {
|
||||||
|
$_.Principal -eq $GroupName -and
|
||||||
|
$_.Role -eq $Role
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($AlreadyAssigned) {
|
||||||
|
Write-Verbose "Permission '$Role' already assigned to '$GroupName' on '$FolderPath'. Skipping."
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Test-PnPGroup $GroupName) {
|
||||||
|
if ($PSCmdlet.ShouldProcess(
|
||||||
|
$FolderPath,
|
||||||
|
"Grant '$Role' to SharePoint group '$GroupName' on '$FolderPath'."
|
||||||
|
)) {
|
||||||
|
|
||||||
|
Write-Verbose "Granting '$Role' to SharePoint group '$GroupName' on '$FolderPath'."
|
||||||
|
|
||||||
|
Set-PnPFolderPermission `
|
||||||
|
-List $List `
|
||||||
|
-Identity $FolderPath `
|
||||||
|
-Group $GroupName `
|
||||||
|
-AddRole $Role
|
||||||
|
}
|
||||||
|
} elseif (Test-EntraIdGroup $GroupName) {
|
||||||
|
if ($PSCmdlet.ShouldProcess(
|
||||||
|
$FolderPath,
|
||||||
|
"Grant '$Role' to Entra ID group '$GroupName' on '$FolderPath'."
|
||||||
|
)) {
|
||||||
|
|
||||||
|
Write-Verbose "Granting '$Role' to Entra ID group '$GroupName' on '$FolderPath'."
|
||||||
|
|
||||||
|
Set-PnPFolderPermission `
|
||||||
|
-List $List `
|
||||||
|
-Identity $FolderPath `
|
||||||
|
-Group $GroupName `
|
||||||
|
-AddRole $Role
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
Export-ModuleMember -Function Set-PnPFolderAcl
|
||||||
Loading…
x
Reference in New Issue
Block a user