0

I'm using the below script to find all list and library items that are shared(to internal and external users) in a SharePoint Online site.

I am able to identify the documents which are shared but not able to get the email address to whom the document is shared and also the link type of sharing.

Also even if a document is shared to multiple users, $LinkTitle is displaying only one SharedLinks object.

Not sure how to retrieve all the email address from $LinkTitle object.

#Load SharePoint CSOM Assemblies
 Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll" 
 Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
 Clear-Content -path "D:\uniquepermissions.csv"

 Function Invoke-LoadMethod() {
 param([Microsoft.SharePoint.Client.ClientObject]$Object = $(throw "Please provide a Client Object"),[string]$PropertyName) 
 $ctx = $Object.Context
 $load = [Microsoft.SharePoint.Client.ClientContext].GetMethod("Load") 
 $type = $Object.GetType()
 $clientLoad = $load.MakeGenericMethod($type)  
 $Parameter = [System.Linq.Expressions.Expression]::Parameter(($type), $type.Name)
 $Expression = [System.Linq.Expressions.Expression]::Lambda([System.Linq.Expressions.Expression]::Convert([System.Linq.Expressions.Expression]::PropertyOrField($Parameter,$PropertyName),[System.Object] ), $($Parameter))
$ExpressionArray = [System.Array]::CreateInstance($Expression.GetType(), 1)
$ExpressionArray.SetValue($Expression, 0)
$clientLoad.Invoke($ctx,@($Object,$ExpressionArray))
}
#Variables for Processing
$SiteUrl = "SiteURL"
$CSVPath = "D:\UniquePermissions.csv"
$UserName="username"
$Password ="password"

#Setup Credentials to connect
$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName,(ConvertTo-SecureString $Password -AsPlainText -Force))

Try {
 #Function to Get all lists from the web
 Function Get-SPOList($Web)
 {
    #Get All Lists from the web
    $Lists = $Web.Lists
    $Context.Load($Lists)
    $Context.ExecuteQuery()

    #Get all lists from the web   
    ForEach($List in $Lists)
    {
        #Get the List Name
     #Get All Lists of the web
     $Listname=$List.Title
#Setup the context
    $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
    $Ctx.Credentials = $Credentials
    $List = $Ctx.Web.Lists.GetByTitle($ListName)
    $Ctx.Load($List)
    $Ctx.ExecuteQuery()
    #Write-host "Total List Items Found in " $List.Title "is : " $List.ItemCount

    #Batch process list items - to mitigate list threshold issue on larger lists
   Do {  
    #Get 2000 items from the list
    $Query = New-Object Microsoft.SharePoint.Client.CamlQuery
    $Query.ViewXml = "<view Scope='RecursiveAll'><rowlimit>2000</rowlimit></view>"
    $ListItems = $List.GetItems($Query)
    $Ctx.Load($ListItems)
    $Ctx.ExecuteQuery()

    $Query.ListItemCollectionPosition = $ListItems.ListItemCollectionPosition

    #Loop through each List item
    ForEach($ListItem in $ListItems)
    {
        Invoke-LoadMethod -Object $ListItem -PropertyName "HasUniqueRoleAssignments"
        Invoke-LoadMethod -Object $ListItem -PropertyName "RoleAssignments"

        $Ctx.ExecuteQuery()
        if ($ListItem.HasUniqueRoleAssignments -eq $true)
        {        
           $Roles= $listItem.RoleAssignments
           $Ctx.load($Roles) 
           $Ctx.ExecuteQuery() 
           $RolesCount = $Roles.Count

            If($RolesCount -gt 0) 
        { 
         for ($i = $RolesCount -1; $i -ge 0 ; --$i)   
           {    
              $Link=$Roles[$i].Member 
              $Ctx.Load($Link) 
              $Ctx.ExecuteQuery() 
              $LinkTitle = $Link.Title
             If($LinkTitle -like "SharingLinks*") 
              { 
           Write-Host -f Green "List Item '$($ListItem["Title"])' with ID '$($ListItem.ID)' has Unique Permissions with count " $RolesCount "Link:" $LinkTitle
           $Site = Get-SPOSite -identity $SiteURL
           $SiteName = $Site.Title
           $SiteURL = $SiteURL
           $ListTitle = $List.Title
           $ItemName = $ListItem.Title
           $ItemID = $ListItem.ID
           $Itemdata = Add-Content -Path D:\ps_scripts\uniquepermissions.csv -Value "$($SiteName.ToString()),$($SiteURL.ToString()), $($ListTitle.ToString()),$($ItemID.ToString()),$($Link.Title.ToString())"                         
           } 
             $Link = $null 
           }   
          $Ctx.ExecuteQuery()            
          }       
          }
          }
       } While ($Query.ListItemCollectionPosition -ne $null)
      }
    }
    #Function to get all webs from given URL
    Function Get-SPOWeb($WebURL) 
     {
      #Set up the context
      $Context = New-Object Microsoft.SharePoint.Client.ClientContext($WebURL)
      $Context.Credentials = $Credentials
      $Web = $context.Web
      $Context.Load($web)
      #Get all immediate subsites of the site
      $Context.Load($web.Webs)  
    $Context.executeQuery()

    #Call the function to Get Lists of the web
    Write-host "Processing Web :"$Web.URL
    Get-SPOList $Web

    #Iterate through each subsite in the current web
    foreach ($Subweb in $web.Webs)
    {
        #Call the function recursively to process all subsites underneaththe current web
        Get-SPOWeb($SubWeb.URL)
    }
}

#Call the function to get all sites
Get-SPOWeb $SiteUrl
}
catch {
 #write-host "Error: $($_.Exception.Message)" -foregroundcolor Red
 }

 $tempCSV = Import-Csv D:\ UniquePermissions.csv -Header "Site Name","Site URL", "List Name", "Item ID", "Item Title" | select -skip 0
$tempCSV | Export-CSV D:\UniquePermissions.csv -NoTypeInformation

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.