Skip to content

[BUG] Set-PnPListItemPermission ignores parameter -User #4814

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
1 of 6 tasks
Scheune10 opened this issue Mar 26, 2025 · 1 comment
Open
1 of 6 tasks

[BUG] Set-PnPListItemPermission ignores parameter -User #4814

Scheune10 opened this issue Mar 26, 2025 · 1 comment
Labels
in review PR or issue is currently being reviewed

Comments

@Scheune10
Copy link

Scheune10 commented Mar 26, 2025

Reporting an Issue or Missing Feature

Set-PnPListItemPermission

Expected behavior

I expect that the cmdlet removes the permissions of a specific user mail

f.e.:
Permissions before executing cmdlet:
user1 has the permission contribute on the file
user2 has the permissions contribute and read on the file

cmdlet:
Set-PnPListItemPermission -List 'Documents' -Identity fileID -User 'User1Mail' -RemoveRole 'contribute'

Permissions after executing cmdlet:
user1 has no permissions on the file
user2 has the permissions contribute and read on the file

Actual behavior

The cmdlet removes the permissions not only of the specific user, but also of any other user who has the same permissions as the specific user

f.e.:
Permissions before executing cmdlet:
user1 has the permission contribute on the file
user2 has the permissions contribute and read on the file

cmdlet:
Set-PnPListItemPermission -List 'Documents' -Identity fileID -User 'User1Mail' -RemoveRole 'contribute'

Permissions after executing cmdlet:
user1 has no permissions on the file
user2 has the permission read on the file

Steps to reproduce behavior

Function Get-PnPFilePermissionsForAllFiles([Microsoft.SharePoint.Client.Web]$Web, [string]$ReportFile, [bool]$RetrieveAllFiles, [array]$FilesToRetrieve, [string]$User, [string]$UserMail, [bool]$UnsubscribeFiles, [array]$FilesToUnsubscribe)
{
    $Lists = Get-PnPProperty -ClientObject $Web -Property Lists
    $ExcludedLists = @("Access Requests","App Packages","appdata","appfiles","Apps in Testing","Cache Profiles","Composed Looks","Content and Structure Reports","Content type publishing error log","Converted Forms",
    "Device Channels","Form Templates","fpdatasources","Get started with Apps for Office and SharePoint","List Template Gallery", "Long Running Operation Status","Maintenance Log Library", "Images", "site collection images"
    ,"Master Docs","Master Page Gallery","MicroFeed","NintexFormXml","Quick Deploy Items","Relationships List","Reusable Content","Reporting Metadata", "Reporting Templates", "Search Config List","Site Assets","Preservation Hold Library",
    "Site Pages", "Solution Gallery","Style Library","Suggested Content Browser Locations","Theme Gallery", "TaxonomyHiddenList","User Information List","Web Part Gallery","wfpub","wfsvc","Workflow History","Workflow Tasks", "Pages")

    foreach ($List in $Lists)
    {
        if ($List.BaseType -eq "DocumentLibrary" -and $List.Hidden -eq $false -and $ExcludedLists -notcontains $List.Title)
        {
            Write-Host "Scanning library: $($List.Title)..."

            if($RetrieveAllFiles -eq $true){
                $ListItems = Get-PnPListItem -List $List -PageSize 2000 | Where-Object {$_.FileSystemObjectType -eq "File"}

                foreach ($FileItem in $ListItems)
                {
                    Get-PnPFilePermissions -FileItem $FileItem -ReportFile $ReportFile
                }
            } else {
                foreach ($File in $FilesToRetrieve){
                    $ListItems = Get-PnPListItem -List $List -PageSize 2000 | Where-Object { $_["FileLeafRef"] -eq $File }
                    
                    if ($ListItems.Count -ne 0) {
                        Write-Host -f Green "$File found in Library: $($List.Title)"
                        foreach ($FileItem in $ListItems)
                        {
                            if ($FileItem.FileSystemObjectType -eq "File")
                            {
                                Get-PnPFilePermissions -FileItem $FileItem -ReportFile $ReportFile -User $User -UserMail $UserMail -UnsubscribeFiles $UnsubscribeFiles -FilesToUnsubscribe $FilesToUnsubscribe -List $List.Title
                            }
                        }
                    }
                }
            }
        }
    }
}

