0

When I follow the guidance from this website https://adamtheautomator.com/send-mailmessage/

Why does the test result state that it's unable to find the file, even though the file appears in my Azure File Explorer?

Below is the code:

$Username ="<username>"
$Password = ConvertTo-SecureString "<password" -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential $Username, $Password
$SMTPServer = "<server>"
$EmailFrom = "<from email>"
[string[]]$EmailTo = "<to email>"
$Subject = "TEST MESSAGE"

# Setting the Azure Storage Context, recommendation is to read sastoken from Runbook assets for security purpose.

$context = New-AzureStorageContext -StorageAccountName "<ACCOUNT NAME>" -SasToken "<SAS TOKEN>"

# Get contents of the file
$attachment = Get-Content "<filename>"
$Body = "<Body Message>"

Send-MailMessage -smtpServer $SMTPServer -Attachments <file_name> -Credential $credential -Usessl -Port 587 -from $EmailFrom -to $EmailTo -subject $Subject -Body $Body -BodyAsHtml
Write-Output ("Email sent succesfully.")

The following error message appears:

Get-Content : Cannot find path 'C:\Temp\4wved2xx.juf\<file name>' because it does not exist.
At line:19 char:15
+ $attachment = Get-Content "<file name>"
+               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\Temp\4wved2xx.juf\<file name>.jpg:String) [Get-Content], 
ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand
 
Send-MailMessage : Cannot validate argument on parameter 'Attachments'. The argument is null or empty. Provide an 
argument that is not null or empty, and then try the command again.
At line:30 char:55
+ ... -MailMessage -smtpServer $SMTPServer -Attachments $attachment -Creden ...
+                                                       ~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Send-MailMessage], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.SendMailMessage
Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • So please explain what is not working as you would like. Any error messages? email badly formed? Not sending the email or what? – Theo Jan 20 '21 at 09:44
  • Hello, I've edited the code and added the error messages - which by the way - are wrong because the `-Attachments` parameter is not empty or invalid in the slightest – Johannes Schulz-Bauer Jan 20 '21 at 09:54
  • The email is sending when the attachment coding is taken out, so it's clearly the attachment code which is the issue. I fail to see how the `-Attachments` argument is empty or invalid when it is blatantly obvious that its neither. – Johannes Schulz-Bauer Jan 20 '21 at 10:02
  • The error message reads `ObjectNotFound: (C:\Temp\4wved2xx.juf\.jpg` - did you redact the error message, or does it *really* contain ``? – Tomalak Jan 20 '21 at 10:24
  • `Attachments` is a string array that specifies the path and file names of files to be attached to the email message. It looks like you are reading the contents of the file and try to send that in this parameter: `$attachment = Get-Content ""` ? \\\ Please also note that if you want to respond to someone's comment, 'ping' that person by typing `@` followed by the user name. – Theo Jan 20 '21 at 10:31
  • @Tomalak No, I have just redacted the filename to protect confidentiality – Johannes Schulz-Bauer Jan 20 '21 at 10:35
  • @Theo That makes sense, so how would I alter the code so as to send the file as opposed to reading the file contents? Cheers – Johannes Schulz-Bauer Jan 20 '21 at 10:39
  • `"Cannot find path 'C:\Temp\4wved2xx.juf\' because it does not exist."` is not an ambiguous error message. The file you try to attach does not exist. Your code does not show where `` comes from, you should include that part. – Tomalak Jan 20 '21 at 10:54
  • @Tomalak it does show where it comes from, the source is the: the `$context = New-AzureStorageContext -StorageAccountName "" -SasToken "" # Get contents of the file $attachment = Get-Content ""` – Johannes Schulz-Bauer Jan 20 '21 at 10:56
  • That sets a context, and it tries to get the content of ``. It does not explain where `` comes from. For all I can see that's a constant value you have hard coded in your script. – Tomalak Jan 20 '21 at 10:58
  • @Tomalak it is a constant because that is where the file is stored. – Johannes Schulz-Bauer Jan 20 '21 at 11:01
  • No, it's not. A "path not found" message has no two ways of interpretation. Either the file is there, then the maximum you could get is "access denied". Or the file is not there, then you get "path not found". – Tomalak Jan 20 '21 at 11:03
  • @Tomalak, but the file is right there, I'm looking at it. – Johannes Schulz-Bauer Jan 20 '21 at 11:07
  • The computer does not lie. If it says "path not found" then that's what's up. What does a `Get-ChildItem -LiteralPath "C:\Temp" -Recurse | Select -ExpandProperty FullName` give you? – Tomalak Jan 20 '21 at 11:10
  • @Theo it gives me the following message: `Get-ChildItem : Cannot find path 'C:\Temp' because it does not exist. At line:1 char:1 + Get-ChildItem -LiteralPath "C:\Temp" -Recurse | Select -ExpandPropert ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (C:\Temp:String) [Get-ChildItem], ItemNotFoundException + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand` – Johannes Schulz-Bauer Jan 20 '21 at 11:16
  • 1) I have the correct file name, 2) I have pointed Azure Runbook PowerShell to the correct file share, with secure SAS took, container name and file share name 3) It's still not seeing the file, there a reason for this, so there is something wrong with either Azure, Runbooks or Powershell – Johannes Schulz-Bauer Jan 20 '21 at 11:19

