Deletion of company-wide and anonymous sharing links with PowerShell
Sharing is a powerful feature for collaboration. However depending on how items, files or folders are shared, a sharing link might be created or unique permissions on these items are created.
The sharing link is created when the copy links is clicked from the sharing pop up options when people other those already have existing access are picked.
However by default, if sharing options have not been configured, links to “People in ” or “Anyone” (if external sharing is allowed) is selected
The sharing behaviour can be changed to “People with existing access” using PowerShell to prevent accidental sharing not to worsen the situation.
The end user will have the option to create links with “People you choose” specifying people or groups. These are the direct sharing links. For this option there has been a conscious permission assignment.
The script will help to remove any sharing links created at the list or library level with the option to include or exclude any direct links, i.e. “People You choose” links
Sample PowerShell Script
param(
[Parameter(Mandatory)]
[ValidateSet('Yes','No')]
[string]$ExcludeDirectSharingLink,#anonymous and company wide links are included by default and this provides an option to include the "People You choose" links in the deletio process.
[Parameter(Mandatory)]
[ValidateSet('Yes','No')]
[string]$DeleteSharingink,
[Parameter(Mandatory)]
[string]$SiteUrl
)
#Parameters
$dateTime = (Get-Date).toString("dd-MM-yyyy-hh-ss")
$invocation = (Get-Variable MyInvocation).Value
$directorypath = Split-Path $invocation.MyCommand.Path
$fileName = "SharedLinksDeletion-" + $dateTime + ".csv"
$ReportOutput = $directorypath + "\Logs\"+ $fileName
$global:Results = @();
$siteUrl = if ($siteUrl[-1] -ne '/') { $siteUrl + '/' } else { $siteUrl }
function getSharingLink($_object,$_type,$_siteUrl,$_listUrl)
{
$relativeUrl = $_object.FileRef
$SharingLinks = if ($_type -eq 0 ) {
Get-PnPFileSharingLink -Identity $relativeUrl
} elseif ($_type -eq 1) {
Get-PnPFolderSharingLink -Folder $relativeUrl
}
ForEach($ShareLink in $SharingLinks)
{
if(($ExcludeDirectSharingLink -eq 'Yes' -and $ShareLink.Link.Scope -ne 'Users') -or $ExcludeDirectSharingLink -eq 'No')
{
$result = New-Object PSObject -property $([ordered]@{
SiteUrl = $_SiteURL
listUrl = $_listUrl
Name = $_object.FileLeafRef
RelativeURL = $_object.FileRef
ObjectType = $_Type -eq 1 ? 'Folder':'File'
ShareId = $ShareLink.Id
RoleList = $ShareLink.Roles -join "|"
Users = $ShareLink.GrantedToIdentitiesV2.User.Email -join "|"
ShareLinkUrl = $ShareLink.Link.WebUrl
ShareLinkType = $ShareLink.Link.Type
ShareLinkScope = $ShareLink.Link.Scope
Expiration = $ShareLink.ExpirationDateTime
BlocksDownload = $ShareLink.Link.PreventsDowload
RequiresPassword = $ShareLink.HasPassword
})
$global:Results +=$result;
if($DeleteSharingink -eq 'Yes'){
if ($_type -eq 0 ) {
Remove-PnPFileSharingLink -FileUrl $relativeUrl -Identity $ShareLink.Id -Force
} elseif ($_type -eq 1) {
Remove-PnPFolderSharingLink -Folder $relativeUrl -Identity $ShareLink.Id -Force
}
}
}
}
}
#Exclude certain libraries
$ExcludedLists = @("Access Requests", "App Packages", "appdata", "appfiles","Apps for SharePoint" ,"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")
Connect-PnPOnline -Url $siteUrl -Interactive
Write-Host "Processing site $siteUrl" -Foregroundcolor "Red";
$ll = Get-PnPList -Includes BaseType, Hidden, Title,HasUniqueRoleAssignments,RootFolder | Where-Object {$_.Hidden -eq $False -and $_.Title -notin $ExcludedLists } #$_.BaseType -eq "DocumentLibrary"
Write-Host "Number of lists $($ll.Count)";
foreach($list in $ll)
{
$listUrl = $list.RootFolder.ServerRelativeUrl;
$selectFields = "ID,HasUniqueRoleAssignments,FileRef,FileLeafRef,FileSystemObjectType"
$Url = $siteUrl + '_api/web/lists/getbytitle(''' + $($list.Title) + ''')/items?$select=' + $($selectFields)
$nextLink = $Url
$ListItems = @()
while($nextLink){
$response = invoke-pnpsprestmethod -Url $nextLink -Method Get
$ListItems += $response.value | where-object{$_.HasUniqueRoleAssignments -eq $true}
if($response.'odata.nextlink'){
$nextLink = $response.'odata.nextlink' -replace "$siteUrl/_api/",""
} else{
$nextLink = $null
}
}
ForEach($item in $ListItems)
{
if($list.BaseType -eq "DocumentLibrary")
{
$type= $item.FileSystemObjectType;
}
getSharingLink $item $type $siteUrl $listUrl;
}
}
$global:Results | Export-CSV $ReportOutput -NoTypeInformation
Write-host -f Green "Sharing Links Report Generated Successfully! to $ReportOutput"
Parameters
$ExcludeDirectSharingLink:
- Type: String
- Mandatory: Yes
- Values: ‘Yes’, ‘No’
- Description: Determines whether to exclude direct sharing links (links shared directly with specific users) from the deletion process.
$DeleteSharingink:
- Type: String
- Mandatory: Yes
- Values: ‘Yes’, ‘No’
- Description: Specifies whether to delete the sharing links found. If set to ‘Yes’, the script will remove the sharing links.
$SiteUrl:
- Type: String
- Mandatory: Yes
- Description: The URL of the SharePoint site where the script will operate.
The script retrieves all list items and files from libraries, excluding certain predefined ones. It will iterate through each list and library to find items with unique permissions.For each item, it will retrieve and optionally delete sharing links based on the provided parameters. It will generate report of the sharing links found, and saves it as a CSV file.
Conclusion
This PowerShell script is a powerful tool for SharePoint administrators to manage and clean up sharing links within their sites. By automating the process of identifying and removing non-direct sharing links, it helps maintain better governance and security. The script also generates a detailed report of the actions taken, providing transparency and accountability. Use this script to ensure that your SharePoint environment remains secure and well-managed.