Attach Azure Blob to email in PowerShell from Azure Function - powershell

I have an Azure Function written in PowerShell with input and output binding as same Blob storage which stores input and output csv files. I was able to send an email from the function with the blob attachment but the email has the attached file of Type File instead of csv. So I have to download and manually add .csv extension to it. How can I send my output csv file with the extension in the attachment? I have my email code as below:
# Send Email using SendGrid with file attachment
$username ="Username"
$password = ConvertTo-SecureString "Password" -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential $username,
$password
$SMTPServer = "smtp.sendgrid.net"
$emailFrom = "No-reply#azureadmin.com"
[string[]]$emailTo = "some-email"
$subject = "Sending sample email using SendGrid Azure and PowerShell"
$body = "This is sample email sent using Sendgrid account create on Microsoft
Azure. The script written is easy to use."
$attachment = $outputBlob
Send-MailMessage -smtpServer $SMTPServer -Credential $credential -Usessl -
Port 587 -From $emailFrom -To $emailTo -Subject $subject -Body $body -
BodyAsHtml -Attachments $attachment
I have the output file created in the same code, but I'm not sure how to attach it to email.
The outputBlob is a csv file called outputfile.csv which is stored in the same container as the inputfile. I am creating this output file in this same script. So my container name is say "mycsvcontainer" and the path for my blob in the Azure Function binding is "mycsvcontainer/outptfile.csv" the name of the blob is outputBlob which i use in my script above. Similar are the names for inputBlob.

$StorageAccountName = 'mystorageaccount'
$StorageAccountKey = "storageaccountkey"
$StorageContext = New-AzureStorageContext $StorageAccountName -StorageAccountKey $StorageAccountKey
$FileName = 'filename'
$ContainerName = 'mycontainer'
#Get attachment from blob storage
$a = Get-AzureStorageBlobContent -Container $ContainerName -Blob $FileName -Context $StorageContext
$attachment = $a.Name
$MyCredential = "SendEMail"
$EmailBody = "Test"
$Body = $EmailBody.replace("|","`n`r")
$subject = "Tets"
$userid= "Test#test.com"
$emailTo = "emailid#emaildomain.com"
#Get the PowerShell credential
$Cred = Get-AutomationPSCredential -Name $MyCredential
Send-MailMessage `
-To $emailTo `
-Subject $subject `
-Body $Body `
-UseSsl `
-Port 587 `
-SmtpServer 'smtp.sendgrid.net' `
-Attachments $attachment `
-From $userid `
-Credential $Cred `

Related

Convert type string to Secure String

I have prepared the PowerShell script for sending emails using SendGrid. But while converting plain text password of SendGrid account into secure string, then I am getting the following error:
“unable to convert type string to secure string”
Sample Script:
$SecurePassword = ConvertTo-SecureString "Demo123" -AsPlainText -Force
So, can anyone suggest me how to resolve this issue.
$Username ="Name#azure.com"
$Password = ConvertTo-SecureString "Demo123" -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential $Username, $Password
$SMTPServer = "smtp.sendgrid.net"
$EmailFrom = "from#mail.com"
$EmailTo = "to#mail.com"
$Subject = "SendGrid test"
$Body = "SendGrid testing successful"
Send-MailMessage -smtpServer $SMTPServer -Credential $credential -Usessl -Port 587 -from $EmailFrom -to $EmailTo -subject $Subject -Body $Body
I am able to run same command in Powershell:
My Powershell Version is 5.7.0.18831.

Powershell Script to send email after validation

