Hi @frob ,
According to your situation, have a try to use below script by CSOM to see if it solves your issue.
#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")
C:\filepath\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()
$camlQuery = New-Object Microsoft.SharePoint.Client.CamlQuery
$camlQuery.ViewXml ="<View Scope='RecursiveAll' />";
$allItems=$list.GetItems($camlQuery)
$ctx.Load($allItems)
$ctx.ExecuteQuery()
$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
})
}
}
}
}
$Result | Export-CSV "C:\SharedFileDetails.CSV" -NoTypeInformation -Encoding UTF8
Please remember to put Load-CSOMProperties.ps1 in your filepath C:\filepath\Load-CSOMProperties.ps1
Load-CSOMProperties.ps1:
<#
.Synopsis
Facilitates the loading of specific properties of a Microsoft.SharePoint.Client.ClientObject object or Microsoft.SharePoint.Client.ClientObjectCollection object.
.DESCRIPTION
Replicates what you would do with a lambda expression in C#.
For example, "ctx.Load(list, l => list.Title, l => list.Id)" becomes
"Load-CSOMProperties -object $list -propertyNames @('Title', 'Id')".
.EXAMPLE
Load-CSOMProperties -parentObject $web -collectionObject $web.Fields -propertyNames @("InternalName", "Id") -parentPropertyName "Fields" -executeQuery
$web.Fields | select InternalName, Id
.EXAMPLE
Load-CSOMProperties -object $web -propertyNames @("Title", "Url", "AllProperties") -executeQuery
$web | select Title, Url, AllProperties
#>
function global:Load-CSOMProperties {
[CmdletBinding(DefaultParameterSetName='ClientObject')]
param (
# The Microsoft.SharePoint.Client.ClientObject to populate.
[Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0, ParameterSetName = "ClientObject")]
[Microsoft.SharePoint.Client.ClientObject]
$object,
# The Microsoft.SharePoint.Client.ClientObject that contains the collection object.
[Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0, ParameterSetName = "ClientObjectCollection")]
[Microsoft.SharePoint.Client.ClientObject]
$parentObject,
# The Microsoft.SharePoint.Client.ClientObjectCollection to populate.
[Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 1, ParameterSetName = "ClientObjectCollection")]
[Microsoft.SharePoint.Client.ClientObjectCollection]
$collectionObject,
# The object properties to populate
[Parameter(Mandatory = $true, Position = 1, ParameterSetName = "ClientObject")]
[Parameter(Mandatory = $true, Position = 2, ParameterSetName = "ClientObjectCollection")]
[string[]]
$propertyNames,
# The parent object's property name corresponding to the collection object to retrieve (this is required to build the correct lamda expression).
[Parameter(Mandatory = $true, Position = 3, ParameterSetName = "ClientObjectCollection")]
[string]
$parentPropertyName,
# If specified, execute the ClientContext.ExecuteQuery() method.
[Parameter(Mandatory = $false, Position = 4)]
[switch]
$executeQuery
)
begin { }
process {
if ($PsCmdlet.ParameterSetName -eq "ClientObject") {
$type = $object.GetType()
} else {
$type = $collectionObject.GetType()
if ($collectionObject -is [Microsoft.SharePoint.Client.ClientObjectCollection]) {
$type = $collectionObject.GetType().BaseType.GenericTypeArguments[0]
}
}
$exprType = [System.Linq.Expressions.Expression]
$parameterExprType = [System.Linq.Expressions.ParameterExpression].MakeArrayType()
$lambdaMethod = $exprType.GetMethods() | ? { $_.Name -eq "Lambda" -and $_.IsGenericMethod -and $_.GetParameters().Length -eq 2 -and $_.GetParameters()[1].ParameterType -eq $parameterExprType }
$lambdaMethodGeneric = Invoke-Expression "`$lambdaMethod.MakeGenericMethod([System.Func``2[$($type.FullName),System.Object]])"
$expressions = @()
foreach ($propertyName in $propertyNames) {
$param1 = [System.Linq.Expressions.Expression]::Parameter($type, "p")
try {
$name1 = [System.Linq.Expressions.Expression]::Property($param1, $propertyName)
} catch {
Write-Error "Instance property '$propertyName' is not defined for type $type"
return
}
$body1 = [System.Linq.Expressions.Expression]::Convert($name1, [System.Object])
$expression1 = $lambdaMethodGeneric.Invoke($null, [System.Object[]] @($body1, [System.Linq.Expressions.ParameterExpression[]] @($param1)))
if ($collectionObject -ne $null) {
$expression1 = [System.Linq.Expressions.Expression]::Quote($expression1)
}
$expressions += @($expression1)
}
if ($PsCmdlet.ParameterSetName -eq "ClientObject") {
$object.Context.Load($object, $expressions)
if ($executeQuery) { $object.Context.ExecuteQuery() }
} else {
$newArrayInitParam1 = Invoke-Expression "[System.Linq.Expressions.Expression``1[System.Func
`2[$($type.FullName),System.Object]]]"
$newArrayInit = [System.Linq.Expressions.Expression]::NewArrayInit($newArrayInitParam1, $expressions)
$collectionParam = [System.Linq.Expressions.Expression]::Parameter($parentObject.GetType(), "cp")
$collectionProperty = [System.Linq.Expressions.Expression]::Property($collectionParam, $parentPropertyName)
$expressionArray = @($collectionProperty, $newArrayInit)
$includeMethod = [Microsoft.SharePoint.Client.ClientObjectQueryableExtension].GetMethod("Include")
$includeMethodGeneric = Invoke-Expression "`$includeMethod.MakeGenericMethod([$($type.FullName)])"
$lambdaMethodGeneric2 = Invoke-Expression "`$lambdaMethod.MakeGenericMethod([System.Func``2[$($parentObject.GetType().FullName),System.Object]])"
$callMethod = [System.Linq.Expressions.Expression]::Call($null, $includeMethodGeneric, $expressionArray)
$expression2 = $lambdaMethodGeneric2.Invoke($null, @($callMethod, [System.Linq.Expressions.ParameterExpression[]] @($collectionParam)))
$parentObject.Context.Load($parentObject, $expression2)
if ($executeQuery) { $parentObject.Context.ExecuteQuery() }
}
}
end { }
}
![237734-microsoftteams-image-8.png][1]
**********************************************************************************************
If the answer is helpful, please click "**Accept Answer**" and kindly upvote it. If you have extra questions about this answer, please click "**Comment**".
Note: Please follow the steps in [our documentation][2] to enable e-mail notifications if you want to receive the related email notification for this thread.
[1]: /api/attachments/237734-microsoftteams-image-8.png?platform=QnA
[2]: http://**********************************************************************************************+If+the+answer+is+helpful,+please+click+"Accept+Answer"+and+kindly+upvote+it.+If+you+have+extra+questions+about+this+answer,+please+click+"Comment".+Note:+Please+follow+the+steps+in+our+documentation+to+enable+e-mail+notifications+if+you+want+to+receive+the+related+email+notification+for+this+thread.