Release Artifacts delivered to user group as an attachment in email - azure-devops

I work with build and release in VSTS. I use Copy Files option in my Build definition and copy the Artifacts in a folder. I want that the Artifacts ( .exe, .dll, .zip etc)created at the end of the release must be attached in an email and must be delivered to a list of email addresses.
How this can be achieved.

Use archive task to zip the files and use powershell script given below to send an email with attachment.
Now use Powershell task and paste following script. Please edit SMTP and email settings.
$SMTPServer = "smtp.gmail.com"
$SMTPPort = "587"
$Username = "Youremail#gmail.com"
$Password = "Pass#1"
$to = "senderemail#gmail.com"
#$cc = "ccemail#gmail.com"
# Below subject line will have todays date and Build status as Succeed or Failed
$subject = "$(get-date -format dd-mm-yy) Automation Test report $(Agent.JobStatus)"
$body = "Your email body text"
# Enter the path of existing Archieve output folder
$attachment = "$(Build.ArtifactStagingDirectory)/YourZipFolderName.zip"
$message = New-Object System.Net.Mail.MailMessage
$message.subject = $subject
$message.IsBodyHTML = $true
$message.body = $body
$message.to.add($to)
#$message.cc.add($cc)
$message.from = $username
$message.attachments.add($attachment)
$smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort);
$smtp.EnableSSL = $true
$smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
$smtp.send($message)
write-host "Mail Sent successfully using GMAIL"
Please make sure to Use run option as "Even if a previous task has failed, unless the build was canceled" as shown below.

You can use Send Email task to achieve it. Details as below:
In the end of your release environment -> Add a Send Email task -> configure required options.
To delivery the artifact files by the Send Email task, you can select the Add Attachment option and specify absolute path for the attachment:

Related

Send email with Outlook application with cutomized permissions (Using PowerShell)

I'm trying to create and send emails using the Outlook application with PowerShell applying Permissions for the email (Example: Encrypt-Only, Do Not Forward, etc.), is currently working on the outlook application (when creating the email manually), however, couldn't find a way to send emails using PowerShell applying this setting:
Permission templates in Outlook
I'm currently using the following code to create and send the emails (Working):
$Outlook = New-Object -ComObject Outlook.Application
$Mail = $Outlook.CreateItem("olMailItem")
$Mail.To = "test#test.com"
$Mail.Subject = "Test Email"
$Mail.Body = "Email sent using PowerShell"
$file = "C:\ExampleFolder\test.txt"
$Mail.Attachments.Add($file)
$Mail.Send()
Is there a way to apply this setting using PowerShell?
I founded the solution for this, this solution involve two properties: "$Outlook.CreateItem("olMailItem").Permission" and "$Outlook.CreateItem("olMailItem").PermissionTemplateGuid", and work as follow:
If $Outlook.CreateItem("olMailItem").Permission is set to "0": The email is sent as unrestricted message, no PermissionTemplateGuid is needed for this value.
If $Outlook.CreateItem("olMailItem").Permission is set to "1": The email is sent as olDoNotForward automatically, no PermissionTemplateGuid is needed for this value.
If $Outlook.CreateItem("olMailItem").Permission is set to "2": The email require a PermissionTemplateGuid, therefore, it's required to get the GUID of the template, since each organization have a different template according with the configuration, send an email with the encryption template to your inbox and read it using the following code:
$olFolderInbox = 6
$outlook = new-object -com outlook.application
$mapi = $outlook.GetNameSpace("MAPI")
$inbox = $mapi.GetDefaultFolder($olFolderInbox)
$items = $inbox.items
$items[1].PermissionTemplateGuid
This is going to provide the correct permissionTemplateGuid with the desired encryption.
Therefore, to send the email the following formula works:
$Outlook = New-Object -ComObject Outlook.Application
$Mail = $Outlook.CreateItem("olMailItem")
$Mail.To = "test#test.com"
$Mail.Subject = "Test Email"
$Mail.Body = "Email sent using PowerShell"
$file = "C:\ExampleFolder\test.txt"
$Mail.Attachments.Add($file)
$Mail.PermissionTemplateGuid = XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
$Mail.Permission = "2"
$Mail.Send()
For more information visit this website: http://jon.glass/blog/reads-e-mail-with-powershell/

Emails not sending when calling multiple scripts

