Export Shared files and Links from SharePoint Online using PowerShell

In this post, we will share CSOM based PowerShell script to get all shared documents from SharePoint Online or OneDrive for Business site. The script also exports sharing links and shared file details to CSV file.

We can easily find shared files by retrieving SharePoint list items that have unique permissions. In this script, we are going to use GitHub open-source library Load-CSOMProperties.ps1 to use lambda expressions to query CSOM object properties (ex: HasUniqueRoleAssignments) in SharePoint CSOM API. For more details, you can refer to this post: How to load additional CSOM properties in PowerShell

Export Sharing Links and Shared file details to CSV file

The PowerShell script includes the following works.

  • Get all list items (files) that have unique (or explicit) permission entries in a given SharePoint Online document library or OneDrive for Business site.
  • Get shared file details such as file id, name, type, URL, author name, editor name, and more.
  • Retrieve sharing object information for the list items which has unique permissions.
  • Export all the sharing links along with their file details.

To use CSOM in PowerShell, we need to load the required Microsoft SharePoint Online SDK assembly files.

#Add required references to SharePoint client assembly to use CSOM 
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime") 
 
#Import the function Load-CSOMProperties to query CSOM object properties
#Read more: https://morgantechspace.com/2017/09/how-to-load-additional-csom-properties-powershell.html
C:\Scripts\Load-CSOMProperties.ps1
$Result = @()
 
#Specify SharePoint or OneDrive site admin account
$adminAccount = "user@<tenant-name>.onmicrosoft.com"
$adminPwd = "<user_password>"
  
#Specify SharePoint Online Site URL or User's OneDrive Site URL
$siteURL = "https://<tenant-name>.sharepoint.com/sites/site_name"
#$siteURL = "https://<tenant-name>-my.sharepoint.com/personal/username_domainame_com"
$documentLibrary ="Documents"
 
#Connect and Load SharePoint Library and Root Folder
$secPwd = $(ConvertTo-SecureString $adminPwd -asplaintext -force) 
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl) 
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($adminAccount,$secPwd) 
$ctx.credentials = $credentials
$list = $ctx.Web.Lists.GetByTitle($documentLibrary)
$ctx.Load($list)
$ctx.ExecuteQuery()

#CAML query to retrieve all list items
$camlQuery = New-Object Microsoft.SharePoint.Client.CamlQuery
$camlQuery.ViewXml = "@
<View Scope='RecursiveAll'>   
    <RowLimit Paged='TRUE'>3000</RowLimit>
</View>"

#Query List items Page by Page to avoid List View Threshold error
Do {

$allItems=$list.GetItems($camlQuery)
$ctx.Load($allItems)
$ctx.ExecuteQuery()

#Set the next page position
$camlQuery.ListItemCollectionPosition = $allItems.ListItemCollectionPosition
 
$i = 0;
$TotoalFiles = $allItems.Count
foreach($item in $allItems)
{ 
$i++
Write-Progress -activity "Processing $($item["FileRef"])" -status "$i out of $TotoalFiles completed"
 
Load-CSOMProperties -object $item -propertyNames @("HasUniqueRoleAssignments");
$ctx.ExecuteQuery()
 
if($item.HasUniqueRoleAssignments) {
 
$sharingInfo = [Microsoft.SharePoint.Client.ObjectSharingInformation]::GetObjectSharingInformation($ctx, $item, $false, $false, $false, $true, $true, $true, $true);
$ctx.Load($sharingInfo);
$ctx.ExecuteQuery();
 
ForEach($shareLink in $sharingInfo.SharingLinks) {
if($shareLink.Url)
{
 
$linkAccess="ViewOnly"
if($shareLink.IsEditLink){
$linkAccess="Edit"
} elseif($shareLink.IsReviewLink){
$linkAccess="Review"
}
 
$Result += New-Object PSObject -property $([ordered]@{ 
FileID = $item.FieldValues["UniqueId"]
Name  = $item.FieldValues["FileLeafRef"]            
FileType = $item.FieldValues["File_x0020_Type"]
RelativeURL = $item.FieldValues["FileRef"]
CreatedByEmail = $item.FieldValues["Author"].Email
CreatedOn  = $item.FieldValues["Created"]
Modified   = $item.FieldValues["Modified"]
ModifiedByEmail  = $item.FieldValues["Editor"].Email
ShareLink  = $shareLink.Url
ShareLinkAccess  =  $linkAccess
ShareLinkType  = $shareLink.LinkKind
AllowsAnonymousAccess  = $shareLink.AllowsAnonymousAccess
IsActive  = $shareLink.IsActive
})
}
}
}
}
} 
While($camlQuery.ListItemCollectionPosition -ne $Null) #Check the next page is available or not
 
$Result | Export-CSV "C:\Temp\SharedFileDetails.CSV" -NoTypeInformation -Encoding UTF8

