0

I am looking to run a script nightly to delete zip files older than 7 days. In Documents I have a folder called folder1 and inside that folder there are subfolders containing zip files. I have seen examples for sites/lists but not folders. The following cold will return:

But I would like to recursively delete all zip files in folder1 that are over 7 days old.

Try {
   #Setup the context
   $securePassword = ConvertTo-SecureString $SPOnlinePassword -AsPlainText -Force
   $Context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL) 
   $Context.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($SPOnlineUserName, $securePassword)

   #Get the List
   $List = $Context.Web.lists.GetByTitle($ListName)

   #Define CAML Query to Filter
   $Query = New-Object Microsoft.SharePoint.Client.CamlQuery
   $Query.ViewXML = "<View Scope=RecursiveAll>
                        <Query>
                            <Where>
                                <And>
                                    <Contains>
                                        <FieldRef Name='FileLeafRef' /><Value Type='Text'>.zip</Value>
                                    </Contains>
                                    <Leq>
                                        <FieldRef Name='Created' Type='DateTime'/>
                                        <Value Type='DateTime'>
                                            <Today OffsetDays='-7'/>
                                        </Value>
                                    </Leq>
                                </And>
                            </Where>
                        </Query>
                    </View>"

   #Get List Items
   $ListItems = $List.GetItems($Query)
   $Context.Load($ListItems)
   $Context.ExecuteQuery()

   Write-host -f Green "Number of List Items Found:"$ListItems.Count
   write-host $ListItems.Name
   #Get Each Item's Created Date
   $ListItems | ForEach-Object { Write-host ("List Item:{0} was created on {1}" -f $_["FileLeafRef"], $_["Created"]) }

   foreach ($item in $ListItems) {
      $List.getItemById($item.id).deleteObject()
   }
   $Context.ExecuteQuery()
}
Catch {
   write-host -f Red "Error:" $_.Exception.Message
}

Edit: I have the above code sort of working until I received 'Error: Exception calling "ExecuteQuery" with "0" argument(s): "The operation has timed out."'

1 Answer 1

0

Yes, it is possible. Use the below PowerShell script.

#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"
cls



$fileName = "File_Deleting_Report"
#'yyyyMMddhhmm   yyyyMMdd
$enddate = (Get-Date).tostring("yyyyMMddhhmmss")
#$filename =  $enddate + '_VMReport.doc'  
$logFileName = $fileName +"_"+ $enddate+"_Log.txt"   
$invocation = (Get-Variable MyInvocation).Value  
$directoryPath = Split-Path $invocation.MyCommand.Path  

$directoryPathForLog=$directoryPath+"\"+"LogFiles"
if(!(Test-Path -path $directoryPathForLog))  
        {  
            New-Item -ItemType directory -Path $directoryPathForLog
            #Write-Host "Please Provide Proper Log Path" -ForegroundColor Red   
        }   


#$logPath = $directoryPath + "\" + $logFileName 

$logPath = $directoryPathForLog + "\" + $logFileName 

$isLogFileCreated = $False 



#DLL location

$directoryPathForDLL=$directoryPath+"\"+"Dependency Files"
if(!(Test-Path -path $directoryPathForDLL))  
        {  
            New-Item -ItemType directory -Path $directoryPathForDLL

        } 

#DLL location

$clientDLL=$directoryPathForDLL+"\"+"Microsoft.SharePoint.Client.dll"
$clientDLLRuntime=$directoryPathForDLL+"\"+"Microsoft.SharePoint.Client.dll"

Add-Type -Path $clientDLL
Add-Type -Path $clientDLLRuntime


#File Download location

$directoryPathForFileDownloadLocation=$directoryPath+"\"+"Downloaded Files"
if(!(Test-Path -path $directoryPathForFileDownloadLocation))  
        {  
            New-Item -ItemType directory -Path $directoryPathForFileDownloadLocation
            #Write-Host "Please Provide Proper Log Path" -ForegroundColor Red   
        } 

#File Download location