Good afternoon -
I have a "trigger file" that calls several scripts to run some morning reports. Each called script contains code that attaches a file to an email and sends (via ComObject). If I run each script individually then there all emails send correctly. However, when i run the "trigger file", only a couple of the emails send and I am not receiving any error messages. Any ideas what is happening? I purposely made the trigger file run the scripts concurrently to save time. But is that overloading Outlook?
EDIT: Updated code to include Try/Catch block. There are 8 scripts that run using this template. All 8 successfully complete the excel open/run/save. However, only some of the emails send. And even with this Try/Catch block, no error message is being sent.
#Establish script file locale
$FullPath = “//fullpath/”
$SavePath = “//savepath/”
#Open Excel file
& {
$Excel = New-Object -ComObject excel.application
$Excel.Visible=$False
$Workbook = $Excel.Workbooks.Open($FullPath)
#Run Macro
$app=$Excel.Application
$app.Run("Macro1")
#Save and close Excel
$Excel.Application.DisplayAlerts=$False
$Workbook.SaveAs($SavePath,51)
$Workbook.Close()
$Excel.Quit()
}
#Send email with attachment
Try
{
$EmailSettings=#{
SMTPServer = "smtp"
From = "me#email.com"
To =
#(
"you#email.com"
)
Subject = "Subject"
Attachments = $SavePath
BodyAsHtml = $true
Body =
"<body><p>
Attached is the thing.
</b></p></body>"
}
Send-MailMessage #EmailSettings
}
Catch
{
$Subject = 'ERROR: '+$EmailSettings.Subject
$ErrorMessage = $_.Exception.Message+' '+$_.Exception.ItemName
Send-MailMessage -From me#email.com -To me#email.com -Subject $Subject -SmtpServer smtp -Body $ErrorMessage
}

Adding attachments to an email generated in powershell

I'm attempting to create a PS script that does the following:
Run 2 programs located on the server
Check for error files
Attach the error files to the email
Wait for 5 minutes, rinse and repeat
I've got the below so far, I can get it working without the attachments, it just sends a link in the email. However I'd rather they be attachments.
Currently the error I'm getting is "Powershell.exe : A positional parameter cannot be found that accepts argument '$null'.".
But I've no idea why this is being generated?
Any advice would be appreciated.
#Hide powershell
Powershell.exe -windowstyle hidden {
#Make sure the program isn't running before starting the script
stop-process -Name WorksOrderCompletionImport
stop-process -Name WorksOrderIssuesImport
#Loop condition
While ($true)
{
$i++
#Bind location to string
$files=Get-ChildItem "E:\Production Siemens Interface Files\error"
#Binding the path to the string
$filechecker = 'E:\Production Siemens Interface Files\error\*.csv'
# Sender and Recipient Info for email
$MailFrom = "myemail#domain.com"
$MailTo = "myemail#domain.com"
# Sender Credentials
$Username = "myemail#domain.com"
$Password = "BadBoiPassword"
# Server Info
$SmtpServer = "smtp.office365.com"
$SmtpPort = "587"
# Message content
$Link = "\\SERVER1\E Drive\Production Siemens Interface Files\error"
$MessageSubject = "Errors have been generated in the Production Siemens Interface Files Folder"
$Message = New-Object System.Net.Mail.MailMessage $MailFrom,$MailTo
$Message.IsBodyHTML = $true
$Message.Subject = $MessageSubject
$Message.Body = #'
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<p>Hello,</p>
<p>Please be advised that errors have been generated in the Siemens Integration Production Folder.</p>
<p>Please follow this link to check : Link to error files</p>
</body>
</html>
'#
#Start the programs
start-process -filepath "C:\Program Files\Datel Computing\Siemens Integration PRODUCTION\WorksOrderIssuesImport.exe"
start-process -filepath "C:\Program Files\Datel Computing\Siemens Integration PRODUCTION\WorksOrderCompletionImport.exe"
Start-Sleep -s 10
#If statement to control email
if (Test-Path $filechecker)
# Construct the SMTP client object, credentials, and send
{$Smtp = New-Object Net.Mail.SmtpClient($SmtpServer,$SmtpPort)
$Smtp.EnableSsl = $true
$Smtp.Credentials = New-Object System.Net.NetworkCredential($Username,$Password)
$attachment = New-Object System.Net.Mail.Attachment –ArgumentList 'E:\Production Siemens Interface Files\error\'$file
$smtp.Attachments.Add($attachment)
$Smtp.Send($Message)}
else { Start-Sleep -s 10
}
#Stop the program
stop-process -Name WorksOrderCompletionImport
stop-process -Name WorksOrderIssuesImport
# Sleep for 300 seconds then loop back
Start-Sleep -s 300
}
}
You're using a lot .net references. I think you can simplify this by using the existing cmdlet Send-MailMessage. For example:
$PSEmailServer = "smtp.office365.com"
$smtpPort = "587"
$mailFrom = "myemail#domain.com"
$mailTo = "myemail#domain.com"
$messageSubject = "Errors have been generated in the Production Siemens Interface Files Folder"
$attachment = "E:\Production Siemens Interface Files\error\$file"
$body = #'
<p>Hello,</p>
<p>Please be advised that errors have been generated in the Siemens Integration Production Folder.</p>
<p>Please follow this link to check : Link to error files</p>
'#
Send-MailMessage -From $mailFrom -To $mailTo -Subject $messageSubject -Body $body -BodyAsHtml -Attachments $attachment -Port $smtpPort -UseSsl
See also: MS Reference Send-MailMessage
Ofcourse you need to supply your credentials for authentication. If you look at the documentation you'll see -Credential is one of the parameters. What you can do is:
# Define your Credentials
$username = 'your username'
$password= 'your password'
# Crete a credential Object
[SecureString]$secureString = $password | ConvertTo-SecureString -AsPlainText -Force
[PSCredential]$credentialObject = New-Object System.Management.Automation.PSCredential -ArgumentList $username, $password
Add the -Credential parameter to the Send-Mailmessage command like -Credential $credentialObject
This is just to show you a way to accomplish what you want, but be careful with this method, because this way you store your password directly in the Script. There are solutions to encrypt your password in external files. You can find a good explanation on: https://pscustomobject.github.io/powershell/howto/Store-Credentials-in-PowerShell-Script/

