From 2d9426e87f0fa7ede2702421763b0bad63bc97af Mon Sep 17 00:00:00 2001 From: Alessandro Battilani Date: Fri, 9 Jan 2026 19:01:12 +0100 Subject: [PATCH] prima release --- ArchiviazioneMail.ps1 | 66 +++++++++++++++++++++++++++ ArchiviazioneMailPst.ps1 | 99 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 ArchiviazioneMail.ps1 create mode 100644 ArchiviazioneMailPst.ps1 diff --git a/ArchiviazioneMail.ps1 b/ArchiviazioneMail.ps1 new file mode 100644 index 0000000..33bfa24 --- /dev/null +++ b/ArchiviazioneMail.ps1 @@ -0,0 +1,66 @@ +# --- CONFIGURAZIONE --- +$archiveName = "Archivio online - alessandro.battilani@intesasanpaolo.com" +$monthsLimit = -6 +# ---------------------- + +try { + $outlook = New-Object -ComObject Outlook.Application + $namespace = $outlook.GetNamespace("MAPI") + + $inbox = $namespace.GetDefaultFolder(6) + $archiveRoot = $namespace.Folders.Item($archiveName) + + if ($null -eq $archiveRoot) { + Write-Host "ERRORE: Archivio non trovato." -ForegroundColor Red + exit + } + + $cutoffDate = (Get-Date).AddMonths($monthsLimit) + $items = $inbox.Items + $items.Sort("[ReceivedTime]", $false) + + $spostate = 0 + Write-Host "Inizio archiviazione..." -ForegroundColor Yellow + + for ($i = $items.Count; $i -ge 1; $i--) { + $item = $items.Item($i) + + if ($item.Class -eq 43) { # olMail + if ($item.ReceivedTime -lt $cutoffDate) { + + $year = $item.ReceivedTime.Year.ToString() + $monthName = $item.ReceivedTime.ToString("MM-MMMM") + + # Navigazione/Creazione cartelle + $yearFolder = $null + try { $yearFolder = $archiveRoot.Folders.Item($year) } catch { } + if ($null -eq $yearFolder) { $yearFolder = $archiveRoot.Folders.Add($year) } + + $monthFolder = $null + try { $monthFolder = $yearFolder.Folders.Item($monthName) } catch { } + if ($null -eq $monthFolder) { $monthFolder = $yearFolder.Folders.Add($monthName) } + + # ESECUZIONE SPOSTAMENTO + # Il trucco รจ aggiungere "| Out-Null" per evitare che PowerShell stampi l'oggetto risultante + $item.Move($monthFolder) | Out-Null + + $spostate++ + + # Feedback minimale: solo un contatore sulla stessa riga + Write-Host "`rEmail archiviate: $spostate" -NoNewline + } + } + # Importante: rilasciare il riferimento all'oggetto singolo per velocizzare + [System.Runtime.Interopservices.Marshal]::ReleaseComObject($item) | Out-Null + } + + Write-Host "`n`nCompletato! Totale spostate: $spostate" -ForegroundColor Green +} +catch { + Write-Host "`nErrore: $($_.Exception.Message)" -ForegroundColor Red +} +finally { + if ($outlook) { + [System.Runtime.Interopservices.Marshal]::ReleaseComObject($outlook) | Out-Null + } +} \ No newline at end of file diff --git a/ArchiviazioneMailPst.ps1 b/ArchiviazioneMailPst.ps1 new file mode 100644 index 0000000..5f3a7db --- /dev/null +++ b/ArchiviazioneMailPst.ps1 @@ -0,0 +1,99 @@ +# --- CONFIGURAZIONE --- +$pstPath = "C:\Percorso\Tuo\File\archivio_vecchio.pst" +$archiveName = "IL NOME DEL TUO ARCHIVIO ONLINE" +$logFile = ".\Report_Migrazione_Totale.txt" +# ---------------------- + +# Inizializza Log e Memoria Duplicati +"REPORT MIGRAZIONE TOTALE PST - $(Get-Date)" | Out-File $logFile +"------------------------------------------" | Out-File $logFile -Append +$script:duplicatiSaltati = 0 +$script:spostateTotali = 0 +$script:mappaEmailEsistenti = @{} + +# Rinominata da Build-ExistMap a Initialize-ExistMap (Verbo approvato) +function Initialize-ExistMap($folder) { + foreach ($item in $folder.Items) { + if ($item.Class -eq 43) { + $key = "$($item.Subject)|$($item.ReceivedTime.Ticks)|$($item.SenderEmailAddress)" + $script:mappaEmailEsistenti[$key] = $true + } + } + foreach ($sub in $folder.Folders) { Initialize-ExistMap $sub } +} + +# Rinominata da Process-Folder a Invoke-FolderMigration (Verbo approvato) +function Invoke-FolderMigration($outlookFolder, $archiveRoot) { + $items = $outlookFolder.Items + $countInFolder = 0 + + if ($items.Count -gt 0) { + Write-Host "`nAnalisi cartella: $($outlookFolder.FolderPath)" -ForegroundColor Cyan + + for ($i = $items.Count; $i -ge 1; $i--) { + $item = $items.Item($i) + if ($item.Class -eq 43) { + $key = "$($item.Subject)|$($item.ReceivedTime.Ticks)|$($item.SenderEmailAddress)" + + if ($script:mappaEmailEsistenti.ContainsKey($key)) { + $script:duplicatiSaltati++ + continue + } + + $year = $item.ReceivedTime.Year.ToString() + $monthName = $item.ReceivedTime.ToString("MM-MMMM") + + $yearFolder = $null + try { $yearFolder = $archiveRoot.Folders.Item($year) } catch { } + if ($null -eq $yearFolder) { $yearFolder = $archiveRoot.Folders.Add($year) } + + $monthFolder = $null + try { $monthFolder = $yearFolder.Folders.Item($monthName) } catch { } + if ($null -eq $monthFolder) { $monthFolder = $yearFolder.Folders.Add($monthName) } + + $item.Move($monthFolder) | Out-Null + $script:spostateTotali++ + $countInFolder++ + Write-Host "`rSpostate: $script:spostateTotali | Duplicati: $script:duplicatiSaltati" -NoNewline + } + [System.Runtime.Interopservices.Marshal]::ReleaseComObject($item) | Out-Null + } + } + + if ($countInFolder -gt 0) { + "Spostate $countInFolder email da: $($outlookFolder.FolderPath)" | Out-File $script:logFile -Append + } + foreach ($subFolder in $outlookFolder.Folders) { Invoke-FolderMigration $subFolder $archiveRoot } +} + +try { + $outlook = New-Object -ComObject Outlook.Application + $namespace = $outlook.GetNamespace("MAPI") + + $archiveRoot = $namespace.Folders.Item($archiveName) + if ($null -eq $archiveRoot) { throw "Archivio Online '$archiveName' non trovato." } + + Write-Host "Mappatura email esistenti nell'archivio cloud..." -ForegroundColor Yellow + Initialize-ExistMap $archiveRoot + Write-Host "Mappatura completata. Email trovate: $($script:mappaEmailEsistenti.Count)" + + Write-Host "`nCaricamento PST: $pstPath" -ForegroundColor Yellow + $namespace.AddStore($pstPath) + $pstStore = $namespace.Stores | Where-Object { $_.FilePath -eq $pstPath } + $pstRoot = $pstStore.GetRootFolder() + + Invoke-FolderMigration $pstRoot $archiveRoot + + Write-Host "`n`nMigrazione terminata con successo!" -ForegroundColor Green + "------------------------------------------" | Out-File $logFile -Append + "TOTALE SPOSTATE: $script:spostateTotali" | Out-File $logFile -Append + "DUPLICATI SALTATI: $script:duplicatiSaltati" | Out-File $logFile -Append +} +catch { + Write-Host "`nErrore: $($_.Exception.Message)" -ForegroundColor Red + "ERRORE: $($_.Exception.Message)" | Out-File $logFile -Append +} +finally { + if ($pstRoot) { $namespace.RemoveStore($pstRoot) } + if ($outlook) { [System.Runtime.Interopservices.Marshal]::ReleaseComObject($outlook) | Out-Null } +} \ No newline at end of file