1 Answers1

0

With this like

$attachment = Get-Content "<filename>"

I am suspecting you are trying to send the contents of the file in parameter -Attachments, rather than the full path and filename itself.

If that is the case, simply remove that line and add the full filename there:

# suppose your file is `'C:\Temp\4wved2xx.juf\MyFile.txt'`
-Attachments 'C:\Temp\4wved2xx.juf\MyFile.txt'

To avoid long, LONG command lines with cmdlets like Send-MailMessage that take lots of parameters, I would suggest using Splatting

$Username   ='<username>'
$Password   = ConvertTo-SecureString '<password>' -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential $Username, $Password

# set up a hashtable for splatting the parameters to the Send-MailMessage cmdlet
$mailParams = @{
    From        = 'someone@yourdomain.com'
    To          = 'someone.else@yourdomain.com'
    Subject     = 'TEST MESSAGE'
    Body        = '<Body Message>'
    BodyAsHtml  = $true
    Attachments = 'C:\Temp\4wved2xx.juf\MyFile.txt'  # can be multiple files in an array of Full filenames
    SmtpServer  = 'smtp.yourdomain.com'
    Port        = 587
    Usessl      = $true
    Credential  = $credential

    # other parameters go here
}

Send-MailMessage @mailParams

Please also note the use of single-quotes which is especially important when specifying the password to make sure PowerShell takes the string literally.

Theo
  • 57,719
  • 8
  • 24
  • 41
  • `Send-MailMessage : Could not find file ''. At line:30 char:1 + Send-MailMessage -smtpServer $SMTPServer -Attachment 'C:\Users\....\...' – Johannes Schulz-Bauer Jan 20 '21 at 11:15
  • @JohannesSchulz-Bauer In that case first check if the file is found: `if (Test-Path -Path 'C:\Temp\4wved2xx.juf\MyFile.txt' -PathType Leaf) { <# send the mail #> } else { Write-Warning "File 'C:\Temp\4wved2xx.juf\MyFile.txt' not found.." }`. \\\ Where do you determine the file name in your code? Since this is in `C:\Temp`, are you sure it still exists? \\\ Try using the UNC path to the file share. Looks like now you are telling PowerShell to search in your local machine's C:\Temp path instead of the server's file share – Theo Jan 20 '21 at 11:19
  • No the file is in my Azure storage account, under the FileShare. Cheers – Johannes Schulz-Bauer Jan 20 '21 at 11:27
  • Keep in mind that Microsoft marked Send-MailMessage as obsolute because it won't guarantee a secure connection to a SMTP server (even when using the -UseSSL switch). – bluuf Jan 20 '21 at 12:57