Copy-Item does not work with FileSystemWatcher - powershell

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}

Related

moving files in order dependant on file name with powershell

I use PS script with filesystemwatcher to monitor a folder. In this folder files need to be picked up in a specific order, not in the order they are created. So:
Files "blabla-Important1.xml", "blabla-Important2.xml" and "blabla-Important3.xml" are placed in the "pick-up folder". Filesystemwatcher wants to move the files according to the script. Now I need the files to be placed in the "destination folder" in the order I want, let's say:
"blabla-Important2.xml",
"blabla-Important4.xml",
"blabla-Important3.xml",
"blabla-Important1.xml".
Any suggestions? Thanks in advance!
Here's the (partial) script:
$folder = '.\tstA'
$filter = '*.xml'
$destination = '.\tstB'
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property #{
IncludeSubdirectories = $false
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 "$timeStamp The file '$name' was $changeType and moved for SFTP to $destination"
"$timeStamp The file '$name' was $changeType and moved for SFTP to $destination" | Set-Content
'.\tst.log'
Move-Item $path -Destination $destination -Force -Verbose
}

Capturing and copying created file in powershell

Im using this script to scan a folder for the created files. Sadly this are temp files and gets created and deleted by a program we use.
Code:
$folder = 'C:\Users\JuanMa\Desktop\RestBar\RestBar'
$filter = '*.*' # <-- set this according to your requirements
$destination = 'C:\Users\JuanMa\Desktop\UNB'
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property #{
IncludeSubdirectories = $true # <-- set this according to your requirements
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 "The file '$name' at '$path'was $changeType at $timeStamp"
Copy-Item $path -Destination $destination -Force -Verbose # Force will overwrite files with same name
}
The Script its not being able to copy the file to the destination folder. Im assuming that the files gets deleted before it can be copied. Its there a way to lock the file so it dosent get deleted but after the copy operation?
Thanks!

Monitor folder on remote PC for changed files

I have a measuring device on a PC in our network. The PC is not joined to the domain, however has a shared folder for which I have a username and password.
I am attempting to build a Powershell script to monitor this folder from a remote server, for new CSV files, the script will then copy the file to a specified folder location. I am struggling to pass through the parameters to the FileSystemWatcher cmdlet.
Any ideas?
$folder = '\\remoteip\folder\subfolder'# <--'<full path to the folder to watch>'
$filter = '*.csv'
$destination = '\\mynetworkstorage\folder\' # <--' Where is the file going?
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property #{
IncludeSubdirectories = $true # <-- set this according to your requirements
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 "The file '$name' was $changeType at $timeStamp"
Copy-Item $path -Destination $destination -Force -Verbose
}
EDIT -
The script will be run from a server joined to our domain, so there is a need to pass through credentials to the folder in order that I can access it. I have these credentials.
I refactored the code a little (mainly so I could more easily understand it):
$folder = '\\localhost\c$\tmp'
$filter = '*.*'
$destination = '\\localhost\c$\tmp_destination\'
$fsw = New-Object IO.FileSystemWatcher
$fsw.Path = $folder
$fsw.Filter = $filter
$fsw.IncludeSubdirectories = $true
$fsw.EnableRaisingEvents = $true
$fsw.NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'
$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 -Verbose
}
$created = Register-ObjectEvent $fsw Created -Action $action
while ($true) {sleep 1}
I ran this code locally and managed to get files created in $folder automatically copied to $destination.
FileSystemWatcher run in the context of the current user. In the case of accessing remote systems that require login, impersonation is required.
If the remote system only got local users, no domain user that the source system can log on as, then impersonation does not seem to be possible.
See this and this link for more details on impersonation.

Copy-Item does not copy item when actioned by filesystemwatcher

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
}

copy in powershell does not work as excpected

I have the following powershell script that not quite work as I thought it would. I want to copy the new created file in the source folder ($folder) to my destination folder ($DestFolder), but no file is copied. Anyone see what could be wrong?
$SourceFolder = 'd:\temp\' # Enter the root path you want to monitor.
$folder = 'd:\temp' # Enter the root path you want to monitor.
$Destfolder = 'd:\temp2\' # Enter the root path you want to monitor.
$global:MySourceFolder = 'd:\temp\' # Enter the root path you want to monitor.
$global:MyDestfolder = 'd:\temp2\' # Enter the root path you want to monitor.
$filter = '*.*' # You can enter a wildcard filter here.
# In the following line, you can change 'IncludeSubdirectories to $true if required.
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property #{IncludeSubdirectories = $false;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'}
Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action {
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
#Write-Host "The file '$name' was $changeType at $timeStamp" -fore green
Write-Host "path : $MyDestfolder$name" -fore green
Copy-Item (Join-Path $MySourceFolder $name) ($Destfolder)
Out-File -FilePath d:\temp\filechange\outlog.txt -Append -InputObject "The file '$name' was $changeType at $timeStamp"}
I believe it is working as intended. If the copy actually is part of the action, try moving that line inside the action script block.
The variable $name is empty outside the action scriptblock since the ObjectEvent has its own scope. If you need to access this variable from outside the Action scriptblock you could declare the variable using $global:name.
The following really should work (replace with this but save a copy of your code so you've got a backup first)
$folder = 'd:\temp'
$Destfolder = 'd:\temp2'
$filter = '*.*'
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property #{
IncludeSubdirectories = $false
NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'
}
Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action {
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
Write-Host "The file '$name' was $changeType at $timeStamp" -fore green
Copy-Item -Path (Join-Path $folder $name) -Destination $Destfolder
Out-File -FilePath "d:\temp\filechange\outlog.txt" -Append -InputObject "The file '$name' was $changeType at $timeStamp"
}