Archive ULS & IIS Log Files in SharePoint using PowerShell

Requirement: Archive Log files of IIS and ULS Log. 

Log files in SharePoint (both IIS Log and ULS Log) could grow and fill up the disk space based on your configurations and usage. There are many scripts available in various blogs and boards, and Here is my script to archive log files on SharePoint servers.

PowerShell to archive IIS ULS Log Files in SharePoint

PowerShell to Archive Log Files in SharePoint:

Set the log file path and archive location in the configuration parameters section and run the script. This script does the following:

  • Copies all log files which are last modified before 7 Days or earlier from today, to a folder.
  • Create a Zip file from the folder containing log files to archive.
  • Deletes old log files.
Add-Type -Assembly System.IO.Compression.FileSystem

#Configuration Parameters
$LogFilesPath="C:\inetpub\logs\LogFiles\W3SVC3"
$ArchivePath="C:\LogArchive"

#Get All Log Files Modified before Last Week
$LogFilesToArchive = Get-ChildItem -Path $LogFilesPath -recurse | where-object {$_.LastWriteTime -le (Get-Date).addDays(-7) }
Write-host "Total Log Files to Archive:"$LogFilesToArchive.count -f Yellow
if($LogFilesToArchive.count -eq 0) { Break }

#Create a Temp Folder
$LogFileDate = Get-Date -Format "yyyyMMdd"
$TempFolder = Join-path -path $ArchivePath $LogFileDate
If (!(Test-Path $TempFolder)) 
{  
    New-Item $TempFolder -type Directory | Out-Null
}

#Copy Log Files to Temp Folder and Remove them
Foreach ($Logfile in $LogFilesToArchive)
{
    #Copy Log file to the Temp Directory
    Copy-Item -Path $Logfile.FullName -Destination $TempFolder
    
    #Delete the copied Log file from the source
    Remove-Item $Logfile.FullName -Confirm:$False
}

#Archive the Temp Folder
$ZipFileName= "$($ArchivePath)\$($LogFileDate).zip"
If (Test-Path $ZipFileName){ Remove-Item $ZipFileName }

$CompressionLevel = [System.IO.Compression.CompressionLevel]::Optimal
[System.IO.Compression.ZipFile]::CreateFromDirectory($TempFolder, $ZipFileName, $CompressionLevel, $False)

#Remove the Temp Folder
Remove-Item $TempFolder -Recurse -Force -Confirm:$False

Write-host "$($LogFilesToArchive.count) Log Files Archived to '$($ZipFileName)'" -f Green

Schedule it in Windows Task scheduler to automate the script. You can also wrap the script inside a reusable function to archive log files from multiple locations. This script removes all log files older than 30 days. You can change the hard-coded value to fit into your requirement.

Add-Type -Assembly System.IO.Compression.FileSystem

Function Archive-Logs($LogFilesPath, $ArchivePath)
{
    #Get All Log Files Modified older than a Last Week
    $LogFilesToArchive = Get-ChildItem -Path $LogFilesPath -recurse | where-object {$_.LastWriteTime -le (Get-Date).addDays(-30) }
    Write-host "Total Log Files to Archive:"$LogFilesToArchive.count -f Yellow
    if($LogFilesToArchive.count -eq 0) { Return }

    #Create a Temp Folder
    $LogFileDate = Get-Date -Format "yyyyMMdd-HHMMss"
    $TempFolder = Join-path -path $ArchivePath $LogFileDate
    If (!(Test-Path $TempFolder)) 
    {  
        New-Item $TempFolder -type Directory | Out-Null
    }

    #Copy Log Files to Temp Folder and Remove them
    Foreach ($Logfile in $LogFilesToArchive)
    {
        #Copy Log file to the Temp Directory
        Copy-Item -Path $Logfile.FullName -Destination $TempFolder
    
        #Delete the copied Log file from the source
        Remove-Item $Logfile.FullName -Confirm:$False
    }

    #Archive the Temp Folder
    $ZipFileName= "$($ArchivePath)\$($LogFileDate).zip"
    If (Test-Path $ZipFileName){ Remove-Item $ZipFileName }

    $CompressionLevel = [System.IO.Compression.CompressionLevel]::Optimal
    [System.IO.Compression.ZipFile]::CreateFromDirectory($TempFolder, $ZipFileName, $CompressionLevel, $False)

    #Remove the Temp Folder
    Remove-Item $TempFolder -Recurse -Force -Confirm:$False

    Write-host "$($LogFilesToArchive.count) Log Files Archived to '$($ZipFileName)'" -f Green
}

