Split large files + LOG + ERRORS CHECKING


  • Authenticates using Microsoft Graph API with client credentials.
  • Retrieves and analyzes mailbox folders to identify those exceeding 99,999 items.
  • Splits large folders into smaller ones by creating new folders and moving emails in batches.
  • Includes robust logging for all operations, including successes, errors, and retries.
  • Implements retry logic to handle errors and ensure reliable execution.
  • Requires user confirmation before proceeding with folder splitting.

# Install Microsoft Graph PowerShell module if not already installed Install-Module Microsoft.Graph -Scope CurrentUser # Step 1: Authenticate with Client Credentials $tenantId = "YOUR_TENANT_ID" $clientId = "YOUR_CLIENT_ID" $clientSecret = "YOUR_CLIENT_SECRET" # Authenticate and get an access token $tokenRequest = @{ TenantId = $tenantId ClientId = $clientId ClientSecret = $clientSecret Scope = "https://graph.microsoft.com/.default" } Connect-MgGraph -ClientId $clientId -TenantId $tenantId -ClientSecret $clientSecret -Scopes "Mail.ReadWrite", "Mail.Move", "MailFolders.ReadWrite" # Confirm authentication $me = Get-MgUser -UserId "me" Write-Host "Authenticated as: $($me.DisplayName)" # Step 2: Get UPN for the user mailbox we are targeting $upn = Read-Host -Prompt "Enter the UPN of the mailbox to analyze" # Define log file name based on UPN $logFileName = "$upn`_splitfile_log.txt" # Function to write log to the file function Write-Log { param ( [string]$message ) $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" $logMessage = "$timestamp - $message" $logMessage | Out-File -FilePath $logFileName -Append Write-Host $logMessage # Also output to console } # Step 3: Get all folders for the user Write-Log "Fetching folders for $upn" $folders = Get-MgUserMailFolder -UserId $upn -All # Step 4: Analyze and summarize folders with more than 99,999 items $largeFolders = $folders | Where-Object { $_.TotalItemCount -gt 99999 } # Display summary of folders to be split foreach ($folder in $largeFolders) { $totalItems = $folder.TotalItemCount $excessItems = $totalItems - 99999 $numNewFolders = [math]::Ceiling($excessItems / 99999) Write-Log "Folder: $($folder.DisplayName) (ID: $($folder.Id))" Write-Log "Total Items: $totalItems" Write-Log "Items to be moved: $excessItems" Write-Log "Proposed new folders: $numNewFolders" } # Step 5: Confirm before proceeding $confirmation = Read-Host -Prompt "Do you want to proceed with splitting the folders? (yes/no)" if ($confirmation -ne "yes") { Write-Log "Operation canceled by user." Write-Host "Operation canceled." Exit } # Error handling function for retries with logging function Retry-Operation { param ( [scriptblock]$ScriptBlock, [int]$MaxRetries = 3, [int]$RetryDelay = 5 # Seconds to wait between retries ) $attempt = 0 while ($attempt -lt $MaxRetries) { try { $attempt++ Write-Log "Attempt $attempt to execute operation." & $ScriptBlock Write-Log "Operation succeeded on attempt $attempt." return # Success, exit the retry loop } catch { Write-Log "Attempt $attempt failed: $($_.Exception.Message)" # Log the entire error details (stack trace, message, etc.) Write-Log "Error Details: $($_ | Out-String)" if ($attempt -eq $MaxRetries) { $errorMsg = "Max retries reached. Operation failed." Write-Log $errorMsg throw $errorMsg } Write-Log "Retrying in $RetryDelay seconds..." Start-Sleep -Seconds $RetryDelay } } } # Function to create a new folder with retry logic and logging function Create-NewMailFolder { param ( [string]$upn, [string]$parentFolderId, [string]$folderName ) Retry-Operation -ScriptBlock { $newFolder = New-MgUserMailFolder -UserId $upn -DisplayName $folderName -ParentFolderId $parentFolderId Write-Log "Created new folder $folderName with ID $($newFolder.Id)" return $newFolder.Id } } # Function to move emails in batches with retry logic and logging function Move-EmailsInBatches { param ( [string]$upn, [string]$sourceFolderId, [string]$destinationFolderId, [int]$batchSize = 99999 ) Retry-Operation -ScriptBlock { # Get messages in the source folder $messages = Get-MgUserMailFolderMessage -UserId $upn -MailFolderId $sourceFolderId -Top $batchSize foreach ($message in $messages) { $messageId = $message.Id # Move the message Retry-Operation -ScriptBlock { Move-MgUserMessage -UserId $upn -MessageId $messageId -DestinationId $destinationFolderId Write-Log "Moved message $messageId to folder $destinationFolderId" } } Write-Log "Moved $batchSize messages from folder $sourceFolderId to folder $destinationFolderId" } } # Process each large folder with error handling, retries, and logging foreach ($folder in $largeFolders) { $folderId = $folder.Id $totalItems = $folder.TotalItemCount $excessItems = $totalItems - 99999 if ($excessItems -gt 0) { $numNewFolders = [math]::Ceiling($excessItems / 99999) # Create the necessary number of new folders and move items for ($i = 1; $i -le $numNewFolders; $i++) { $newFolderName = "split_${folderId}_$i" $newFolderId = Create-NewMailFolder -upn $upn -parentFolderId $folderId -folderName $newFolderName # Move emails to the new folder if ($i -lt $numNewFolders) { # Move a full batch of 99,999 emails Move-EmailsInBatches -upn $upn -sourceFolderId $folderId -destinationFolderId $newFolderId -batchSize 99999 } else { # Move the remainder (less than 99,999 emails) $remainder = $excessItems % 99999 Move-EmailsInBatches -upn $upn -sourceFolderId $folderId -destinationFolderId $newFolderId -batchSize $remainder } } } } Write-Log "All folder splits and moves for $upn are completed!" Write-Host "All folder splits and moves are completed!"

test Exchange Administrator Tecism
Sorry! The Author has not filled his profile.
0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments