forked from PowerShell/PowerShell
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSend-MailMessage.cs
More file actions
403 lines (354 loc) · 14.6 KB
/
Copy pathSend-MailMessage.cs
File metadata and controls
403 lines (354 loc) · 14.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Management.Automation;
using System.Net.Mail;
using System.Text;
namespace Microsoft.PowerShell.Commands
{
#region SendMailMessage
/// <summary>
/// Implementation for the Send-MailMessage command.
/// </summary>
[Obsolete("This cmdlet does not guarantee secure connections to SMTP servers. While there is no immediate replacement available in PowerShell, we recommend you do not use Send-MailMessage at this time. See https://aka.ms/SendMailMessage for more information.")]
[Cmdlet(VerbsCommunications.Send, "MailMessage", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=2097115")]
public sealed class SendMailMessage : PSCmdlet
{
#region Command Line Parameters
/// <summary>
/// Gets or sets the files names to be attached to the email.
/// If the filename specified can not be found, then the relevant error
/// message should be thrown.
/// </summary>
[Parameter(ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[Alias("PsPath")]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public string[] Attachments { get; set; }
/// <summary>
/// Gets or sets the address collection that contains the
/// blind carbon copy (BCC) recipients for the e-mail message.
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public string[] Bcc { get; set; }
/// <summary>
/// Gets or sets the body (content) of the message.
/// </summary>
[Parameter(Position = 2, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
public string Body { get; set; }
/// <summary>
/// Gets or sets the value indicating whether the mail message body is in Html.
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true)]
[Alias("BAH")]
public SwitchParameter BodyAsHtml { get; set; }
/// <summary>
/// Gets or sets the encoding used for the content of the body and also the subject.
/// This is set to ASCII to ensure there are no problems with any email server.
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true)]
[Alias("BE")]
[ValidateNotNullOrEmpty]
[ArgumentEncodingCompletions]
[ArgumentToEncodingTransformation]
public Encoding Encoding
{
get
{
return _encoding;
}
set
{
EncodingConversion.WarnIfObsolete(this, value);
_encoding = value;
}
}
private Encoding _encoding = Encoding.ASCII;
/// <summary>
/// Gets or sets the address collection that contains the
/// carbon copy (CC) recipients for the e-mail message.
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Cc")]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public string[] Cc { get; set; }
/// <summary>
/// Gets or sets the delivery notifications options for the e-mail message. The various
/// options available for this parameter are None, OnSuccess, OnFailure, Delay and Never.
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true)]
[Alias("DNO")]
[ValidateNotNullOrEmpty]
public DeliveryNotificationOptions DeliveryNotificationOption { get; set; }
/// <summary>
/// Gets or sets the from address for this e-mail message. The default value for
/// this parameter is the email address of the currently logged on user.
/// </summary>
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
public string From { get; set; }
/// <summary>
/// Gets or sets the name of the Host used to send the email. This host name will be assigned
/// to the Powershell variable PSEmailServer, if this host can not reached an appropriate error.
/// message will be displayed.
/// </summary>
[Parameter(Position = 3, ValueFromPipelineByPropertyName = true)]
[Alias("ComputerName")]
[ValidateNotNullOrEmpty]
public string SmtpServer { get; set; }
/// <summary>
/// Gets or sets the priority of the email message. The valid values for this are Normal, High and Low.
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
public MailPriority Priority { get; set; }
/// <summary>
/// Gets or sets the Reply-To field for this e-mail message.
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true)]
public string[] ReplyTo { get; set; }
/// <summary>
/// Gets or sets the subject of the email message.
/// </summary>
[Parameter(Mandatory = false, Position = 1, ValueFromPipelineByPropertyName = true)]
[Alias("sub")]
public string Subject { get; set; }
/// <summary>
/// Gets or sets the To address for this e-mail message.
/// </summary>
[Parameter(Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public string[] To { get; set; }
/// <summary>
/// Gets or sets the credential for this e-mail message.
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true)]
[Credential]
[ValidateNotNullOrEmpty]
public PSCredential Credential { get; set; }
/// <summary>
/// Gets or sets if Secured layer is required or not.
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true)]
public SwitchParameter UseSsl { get; set; }
/// <summary>
/// Gets or sets the Port to be used on the server. <see cref="SmtpServer"/>
/// </summary>
/// <remarks>
/// Value must be greater than zero.
/// </remarks>
[Parameter(ValueFromPipelineByPropertyName = true)]
[ValidateRange(0, int.MaxValue)]
public int Port { get; set; }
#endregion
#region Private variables and methods
// Instantiate a new instance of MailMessage
private readonly MailMessage _mMailMessage = new();
private SmtpClient _mSmtpClient = null;
/// <summary>
/// Add the input addresses which are either string or hashtable to the MailMessage.
/// It returns true if the from parameter has more than one value.
/// </summary>
/// <param name="address"></param>
/// <param name="param"></param>
private void AddAddressesToMailMessage(object address, string param)
{
string[] objEmailAddresses = address as string[];
foreach (string strEmailAddress in objEmailAddresses)
{
try
{
switch (param)
{
case "to":
{
_mMailMessage.To.Add(new MailAddress(strEmailAddress));
break;
}
case "cc":
{
_mMailMessage.CC.Add(new MailAddress(strEmailAddress));
break;
}
case "bcc":
{
_mMailMessage.Bcc.Add(new MailAddress(strEmailAddress));
break;
}
case "replyTo":
{
_mMailMessage.ReplyToList.Add(new MailAddress(strEmailAddress));
break;
}
}
}
catch (FormatException e)
{
ErrorRecord er = new(e, "FormatException", ErrorCategory.InvalidType, null);
WriteError(er);
continue;
}
}
}
#endregion
#region Overrides
/// <summary>
/// BeginProcessing override.
/// </summary>
protected override void BeginProcessing()
{
try
{
// Set the sender address of the mail message
_mMailMessage.From = new MailAddress(From);
}
catch (FormatException e)
{
ErrorRecord er = new(e, "FormatException", ErrorCategory.InvalidType, From);
ThrowTerminatingError(er);
}
// Set the recipient address of the mail message
AddAddressesToMailMessage(To, "to");
// Set the BCC address of the mail message
if (Bcc != null)
{
AddAddressesToMailMessage(Bcc, "bcc");
}
// Set the CC address of the mail message
if (Cc != null)
{
AddAddressesToMailMessage(Cc, "cc");
}
// Set the Reply-To address of the mail message
if (ReplyTo != null)
{
AddAddressesToMailMessage(ReplyTo, "replyTo");
}
// Set the delivery notification
_mMailMessage.DeliveryNotificationOptions = DeliveryNotificationOption;
// Set the subject of the mail message
_mMailMessage.Subject = Subject;
// Set the body of the mail message
_mMailMessage.Body = Body;
// Set the subject and body encoding
_mMailMessage.SubjectEncoding = Encoding;
_mMailMessage.BodyEncoding = Encoding;
// Set the format of the mail message body as HTML
_mMailMessage.IsBodyHtml = BodyAsHtml;
// Set the priority of the mail message to normal
_mMailMessage.Priority = Priority;
// Get the PowerShell environment variable
// globalEmailServer might be null if it is deleted by: PS> del variable:PSEmailServer
PSVariable globalEmailServer = SessionState.Internal.GetVariable(SpecialVariables.PSEmailServer);
if (SmtpServer == null && globalEmailServer != null)
{
SmtpServer = Convert.ToString(globalEmailServer.Value, CultureInfo.InvariantCulture);
}
if (string.IsNullOrEmpty(SmtpServer))
{
ErrorRecord er = new(new InvalidOperationException(SendMailMessageStrings.HostNameValue), null, ErrorCategory.InvalidArgument, null);
this.ThrowTerminatingError(er);
}
if (Port == 0)
{
_mSmtpClient = new SmtpClient(SmtpServer);
}
else
{
_mSmtpClient = new SmtpClient(SmtpServer, Port);
}
if (UseSsl)
{
_mSmtpClient.EnableSsl = true;
}
if (Credential != null)
{
_mSmtpClient.UseDefaultCredentials = false;
_mSmtpClient.Credentials = Credential.GetNetworkCredential();
}
else if (!UseSsl)
{
_mSmtpClient.UseDefaultCredentials = true;
}
}
/// <summary>
/// ProcessRecord override.
/// </summary>
protected override void ProcessRecord()
{
// Add the attachments
if (Attachments != null)
{
string filepath = string.Empty;
foreach (string attachFile in Attachments)
{
try
{
filepath = PathUtils.ResolveFilePath(attachFile, this);
}
catch (ItemNotFoundException e)
{
// NOTE: This will throw
PathUtils.ReportFileOpenFailure(this, filepath, e);
}
Attachment mailAttachment = new(filepath);
_mMailMessage.Attachments.Add(mailAttachment);
}
}
}
/// <summary>
/// EndProcessing override.
/// </summary>
protected override void EndProcessing()
{
try
{
// Send the mail message
_mSmtpClient.Send(_mMailMessage);
}
catch (SmtpFailedRecipientsException ex)
{
ErrorRecord er = new(ex, "SmtpFailedRecipientsException", ErrorCategory.InvalidOperation, _mSmtpClient);
WriteError(er);
}
catch (SmtpException ex)
{
if (ex.InnerException != null)
{
ErrorRecord er = new(new SmtpException(ex.InnerException.Message), "SmtpException", ErrorCategory.InvalidOperation, _mSmtpClient);
WriteError(er);
}
else
{
ErrorRecord er = new(ex, "SmtpException", ErrorCategory.InvalidOperation, _mSmtpClient);
WriteError(er);
}
}
catch (InvalidOperationException ex)
{
ErrorRecord er = new(ex, "InvalidOperationException", ErrorCategory.InvalidOperation, _mSmtpClient);
WriteError(er);
}
catch (System.Security.Authentication.AuthenticationException ex)
{
ErrorRecord er = new(ex, "AuthenticationException", ErrorCategory.InvalidOperation, _mSmtpClient);
WriteError(er);
}
finally
{
_mSmtpClient.Dispose();
// If we don't dispose the attachments, the sender can't modify or use the files sent.
_mMailMessage.Attachments.Dispose();
}
}
#endregion
}
#endregion
}