locked
System.Net.Mail.MailMessage "UseDefaultCredentials" parameter RRS feed

  • Question

  • I'm trying to send SMTP mail using the credentials of the currently logged in user, here's my code:

    $smtpServer = "relay.contoso.com"
    $smtpPort = "587"
    $SmtpFrom = (get-aduser ([environment]::username) -Properties mail).mail
    $smtpTo = "recipient@contoso.com"
    $messageSubject = "THIS IS WHERE YOUR SUBJECT GOES"
    $date = get-date -UFormat "%d.%m.%y - %H.%M.%S"
    
    $message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpto
    $message.Subject = $messageSubject
    $message.IsBodyHTML = $true
    $message.Body = "This is a test of relayed email at $date from user $smtpFrom"
    
    $smtp = New-Object Net.Mail.SmtpClient($smtpServer, $smtpPort)
    $smtp.UseDefaultCredentials = $true
    $smtp.Send($message)

    The way I understand the parameter "UseDefaultCredentials" (and the way it works with invoke-webrequest) is to pull the creds from the currently logged in user and pass them on. However, I get a strange error message:

    "Exception calling 'send' with '1' argument(s): 'Syntax Error, command unrecognized. The  server response was 5.3.3 Unrecognized command"

    It works just fine if I hard-code creds into the script (which I'd rather not do), and error code 5.3.3 is a server hardware error from Exchange. 

    Is it even possible to send mail using the credentials as the currently logged in user, or do I have to prompt for creds or hard-code it?


    zarberg@gmail.com

    Friday, June 1, 2018 3:46 PM

All replies

  • The following is the correct way to send email on PowerShell since PS V2.  You are using V1 methods which are not necessary.

    $from = (get-aduser $env:USERNAME -Properties mail).mail
    $mailsplat - @{
        SmtpServer = 'relay.contoso.com'
        Port = 587
        From = $from
        To = 'recipient@contoso.com'
        Subject = 'THIS IS WHERE YOUR SUBJECT GOES'
        BodyAsHtml = $true
        Body = "This is a test of relayed email at $([datetime]::Now.ToString('dd.MM.yyyy - HH.MM.SS')) from user $from"
    }
    Send-MailMessage @mailsplat
    If you need credentials just add "-Credential $cred" to the command.


    \_(ツ)_/



    • Edited by jrv Friday, June 1, 2018 4:14 PM
    Friday, June 1, 2018 4:01 PM
  • Here is the info on how credentials are used.

    https://msdn.microsoft.com/en-us/library/system.net.mail.smtpclient.usedefaultcredentials%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

    With both "System.Net.SMTPClient" and "Send-MailMessage" the default credentials are always sent if the remote prompts for creds.  Domain servers use the users logon by default unless you add a credential parameter.  With the SMTPClient you cannot specify both name/password and "UseDefault.

    Send-MailMessage manages this automatically. Almost all Windows Exchenge servers block access to SMTP servers internally.  Public servers always require a username and password sent explicitly.


    \_(ツ)_/

    Friday, June 1, 2018 4:09 PM
  • WARNING: I fixed a typo in my example above.


    \_(ツ)_/

    Friday, June 1, 2018 4:13 PM
  • I was hoping to be able to pull the default credentials not unlike invoke-webrequest does, but I guess that's not possible with Powershell sending to Exchange?

    And just as an FYI, I am the Exchange admin here, and we do indeed have anonymous relaying turned off; hence why I was hoping to just pass the default creds rather than store them or have them in an xml file somewhere.

    Ultimately the issue is this; I've been tasked to slap a GUI on some basic Powershell Exchange functions for delegation (I'm well aware of Exchange RBAC, but the default RBAC interface doesn't expose quotas, primary SMTP manipulation, or mailbox delegation). The team that I'm delegating to has asked to have the GUI'ed script send an e-mail after and ideally I'd rather have it just send as the person running the script, I.E. the currently logged-in user. 

    If that's not possible, I can probably just create a service account for just that purpose and send as the service account, passing the credentials inside the script since I'm using PS2EXE to turn the GUI into a little program they can just run; theoretically you could decompile the .exe and strip the password out if you knew what you were doing, but this will be internal only so I'm not really worried about it.


    zarberg@gmail.com

    Friday, June 1, 2018 6:32 PM
  • You are not sending to Exchange.  You are sending to a public SMTP server.  If it is managed by Exchange then it can use the credentials parameter if it is optioned to allow that. You may also need to use SSL to authentic.  Ask the Exchange admin for help with the available methods.

    If you use outlook to Exchange with SMTP then copy the Outlook settings.


    \_(ツ)_/

    Friday, June 1, 2018 6:36 PM
  • If you're using port 587 (SMTP client) then you most likely need to use SSL. You can add "$smtp.EnableSSL=$TRUE" or use the newer Send-MailMessage cmdlet (as per jrv) with the -UseSSL switch.

    If you're having problems understanding what the SMTP conversation between your client and server looks like, enable SMTP Protocol Logging on your Exchange server. Your client is probably expected to initiate the conversation with "STARTTLS" if the server demands the use of an encrypted connection. That 5.3.3 error is very likely due to your client trying to simply start with the standard "HELO" command instead.


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    Friday, June 1, 2018 6:40 PM
  • Exchange usually restricts the use of port 25 (anonymous SMTP Server) connections, but allows connections on port 587 (authenticated/encrypted SMTP Client). That is, of course, entirely configurable by the Exchange admin.

    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    Friday, June 1, 2018 6:43 PM
  • Pretty sure he needs "-UseSSL" in the @mailsplat if he's using port 587.

    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    Friday, June 1, 2018 6:44 PM
  • Is there any way to pass the currently logged in user's credentials?

    zarberg@gmail.com

    Friday, June 1, 2018 6:44 PM
  • Yes. 587 should always use only SSL. Microsoft has just set all of their Exchange servers to accept only TLS 1.2 which is not enabled by default in Windows. It can be enabled on demand in script.

    #Here is an SSL example with credentials.
    
    $from = (get-aduser $env:USERNAME -Properties mail).mail
    $cred = Get-Credential useremail
    $mailsplat - @{
        From = $from
        To = 'recipient@contoso.com'
        Subject = 'THIS IS WHERE YOUR SUBJECT GOES'
        Body = "This is a test of relayed email at $([datetime]::Now.ToString('dd.MM.yyyy - HH.MM.SS')) from user $from"
        SmtpServer = 'relay.contoso.com'
        BodyAsHtml = $true
        Port = '587'
        UseSSL = $true
        Credential = $cred
    }
    Send-MailMessage @mailsplat


    \_(ツ)_/


    • Edited by jrv Friday, June 1, 2018 6:50 PM
    Friday, June 1, 2018 6:50 PM
  • Exchange usually restricts the use of port 25 (anonymous SMTP Server) connections, but allows connections on port 587 (authenticated/encrypted SMTP Client). That is, of course, entirely configurable by the Exchange admin.

    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    True but 587 is used only for mail clients.  No ISP allows clients on dynamic IPs to use port 25.  Port 25 is blocked and even blocked for static IPs but you can request it to be opened.  Sending to 25 from static IPs iss allowed for now but will likely also be blocked and require asking for access.


    \_(ツ)_/

    Friday, June 1, 2018 7:03 PM
  • Is there any way to pass the currently logged in user's credentials?

    zarberg@gmail.com

    They are not accessible and are not required in  domain.  SMTP authentication requires explicit credentials.  You have to know what credentials a user has set up for port 587.

    Only your Exchange Admin can tell you that or an ISP help desk if this is a public Exchange server.

    If you use Get-Credential and enter the users credentials Send=MailMessage will deal with the authentication correctly for all cases.  The SMTPClient will not do it automatically.


    \_(ツ)_/


    • Edited by jrv Friday, June 1, 2018 7:07 PM
    Friday, June 1, 2018 7:06 PM
  • While you're not going to get a password from the AD, you can store and retrieve credentials from the Windows Credential Manager on the client machine (think "remember me"). For an example, see https://stackoverflow.com/questions/29103238/accessing-windows-credential-manager-from-powershell

    As for the Exchange side of things, how wide is the scope of IP addresses that will be accessing your SMTP connector? You could create a new SMTP connector, allow it to accept anonymous connections on port 25, and restrict the set of IP addresses that are permitted to use the connection. That's a pretty common way to deal with the problem, and it avoids the need for managing passwords at the client. The problem then becomes one of whether or not you use DHCP to assign dynamic IP addresses to clients or if the clients use static IP addresses. Dynamic IP addresses will be a PITA unless you can allow an entire network access. If you can do that you'll make you life a lot easier.

    I think that you should really be asking your question in one of the Exchange forums if none of the above is acceptable, because your problem isn't with Powershell.


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    Friday, June 1, 2018 9:45 PM
  • Exchange usually restricts the use of port 25 (anonymous SMTP Server) connections, but allows connections on port 587 (authenticated/encrypted SMTP Client). That is, of course, entirely configurable by the Exchange admin.


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    True but 587 is used only for mail clients.  No ISP allows clients on dynamic IPs to use port 25.  Port 25 is blocked and even blocked for static IPs but you can request it to be opened.  Sending to 25 from static IPs iss allowed for now but will likely also be blocked and require asking for access.


    \_(ツ)_/

    Well, Send-MailMessage is a client!


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    Friday, June 1, 2018 9:49 PM
  • Never said it wasn't. In fact Send-MM uses SMTPClient but it adds other capabilities under the covers. By "used only for mail clients" I was indicating that it is not a target for public mail servers. Public mail servers connect to port 25 without encryption and with no credentials. Port 25 is the public port and 587 is the mail client port. This is by convention and because all ISPs stopped passing outbound port 25 traffic from dynamic addresses to reduce the huge amount of spam generated by bots and malware. Since there is no authentication on port 25 there is nothing to stop a mail sender from sending to a users domain on port 25. Spam and malware still uses port 25 but it cannot do it from a dynamic address and static addresses are hard to come by for a personal ISP account. Business accounts are validated as legitimate businesses before they are allowed a static address or access to outbound port 25. Of course there are small ISPs that may not enforce these voluntary rules but no major ISP allows p25 traffic and has blocked it for many years now.

    \_(ツ)_/

    Friday, June 1, 2018 10:04 PM
  • Never said it wasn't. In fact Send-MM uses SMTPClient but it adds other capabilities under the covers. By "used only for mail clients" I was indicating that it is not a target for public mail servers. Public mail servers connect to port 25 without encryption and with no credentials. Port 25 is the public port and 587 is the mail client port. This is by convention and because all ISPs stopped passing outbound port 25 traffic from dynamic addresses to reduce the huge amount of spam generated by bots and malware. Since there is no authentication on port 25 there is nothing to stop a mail sender from sending to a users domain on port 25. Spam and malware still uses port 25 but it cannot do it from a dynamic address and static addresses are hard to come by for a personal ISP account. Business accounts are validated as legitimate businesses before they are allowed a static address or access to outbound port 25. Of course there are small ISPs that may not enforce these voluntary rules but no major ISP allows p25 traffic and has blocked it for many years now.

    \_(ツ)_/

    I spent six years in a technical support role for Exchange (starting with release 4.0) at a MS Authorized Support Center, and 14 years managing the Exchange organization for a mid-sized multi-national company. Believe me, I know a lot (but not everything) about SMTP, spam, IP port allocation, port blocking, etc. (and a lot about X.400 that I'd like to forget!) :-)

    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    Saturday, June 2, 2018 1:40 AM
  • Me too.  Exchange 4.5 on.  Unix mail of various kinds.  All of that stuff.  Mail was just background as most companies I worked for were clueless.  I lobbied to set up Exchange whenwe had to closely mange large amounts of mail and data from our clients.  Having "hands-on" with the mail made my life easier and Exchange allowed me to customize anything I needed to customize.

    I also set up global voice/data networks and worked on finalizing the first circum-global  voice/data network.

    Been playing with and building computers since 1959.  Old farts die hard.

    SMTP is a kludge but has gotten better.  It was built based on all interactive text interfaces which can work, but not without adding all kinds of nastiness. 

    I expect we will move to a new version soon that runs only on secure cert-based communications.


    \_(ツ)_/

    Saturday, June 2, 2018 1:51 AM