Search code examples
powershellpowershell-3.0

PowerShell Email Attachment: Could not find file 'D:\20201124131044\TRACS-20201124034849\error.log environment.log RACS-20201124034849.sterr.stdout


I am trying to send out an email with only the attachments that exist in the directory. There are three sets of files i am monitoring: error.log, environment.log and a .stdout. I want to check whether each one of the files exist and if they do then add it in a list and send it out as attachments. I dont want to do anything if the files dont exist. I attempted to loop through the list of files (this is in windows) and then if the files exist send them out. My code below:

$PSEmailServer = "xxxxxxxxxxx"
$Password ="xxxxxxxxx"
$mypassword = ConvertTo-SecureString $Password -AsPlainText -Force
$mycredential = New-Object System.Management.Automation.PSCredential ("xxxxx", $mypassword)
$EmailSubject ="test"
$filepath ="D:\20201124131044\TRACS-20201124034849\"
$files = @('error.log','environment.log','TRACS-20201124034849.sterr.stdout')
$FromEmail ="xxxxxxxxxx"     


if(($files | foreach{Test-path $filepath }) -contains $True){

$newfile = $filepath  + $files
Send-MailMessage -From $FromEmail -To "xxxxxxx" -Subject $EmailSubject -Body "test" -Credential $mycredential -Attachments $newfile
}
 else {
  echo "nothing"
  exit
 }

when i run the above i get the following error:

Send-MailMessage : Could not find file 'D:\20201124131044\TRACS-20201124034849\error.log environment.log TRACS-20201124034849.sterr.stdout'. At C:\Users\Downloads\powershell.ps1:22 char:1
+ Send-MailMessage -From $FromEmail -To "xxxxxxx" -Subje ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Send-MailMessage], FileNotFoundException
    + FullyQualifiedErrorId : > System.IO.FileNotFoundException,Microsoft.PowerShell.Commands.SendMailMessage

I think I need to iterate the list to attach each filename to the it's filepath and then store it in a list and then send out the email? Please advise.


Solution

  • You can simply use -contains or -in to find filenames in an array. Also, I would recommend using splatting for the parameters to Send-MailMessage:

    $filepath = "D:\20201124131044\TRACS-20201124034849"
    $files    = 'error.log','environment.log','TRACS-20201124034849.sterr.stdout'
    
    # find files with names that can be found in the $files array
    $attachments = @(Get-ChildItem -Path $filepath -File | Where-Object { $files -contains $_.Name })
    
    # if we have any files to send
    if ($attachments.Count) {
        $Password     = "xxxxxxxxx"
        $mypassword   = ConvertTo-SecureString $Password -AsPlainText -Force
        $mycredential = New-Object System.Management.Automation.PSCredential ("xxxxx", $mypassword)
        # use splatting for better readability
        $mailParams = @{
            To          = "xxxxxxx"
            From        = "xxxxxxxxxx"
            Subject     = "test"
            Body        = "test"
            Credential  = $mycredential
            Attachments = $attachments.FullName
            SmtpServer  = "xxxxxxxxxxx"
            # more parameters can be added here
        }
        # send the email
        Send-MailMessage @mailParams
    }
    else {
        Write-Host 'Nothing to send..'
    }