powershell icon indicating copy to clipboard operation
powershell copied to clipboard

[BUG] Set-PnPListItemPermission ignores parameter -User

Open Scheune10 opened this issue 8 months ago • 1 comments

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 = "[email protected]"

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?

  • [x] Windows
  • [ ] Linux
  • [ ] MacOS
  • [ ] Azure Cloud Shell
  • [ ] Azure Functions
  • [ ] Other : please specify

Scheune10 avatar Mar 26 '25 09:03 Scheune10