I have a Powershell script that logs the result to a text file (this is working fine), now I need to update it to send email instead of a Log file (see actual script below). I'm kind of a new to powershell, hopefully you can help me out.
# details of the script
# if a file "FILE.400" is found and check the modified date, it will send a log file (txt file)
# need to update the script, to send email instead of a log file
$svr=$env:ComputerName
$date=[datetime]::Today.ToString('MM-dd-yyyy')
$filename = "FILE.400"
$DestLogs1 = "E:\sample\pfupdatedfin-$date.txt"
$DestLogs2 = "E:\sample\pfoutdatedfin-$date.txt"
$SrcPath = "E:\sample\$filename"
If ((Get-ChildItem $SrcPath).LastWriteTime -gt $date)
{
$date | Out-File $DestLogs1
Write-Output "Found latest FILE.400 file" | Out-File $DestLogs1 -Append
(Get-ChildItem -Recurse -Path $SrcPath).LastWriteTime | Out-File $DestLogs1 -Append
}
Else
{
Write-Output "FILE.400 - is not updated, please verify " | Out-File $DestLogs2
(Get-ChildItem -Recurse -Path $SrcPath).LastWriteTime | Out-File $DestLogs2 -Append
}
Send-MailMessageis pretty easy to use. The online documentation for cmdlets is very easy to find. Just enter the name of the cmdlet in your favorite search engine. Or use the Get-Help cmdlet. Here is an example how to use it just fille the Variables reasonably :
Send-MailMessage -From $From -To $To -Subject $Subject -Body $Body -SmtpServer $SMTPServer -Port $SMTPPort -Credential $Credential # -UseSsl:$UseSsl
-useSsl is a switch so it is not necessary unless it's $true. If you want to provide a variable to a switch parameter, don't use a whitespace but a : in between.
Credentials in Powershell are stored in credential objects. You can't just use a plain text password. However don't think they are stored extremly save since the password can be easly extracted if you know how. Here is how you create the necessary credential object:
$SecPw = ConvertTo-SecureString -AsPlainText $Password -Force
$Credential = New-Object System.Management.Automation.PSCredential -ArgumentList $UserName,$SecPw
the script is working as expected, in my Home network
$svr=$env:ComputerName
$date=[datetime]::Today.ToString('MM-dd-yyyy')
$filename = "FILE.400"
$DestLogs1 = "E:\sample\pfupdatedfin-$date.txt"
$DestLogs2 = "E:\sample\pfoutdatedfin-$date.txt"
$SrcPath = "E:\sample\$filename"
# email settings
$MyEmail = "myemail#gmail.com"
$SMTP = "smtp.gmail.com"
$To = "samplereceiver#gmail.com"
$Subject1 = "JDA-Alert || Found FILE.400 file - Successful"
$Body1 = "JDA-Alert || Found FILE.400 file - Successful"
$Subject2 = "JDA-Alert || FILE.400 file - Outdated File"
$Body2 = "JDA-Alert || FILE.400 file - Outdated File"
$Creds = (Get-Credential -Credential "$MyEmail")
If ((Get-ChildItem $SrcPath).LastWriteTime -gt $date)
{
Start-Sleep 2
Send-MailMessage -To $To -From $MyEmail -Subject $Subject1 -Body $Body1 -SmtpServer $SMTP -Credential $Creds -UseSsl -Port 587 -DeliveryNotificationOption Never
}
Else
{
Start-Sleep 2
Send-MailMessage -To $To -From $MyEmail -Subject $Subject2 -Body $Body2 -SmtpServer $SMTP -Credential $Creds -UseSsl -Port 587 -DeliveryNotificationOption Never
}

Send-Mailmessage timing out

I am looking to improve an old batch script and upgrade it to powershell, this is a robocopy batch script and i would like it to send a mail with the logfile attatched when it is finished. i managed to get the drive mappings and robocopy part sorted but im having some issues getting the send-mailmessage part to work
`$SourceFolder = "V:\"
$DestinationFolder = "Y:\"
$Dateandtime = Get-Date -format filedate
$password = XXXXXXXXX
$Subject = "Robocopy Results: Backup USA - NL"
$SMTPServer = "mailserver.domain.com"
$Sender = "backupusr#domain.com"
$Username = "backupusr"
$Recipients = "administrator#domain.com"
$Admin = "administrator#domain.com"
$SendEmail = $True
$IncludeAdmin = $True
$AsAttachment = $False
$Cred = new-object Management.Automation.PSCredential $Username, ($password
| ConvertTo-SecureString -AsPlainText -Force)`
This is the line that causes the script to timeout
Send-MailMessage -SmtpServer $SMTPServer -From $Sender -To $Recipients -Subject $Subject -Body "Robocopy results are attached." -DeliveryNotificationOption onFailure -UseSsl -Credential $Cred
this is the error i recieve
Send-MailMessage : The operation has timed out.
At C:\Scripts\bpcti-robocopy.ps1:113 char:1
+ Send-MailMessage -SmtpServer $SMTPServer -From $Sender -To $Recipient ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.Mail.SmtpClient:SmtpClient) [Send-MailMessage], SmtpException
+ FullyQualifiedErrorId : SmtpException,Microsoft.PowerShell.Commands.SendMailMessage
Any help would be greatly appreciated.
The -Credential parameter takes a PSCredential object. You can use Get-Credential to interactively create one using a username and password combination. More detail here.
Alternatively, as your password is already in plaintext in your script, you can use the process as described here and construct a new PSCredential.
# Convert the plaintext password into a secure string.
$SecurePassword = ConvertTo-SecureString "XXXXXXXXX" -AsPlainText -Force
# Create a new PSCredential using the username and secure string password.
$Cred = New-Object System.Management.Automation.PSCredential ("backupusr#domain.com", $SecurePassword)
Send-MailMessage -SmtpServer mailserver.domain.com -From backupusr#domain.com -To administrator#domain.com -Subject testing -Body "Robocopy results are attached." -DeliveryNotificationOption onFailure -Credential $Cred
Beware that the username should include the #domain.com.

Powershell to send mail

