none
What is the proper wait syntax for Send-MailMessage? RRS feed

  • Question

  • Hey Scripting Guys,

    In the following script I would like to add a wait for the Send-MailMessage cmdlet to finish.  I have seen a variety of techniques such as Start-Process with -wait, out-null, and so forth.  I decided I should ask which is the proper method in this case.

    $secPassword = ConvertTo-SecureString "myPwd" -AsPlainText -Force
    $myCredentials = New-Object System.Management.Automation.PSCredential("myEmail",$secPassword)
    $myComputer = Get-Content env:computername
    $param = @{
        SmtpServer = 'myMailServer'
        Port = myPort
        Credential  = $myCredentials
        From = $myComputer + ' <myFromEmail>'
        To = 'myToEmail'
        Subject = 'mySubject'
    }
    Send-MailMessage @param

    Thanks

    Tuesday, May 5, 2015 10:49 PM

Answers

  • Send-MailMessage does not return before the message has been delivered to the mail server.  Unplug the net cable and run it and you will see a very long delay before it fails.

    A computer shutdown always polls all processes for completion and then waits if some processes are busy.  If you use the force on a shutdown then processes will be terminated without wait.  No amount of code will change that.


    \_(ツ)_/

    • Marked as answer by Alan Wheeler Wednesday, May 6, 2015 7:43 PM
    Wednesday, May 6, 2015 8:49 AM

