Link to home
Start Free TrialLog in
Avatar of Ingrid Mengdehl
Ingrid Mengdehl

asked on

SharePoint online PowerShell script: Error (403) Forbidden

Hi,

I'm trying to run a report on the version history of the files we have stored on our SharePoint online, as I ideally want to bulk delete a lot of old versions. I found a script to do that, and modified it so that it works with MFA, but whenever I run it in the SharePoint Online Management Shell, I end up with the following error:

Error Exporting version History to CSV! Exception calling "ExecuteQuery" with "0" argument(s): "The remote server returned an error: (403) Forbidden."

Open in new window

(I'm Global Admin and owner of the site, so there's no permission issue)

I've tried a few things, installed the latest versions of the SharePoint Online Client Components SDK, but nothing seems to work. Any help would be brilliant.

The script I'm using is the following:

#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"
 
Function Export-VersionHistory()
{
  param
    (
	    [Parameter(Mandatory=$true)] [string] $SiteURL,
        [Parameter(Mandatory=$true)] [string] $ListName,
        [Parameter(Mandatory=$true)] [string] $CSVFile,
		# Tenant Name
		[Parameter(Mandatory=$true,HelpMessage="xxxxxxxxxxxx")]
		[String]
		$TenantName,
		# Use MFA login
		[Switch]$MFA
        
    )
	
    Connect-SPOService -Url https://xxxxxxxxxxxx-admin.sharepoint.com
	
    Try {
 
        #Delete the Output report file if exists
        if (Test-Path $CSVFile) { Remove-Item $CSVFile }
 
        #Setup the context
        $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
        $Ctx.Credentials = $Credentials
         
        #Get the List
        $List = $Ctx.Web.Lists.GetByTitle($ListName)
        $Ctx.Load($List)
        $Ctx.ExecuteQuery()
         
        #Get all items
        $Query = [Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery()
        $ListItems = $List.GetItems($Query)
        $Ctx.Load($ListItems)
        $Ctx.ExecuteQuery()
 
        #Array to hold result
        $VersionHistoryData = @()
 
        #Iterate throgh each item
        Foreach ($Item in $ListItems)
        {
            write-host "Processing Item:" $item.id -f Yellow
             
            #Get all versions of the list item
            $Versions = $Item.versions
            $ctx.Load($Versions)
            $Ctx.ExecuteQuery()
 
            If($Versions.count -gt 0)
            {
                #Iterate each version
                Foreach($Version in $Versions)
                {
                    #Get the Creator object of the version
                    $CreatedBy =  $Version.createdby
                    $Ctx.Load($CreatedBy)
                    $Ctx.ExecuteQuery()
 
                    #Send Data to object array
                    $VersionHistoryData += New-Object PSObject -Property @{
                    'Item ID' = $Item.ID
                    'Title' =  $Version.FieldValues["Title"]
                    'Version Label' = $Version.VersionLabel 
                    'Version ID' = ($Version.VersionId/512)
                    'Created On' = (Get-Date ($Version.Created) -Format "yyyy-MM-dd/HH:mm:ss")
                    'Created By' = $CreatedBy.Email
                    }
                }
            }
        }
         
        #Export the data to CSV
        $VersionHistoryData | Export-Csv $CSVFile -Append -NoTypeInformation
 
        write-host -f Green "Version History Exported Successfully to:" $CSVFile
     }
    Catch {
        write-host -f Red "Error Exporting version History to CSV!" $_.Exception.Message
    }
}
 
#Set parameter values
$SiteURL="https://xxxxxxx.sharepoint.com/sites/xxxxx/xxxxx"
$ListName="xxxx"
$CSVFile="C:\Temp\VersionHistory.csv"
 
#Call the function to generate version History Report
Export-VersionHistory -SiteURL $SiteURL -ListName $ListName -CSVFile $CSVFile

Open in new window

Avatar of Robb Hill
Robb Hill
Flag of United States of America image

Curious for my own understanding.  Does sharepoint online not help you manage this.  Was powershell the only way to go.
Avatar of Ingrid Mengdehl
Ingrid Mengdehl

ASKER

SharePoint lets you see the version history, plus set your limits, but if I now decide to only keep 5 major versions instead of 100, it won't delete the 95 other versions automatically. It seems the only way to do that is to go via PowerShell.
Would it be possible to temporarily exclude the Admin account from MFA and attempt the script.

I've seen a bunch of such permissions issues with MFA in place.
I've tried with MFA disabled and it still gives me the same error.
Which line of the script gives the error message? Need to narrow down which action is implicated.
Hi Jamie,
It doesn't reference any line of the script. It just throws in that error message.
The error message comes from the Catch block, but it'd be good to step through and discover which line of script causes the exception.
Hi,

If this is a team site, based on the team site template (STS#0), check if publishing is enabled and if Minimal download strategy shows deactivated.  Then deactivate\disable publishing and see if MDS shows activated without you having to do anything.  If it does then deactivate MDS and reactivate publishing again.  The AjaxDelta controls that MDS brings to the game do not play nice with the object cache and publishing and they fight under the covers.  So, rule that out and let us know what you find and best of luck and it might be the cause of the catch block generating an error.

-Stacy

this post is not necessarily the view of my employer or other MVP types, use at your own risk
This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.