Forum Discussion

Turion986's avatar
Turion986
Copper Contributor
Aug 31, 2023
Solved

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.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
    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?

    • Turion986's avatar
      Turion986
      Copper 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.....

      • Turion986 

         

        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)

Resources