I'd like to know if it's possible to create a script to check a library for all guest access links (authenticated, not anonymous) and if they are older than 90 days, remove them. So for each folder that was shared with an external user <90 days ago, remove link.

Here is a script to remove all links (tweaked from this post Remove a specific link from SharePoint Online):

Function Remove-SPSharingLink { 

param (    

    Connect-PnPOnline -Url $SPURL  
    $Ctx= Get-PnPContext 

    $Files= Get-PnPListItem -List "Documents" 
    foreach( $File in $Files) 

            $Froles= $File.RoleAssignments 

            If($Froles.Count -gt 0) 

              for ($i = $Froles.Count -1; $i -ge 0 ; --$i)   
                  If($Link.title -like "SharingLinks*") 
                  $Link = $null 


Remove-SPSharingLink -SPURL "https://MyTenant.sharepoint.com/sites/MySite"

But I'm not sure how to get the sharing link details and filter by date.


  • Why not just implement the 90 day expiration in the SPO admin center's sharing settings? – Trevor Seward Nov 1 '19 at 14:24
  • That's only possible for anonymous "anyone" links, right? Not for "Specific People" links. Also unfortunately I'm in a shared tenant and I don't have the right to make tenant-wide decisions like that. Thanks! – Sylvie Nov 1 '19 at 14:46
  • That's correct. Your usage of "guest access links" refers to anonymous links rather than 'specific people'. – Trevor Seward Nov 1 '19 at 14:47
  • Thanks, edited the original post so it is clearer. – Sylvie Nov 1 '19 at 14:49

There is no way, that I am aware of, to get the link shared date. You could store it as part of a script or app but that won't help for the first time you run it.

You can find guests using a search query and appending ViewableByExternalUsers=true. It is less expensive and quicker than what you are trying. So something like:

#This checks the last modified date. Not the link date...
#The important part is ViewableByExternalUsers:true
#You can figure this query out to suit you from a search box. 
#This only returns docs. You may want folders etc.
$query = "Write>=$((Get-date).AddDays(-90).ToString("dd/MM/yyyy")) AND ViewableByExternalUsers:true AND IsDocument:true AND NOT contentclass:STS_ListItem_WebPageLibrary"

$keyWordQry = New-Object Microsoft.SharePoint.Client.Search.Query.KeywordQuery($ctx)
$keyWordQry.TrimDuplicates = $false
$keyWordQry.EnableStemming = $false
$keyWordQry.QueryText = $query
$searchExec = New-Object Microsoft.SharePoint.Client.Search.Query.SearchExecutor($ctx)
$results = $searchExec.ExecuteQuery($keyWordQry)

At this point you have an object you can enumerate to get what you want:


Do note that this only returns the first 50 results by default. You can return more by setting $keyWordQry.RowLimit and/or passing a start point to the query via $keyWordQry.StartRow

Also you would need to handle folder, library and site sharing. All possible with search though.

  • Thanks Bunzab! The strange thing is that you can get the shared date in Flow with the "Shared with details", but there is no action in Flow to remove that specific sharing link. Only removing all access. So it's like I have half of what I need in Flow and half of what I need in PS. But surely if I can get the data in Flow I should be able to get it in PS, no? – Sylvie Nov 4 '19 at 13:03

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.