user12821291
user12821291

Reputation:

Can´t send an email with attachments with powershell script

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

Answers (1)

Theo
Theo

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

Related Questions