Function Get-PnPFilePermissions([Microsoft.SharePoint.Client.ListItem]$FileItem, [string]$ReportFile, [string]$User, [string]$UserMail, [bool]$UnsubscribeFiles, [array]$FilesToUnsubscribe, [string]$List)
{
    $FileName = $FileItem["FileLeafRef"]
    $FileURL = $FileItem["FileRef"]

    $FileItemRoleAssignments = Get-PnPProperty -ClientObject $FileItem -Property RoleAssignments
    $PermissionCollection = [System.Collections.Generic.List[object]]::new()

    foreach ($RoleAssignment in $FileItemRoleAssignments)
    {
        Get-PnPProperty -ClientObject $RoleAssignment -Property RoleDefinitionBindings, Member
        $PermissionType = $RoleAssignment.Member.PrincipalType
        $PermissionLevels = $RoleAssignment.RoleDefinitionBindings | Select -ExpandProperty Name
        $PermissionLevels = ($PermissionLevels | Where { $_ -ne "Limited Access" }) -join "; "
        If ($PermissionLevels.Length -eq 0) { Continue }

        If ($PermissionType -eq "SharePointGroup")
        {
            $GroupMembers = Get-PnPGroupMember -Identity $RoleAssignment.Member.LoginName
            If ($GroupMembers.count -eq 0) { Continue }

            $GroupUsers = ($GroupMembers | Select -ExpandProperty Title | Where { $_ -ne "System Account" }) -join "; "
            If ($GroupUsers.Length -eq 0) { Continue }

            $IsSharingLink = $RoleAssignment.Member.LoginName -match "SharingLinks"
            if ($IsSharingLink){
                $Permissions = New-Object PSObject
                $Permissions | Add-Member NoteProperty FileName($FileName)
                $Permissions | Add-Member NoteProperty FileURL($FileURL)
                $Permissions | Add-Member NoteProperty Users($GroupUsers)
                $Permissions | Add-Member NoteProperty Type("SharingLink")
                $Permissions | Add-Member NoteProperty Permissions($PermissionLevels)
                $Permissions | Add-Member NoteProperty GrantedThrough($RoleAssignment.Member.LoginName)
                $PermissionCollection.Add($Permissions)
            } else {
                $Permissions = New-Object PSObject
                $Permissions | Add-Member NoteProperty FileName($FileName)
                $Permissions | Add-Member NoteProperty FileURL($FileURL)
                $Permissions | Add-Member NoteProperty Users($GroupUsers)
                $Permissions | Add-Member NoteProperty Type($PermissionType)
                $Permissions | Add-Member NoteProperty Permissions($PermissionLevels)
                $Permissions | Add-Member NoteProperty GrantedThrough("SharePoint Group: $($RoleAssignment.Member.LoginName)")
                $PermissionCollection.Add($Permissions)
            }
        }
        ElseIf ($PermissionType -eq "User")
        {
            $PrincipalTitle = if ($RoleAssignment.Member.Title) { $RoleAssignment.Member.Title } else { $RoleAssignment.Member.LoginName }

            $Permissions = New-Object PSObject
            $Permissions | Add-Member NoteProperty FileName($FileName)
            $Permissions | Add-Member NoteProperty FileURL($FileURL)
            $Permissions | Add-Member NoteProperty Users($PrincipalTitle)
            $Permissions | Add-Member NoteProperty Type($PermissionType)
            $Permissions | Add-Member NoteProperty Permissions($PermissionLevels)
            $Permissions | Add-Member NoteProperty GrantedThrough("Direct Permissions")
            $PermissionCollection.Add($Permissions)
        }
    }

    $UnsubscribedFiles = @()
    if ($UnsubscribeFiles -eq $true){
        foreach($FileName in $FilesToUnsubscribe){
            $File = Get-PnPListItem -List $List -PageSize 2000 | Where-Object { $_["FileLeafRef"] -eq $FileName }
            $UnsubscribedFiles += $File
        }
        foreach ($FileItem in $UnsubscribedFiles){
            Unsubscribe_Files -FileItem $FileItem -User $User -UserMail $UserMail -List $List
        }
    }

    $PermissionCollection | Export-CSV $ReportFile -NoTypeInformation -Append
}

