Can't use send-mailmessage when using PSFTP Module - email

I've made a Powershell script which uploads data to a NAS.
After the Upload is completed the script should send an Email message.
When the script tries to send a mailmessage I get an error saying I used an incorrect security certificate.
This error only shows up when I use the PSFTP module. When i run the sendmail code on its own it works just fine.
The FTP session itself isn't alive anymore so this shouldn't be a problem.
Can someone point me in the right direction to sort this problem out?I've made a Powershell script which uploads data to a NAS.
After the Upload is completed the script should send an Email message.
When the script tries to send a mailmessage I get an error saying I used an incorrect security certificate.
This error only shows up when I use the PSFTP module. When i run the sendmail code on its own it works just fine.
The FTP session itself isn't alive anymore so this shouldn't be a problem.
Can someone point me in the right direction to sort this problem out?
$Execution = Get-ExecutionPolicy
If($Execution -eq "RemoteSigned")
{
Write-Host "HOI" -BackgroundColor Black -ForegroundColor Green
}
Else
{
Set-ExecutionPolicy Remotesigned
}
1.Module PSFTP importing
Import-Module PSFTP
$secpasswd = ConvertTo-SecureString “Wachtwoord” -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential (“Admin”, $secpasswd)
Variables
$Session = "Alive"
$ftp = "IP"
$Credentials = "Admin"
$FtpFile = "C:\Test\Back-up.ps1"
$ftpDestination = "FTPLOCATIE"
2.Connect to FTP with module PSFTP
Set-FTPConnection -Server $ftp -Credentials $mycreds -Session $Session
( Connect to ftp)
3.TPItem for uploading to NAS
Get-ChildItem $FtpFile | Add-FTPItem -Session $Session -Path $ftpDestination -Overwrite
4.Section for mailing,variables
$secpasswd = ConvertTo-SecureString “Wachtwoord” -AsPlainText -Force
$mycredsMail = New-Object System.Management.Automation.PSCredential (“Email-address”, $secpasswd)
5. Section for mailing
$Smtp = "smtp.office365.com"
$Port = "587"
$To = "Email"
$Subject = "Back-up"
$From = "Email
6. this is where i want send the mail i use ssl
Send-MailMessage -to $To -from $From -Subject $Subject -SmtpServer $Smtp -Credential $mycredsMail -Port $Port -UseSsl

Related

How to use different owner in new-pnpsite command in powershell

I use New-PNPSite from PNP Module to create a new SharePoint communication site like this
$username = "admin#gmail.com"
$secpasswd = ConvertTo-SecureString -String "password" -AsPlainText -Force
$UserCredential = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList $username, $secpasswd
$Url = 'https://companyAdmin.sharepoint.com/'
Connect-PnPOnline -url $Url -Credentials $UserCredential
New-PNPSite -Type CommunicationSite -Title "Testing 2" -Owner "differentuser#gmail.com" -url "https://company.sharepoint.com/sites/jontesting2" -Lcid 1033
but I'm getting this error for some reason
New-PNPSite : {"SiteId":"","SiteStatus":3,"SiteUrl":""}
if I use the admin address admin#gmail.com in the owner parameter then I don't get the error and I'm able to create a new site. Any idea why it might be?
I wanted to use the admin account to create a new site for different owners that's why.

Powershell: Move email to a different folder in Gmail

