Reputation:
I have a script that runs this script every 30 mins. This script should send an email if a file is on the folder. The problem i have is that im getting an error: "the file is being used by another process..." which is "Send-MailMessage @Msg"
How i can fix this?
$Email = "myemail"
$Internal = "cc"
$Subject = "Form"
[array]$attachments = Get-ChildItem "\\ip\ftp$\c\1\files\Backorder" *.err
if ([array]$attachments -eq $null) {
}
else {
$Msg = @{
to = $Email
cc = $Internal
from = "address"
Body = "some text"
subject = "$Subject"
smtpserver = "server"
BodyAsHtml = $True
Attachments = $attachments.fullname
}
Send-MailMessage @Msg
Start-Sleep -Seconds 1800
}
Upvotes: 0
Views: 130
Reputation: 61028
You need to build in a test to see if the file are locked (still being written to) or not. For that, you can use this function:
function Test-LockedFile {
param (
[parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
[Alias('FullName', 'FilePath')]
[string]$Path
)
$file = [System.IO.FileInfo]::new($Path)
# old PowerShell versions use:
# $file = New-Object System.IO.FileInfo $Path
try {
$stream = $file.Open([System.IO.FileMode]::Open,
[System.IO.FileAccess]::ReadWrite,
[System.IO.FileShare]::None)
if ($stream) { $stream.Close() }
return $false
}
catch {
return $true
}
}
Having that in place, somewhere above your current code, you can do:
$Email = "myemail"
$Internal = "cc"
$Subject = "Form"
# get the fullnames of the *.err files in an array
$attachments = @(Get-ChildItem -Path "\\ip\ftp$\c\1\files\Backorder" -Filter '*.err' -File)
if ($attachments.Count) {
# wait while the file(s) are locked (still being written to)
foreach ($file in $attachments) {
while (Test-LockedFile -Path $file.FullName) {
Start-Sleep -Seconds 1
}
}
$Msg = @{
To = $Email
Cc = $Internal
From = "address"
Body = "some text"
Subject = $Subject
SmtpServer = "server"
BodyAsHtml = $True
Attachments = $attachments.FullName
}
Send-MailMessage @Msg
Start-Sleep -Seconds 1800
}
Hope that helps
Upvotes: 1