locked
Powershell Email Authentication & Not RRS feed

  • Question

  • Hi Folks -

    JRV has been very nice in helping with an email script I wanted to make. It's working 100% now. However, I have some clients (i.e. on 0365) that require authentication (username & password) while other clients don't require it but I'm trying ot use the same script. I came up with a solution to use (2) mailparams portions based on what's passed from the Parent script.  If a port is being passed (pr password) I execute one section and if not, I execute the other.  Is there a cleaner way of doing this? I tried to do an if statement within the mailparams block but i didn't work.

    Here is my code, thanks!

    Param(
    	#::-- Required & cannot be Null --::#
    	[Parameter(Mandatory=$True)]
    	[ValidateNotNull()]
    		[string]$EmailSMTPServer,
    	[Parameter(Mandatory=$True)]
    	[ValidateNotNull()]
    		[string]$EmailFrom,
    	[Parameter(Mandatory=$True)]
    	[ValidateNotNull()]
    		[string]$EmailTo,
    	#::-- Optional & can be Null --::#
    	[int]$EmailPort,
        [string]$EmailPassword
    )
    
    #::-- Execute Password Protocol --::# 
    If($EmailPort -ne "0") {
    	$EmailSecurePassword = ConvertTo-SecureString $EmailPassword -AsPlainText -Force
    	$EmailSecureCreds = New-Object System.Management.Automation.PSCredential ($EmailFrom, $EmailSecurePassword)
    	$SSLFlag = $True
    } Else {
    	$SSLFlag = $False
    }
    
    #:-- Set Name of Parent Script --::#
    $ParentScript = $Env:PLOGPATH -replace ".{6}$"
    
    If($EmailPort -eq "0") {
    	$mailparams = @{
    		SmtpServer = $EmailSMTPServer
    		From = $EmailFrom
    		To = $EmailTo
    		Subject = $Null
    		Body = $Null
    		Attachments = (Get-ChildItem "$env:INTRPATH*txt" -File).Fullname
    	}
    } Else {
    	$mailparams = @{
    		SmtpServer = $EmailSMTPServer
    		From = $EmailFrom
    		To = $EmailTo
    		Subject = $Null
    		Body = $Null
    		Attachments = (Get-ChildItem "$env:INTRPATH*txt" -File).Fullname
    		Port = $EmailPort
    		Credential = $EmailSecureCreds
    		UseSsl = $SSLFlag
    	}
    }
    
    #::-- Determine Script Success from Parent Script --::#
    If($env:ERR -ne 'T'){
    	$mailparams.Subject = "ATTENTION : $ParentScript.cmd completed successfully"
        $mailparams.Body = 'The process completed successfully.  Please the check log file(s) for additional details.'
    } Else {
    	$mailparams.Subject = "WARNING : $ParentScript.cmd failed to complete successfully"
    	$mailparams.Body = 'The process failed to complete successfully.  Please the check log file(s) for additional details.'
    }
    
    #::-- Send Email --::#
    Send-MailMessage @mailparams

    Monday, March 30, 2020 10:43 AM

