UPDATED:
Hi. Apologies if my question sounds vague. When I run both Scripts below together all the csv files from ES and LTC sub-folder end up in one folder instead of two folders. I have two separate scripts
to monitor two sub-folders LTC and ES and copy the files to the folders.
LTC Script:
$folder = 'C:\2014-15'
$destination = 'N:\Test'
$fsw = New-Object System.IO.FileSystemWatcher $folder -Property #{
IncludeSubdirectories = $true
NotifyFilter = [IO.NotifyFilters]'DirectoryName'
}
$created = Register-ObjectEvent $fsw -EventName Created -Action {
$item = Get-Item $eventArgs.FullPath
If ($item.Name -ilike "LTC") {
Copy-Item -Path $folder -Destination $destination
}
}
$renamed = Register-ObjectEvent $fsw -EventName Renamed -Action {
$item = Get-Item $eventArgs.FullPath
If ($item.Name -ilike "LTC") {
Copy-Item -Path $folder -Destination $destination
}
}
ES Script:
$folder = 'C:\2014-15'
$destination = 'N:\Test1'
$fsw = New-Object System.IO.FileSystemWatcher $folder -Property #{
IncludeSubdirectories = $true
NotifyFilter = [IO.NotifyFilters]'DirectoryName'
}
$created = Register-ObjectEvent $fsw -EventName Created -Action {
$item = Get-Item $eventArgs.FullPath
If ($item.Name -ilike "ES") {
Copy-Item "$item\*.csv" -Destination $destination
}
}
$created = Register-ObjectEvent $fsw -EventName Created -Action {
$item = Get-Item $eventArgs.FullPath
If ($item.Name -ilike "ES") {
Copy-Item "$item\*.csv" -Destination $destination
}
}
$folder = 'C:\2014-15'
$destination = 'N:\Test'
$destination1 = 'N:\Test1'
$fsw = New-Object System.IO.FileSystemWatcher $folder -Property #{
IncludeSubdirectories = $true
NotifyFilter = [IO.NotifyFilters]'DirectoryName'
}
$created = Register-ObjectEvent $fsw -EventName Created -Action {
$item = Get-Item $eventArgs.FullPath
If ($item.Name -ilike "LTC") {
Copy-Item -Path $folder -Destination $destination
}
}
$renamed = Register-ObjectEvent $fsw -EventName Renamed -Action {
$item = Get-Item $eventArgs.FullPath
If ($item.Name -ilike "LTC") {
Copy-Item -Path $folder -Destination $destination
}
}
$fsw = New-Object System.IO.FileSystemWatcher $folder -Property #{
IncludeSubdirectories = $true
NotifyFilter = [IO.NotifyFilters]'DirectoryName'
}
$created = Register-ObjectEvent $fsw -EventName Created -Action {
$item1 = Get-Item $eventArgs.FullPath
If ($item1.Name -ilike "ES") {
Copy-Item "$item1\*.csv" -Destination $destination1
}
}
$created = Register-ObjectEvent $fsw -EventName Created -Action {
$item1 = Get-Item $eventArgs.FullPath
If ($item1.Name -ilike "ES") {
Copy-Item "$item1\*.csv" -Destination $destination1
}
}
Related
Please find below my powershell script that is used to move files from one folder to another :
$folder = 'C:\test'
$filter = '*.*'
$directory_source = $directory_source = 'C:\test1\*' # <-- set this according to your requirements
$directory_target_cop = 'C:\Folder1'
$directory_target_prop = 'C:\Folder2'
$directory_target_dom = 'C:\Folder3'
$LogTime = Get-Date -Format "MM-dd-yyyy"
$dtNow = Get-Date -Format "MM-dd-yyyy_hh-mm-ss"
$script:loggingpathpreference = 'C:\PSLogs\'+$LogTime+".log"
Set-PSBreakpoint -Variable Now -Mode Read -Action {Set-Variable Now (get-date -uformat '%Y\%m\%d %H:%M:%S') -Option ReadOnly, AllScope -Scope Global -Force -ErrorAction SilentlyContinue} -ErrorAction SilentlyContinue
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property #{
IncludeSubdirectories = $true # <-- set this according to your requirements
NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'
}
Function Write-Log {
[cmdletbinding()]
Param(
[Parameter(Position = 0, ValueFromPipeline = $true)]
[ValidateNotNull()]
$Message,
[switch]$Warning
)
Process{
if($Message -isnot [string]){
$Message = $Message | Out-String
}
Write-Verbose $message
Add-Content -Path $script:LoggingPathPreference -Value "`n$($dtNow) : $($Message)"
if($Warning){
Write-Warning $Message
}
}
}
$onCreated = Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action {
$path = $Event.SourceEventArgs.FullPath
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
Write-Log "The file '$name' was $changeType at $timeStamp"
try{
$files = $(ls $directory_source)
foreach ($file in $files) {
if ( $(gc $file | Select-String "PROP" -Quiet) ) {
mv -Path $file.Fullname -Destination $directory_target_prop
} elseif ( $(gc $file | Select-String "COP" -Quiet) ) {
mv -Path $file.Fullname -Destination $directory_target_cop
} elseif ( $(gc $file | Select-String "DOM" -Quiet) ) {
mv -Path $file.Fullname -Destination $directory_target_dom
}
}
}catch{
$ErrorMessage = $_.Exception.Message
Write-Log $ErrorMessage
}
}
Now if I remove my Write-Log function then the above script moves the files from test folder to respective three folders, but when I do include the Write-Log function, the above code is not able to move the files.
The above code is doing the logging but not moving the files.
What am I doing wrong here?
Looking forward to your solutions and thanks in advance.
I'm trying to create a watch folder on a network share that simply copies files (300mb-20gb) in size to a destination folder. The FileSystemWatcher and subscription works great with small files (i.e. 1-3kb). However, larger files do not copy. I do see a copy is triggered in the verbose stream, but no file is copied to the destination folder.
$Folder = "\\10.11.233.91\vol_tx01\delivered_media"
$Filter = "*.mxf"
$destination = "C:\Users\Leeds TX 11\Desktop\support\Testy"
$Watcher = New-Object IO.FileSystemWatcher $Folder, $Filter -Property #{
NotifyFilter = [IO.NotifyFilters]'Filename, LastAccess'
}
$onCreated = Register-ObjectEvent $Watcher Created -SourceIdentifier `
FileCreated -Action {
$path = $event.SourceEventArgs.FullPath
$name = $event.SourceEventArgs.Name
$ChangeType = $event.SourceEventargs.ChangeType
$Timestamp = $event.TimeGenerated
Write-Host "The file '$name' was $ChangeType at $Timestamp"
Copy-Item $path -Destination $destination -Force -Recurse -Verbose
}
Combination of issue were at hand. Firstly thank you JohnLBevan for pointing out LastWrite should be the notifyfilter to use. Also found that in this case copy-item does not wait for the file transfer in the source directory to close. I fixed this by putting in a while loop waiting for the file to be locked:
##################### DANGER BOX ####################################
$Folder = "C:\Users\Leeds TX 12\Desktop\Source" #Source dir
$Filter = "*.mxf" # MXF Filter
$destination = "C:\Users\Leeds TX 12\Desktop\Destination" # Destination dir
################### Watch for file system events###########################
$Watcher = New-Object IO.FilesystemWatcher $Folder, $Filter -Property #{
NotifyFilter = [IO.NotifyFilters]'LastWrite, Filename'
}
################### Register filesystemwatcher & subscribe to notifyfilters #################
$onCreated = Register-ObjectEvent $Watcher Created -SourceIdentifier filecreated -Action {
$path = $event.SourceEventArgs.FullPath
$name = $Event.SourceEventArgs.Name
$ChangeType = $Event.SourceEventargs.ChangeType
$Timestamp = $event.TimeGenerated
write-host "The file '$name' was $ChangeType at $Timestamp" # Debug
################# Wait for file lock collapse #########################################
while($True)
{
Try {
[IO.File]::OpenWrite($path).Close()
Break
}
Catch { Start-Sleep -Seconds 1}
}
#################### Copy item #############################
Copy-item $path -Destination $Destination -force -Recurse -Verbose}
I'm trying to create a watch folder on a network share that simply copies files (300mb-20gb) in size to a destination folder. The filesystemwatcher and subscription works great with small files (i.e. 1-3kb). However, larger files do not copy. I do see a copy is triggered in the verbose stream, but no file is copied to the destination folder.
$Folder = "\\10.11.233.91\vol_tx01\delivered_media"
$Filter = "*.mxf"
$destination = "C:\Users\Leeds TX 11\Desktop\support\Testy"
$Watcher = New-Object IO.FileSystemWatcher $Folder, $Filter -Property #{
NotifyFilter = [IO.NotifyFilters]'Filename, LastAccess'
}
$onCreated = Register-ObjectEvent $Watcher Created -SourceIdentifier FileCreated -Action {
$path = $event.SourceEventArgs.FullPath
$name = $event.SourceEventArgs.Name
$ChangeType = $event.SourceEventargs.ChangeType
$Timestamp = $event.TimeGenerated
Write-Host "The file '$name' was $ChangeType at $Timestamp"
Copy-Item $path -Destination $destination -Force -Recurse -Verbose
}
I wrote a script which detects a folder called Post within the subfolders of W:\SUS Test2 and moves CSV file which has "EMMain" in the filename. But the problem I have is the CSV files doesn't copy to the destination folder W:\SUS Test3 it copies it to W:\SUS Test2 folder.
$path = "W:\SUS Test2\"
$destination = "W:\SUS Test3\"
$fsw = New-Object System.IO.FileSystemWatcher $path -Property #{
IncludeSubdirectories = $true
NotifyFilter = [IO.NotifyFilters]'DirectoryName
}
$createdLTC = Register-ObjectEvent $fsw -EventName Created -Action {
$item = Get-Item $eventArgs.FullPath
if ($item.Name -like "Post") {
Get-ChildItem $item -filter "*EMMain*" | Copy-Item -dest $destination
}
}
You are trying to access the $destination variable in a portion of code that it is not available in. The script block in your Register-OjbectEvent will not have access to this variable. Try declaring $destination in the script block directly.
$createdLTC = Register-ObjectEvent $fsw -EventName Created -Action {
$destination = "W:\SUS Test3\"
$item = Get-Item $eventArgs.FullPath
If ($item.Name -like "Post") {
Get-ChildItem $item -filter "*EMMain*" | Copy-Item -dest $destination
}
}
I have a folder called C:\2014-15 and new sub folders are created every month which contain csv files i.e
C:\2014-15\Month 1\LTC
C:\2014-15\Month 2\LTC
C:\2014-15\Month 3\LTC
How to write a script which would detect when a LTC sub folder is created for every month and move the csv files to N:\Test?
UPDATED:
$folder = 'C:\2014-15'
$filter = '*.*'
$destination = 'N:Test\'
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property #{
IncludeSubdirectories = $true
NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'
}
$onCreated = Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action {
$path = $Event.SourceEventArgs.FullPath
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
Write-Host
Copy-Item -Path $path -Destination $destination
}
The error I get is:
Register-ObjectEvent : Cannot subscribe to event. A subscriber with source identifier 'FileCreated' already exists.
At line:8 char:34
+ $onCreated = Register-ObjectEvent <<<< $fsw Created -SourceIdentifier FileCreated -Action {
+ CategoryInfo : InvalidArgument: (System.IO.FileSystemWatcher:FileSystemWatcher) [Register-ObjectEvent], ArgumentException
+ FullyQualifiedErrorId : SUBSCRIBER_EXISTS,Microsoft.PowerShell.Commands.RegisterObjectEventCommand
Credit to this post.
Notify on a different event: [IO.NotifyFilters]'DirectoryName'. This removes the need for $filter since filename events are not relevant.
You should also notify for renamed folders and created folders, making your final script something like this
$folder = 'C:\2014-15'
$destination = 'N:\Test'
$fsw = New-Object System.IO.FileSystemWatcher $folder -Property #{
IncludeSubdirectories = $true
NotifyFilter = [IO.NotifyFilters]'DirectoryName'
}
$created = Register-ObjectEvent $fsw -EventName Created -Action {
$item = Get-Item $eventArgs.FullPath
If ($item.Name -ilike "LTC") {
# do stuff:
Copy-Item -Path $folder -Destination $destination
}
}
$renamed = Register-ObjectEvent $fsw -EventName Renamed -Action {
$item = Get-Item $eventArgs.FullPath
If ($item.Name -ilike "LTC") {
# do stuff:
Copy-Item -Path $folder -Destination $destination
}
}
From the same console you can unregister since that console knows about $created and $renamed:
Unregister-Event $created.Id
Unregister-Event $renamed.Id
Otherwise you need to use this which is bit uglier:
Unregister-Event -SourceIdentifier Created -Force
Unregister-Event -SourceIdentifier Renamed -Force
Also, thanks for the question. I didn't realise these event captures existed in powershell until now...