I need to use Powershell and move an email in my GMAIL INBOX to a different folder.
I am using the Powershell module Mailozaurr to connect to Gmail via IMAP (https://evotec.xyz/mailozaurr-new-mail-toolkit-smtp-imap-pop3-with-support-for-oauth-2-0-and-graphapi-for-powershell/). I am able to correctly login and read emails in my Inbox.
Here is my code:
$FromAddress = "A12345#gmail.com"
$Password = "MY_password"
$Client = Connect-IMAP -Server 'imap.gmail.com' -Password $Password -UserName $FromAddress -Port 993 -Options Auto
Get-IMAPFolder -Client $Client -Verbose
foreach ($Email in $client.Data.Inbox)
{
if ($Email.from -notlike "test") {continue}
$Email
Break
}
At this stage I want to move $email to a new folder named "NewFolder". How do i achieve this?
I finally figured out why it was not working. Looking at the backend code for the module (https://www.powershellgallery.com/packages/Mailozaurr/0.0.16/Content/Mailozaurr.psm1), the Inbox is open in ReadOnly mode. Hence the solution is closing the inbox and opening it in readwrite mode or Set the FolderAccess on the Get-ImapFolder command. Hence
$FromAddress = "A12345#gmail.com"
$Password = "MY_password"
$Client = Connect-IMAP -Server 'imap.gmail.com' -Password $Password -UserName $FromAddress -Port 993 -Options Auto
Get-IMAPFolder -Client $Client -FolderAccess ReadWrite -Verbose
foreach ($Email in $client.Data.Inbox)
{
$Email
$TestFolder = $Client.data.GetFolder("Test")
$client.Data.Inbox.MoveTo(0, $TestFolder)
Break
}
The ZERO in the Moveto Command represents the 1st email to be moved. Thanks to #PrzemyslawKlys for assistance at https://github.com/EvotecIT/Mailozaurr/issues/22

Using encrypted password to send mail is failing

I'm trying to use a stored encrypted password in a script that sends an email but I keed getting the error:
send-mailmessage : The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.57 SMTP; Client was not authenticated to send anonymous mail during MAIL FROM
[DM6PR66666019.namprd456.prod.outlook.com]
I used the following code to create the text file:
$passwordtostore = 'NotTheRealPassword$9gv8z6VHnPfDd8zc'
$secureStringPWD = $passwordtostore | ConvertTo-SecureString -AsPlainText -Force
$secureStringText = $secureStringPWD | ConvertFrom-SecureString
Set-Content "c:\temp\scriptsencrypted_password1.txt" $secureStringText
I use the following to import the password:
$passwordFile = "c:\temp\scriptsencrypted_password1.txt"
$password = Get-Content $passwordFile | ConvertTo-SecureString
Here's the sendmail function I am using:
function SendMail($ToEmails,$FromEmail,$Subj,$Body,$UserName,$Password){
$cred = New-Object System.Management.Automation.PSCredential $UserName,$Password
$MailParams=#{"from"=$FromEmail; "to"=$ToEmails;"body"=$Body;"subject"=$Subj;"smtpserver"="smtp.office365.com"}
send-mailmessage #MailParams -Credential $cred -UseSsl $true -port 587
}
Here's the code which calls the function:
$alertEmail = "me.stillme#mydomain.com"
$username="psemail#mydomain.com"
$passwordFile = "c:\temp\scriptsencrypted_password1.txt"
$password = Get-Content $passwordFile | ConvertTo-SecureString
$credential = New-Object System.Management.Automation.PsCredential($username, $password)
Import-Module -Name "..\SendMail.psm1"
... Doing some stuff
SendMail $alertEmail $username "This is the subject" "this is the body" $credential.UserName $credential.Password
Personally, I fail to see why you would make a function in a module you need to import for the Send-MailMessage cmdlet..
This makes things a lot harder to use.
Also, it kind of looks like you are switching the emailaddresses To and From inside the function.
Anyway, things go wrong when you are creating the credentials, split it into username and (secure) password to send as parameters to the function and recombine them into a credentials object in there.
Why not skip that module function and simply do:
$password = Get-Content 'c:\temp\scriptsencrypted_password1.txt' -Raw | ConvertTo-SecureString -AsPlainText -Force
$credential = New-Object System.Management.Automation.PsCredential('YourLoginName', $password)
$MailParams=#{
From = 'me.stillme#mydomain.com'
To = 'psemail#mydomain.com'
Body = "this is the body"
Subject = "This is the subject"
SmtpServer = 'smtp.office365.com'
Port = 587
UseSsl = $true
Credential = $credential
}
Send-MailMessage #MailParams
This will make your script far more readable/maintainable
I found two issues with my code above:
An unescaped $ in the password.
Once I added " -NoNewline" to the set-content, it began to work.
So, to create the encrypted file:
$passwordtostore = "7K9CBgvc4rttvfctrsef6PVHqnP6fDdwhatevervtfdscttzSc"
$secureStringPWD = $passwordtostore | ConvertTo-SecureString -AsPlainText -Force
$secureStringText = $secureStringPWD | ConvertFrom-SecureString
Set-Content "D:\Powershell Scripts\encrypted.hash" $secureStringText -NoNewline
Then to retrieve the password and use it in a credential:
$password = Get-Content $passwordFile -Raw | ConvertTo-SecureString
$credential = New-Object System.Management.Automation.PsCredential($username, $password)
It wasn't the source of the issue, but I did implement #Theo's suggestion re: using send-mailmessage.

Send-MailMessage Argument Null or empty

Can someone please help me figure this part out.
#Mail Configuration
$smtpUser = "email#domain.com"
$smtppass = ConvertTo-SecureString "PasswordAsPlainText" -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential -ArgumentList ($smtpuser, $smtppass)
$ToAddress = "toaddress#domain.com"
$FromAddress = "send#domain.com"
$SMTPSERVER = "smtp.office365.com"
$SMTPPORT = "587"
$MailParam = #{
To = $ToAddress
From = $FromAddress
Subject = $subject
Body = $Mail
SMTPServer = $SMTPServer
Port = $SMTPPORT
Credential = $pscred
}
#Send Email
$GetChildItem = Get-ChildItem -Path C:\Temp
if ($GetChildItem -ne $Null)
{
Write-Host "Backup Success"
$subject = "$env:COMPUTERNAME SQL Backup Success"
$Mail = "SQL Backup Succeded on the server, please see the attached report for more details"
$attachment = $reportfile
Send-MailMessage #MailParam -BodyAsHtml -usessl
#Exit
}
if ($GetChildItem -eq $Null)
{
Write-Host "Backup Failed"
$subject = "$env:COMPUTERNAME SQL Backup Failed"
$Mail = "SQL Backup Failed on the server, please see the attached report for more details"
$attachment = $reportfile, $debuglog
Send-MailMessage #MailParam -usessl -BodyAsHtml
#Exit
}
Now I don't think anything is wrong with the code above, I am no expert coder but I can pretty much copy and paste :) and take stuff from there to get it working for me.
The issue with the above code is that when run it, it doesn't work for the 1st time but when you run it again it works fine. The error you get the first time is
Send-MailMessage : Cannot validate argument on parameter 'Body'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At C:\Users\Aasim\Desktop\Untitled1.ps1:29 char:26
+ Send-MailMessage #MailParam -BodyAsHtml -usessl
+ ~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Send-MailMessage], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.SendMailMessage
I am not sure what the issue is and why it doesn't work only the first time but works every other subsequent time until you close and reopen the script.
Basically I am creating a SQL backup script that backs up databases to our Network Share and then emails me whether it was successful or not. so far the rest of the script works just fine.
In your If and Else blocks, instead of creating a variable $subject, or $Mail, update the hashtable, $MailParam. Also, you seem to be missing the Attachment variable in your Send-MailMessage
if ($GetChildItem -eq $Null)
{
Write-Host "Backup Failed"
$MailParam.Subject = "$env:COMPUTERNAME SQL Backup Failed"
$MailParam.Body = "SQL Backup Failed on the server, please see the attached report for more details"
$attachment = $reportfile, $debuglog
Send-MailMessage #MailParam -usessl -BodyAsHtml -Attachments $attachment
#Exit
}

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/