Forum Discussion
Turion986
Aug 31, 2023Copper Contributor
Help with Watcher
Hey guys, some of you can help me to check what is wrong with this script?
thank you in advance!
# Cartella da monitorare (stessa cartella)
$cartellaDaMonitorare = "C:\TEST"
# Crea un registro per i file già rinominati
$registroFileRinominati = "C:\TEST\registro.txt"
# Funzione per rinominare i file MSG con data e ora
function Rinomina-FileMSG {
param (
[string]$file
)
if ($file -match "\.msg$" -and -not $registroFileRinominati.ContainsKey($file)) {
$now = Get-Date -Format "yyyyMMddHHmm"
$nomeFile = [System.IO.Path]::GetFileNameWithoutExtension($file)
$estensione = [System.IO.Path]::GetExtension($file)
$nuovoNome = "${now}_${nomeFile}${estensione}"
Rename-Item -Path $file -NewName $nuovoNome
Write-Host "Rinominato $file in $nuovoNome"
$registroFileRinominati[$file] = $true
}
}
# Crea un oggetto FileSystemWatcher per monitorare la cartella
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = $cartellaDaMonitorare
$watcher.Filter = "*.msg"
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $true
# Azione da intraprendere quando viene rilevato un nuovo file
$action = {
$changeType = $Event.SourceEventArgs.ChangeType
$file = $Event.SourceEventArgs.FullPath
if ($changeType -eq "Created" -or $changeType -eq "Renamed") {
Rinomina-FileMSG -file $file
}
}
# Associa l'azione all'evento Created e Renamed
Register-ObjectEvent -InputObject $watcher -EventName Created -Action $action
Register-ObjectEvent -InputObject $watcher -EventName Renamed -Action $action
# Attendi che lo script venga interrotto
Write-Host "Waiting for new MSG files..."
while ($true) {
Start-Sleep -Seconds 30
}
Turion986 Ok... I found another script example and rewrote it again for you... I had some issues with files being renamed repeatedly and added renamed to the filename to exclude that...
#https://dotnet-helpers.com/powershell/how-to-monitor-a-folder-changes-using-powershell/ ### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO $filewatcher = New-Object System.IO.FileSystemWatcher #Mention the folder to monitor $filewatcher.Path = "C:\Test" $filewatcher.Filter = "*.msg" $log = "C:\Test\FileWatcher_log.txt" #include subdirectories $true/$false $filewatcher.IncludeSubdirectories = $true $filewatcher.EnableRaisingEvents = $true ### DEFINE ACTIONS AFTER AN EVENT IS DETECTED $writeaction = { $path = $Event.SourceEventArgs.FullPath $changeType = $Event.SourceEventArgs.ChangeType if (-not ($path -match 'renamed')) { $now = Get-Date -Format "yyyyMMddHHmm" $filename = [System.IO.Path]::GetFileNameWithoutExtension($path) $extension = [System.IO.Path]::GetExtension($path) $newname = "${now}_renamed_${filename}${extension}" Rename-Item -Path $path -NewName $newname $logline = "$(Get-Date), $changeType, $path, $newname" Add-content $log -value $logline } } ### DECIDE WHICH EVENTS SHOULD BE WATCHED #The Register-ObjectEvent cmdlet subscribes to events that are generated by .NET objects on the local computer or on a remote computer. #When the subscribed event is raised, it is added to the event queue in your session. To get events in the event queue, use the Get-Event cmdlet. Register-ObjectEvent $filewatcher "Created" -Action $writeaction Register-ObjectEvent $filewatcher "Changed" -Action $writeaction Register-ObjectEvent $filewatcher "Renamed" -Action $writeaction while ($true) { Write-Host ("Monitoring folder {0}" -f $filewatcher.Path) Start-Sleep 5 }
Logfile:
09/22/2023 21:00:45, Renamed, C:\Test\test1.msg, 202309222100_renamed_test1.msg
09/22/2023 21:00:45, Renamed, C:\Test\test1.msg, 202309222100_renamed_test1.msg
09/22/2023 21:01:00, Renamed, C:\Test\test2.msg, 202309222101_renamed_test2.msg
09/22/2023 21:01:00, Renamed, C:\Test\test2.msg, 202309222101_renamed_test2.msg
09/22/2023 21:01:20, Renamed, C:\Test\Testfolder\test3.msg, 202309222101_renamed_test3.msg
09/22/2023 21:01:20, Renamed, C:\Test\Testfolder\test3.msg, 202309222101_renamed_test3.msg
09/22/2023 21:01:41, Renamed, C:\Test\Testfolder\Testsubfolder\test5.msg, 202309222101_renamed_test5.msg
09/22/2023 21:01:41, Renamed, C:\Test\Testfolder\Testsubfolder\test5.msg, 202309222101_renamed_test5.msg09/22/2023 21:03:08, Created, C:\Test\test6.msg, 202309222103_renamed_test6.msg
09/22/2023 21:03:08, Created, C:\Test\test6.msg, 202309222103_renamed_test6.msg
09/22/2023 21:03:08, Created, C:\Test\test6.msg, 202309222103_renamed_test6.msg
Logging is doubled, tripled per file... I'm not sure why that is happening... Is this something you can work with?
- Did this work out for you?
Could you paste the code into a script block? (More readable) But what's the issue? What does work and doesn't work?
- Turion986Copper Contributor
# Cartella da monitorare (stessa cartella) $cartellaDaMonitorare = "C:\TEST" # Crea un registro per i file già rinominati $registroFileRinominati = "C:\TEST\registro.txt" # Funzione per rinominare i file MSG con data e ora function Rinomina-FileMSG { param ( [string]$file ) if ($file -match "\.msg$" -and -not $registroFileRinominati.ContainsKey($file)) { $now = Get-Date -Format "yyyyMMddHHmm" $nomeFile = [System.IO.Path]::GetFileNameWithoutExtension($file) $estensione = [System.IO.Path]::GetExtension($file) $nuovoNome = "${now}_${nomeFile}${estensione}" Rename-Item -Path $file -NewName $nuovoNome Write-Host "Rinominato $file in $nuovoNome" $registroFileRinominati[$file] = $true } } # Crea un oggetto FileSystemWatcher per monitorare la cartella $watcher = New-Object System.IO.FileSystemWatcher $watcher.Path = $cartellaDaMonitorare $watcher.Filter = "*.msg" $watcher.IncludeSubdirectories = $true $watcher.EnableRaisingEvents = $true # Azione da intraprendere quando viene rilevato un nuovo file $action = { $changeType = $Event.SourceEventArgs.ChangeType $file = $Event.SourceEventArgs.FullPath if ($changeType -eq "Created" -or $changeType -eq "Renamed") { Rinomina-FileMSG -file $file } } # Associa l'azione all'evento Created e Renamed Register-ObjectEvent -InputObject $watcher -EventName Created -Action $action Register-ObjectEvent -InputObject $watcher -EventName Renamed -Action $action # Attendi che lo script venga interrotto Write-Host "Waiting for new MSG files..." while ($true) { Start-Sleep -Seconds 30 }
Harm_Veenstra sorry i didnt see the special box for the scripts, actually is doing nothing.....this script should monitoring a folder and whatever .msg file will be copied or moved inside, the script should activate the rename function.....
Error is:
PS>TerminatingError(): "Method invocation failed because [System.String] does not contain a method named 'ContainsKey'."
I found that by adding transcript logging :
function Rinomina-FileMSG { param ( [string]$file ) Start-Transcript C:\test\script.log
I changed it to this now and that seems to work, file is renamed with a timestamp now
function Rinomina-FileMSG { param ( [string]$file ) if ($file -match "\.msg$" -and -not $registroFileRinominati.Contains($file)) { $now = Get-Date -Format "yyyyMMddHHmm" $nomeFile = [System.IO.Path]::GetFileNameWithoutExtension($file) $estensione = [System.IO.Path]::GetExtension($file) $nuovoNome = "${now}_${nomeFile}${estensione}" Rename-Item -Path $file -NewName $nuovoNome Write-Host "Rinominato $file in $nuovoNome" $registroFileRinominati[$file] = $true } }
Is this correct now? The filename is 202309041124_test.msg now (Was test.msg)