#Call The function
Archive-Logs -LogFilesPath "C:\inetpub\logs\LogFiles\W3SVC3232" -ArchivePath "C:\LogArchive"
Archive-Logs -LogFilesPath "C:\inetpub\logs\LogFiles\W3SVC6245" -ArchivePath "C:\LogArchive"
Archive-Logs -LogFilesPath "D:\SPLogs\ULS" -ArchivePath "C:\LogArchive"

PowerShell to Archive Old Files

We moved all old files with the same folder, sub-folder structure, to another folder in another situation.

Function Archive-OldFiles
{
 param
    (
        [Parameter(Mandatory=$true)] [string] $SourcePath,
        [Parameter(Mandatory=$true)] [string] $ArchivePath,
        [Parameter(Mandatory=$true)] [string] $LogFile,
        [Parameter(Mandatory=$false)] [Int] $Days = -30 #Number of Days to check beyyond - based on last modified by date
    )

    Try {
        Add-content $Logfile -value "`n------------------- Archive Files Script Started: $(Get-date -format 'dd/MM/yyy hh:mm:ss tt')----------------" 

        #Get All Files from the Source - matching given condition
        $SourceFiles = Get-ChildItem -Path $SourcePath -Recurse -File | Where {$_.LastWriteTime -lt (Get-Date).AddDays($Days)}
        Write-host "Total Number of Files matching in the Source: $($SourceFiles.Count)"
        Add-content $Logfile -value "Total Number of Files matching in the Source: $($SourceFiles.Count)" 
        
        $Counter = 1     
        #Move Files to Archive Folder
        $SourceFiles | ForEach-Object {
            #Get the File name and Folder of the File
            $FileName = $_.FullName
            $FolderPath = $_.Directory.FullName
            $TargetFolder = $FolderPath.Replace($SourcePath, $ArchivePath)

            #Display Progress bar
            $Status  = "Archiving '" + $FileName + "' to " + $TargetFolder +" ($($Counter) of $($SourceFiles.Count))"
            Write-Progress -Activity "Archiving Files..." -Status $Status -PercentComplete (($Counter / $SourceFiles.Count) * 100)

            Try {
                #Create Folder in the destination, if it doesn't exist
                If(!(Test-Path $TargetFolder))
                {
                    New-Item -ItemType Directory -Force -Path $TargetFolder | Out-Null -ErrorAction stop
                }

                #Move Files to Archive
                Move-Item $_.FullName -Destination $TargetFolder -Force -ErrorAction Stop
                Write-Host "Successfully moved $FileName to $TargetFolder\$($_.Name)" -f Green
                Add-Content $LogFile -Value "Successfully moved $FileName to $TargetFolder\$($_.Name)" 
            }
            Catch {  
                Write-host -f Red "Error Moving $FileName to $TargetFolder, $($_.Exception.Message)"  
                Add-Content $LogFile -Value "Error moving $FileName $($_.Exception.Message)"
            }
            $Counter++       
        }
    }
    catch {
        Write-host -f Red "Error Moving $FileName to $TargetFolder, $($_.Exception.Message)"  
        Add-Content $LogFile -Value "Error moving $FileName $($_.Exception.Message)"
    }
    Finally {
        Add-content $Logfile -value "---------------------- Archive Files Script Completed: $(Get-date -format 'dd/MM/yyy hh:mm:ss tt')-----------------"
    }    
}
#Parameters
$SourcePath = "E:\Reports"
$ArchivePath = "E:\Reports-Archive"
$Days = "-365"
$LogFile = "E:\Reports\Log.txt"
Archive-OldFiles -SourcePath $SourcePath -ArchivePath $ArchivePath -Days $Days -LogFile $LogFile

Archiving IIS logs using PowerShell is a simple and effective way to free up storage space on your server and ensure that your IIS logs are organized and easy to access. Following these steps, you can easily archive IIS logs using PowerShell, saving time and effort.

Salaudeen Rajack

Salaudeen Rajack - Information Technology Expert with Two-decades of hands-on experience, specializing in SharePoint, PowerShell, Microsoft 365, and related products. He has held various positions including SharePoint Architect, Administrator, Developer and consultant, has helped many organizations to implement and optimize SharePoint solutions. Known for his deep technical expertise, He's passionate about sharing the knowledge and insights to help others, through the real-world articles!

Leave a Reply

Your email address will not be published. Required fields are marked *