Send mail via powershell without authentication

I was using nant to send mail and it is working fine - something like
<mail
from="Test#b.c"
tolist="A#b.c"
subject="Test"
mailhost="myhost.mydomain.com"
isbodyhtml="true"
message= "${Test}">
</mail>
I didn't have to use any kind of authentication.
Now when using powershell it seems I am forced to use authentication - something like this would fail:
Send-MailMessage -To $to -From $from -Subject "Test" –Body “Test (body) -SmtpServer "myhost.mydomain.com"
I would get the following message:
Send-MailMessage : No credentials are available in the security package
Am I missing some way to send mails without specifying credentials if the server supports that?
Edit:
I've also tried the answer here to send anonymous mails but it just times out:
send anonymous mails using powershell
Sending mails using Powershell v1 method works fine without authentication as shown here
My Powershell version is 5 yet this is apparently the way to go, unless someone has another idea.
$smtpServer = "ho-ex2010-caht1.exchangeserverpro.net"
$smtpFrom = "reports#exchangeserverpro.net"
$smtpTo = $to
$messageSubject = $subject
$messageBody = $body
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($smtpFrom,$smtpTo,$messagesubject,$messagebody)
I was looking for another issue and found this question here...
As #AngelicCore already explained one approach,
Here is another one if someone using Outlook dektop app...
The mail sent will appear in your outbox.
using outlook object
Try
{
#Email structure
$Outlook = New-Object -ComObject Outlook.Application
$Mail = $Outlook.CreateItem(0)
#Email Recipients
$Mail.To = "abc#domain.com;xyz#domain.com"
$Mail.Cc = "tuv#domain.com; pqr#domain.com"
#Email Subject
$date = Get-Date -Format g
$Mail.Subject = "Subject here $date"
#Email Body
$Mail.Body = "Body Here"
#Html Body
$Mail.HTMLBody == "<html> HTML Body Here </html>"
#Email Attachment
$file = "C:\path\xyz.txt"
$Mail.Attachments.Add($file)
$Mail.Send()
Write-Host -foreground green "Mail Sent Successfully"
}
Catch
{
write-host -foreground red $error[0].Exception.Message
}
pause
exit

Powershell Grab 2 files and email them to a group of people

I am trying to figure out how I can schedule a task to run once a week with task scheduler to copy two files and attach them to an email and email them to a group of people. Is this possible to do? To have a script that will run using power shell grab two files from certain locations and then email them? Would it be similar to what I have below or am I going in the wrong direction?
$ol = New-Object -comObject Outlook.Application
$message = $ol.CreateItem(0)
$message.Recipients.Add("Deployment")
$message.Subject = "Website deployment"
$message.Body = "See attached file"
$file = "K:\Deploy-log.csv, K:\Deploy-log2.csv"
$message.Attachments.Add($file)
Error
Exception calling "Add" with "1" argument(s): "File name or directory
name is not valid." At C:\Users\davidb\Desktop\email.ps1:8 char:1
+ $message.Attachments.Add($file)
FullyQualifiedErrorId : ComMethodTargetInvocation
If I take , K:\Deploy-log2.csv off it will not error but I still do not receive the email either
In your code, $file is one string which when interpreted as just one path isn't valid. What you are intending is an array of strings, each element of the array is a string with one path. You could loop over the array with either a foreach or a ForEach-Object loop, using the Add() once on each separate path. Would look like this:
$ol = New-Object -comObject Outlook.Application
$message = $ol.CreateItem(0)
$message.Recipients.Add("Deployment")
$message.Subject = "Website deployment"
$message.Body = "See attached file"
$files = "K:\Deploy-log.csv","K:\Deploy-log2.csv"
foreach ($file in $files) {
$message.Attachments.Add($file)
}
$message.Send()
Alternatively, you could use the Send-MailMessage cmdlet
Send-MailMessage -From 'Sender <Sender#example.com>' -To "Recipient <Recipient#example.com>" -Subject "Website deployment" -Body "See attached file" -Attachments #("K:\Deploy-log.csv", "K:\Deploy-log2.csv") -SmtpServer smtp.example.com