Error
New-Object : Cannot find an overload for "PSCredential" and the
argument count: "2". At D:\Scripts\gsend.ps1:12 char:15
Code
#Create Password File (Only need once)
#$Credential = Get-Credential
#$Credential.Password | ConvertFrom-SecureString | Set-Content "D:\scripts\gsendcred.txt"
#Send Email
$EncryptedCredential = "D:\scripts\gsendcred.txt"
$EmailUsername = "me#gmail.com"
$EncryptedPW = Get-Content "D:\scripts\gsendcred.txt"
$EncryptedCredential = ConvertTo-SecureString -String $EncryptedCredential -
AsPlainText -Force
$Credential = New-Object Management.Automation.PSCredential ($EmailUsername,
$EncryptedPW)
$EmailFrom = "me#gmail.com"
$EmailTo = "me#gmail.com"
$EmailSubject = "GSEND Test Subject"
$EmailBody = "Test Body"
$SMTPServer = "smtp.gmail.com"
$SMTPPort = 587
$SMTPSsl = $true
I believe your issue is handling credentials. Here is how I handle the smtp credentials:
$smtpPwd = "password"
$smtpCredentialsUsername = "jdonnelly#xxxxx.com"
$smtpCredentialsPassword = ConvertTo-SecureString -String $smtpPwd -AsPlainText -Force
$Credentials = New-Object –TypeName System.Management.Automation.PSCredential
–ArgumentList $smtpCredentialsUsername, $smtpCredentialsPassword
Then:
$smtp.Credentials = $Credentials
Or if you are using Send-MailMessage store your email credentials locally by running this short script by itself beforehand:
Get-Credential | Export-Clixml C:\fso\myemailcreds.xml
It will prompt you to enter your credentials and then store them locally in (in this case) a folder called fso. Then in any Send-MailMessage cmdlet use the locally stored credentials as follows:
Send-MailMessage -To 'Recipient <recipient#yahoo.com>' -from 'John Donnelly <jdonnelly#xxx.com>'
-cc 'whoever <whoever#xxx.com>' -Subject $subject -Body $body
-BodyAsHtml -smtpserver "smtp.office365.com" -usessl
-Credential (Import-Clixml C:\fso\myemailcreds.xml) -Port 587
You Can use below Powershell script for send mail
Send-MailMessage -To "abc#abc.com" -From "def#abc.com" -Cc "gef#abc.com","hij#abc.com" -Subject Test Mail -BodyAsHtml $htmlbody -SmtpServer "mailhost.abc.com"
where $htmlbody is string variable that contain html.

Sending a email with powershell

I want to send a email with powershell. The script works fine if I type my credential in manualy. But I want to give the credential parameters within the script. My script looks like this:
$From = "test#yahoo.de"
$To = "test2#yahoo.de"
$Cc = "test#yahoo.de"
$Attachment = "C:\Users\test\test\test.ini"
$Subject = "Email Subject"
$Body = "Insert body text here"
$SMTPServer = "smtp.mail.yahoo.com"
$SMTPPort = "587"
Send-MailMessage -From $From -to $To -Cc $Cc -Subject $Subject `
-Body $Body -SmtpServer $SMTPServer -port $SMTPPort -UseSsl `
-Credential (
$MyClearTextUsername=’test#yahoo.de’
$MyClearTextPassword=’test123’
$SecurePassword=Convertto-SecureString –String $MyClearTextPassword –AsPlainText –force
$MyCredentials=New-object System.Management.Automation.PSCredential $MyClearTextPassword,$SecurePassword) -Attachments $Attachment
Here's how you can create a credentials object:
$cred = ([pscredential]::new('test#yahoo.de',(ConvertTo-SecureString -String 'test123' -AsPlainText -Force)))
so in your case use:
Send-MailMessage -From $From -to $To -Cc $Cc -Subject $Subject `
-Body $Body -SmtpServer $SMTPServer -port $SMTPPort -UseSsl `
-Credential $cred -Attachments $Attachment
I see no point in trying to fit that into the Send-MailMessage, just create it before and reference it. easier to read.
If you're using Office365 to send email, you might want to try this:
# Sending an email from PowerShell 5.1 script through outlook.office365.com
#
# 1. Create an encrypted password file
# PS > Read-Host -AsSecureString | ConvertFrom-SecureString | Out-File -FilePath <passwordfile>
# This will prompt you for a password, encrypt and save in <passwordfile>
# 2. Obtain Outlook Office365 SMTP server name.
# Go to your ISP and find the value of the MX record. For example <yourdomain>.mail.protection.outlook.com
# 3. If after running the script you get this error:
# Send-MailMessage : Mailbox unavailable. The server response was: 5.7.606 Access denied, banned sending IP [X.X.X.X].
# You will need to delist your IP by going here: https://sender.office.com/
# Note: Removing you IP from the block list could take up to 30 minutes.
#
$User = "<SMPT loging username>"
$PasswordFile = "<passwordfile>"
$SMTPCredentials=New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, (Get-Content $PasswordFile | ConvertTo-SecureString)
$EmailTo = "<to email address>"
$EmailFrom = "<from email address>"
$Subject = "<email subject>"
$Body = "<email body>"
$SMTPServer = "<Outlook STMP Server from MX record>"
Send-MailMessage -From $EmailFrom -To $EmailTo -Subject $Subject -Body $Body -SmtpServer $SMTPServer -Port 25 -Credential $SMTPCredentials -UseSsl