All replies

  • Once again you are guessing at how to write code.  Why would you use the port to make this change.

    To do this you would use two sets of parameters called ParameterSets.  One would be triggered by the addition of a credential.

    The first thing you are failing at is knowing at how to design code.  This would become more obvious if you stopped trying now and learned PowerShell.

    You are, once again, asking others to write code for you one line at a time.

    I would suggest that you just use what you have if it works.  Your approach requires more code than necessary but to redesign it for you is beyond the scope of this forum.  I also have given you many suggestions and now it is up to you to actually put in some effort to learn basic PowerShell.


    \_(ツ)_/

    Monday, March 30, 2020 10:55 AM
  • Sorry, I copied in outdated code. I'm using password to check...

    If($EmailPassword.length -eq 0

    Monday, March 30, 2020 11:29 AM
  • The problem is, neither of them addressed both your needs (Attachment with a password), so I did some combination of the two and came up with this:

    $EmailTo = "myself@gmail.com"
    $EmailFrom = "me@mydomain.com"
    $Subject = "Test" 
    $Body = "Test Body" 
    $SMTPServer = "smtp.gmail.com" 
    $filenameAndPath = "C:\CDF.pdf"
    $SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom,$EmailTo,$Subject,$Body)
    $attachment = New-Object System.Net.Mail.Attachment($filenameAndPath)
    $SMTPMessage.Attachments.Add($attachment)
    $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587) 
    $SMTPClient.EnableSsl = $true 
    $SMTPClient.Credentials = New-Object System.Net.NetworkCredential("username", "password"); 
    $SMTPClient.Send($SMTPMessage)


    Monday, March 30, 2020 11:39 AM
  • The problem is, neither of them addressed both your needs (Attachment with a password), so I did some combination of the two and came up with this:

    $EmailTo = "myself@gmail.com"
    $EmailFrom = "me@mydomain.com"
    $Subject = "Test" 
    $Body = "Test Body" 
    $SMTPServer = "smtp.gmail.com" 
    $filenameAndPath = "C:\CDF.pdf"
    $SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom,$EmailTo,$Subject,$Body)
    $attachment = New-Object System.Net.Mail.Attachment($filenameAndPath)
    $SMTPMessage.Attachments.Add($attachment)
    $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587) 
    $SMTPClient.EnableSsl = $true 
    $SMTPClient.Credentials = New-Object System.Net.NetworkCredential("username", "password"); 
    $SMTPClient.Send($SMTPMessage)


    Not helpful as you are using old and un-useful code copied from the Internet. 

    Please take the time to read the users request and try to understand it.  Your code has nothing to do with the question or with the code posted.

     

    \_(ツ)_/

    Monday, March 30, 2020 12:08 PM
  • My final code, thank you!

    #::-- Param values passed in from Parent script in strict order --::#
    Param(
    	#::-- Required & cannot be Null --::#
    	[Parameter(Mandatory=$True)]
    	[ValidateNotNull()]
    		[string]$EmailSMTPServer,
    	[Parameter(Mandatory=$True)]
    	[ValidateNotNull()]
    		[string]$EmailFrom,
    	[Parameter(Mandatory=$True)]
    	[ValidateNotNull()]
    		[string]$EmailTo,
    	#::-- Optional & can be Null --::#
    	[int]$EmailPort,
        [string]$EmailPassword
    )
    
    #::-- Determine Cloud Environment --::#
    If($env:CLOUDURL -ilike "*test*") {$EmailEnv = "[TEST]"} Else {$EmailEnv = "[PROD]"}
    
    #::-- Execute Password Protocol --::# 
    If($EmailPassword.length -gt 0) {
    	$EmailSecurePassword = ConvertTo-SecureString $EmailPassword -AsPlainText -Force
    	$EmailSecureCreds = New-Object System.Management.Automation.PSCredential ($EmailFrom, $EmailSecurePassword)
    	$SSLFlag = $True
    } Else {
    	$SSLFlag = $False
    }
    
    #:-- Set Name of Parent Script --::#
    $ParentScript = $Env:PLOGPATH -replace ".{6}$"
    
    #::-- Extensions to exclude from Email Attachments --::#
    $EmailExtArray = "*.cmd","*.bat","*.exe", "*.ps1"
    
    If($EmailPassword.length -eq 0) {
    	$mailparams = @{
    		SmtpServer = $EmailSMTPServer
    		From = $EmailFrom
    		To = $EmailTo
    		Subject = $Null
    		Body = $Null
    		Priority = $Null
    	}
    } Else {
    	$mailparams = @{
    		SmtpServer = $EmailSMTPServer
    		From = $EmailFrom
    		To = $EmailTo
    		Subject = $Null
    		Body = $Null
    		Port = $EmailPort
    		Credential = $EmailSecureCreds
    		UseSsl = $SSLFlag
    		Priority = $Null
    	}
    }
    
    #::-- Determine if there are any Attchments --::#
    $EmailAttachments = Get-ChildItem $env:INTRAPATH -exclude $EmailExtArray `
    					| Where-Object { !( $_ | Select-String "0% loss" -quiet) } `
    					| Where { !$_.PSisContainer } |
    					Select -ExpandProperty FullName
    If($EmailAttachments -ne $Null){
    	$mailparams.Attachment = $EmailAttachments
    }
    
    #::-- Determine Script Success from Parent Script --::#
    If($env:ERR -ne "T"){
    	$mailparams.Subject = "ATTENTION : $ParentScript.cmd Succeeded $EmailEnv"
        $mailparams.Body = "The $EmailEnv $ParentScript.cmd process completed successfully.  Please the check log file(s) for additional details."
    	$mailparams.Priority = "Normal"
    } Else {
    	$mailparams.Subject = "WARNING : $ParentScript.cmd Failed $EmailEnv"
    	$mailparams.Body = "The $EmailEnv $ParentScript.cmd process failed to complete successfully.  Please the check log file(s) for additional details."
    	$mailparams.Priority = "High"
    }
    
    #::-- Send Email --::#
    Send-MailMessage @mailparams

    JRV - I find it silly that you comment quite regularly about "copying code from the internet" as if that is bad. I understand it serves no purpose if one doesn't know how to extrapolate and understand what the code is actually doing and apply it to said solution.  However, you can't reasonably expect people to be able to write code of the blue sky with no reference/examples (I'm talking semi-complex code).  If you personally can, I applaud you and would love to buy you a beer the next time you are in Boston.


    • Edited by cdtakacs1 Monday, March 30, 2020 7:27 PM
    Monday, March 30, 2020 7:05 PM

  • JRV - I find it silly that you comment quite regularly about "copying code from the internet" as if that is bad. I understand it serves no purpose if one doesn't know how to extrapolate and understand what the code is actually doing and apply it to said solution.  However, you can't reasonably expect people to be able to write code of the blue sky with no reference/examples (I'm talking semi-complex code).  If you personally can, I applaud you and would love to buy you a beer the next time you are in Boston.


    Part of the problem is that this forum insists you know how to code PowerShell before you come here.

    Part of the problem is that people don't bother to learn even the basics of PowerShell works and come here with "spaghetti code" hoping we will make it work for free.

    For example, someone who has taken the time to study PowerShell may have known about using parameter sets.

    But...  There's no real point in this discussion, not for me at least, so I'll stop here.

    Monday, March 30, 2020 9:25 PM

  • JRV - I find it silly that you comment quite regularly about "copying code from the internet" as if that is bad. I understand it serves no purpose if one doesn't know how to extrapolate and understand what the code is actually doing and apply it to said solution.  However, you can't reasonably expect people to be able to write code of the blue sky with no reference/examples (I'm talking semi-complex code).  If you personally can, I applaud you and would love to buy you a beer the next time you are in Boston.


    Point being that we, as humans, invented books and writing centuries ago to solve your dilemma.  Failure to learn how to use these tools relegates your endeavors to the primitive.

    You cannot understand what you copy without a complete and operative understanding of the basics.  Using polemics tro excuse an aberrated behavior is a non-starter for all who do know.

    You cannot learn any complex technology by trial and error.  Once you accept that, very ancient, knowledge you will have a clue as to where to find the keys to the kingdom.

    Don't listen to or copy the great unwashed of the Internet.  Pursue your own knowledge.  Knowledge is an individual quest.  It is not a crowd sourced entertainment.  It can only be pursued in solitude and individual thought.

    Wake up your intellect and put it to work for you.  Don't ask others to do your thinking for you.  They will gain and you will be left behind.

    Just a simple thought for you to consider.


    \_(ツ)_/

    Tuesday, March 31, 2020 3:14 AM