Function Unsubscribe_Files([Microsoft.SharePoint.Client.ListItem]$FileItem, [string]$User, [string]$UserMail, [string]$List)
{
    Write-Host -f Blue "Trying to unsubscribe Permissions of the User $User from file: $($FileItem["FileLeafRef"])"
    
    $FileItemRoleAssignments = Get-PnPProperty -ClientObject $FileItem -Property RoleAssignments

    foreach ($RoleAssignment in $FileItemRoleAssignments)
    {
        Get-PnPProperty -ClientObject $RoleAssignment -Property RoleDefinitionBindings, Member
        $PermissionType = $RoleAssignment.Member.PrincipalType
        $PermissionLevels = $RoleAssignment.RoleDefinitionBindings | Select -ExpandProperty Name
        $PermissionLevels = ($PermissionLevels | Where { $_ -ne "Limited Access" }) -join "; "
        If ($PermissionLevels.Length -eq 0) { Continue }

        If ($PermissionType -eq "SharePointGroup")
        {
            $GroupMembers = Get-PnPGroupMember -Identity $RoleAssignment.Member.LoginName
            If ($GroupMembers.Count -eq 0) { Continue }

            $GroupUser = $GroupMembers | Where-Object { $_.Title -eq $User }
            If ($GroupUser)
            {
                Write-Host -f Red "Permission of $User cannot be deleted because they are part of the SharePoint group $($RoleAssignment.Member.LoginName), which has permissions on file $($FileItem["FileLeafRef"])"
            }
        }
        ElseIf ($PermissionType -eq "User")
        {
            If ($RoleAssignment.Member.LoginName -match $UserMail)
            {
                $RoleDefinitions = $RoleAssignment.RoleDefinitionBindings
                
                foreach ($RoleDefinition in $RoleDefinitions)
                {
                    Write-Host -f Yellow "Removing permission $($RoleDefinition.Name) for user $User on file $($FileItem['FileLeafRef'])"
                    Set-PnPListItemPermission -List $List -Identity $FileItem.Id -User $UserMail -RemoveRole $RoleDefinition.Name 
                }
            }
        }
    }
}

$SiteURL = "sharepoint URL"
$ReportFile = "CSV path"
$RetrieveAllFiles = $false
$FilesToRetrieve = @("filename")
$UnsubscribeFiles = $true
$FilesToUnsubscribe = @("filename")
$User = "firstname lastname"
$UserMail = "firstname.lastname@mail.com"

Connect-PnPOnline -Url $SiteURL -UseWebLogin

Get-PnPFilePermissionsForAllFiles -Web (Get-PnPWeb) -ReportFile $ReportFile -RetrieveAllFiles $RetrieveAllFiles -FilesToRetrieve $FilesToRetrieve -User $User -UserMail $UserMail -UnsubscribeFiles $UnsubscribeFiles -FilesToUnsubscribe $FilesToUnsubscribe

What is the version of the Cmdlet module you are running?

2.12.0

Which operating system/environment are you running PnP PowerShell on?

  • Windows
  • Linux
  • MacOS
  • Azure Cloud Shell
  • Azure Functions
  • Other : please specify
@Scheune10 Scheune10 added the bug Something isn't working label Mar 26, 2025
@KoenZomers
Copy link
Collaborator

I cannot reproduce this on the latest nightly build. Could you try it with the latest build and see if this works for you there?

@KoenZomers KoenZomers added in review PR or issue is currently being reviewed and removed bug Something isn't working labels Apr 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in review PR or issue is currently being reviewed
Projects
None yet
Development

No branches or pull requests

2 participants