Trovare PST in rete con PowerShell

In un recente progetto di migrazione a Exchange Online da una precedente soluzione di posta elettronica, mi sono trovato ad avere a che fare con molti client su cui la posta era archiviata in numerosi file PST locali.

Questo ovviamente esponeva a numerosi rischi il sistema, primo di tutti la perdita di dati: se un file PST si corrompe – e non è difficile con PST da 20 o 30 GB – i dati sono quasi sicuramente persi, anche perché non c’era backup dei client. Oltretutto, i PST non offrono agli amministratori la possibilità di controllarne l’uso ed il contenuto facilmente: insomma, un vero incubo per un admin di Exchange!

Dopo aver migrato le caselle di produzione da server a server, dovevo quindi “scovare” tutti i PST sparsi nei vari computer del dominio, per poi raccoglierli su una share di rete e importarli in Exchange Online.

Ho deciso di scrivere da solo un piccolo tool in PowerShell allora che andasse a fare questo lavoro per me, risparmiando molte ore uomo di lavoro. I requisiti per eseguire lo script sono i seguenti:

– privilegi di amministratore sulle macchine in cui cercare
– un computer Windows con almeno PowerShell 5.1
– raggiungibilità dei computer target via rete

Durante l’esecuzione, lo script mostra a console quello che sta facendo:

Alla fine vi troverete un file CSV con tutti i PST (con nome del computer, nome del file, path completo e dimensione in GB), che poi potrete importare anche in Excel e procedere quindi poi con la raccolta dei file PST:

I computer che risulteranno offline dalla prima esecuzione potranno poi essere facilmente riscansionati in seguito, confrontando il file di log e quello dei computer da processare:

Questo il codice dello script – che potete altrimenti scaricare da GitHub:

#region Credits
# Author: Federico Lillacci - Coesione Srl - www.coesione.net
# GitHub: https://github.com/tsmagnum
# Version: 1.1
# Date: 26/02/2024
#endregion

#region TODO

#endregion

#Storing the execution time in a variable; used to name the log and results file
$executionTime = (Get-Date).ToString('yyyyMMdd-hhmm')

#region VARIABLES
#please set these variables before running the script

#Txt file with the computers to process, one per line
$Computers = Get-Content -Path "C:\Scripts\ClientsTest.txt"

#Log file of the processed computers
$processedPCs = "C:\Scripts\$($executionTime)_ProcessedPC.txt"

#Results file
$csvPath = "C:\Scripts\$($executionTime)_PstFilesFound.csv"
#endregion

#Begin script execution

#Creating an empty array for the results
$results = @()

Set-Content $processedPCs -Value "Logging script execution - $($executionTime)"

Foreach ($Computer in $Computers)
{
   #Checking if the target computer is online: if so, the check continues
   Write-Host -ForegroundColor Cyan "Checking if $($Computer) is online"
   $pingtest = Test-Connection -ComputerName $Computer -Quiet -Count 1 -ErrorAction SilentlyContinue

   if ($pingtest)
   {
      $message = "$($Computer) is online, looking for PST files..."
      Write-Host -ForegroundColor Cyan $message
      Add-Content -Path $processedPCs -Value $message
      #Performing the search
      $pstFiles = Get-Wmiobject -namespace "root\CIMV2" -computername $Computer -Query "Select * from CIM_DataFile Where Extension = 'pst'"

      #Storing the results in PS Object
      Foreach ($file in $PstFiles)
      {
      $result = [PSCustomObject]@{
         Computer = $file.CSName
         Name = $file.Filename
         Path = $file.Description
         Size = ($file.FileSize)/1GB
         LastAccess = ($file.LastAccessed.Split("."))[0]
      }  

      Write-Host -ForegroundColor Green "PST found! Adding $($result.Name) to results"
      $results += $result
      
      #End 3rd foreach
      }

   #End 2nd foreach
   }

   #Logging offline computers
   else {
      $message = "$($Computer) is offline, skipping PST search"
      Write-Host -ForegroundColor Red $message
      Add-Content -Path $processedPCs -Value $message
   }
#End 1st foreach
}

#Saving results to a CSV file
$results | Export-Csv -Path $csvPath -NoTypeInformation