$drive = "C:" $pollIntervalMs = 1000 function Get-NextUsn { $line = fsutil usn queryjournal $drive | Select-String "Usn successivo" if ($line -match '0x[0-9A-Fa-f]+') { return $matches[0] } throw "Impossibile ricavare l'Usn successivo." } function Resolve-FilePath { param( [string]$FileId, [string]$FileName ) if (-not $FileId) { return "[percorso non disponibile]" } $id = if ($FileId.StartsWith("0x")) { $FileId } else { "0x$FileId" } try { $result = fsutil file queryfilenamebyid $drive $id 2>$null if ($LASTEXITCODE -eq 0 -and $result) { $text = ($result | Out-String).Trim() # Estrae il percorso \\?\C:\... dall'output di fsutil if ($text -match '(\\\\\?\\.+)$') { return $matches[1] } return $text } } catch { } return "[non più risolvibile] $FileName" } function Read-UsnDelta { param( [string]$StartUsn ) $raw = fsutil usn readjournal $drive startusn=$StartUsn | Out-String -Stream $record = @{} foreach ($line in $raw) { if ($line -match '^USN\s*:\s*(.+)$') { $record.USN = $matches[1].Trim() } elseif ($line -match '^Nome file\s*:\s*(.+)$') { $record.FileName = $matches[1].Trim() } elseif ($line -match '^Motivo\s*:\s*0x[0-9A-Fa-f]+:\s*(.+)$') { $record.Reason = $matches[1].Trim() } elseif ($line -match '^Timestamp\s*:\s*(.+)$') { $record.Timestamp = $matches[1].Trim() } elseif ($line -match '^ID File\s*:\s*([0-9A-Fa-f]+)$') { $record.FileId = $matches[1].Trim() } elseif ($line -match '^Lunghezza record\s*:') { if ( $record.FileName -and $record.Timestamp -and $record.Reason ) { $path = Resolve-FilePath ` -FileId $record.FileId ` -FileName $record.FileName [PSCustomObject]@{ Timestamp = $record.Timestamp Operazione = $record.Reason File = $record.FileName Percorso = $path USN = $record.USN } } $record = @{} } } } # --------------------------------------------------------- # Avvio monitor # --------------------------------------------------------- $currentUsn = Get-NextUsn Write-Host "" Write-Host "USN Journal Monitor - $drive" Write-Host "Usn iniziale: $currentUsn" Write-Host "Vengono mostrate solo le modifiche successive." Write-Host "Premi CTRL+C per terminare." Write-Host "" while ($true) { Start-Sleep -Milliseconds $pollIntervalMs $newUsn = Get-NextUsn if ($newUsn -ne $currentUsn) { Read-UsnDelta -StartUsn $currentUsn | Format-Table Timestamp, Operazione, Percorso -AutoSize -Wrap $currentUsn = $newUsn } }