function Write-Log([string]$logMsg)  
{   
    if(!$isLogFileCreated){   
        Write-Host "Creating Log File..."   
        if(!(Test-Path -path $directoryPath))  
        {  
            Write-Host "Please Provide Proper Log Path" -ForegroundColor Red   
        }   
        else   
        {   
            $script:isLogFileCreated = $True   
            Write-Host "Log File ($logFileName) Created..."   
            [string]$logMessage = [System.String]::Format("[$(Get-Date)] - {0}", $logMsg)   
            Add-Content -Path $logPath -Value $logMessage   
        }   
    }   
    else   
    {   
        [string]$logMessage = [System.String]::Format("[$(Get-Date)] - {0}", $logMsg)   
        Add-Content -Path $logPath -Value $logMessage   
    }   
} 




#Parameters
$siteURL="https://globalsharepoint.sharepoint.com/sites/SharePointRND/"
$listName="Documents"
$fromDate="2019-12-08"
$toDate="2019-12-12"
$downloadLocation=$directoryPathForFileDownloadLocation;
$userName = "[email protected]"
$password = "YourSPOPassWord"
$securePassword= $password | ConvertTo-SecureString -AsPlainText -Force
$batchSize =1000

#Parameters ends here.


#Setup the Context
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteURL)
$ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($userName, $securePassword)

  <#
  $web = $ctx.Web
  $ctx.Load($web)
  $ctx.Load($web.Webs)
  $ctx.ExecuteQuery()#>



  #The below code is for root site

$docLibraryColl=$ctx.Web.Lists
$ctx.Load($docLibraryColl)
$ctx.ExecuteQuery()

foreach($oneList in $docLibraryColl)
{

if($oneList.BaseTemplate -eq "101" -and $oneList.BaseType -eq "DocumentLibrary" -and $oneList.Hidden -eq $False -and $oneList.IsCatalog -eq $False -and $oneList.IsApplicationList -eq $False) 
{



#Get the List
$list = $ctx.Web.Lists.GetByTitle($oneList.Title)
$ctx.Load($list)
$ctx.ExecuteQuery()
$emptyString = ""
#Define CAML Query to get Files from the list in batches
$Query = New-Object Microsoft.SharePoint.Client.CamlQuery


$startDateVar=$fromDate+"T13:35:58Z"
#$startDate=Get-Date -Date $startDateVar; 
$endDateVar=$toDate+"T13:36:34Z"
#$endDate=Get-Date -Date $endDateVar;



$Query.ViewXml = "@
    <View Scope='Recursive'>
        <Query>
   <Where>
      <And>
         <Geq>
            <FieldRef Name='Created' />
            <Value IncludeTimeValue='TRUE' Type='DateTime'>$startDateVar</Value>
         </Geq>
         <Leq>
            <FieldRef Name='Created' />
            <Value IncludeTimeValue='TRUE' Type='DateTime'>$endDateVar</Value>
         </Leq>
      </And>
   </Where>
</Query>        
    </View>"



$count =0

#Get List Items in Batches
Do
{


    $ListItems = $List.GetItems($Query)
    $Ctx.Load($ListItems)
    $Ctx.ExecuteQuery()
    $ListItems.Count

    #Update Postion of the ListItemCollectionPosition
    $Query.ListItemCollectionPosition = $ListItems.ListItemCollectionPosition
    $Query.ListItemCollectionPosition

    If ($ListItems.Count -eq 0) { Break }

    $fileCount=1;

    #Update List Item
    ForEach($Item in $ListItems)
    {                    


            try
            {

              $Ctx.Load($Item.File)
              $Ctx.ExecuteQuery()

              $Item.File.DeleteObject();
              $Ctx.ExecuteQuery()              


             Write-Host $Item.File.Name "has been deleted successfully" -BackgroundColor DarkGreen




        }
        catch
        {
            $ErrorMessage = $_.Exception.Message +$file.Name
            Write-Host $ErrorMessage -BackgroundColor Red
            Write-Log $ErrorMessage 

        }       



    }
    Write-Host "============================================================="
    Write-Host $count
    Write-Host "============================================================="

}While ($Query.ListItemCollectionPosition -ne $null)

}


}

Notes:

  • In the above script you can pass from date to date as parameters those files will be deleted. Or in the camel query you can extract the data greater than X date.

  • Inside for each loop, using the $Item.File property you can check the zip file type before deleting or even you can add this in the camel query itself.

  • This is tested in SharePoint online but it will work in SharePoint On-Premise as well, as this is developed in client object model.

For details details refer to the below article :

SharePoint Online: Delete All Files from document library for the given date – PowerShell CSOM

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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