All replies

  • Hello,

    Win 8.1, powershell

    I have a simple script to send a startup SMTP email.

    I moved it into the folder C:\Windows\System32\GroupPolicy\Machine\Scripts\Startup and I can run it and it works properly sending an email as expected.  I then added it in the Local Group Policy Editor > Computer Configuration > Windows Settings > Scripts (Startup/Shutdown) > Startup > PowerShell Scripts tab as shown below:

    I added the ".txt file writes" shown in the script below as markers to show if the script had at least run even if the email wasn't successfully transmitted.  The log file doesn't show and the script does not seem to be running.

    What other factors affect whether or not a script will run on system startup?  I will also want to run a script on shutdown, but until I can get past this step I need to focus here.

    Script:

    "ps email script started" > \batchFiles\ps\log.txt
    $secPassword = ConvertTo-SecureString "<mypwd>" -AsPlainText -Force
    $myCredentials = New-Object System.Management.Automation.PSCredential("myusername",$secPassword)
    $param = @{
        SmtpServer = 'myemailserver'
        Port = 80
        Credential  = $myCredentials
        From = 'pc <thesendingemail>'
        To = 'therecipient'
        Subject = 'ps email test'
    }
    Send-MailMessage @param
    "ps email script ended" >> \batchFiles\ps\log.txt

    Added after original post:

    I checked the security for the startup folder.  For SYSTEM all permissions are checked except 'Special Permissions', but do I need a different permission listed for the computer to run the script?  Also, I have separate logons for this PC.  One is just a local user name, the other is a domain logon.  Will that have an impact?

    Monday, May 4, 2015 5:03 PM
  • This will execute before the system is ready and it will output nothing and it will not send any mail.

    The password in the file will be available to anyone in the network who can attach a computer even if it is not joined to the domain.

    Why not tell us what the purpose of this is.  There is likely a good way to do what you need.


    \_(ツ)_/

    Monday, May 4, 2015 5:18 PM
  • This is ultimately for my system server.  I am currently programming the script on my client workstation just to get the script correct first.

    When AC power fails, my UPS sends an SMTP email letting me know it is on battery.  If the power is not restored before the batteries run down, then the UPS gracefully shuts down my server.  When AC power is restored, then the server automatically restarts, hopefully bringing up all the VM servers within.

    So the first event I want to know after an AC power failure is if the host and it's VM servers are actually shutting down.  My UPS won't send that email, so I need the server(s) to send those emails if they are shutting down.

    The next event I want to know about is if the server(s) have rebooted.

    I figured I would simply write a script that sends an email for these events and I would be appraised of what was happening at the server location for both the host and the individual VM servers.

    That's why I was trying to run the powershell scrip through gpedit.msc.

    Monday, May 4, 2015 5:32 PM
  • To do this you need a network UPS and install the drivers into each VM.  This way they will get the shutdown message. The UPS software for networked UPS system can and will send an email.

    As an alternative you can trigger an email from the Event log as an event log task.

    If you do this as intended you will have less trouble.


    \_(ツ)_/

    Monday, May 4, 2015 5:36 PM
  • Perhaps I should try working with the Event Log.

    I'm not sure to which paragraph your final sentence applies.  Did you mean that I will have less trouble using the Event Log?  I am currently looking up guidance on the Event Log solution.  If you could clarify a point for me.  When I think of attaching a task to a log event it at first seems confusing, because in my mind a log is "after the fact".  Does this terminology of "triggering a task from the Event log" merely mean we are using a log to determine what event is available, and when we attach a task to that event, then in the future when that event occurs the task will be executed?

    I think I understand your meaning regarding the UPS software and installing the shutdown client on each machine.  Since I only have one physical machine, the host, I was thinking I would setup Hyper-V to shutdown the VM servers using the standard provided shutdown mechanisms within Hyper-V.  Do you think that will work OK?



    Monday, May 4, 2015 6:32 PM
  • Regarding your first response to this post, you commented that this will execute before the system is ready.

    That causes me to ask what can I run at the time those scripts are executed if the system is not ready?  I'm certain there is value in running scripts at that point in the sequence, I'm just wondering what it is.


    Monday, May 4, 2015 6:41 PM
  • You are asking for complex design assistance. Why? Just install the network UPS software into each VM.  They will all get the message.


    \_(ツ)_/

    Monday, May 4, 2015 8:02 PM
  • I appreciate your suggestions.  I certainly didn't mean to wander into a question that seemed like design assistance, so disregard that part.

    Regarding UPS emails, my UPS software only sends emails when the UPS is going to shutdown computers.  Although I'm only using the basic versions of UPS software, I checked and even the full-blown networked version doesn't send emails regarding the computers, only for the UPS unit(s).  Beyond which, I also want emails when the system comes back up.

    So I'm back to using scripts to have the servers send emails at some point during boot.  And that takes me back to asking the best way to run a power shell script that sends an email.

    You've told me that it won't work with the Local Group Policy Editor because the system won't be ready, so I need to learn how to reliably trigger my power shell script at an appropriate point during server startup.

    What is the best way to do that?

    Monday, May 4, 2015 9:35 PM
  • All networked UPS software that I have ever used has had the ability to execute a program (or script) on all power events.  That is just how it works. There is no way to do this if the UPS is not network based.  Most standalone local UPS systems do not do much of anything.  Windows compatible UPSs raise events that can be scripted. 


    \_(ツ)_/

    Monday, May 4, 2015 9:59 PM
  • What exactly are you waiting for? A response that the email was sent? You're not going to get any response or verification that it is sent. Once it's run, it's done. Or, maybe I'm miss understanding something, and you'd like to explain more...?
    Tuesday, May 5, 2015 10:54 PM
  • Hi Tommy,

    Thanks for your response.

    I debated giving the context of my question and clearly chose poorly... I'm sorry.

    I'm trying to run this during OS shutdown.  It occurred to me that if the script doesn't wait, then the system might go on shutting down various services necessary for the Send-MailMessage cmdlet to finish properly.  My PC processes shutdown pretty quick.

    Obviously I'm assuming that when this script runs it 'owns' the system until it's done.  If that's wrong then I guess my previous thought is not applicable.  Or maybe there's a way to ensure it does 'own' the system; that I wouldn't be familiar with just yet either.

    Tuesday, May 5, 2015 11:04 PM
  • Send-MailMessage does not return before the message has been delivered to the mail server.  Unplug the net cable and run it and you will see a very long delay before it fails.

    A computer shutdown always polls all processes for completion and then waits if some processes are busy.  If you use the force on a shutdown then processes will be terminated without wait.  No amount of code will change that.


    \_(ツ)_/

    • Marked as answer by Alan Wheeler Wednesday, May 6, 2015 7:43 PM
    Wednesday, May 6, 2015 8:49 AM
  • I am in the process of asking my UPS manufacturer about how they are controlling my server.  I am asking this regarding your comment about a raised event that could be scripted.

    I presume that since my UPS talks to my server via USB, it would fall in your category of a 'Windows compatible UPS'.  I only state this to confirm I'm thinking properly regarding your comment above.

    Wednesday, May 6, 2015 5:00 PM
  • IF it is Windows compatible and has been installed as a Windows device then the Hyper-V systems will get the event too.  You will likely need to enable the UPS in the VMs in Power Options in the control panel.


    \_(ツ)_/

    Wednesday, May 6, 2015 5:09 PM
  • That's a great point about the power options in the VM.  I just went and looked there.  The host OS seems to know there's a UPS because it has the Battery Option in all the power profiles.  However, the VM's do not sense the UPS.

    It isn't apparent to me how I enable UPS as you suggest above so I thought I would ask how that is done. (I did look and didn't find anything)

    Unrelated to my question re UPS enabling, I am concerned about this thread.  Typically we like to stay on a topic, but I note that the moderator merged the threads under this title, so I'm assuming it's OK.  But anytime we need to start a new thread as we discuss this topic I'll need guidance to do that.

    Just let me know.

    Wednesday, May 6, 2015 7:16 PM
  • I had noticed that when I was in a state where the PowerShell window could be seen, it seemed to stay open for varying amounts of time which I thought might indicate it was waiting for a result from the email server, but I wasn't sure.  Thank you for your confirmation.

    So your last response actually explains why I don't really need to apply a wait for the Send-MailMessage cmdlet and technically closes this thread.

    While it seems as though I don't really have a need to apply a wait to a cmdlet in powershell at this time, should the need arise for some other script I will create a new question at that time.

    Thanks for your help with this question.

    However, I am still having problems with the Local Policy Editor scripts.  Should I create a new thread for that?

    Wednesday, May 6, 2015 7:26 PM