Below is a script that tracks the directory and its subfolders for stored files. About every 10 minutes I search for new files, and then compare them with the database table, which indicates where to transfer them, then copies the files to the local archive, moves them to the places that need to be moved and inserts the record into another database table data with file attributes, as well as where it came and went. If there are no matches in the database - or there is a script error - he sends me an email.
However, since the files are constantly placed in the directory, it is possible that the file is still being written during script execution. As a result, I get the error The process cannot access the file because it is being used by another process. email me all the time. Also, because I do not deal with the error in advance; it goes through a cycle, and a false record with invalid file attributes is inserted into my log table in the database. When the file is finally freed, it is inserted again.
I am looking for a way to identify the files to which processes are attached; and skip them when running the script - but several days of searching the Internet and some testing have not yet given an answer.
## CLEAR ERROR LOG $error.clear() Write-Host "***File Transfer Script***" ## PARAMETERS $source_path = "D:\Files\In\" $xferfail_path = "D:\Files\XferFailed\" $archive_path = "D:\Files\XferArchive\" $email_from = "SQLMail <SQLMail@bar.com>" $email_recip = [STRING]"foo@bar.com" $smtp_server = "email.bar.com" $secpasswd = ConvertTo-SecureString "Pa$$w0rd" -AsPlainText -Force $smtp_cred = New-Object System.Management.Automation.PSCredential ("BAR\SQLAdmin", $secpasswd) ## SQL LOG FUNCTION function Run-SQL ([string]$filename, [string]$filepath, [int]$filesize, [int]$rowcount, [string]$xferpath) { $date = get-date -format G $SqlConnection = New-Object System.Data.SqlClient.SqlConnection $SqlConnection.ConnectionString = "Server=SQLSERVER;Database=DATABASE;Uid=SQLAdmin;Pwd=Pa$$w0rd;" $SqlConnection.Open() $SqlCmd = New-Object System.Data.SqlClient.SqlCommand $SqlCmd.CommandText = "INSERT INTO DATABASE..Table VALUES ('$date','$filename','$filepath',$filesize,$rowcount,'$xferpath',0)" $SqlCmd.Connection = $SqlConnection $SqlCmd.ExecuteNonQuery() $SqlConnection.Close() } ## DETERMINE IF THERE ARE ANY FILES TO PROCESS $file_count = Get-ChildItem -path $source_path |? {$_.PSIsContainer} ' | Get-ChildItem -path {$_.FullName} -Recurse | Where {$_.psIsContainer -eq $false} | Where {$_.Fullname -notlike "D:\Files\In\MCI\*"} ' | Measure-Object | Select Count If ($file_count.Count -gt 0) { Write-Host $file_count.Count "File(s) Found - Processing." Start-Sleep -s 5 ## CREATE LIST OF DIRECTORIES $dirs = Get-ChildItem -path $source_path -Recurse | Where {$_.psIsContainer -eq $true} | Where {$_.Fullname -ne "D:\Files\In\MCI"} ' | Where {$_.Fullname -notlike "D:\Files\In\MCI\*"} ## CREATE LIST OF FILES IN ALL DIRECTORIES $files = ForEach ($item in $dirs) { Get-ChildItem -path $item.FullName | Where {$_.psIsContainer -eq $false} | Sort-Object -Property lastWriteTime -Descending } ## START LOOPING THROUGH FILE LIST ForEach ($item in $files) { ## QUERY DATABASE FOR FILENAME MATCH, AND RETURN TRANSFER DIRECTORY $SqlConnection = New-Object System.Data.SqlClient.SqlConnection $SqlConnection.ConnectionString = "Server=SQLSERVER;Database=DATABASE;Uid=SQLAdmin;Pwd=Pa$$w0rd;" $SqlConnection.Open() $SqlCmd = New-Object System.Data.SqlClient.SqlCommand $SqlCmd.CommandText = "SELECT F.DirTransfer FROM DATABASE..Files F WHERE '$item.Name.Trim()' LIKE F.FileName" $SqlCmd.Connection = $SqlConnection $DirTransfer = $SqlCmd.ExecuteScalar() $SqlConnection.Close() If ($DirTransfer) # if there is a match { Write-Host $item.FullName"'t->'t"$DirTransfer $filename = $item.Name $filepath = $item.FullName $filesize = $item.Length If (!($filesize)) { $filesize = 0 } $rowcount = (Get-Content -Path $item.FullName).Length If (!($rowcount)) { $rowcount = 0 } $xferpath = $DirTransfer Run-SQL -filename "$filename" -filepath "$filepath" -filesize "$filesize" -rowcount "$rowcount" -xferpath "$DirTransfer" Copy-Item -path $item.FullName -destination $DirTransfer -force -erroraction "silentlycontinue" Move-Item -path $item.FullName -destination $archive_path -force -erroraction "silentlycontinue" #Write-Host "$filename $filepath $filesize $rowcount $xferpath" } Else # if there is no match { Write-Host $item.FullName "does not have a mapping" Move-Item -path $item.FullName -destination $xferfail_path -force $filename = $item.FullName $email_body = "$filename 'r'n'r'n does not have a file transfer mapping setup" Send-MailMessage -To $email_recip ' -From $email_from ' -SmtpServer $smtp_server ' -Subject "File Transfer Error - $item" ' -Body $email_body ' -Priority "High" ' -Credential $smtp_cred } } } ## IF NO FILES, THEN CLOSE Else { Write-Host "No File(s) Found - Aborting." Start-Sleep -s 5 } ## SEND EMAIL NOTIFICATION IF SCRIPT ERROR If ($error.count -gt 0) { $email_body = "$error" Send-MailMessage -To $email_recip ' -From $email_from ' -SmtpServer $smtp_server ' -Subject "File Transfer Error - Script" ' -Body $email_body ' -Priority "High" ' -Credential $smtp_cred }
powershell
chrisnre
source share