The above commands store the details in the array object $Result, we can generate the required report from this result array. Run the following command to list only the links which give Edit access to the users.

$Result | Where-Object { $_.ShareLinkAccess -eq 'Edit'}

The below command lists sharing links that allow view-only access for the users.

$Result | Where-Object { $_.ShareLinkAccess -eq 'ViewOnly'}

Run the following command to list all anonymous access links.

$Result | Where-Object { $_.AllowsAnonymousAccess -eq $true}
Advertisement

9 thoughts on “Export Shared files and Links from SharePoint Online using PowerShell”

  1. This is excellent however, why does my export on one site work fine, and the other site just exports “”.

    Reply
    • Check the count in $Result variable ($Result.Count) for your problematic site. If the count is 0, then there is no shared links in the site.

      Reply
  2. Here is my error. Not sure why it is saying i have browse to the site first. Any help is appreciated.

    I am trying to pull the locations that each sharing link points to in a onedrive site. I have #’d out the site line and removed the # on the personal line.

    Exception calling “ExecuteQuery” with “0” argument(s): “Cannot contact web site
    ‘https://higherecheloninc-my.sharepoint.com/’ or the web site does not support SharePoint Online credentials. The
    response status code is ‘Unauthorized’. The response headers are ‘MS-CV=oFgOFJ/AACBHlTQppIMZ/Q.0,
    X-Cache=CONFIG_NOCACHE, Connection=Keep-Alive, request-id=140e58a0-c09f-2000-4795-3429a48319fd, SPIisLatency=0,
    X-MSEdge-Ref=Ref A: 5C027503A2CE46F8AEA2D408A5254DA8 Ref B: MIA301000102019 Ref C: 2022-08-05T15:51:35Z,
    SPRequestGuid=140e58a0-c09f-2000-4795-3429a48319fd, X-MS-InvokeApp=1; RequireReadOnly, X-MSDAVEXT_Error=917656; Access+
    denied.+Before+opening+files+in+this+location%2c+you+must+first+browse+to+the+web+site+and+select+the+option+to+login+a
    utomatically., SPRequestDuration=11, X-Content-Type-Options=nosniff, X-SharePointHealthScore=2,
    Strict-Transport-Security=max-age=31536000, MicrosoftSharePointTeamServices=16.0.0.22720, Content-Length=0,
    Content-Type=text/plain; charset=utf-8, Date=Fri, 05 Aug 2022 15:51:35 GMT, P3P=CP=”ALL IND DSP COR ADM CONo CUR CUSo
    IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI”, X-Powered-By=ASP.NET’.”
    At D:\work\Powershell\Sharepoint\sharedfile.ps1:26 char:1
    + $ctx.ExecuteQuery()
    + ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : NotSupportedException

    Exception calling “ExecuteQuery” with “0” argument(s): “Cannot contact web site
    ‘https://xxx.sharepoint.com/’ or the web site does not support SharePoint Online credentials. The
    response status code is ‘Unauthorized’. The response headers are ‘MS-CV=oFgOFLNgACAYvFKtfwAx2w.0,
    X-Cache=CONFIG_NOCACHE, Connection=Keep-Alive, request-id=140e58a0-60b3-2000-18bc-52ad7f0031db, SPIisLatency=0,
    X-MSEdge-Ref=Ref A: 5B6691267A874A07995A59BB538F8539 Ref B: MIA301000102019 Ref C: 2022-08-05T15:51:35Z,
    SPRequestGuid=140e58a0-60b3-2000-18bc-52ad7f0031db, X-MS-InvokeApp=1; RequireReadOnly, X-MSDAVEXT_Error=917656; Access+
    denied.+Before+opening+files+in+this+location%2c+you+must+first+browse+to+the+web+site+and+select+the+option+to+login+a
    utomatically., SPRequestDuration=20, X-Content-Type-Options=nosniff, X-SharePointHealthScore=2,
    Strict-Transport-Security=max-age=31536000, MicrosoftSharePointTeamServices=16.0.0.22720, Content-Length=0,
    Content-Type=text/plain; charset=utf-8, Date=Fri, 05 Aug 2022 15:51:35 GMT, P3P=CP=”ALL IND DSP COR ADM CONo CUR CUSo
    IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI”, X-Powered-By=ASP.NET’.”
    At D:\work\Powershell\Sharepoint\sharedfile.ps1:31 char:1
    + $ctx.ExecuteQuery()
    + ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : NotSupportedException

    The collection has not been initialized. It has not been requested or the request has not been executed. It may need
    to be explicitly requested.
    At D:\work\Powershell\Sharepoint\sharedfile.ps1:36 char:9
    + foreach($item in $allItems)
    + ~~~~~
    + CategoryInfo : OperationStopped: (:) [], CollectionNotInitializedException
    + FullyQualifiedErrorId : Microsoft.SharePoint.Client.CollectionNotInitializedException

    Reply

Leave a Comment