Skip to content

Commit 4601a6b

Browse files
Merge pull request #12 from PowershellFrameworkCollective/development
1.1.7
2 parents ad55ae3 + a88e318 commit 4601a6b

9 files changed

Lines changed: 253 additions & 139 deletions

File tree

MailDaemon/MailDaemon.psd1

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
RootModule = 'MailDaemon.psm1'
44

55
# Version number of this module.
6-
ModuleVersion = '1.1.3'
6+
ModuleVersion = '1.2.14'
77

88
# ID used to uniquely identify this module
99
GUID = 'd5ba333f-5210-4d69-83f0-150dd0909139'
@@ -21,12 +21,12 @@
2121
Description = 'Mail Daemon as PowerShell Module'
2222

2323
# Minimum version of the Windows PowerShell engine required by this module
24-
PowerShellVersion = '5.0'
24+
PowerShellVersion = '5.1'
2525

2626
# Modules that must be imported into the global environment prior to importing
2727
# this module
2828
RequiredModules = @(
29-
@{ ModuleName='PSFramework'; ModuleVersion='1.12.346' }
29+
@{ ModuleName='PSFramework'; ModuleVersion='1.13.416' }
3030
)
3131

3232
# Assemblies that must be loaded prior to importing this module

MailDaemon/changelog.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,25 @@
11
# Changelog
22

3+
## 1.2.14 (2026-02-12)
4+
5+
+ Fix: Update-MDFolderPermission - does not set permissions for the failed folder
6+
7+
## 1.2.13 (2026-02-11)
8+
9+
+ New: Emails that could not be sent will no longer be permanently attempted to resend - after 14 days
10+
+ Upd: Install-MDDaemon - now supports remote-deployment of the daemon task using credentials
11+
+ Upd: Install-MDDaemon - now installs eventlog for MailDaemon
12+
+ Upd: Invoke-MDDaemon - adds logging to the Windows Eventlog by default
13+
+ Fix: Install-MDDaemon - no longer fails when the daemon task already exists
14+
+ Fix: Invoke-MDDaemon - fails to use authentication for SMTP
15+
16+
## 1.1.7 (2026-02-10)
17+
18+
+ Upd: Invoke-MDDaemon - implements `UseSSL` as configured
19+
+ Upd: Set-MDDaemon - supports `-UseSSL`
20+
+ Upd: Install-MDDaemon - supports `-UseSSL`
21+
+ Fix: Install-MDDaemon - now exports credentials without prompting.
22+
323
## 1.1.3 (2024-11-11)
424

525
+ Upd: Added ability to directly embed attachments in the email task, rather than only providing a path to them. (thanks @jebbster88 ; #10)
@@ -18,7 +38,7 @@
1838
## 0.1.1 (2019-02-09)
1939

2040
+ Fix: Bug in Install-MDDaemon causing errors during installation
21-
41+
2242
## 0.1.0 (2019-02-09)
2343

2444
+ New: Everything

MailDaemon/en-us/strings.psd1

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,30 @@
22
# Write-PSFMessage, Stop-PSFFunction or the PSFramework validation scriptblocks
33
@{
44
# General
5-
'General.ModuleMissing' = 'The MailDaemon module could not be found in sufficient version on: {0}. Terminating Execution. To install or update to the current version, use Install-MDDaemon or access the PSGallery directly using "Install-Module MailDaemon".'
5+
'General.ModuleMissing' = 'The MailDaemon module could not be found in sufficient version on: {0}. Terminating Execution. To install or update to the current version, use Install-MDDaemon or access the PSGallery directly using "Install-Module MailDaemon".'
66

77
# Invoke-MDDaemon
8-
'Invoke-MDDaemon.SendMail.Start' = '{0} - Sending Mail: "{1}" From {2} to {3}'
9-
'Invoke-MDDaemon.SendMail.Failed' = '{0} - Failed to send email!'
10-
'Invoke-MDDaemon.SendMail.Success' = '{0} - Email sent successfully'
11-
'Invoke-MDDaemon.ManageSuccessJob.Failed' = '{0} - Failed to move mail task to the "sent" folder!'
8+
'Invoke-MDDaemon.SendMail.Abandon' = '{0} - Abandoning email after failing to send it within the configured timespan ({1})' # $email.Taskname, $abandonThreshold
9+
'Invoke-MDDaemon.SendMail.Start' = '{0} - Sending Mail: "{1}" From {2} to {3}'
10+
'Invoke-MDDaemon.SendMail.Failed' = '{0} - Failed to send email!'
11+
'Invoke-MDDaemon.SendMail.Success' = '{0} - Email sent successfully'
12+
'Invoke-MDDaemon.ManageSuccessJob.Failed' = '{0} - Failed to move mail task to the "sent" folder!'
1213

1314
# Copy-Module
14-
'Copy-Module.ReceivingModule' = 'Receiving Module from {0}: {1}'
15-
'Copy-Module.ReceivingModule.Failed' = 'Failed to receive Module from {0}: {1}'
16-
'Copy-Module.InstallingModule' = 'Installing module {0} on: {1}'
15+
'Copy-Module.ReceivingModule' = 'Receiving Module from {0}: {1}'
16+
'Copy-Module.ReceivingModule.Failed' = 'Failed to receive Module from {0}: {1}'
17+
'Copy-Module.InstallingModule' = 'Installing module {0} on: {1}'
1718

1819
# Send-MDMail
19-
'Send-MDMail.Folder.CreationFailed' = 'Failed to create outgoing mail folder: {0}'
20-
'Send-MDMail.Email.NotRegisteredYet' = 'No email has been set up yet!'
21-
'Send-MDMail.Email.Sending' = 'Queueing email for sending: {0}'
22-
'Send-MDMail.Email.SendingFailed' = 'Failed to queue email for sending: {0}'
23-
'Send-MDMail.Email.TriggerFailed' = 'Failed to trigger the Mail Daemon task to send {0}'
20+
'Send-MDMail.Folder.CreationFailed' = 'Failed to create outgoing mail folder: {0}'
21+
'Send-MDMail.Email.NotRegisteredYet' = 'No email has been set up yet!'
22+
'Send-MDMail.Email.Sending' = 'Queueing email for sending: {0}'
23+
'Send-MDMail.Email.SendingFailed' = 'Failed to queue email for sending: {0}'
24+
'Send-MDMail.Email.TriggerFailed' = 'Failed to trigger the Mail Daemon task to send {0}'
2425

2526
# Set-MDDaemon
26-
'Set-MDDaemon.UpdatingSettings' = 'Starting Daemon configuration update on {0}'
27-
'Set-MDDaemon.UpdateSetting' = 'Updating the Daemon configuration setting {0} to {1}'
27+
'Set-MDDaemon.UpdatingSettings' = 'Starting Daemon configuration update on {0}'
28+
'Set-MDDaemon.UpdateSetting' = 'Updating the Daemon configuration setting {0} to {1}'
2829

2930
# Update-MDFolderPermission
3031
'Update-MDFolderPermission.Granting.DaemonUser' = 'Assigning write permissions as daemon account to {0} on "{1}" and "{2}"'

MailDaemon/functions/Install-MDDaemon.ps1

Lines changed: 69 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
function Install-MDDaemon
2-
{
3-
<#
1+
function Install-MDDaemon {
2+
<#
43
.SYNOPSIS
54
Configures a computer for using the Mail Daemon
65
@@ -31,6 +30,9 @@
3130
3231
.PARAMETER SentPath
3332
The folder in which emails that were successfully sent are stored for a specified time before being deleted.
33+
34+
.PARAMETER FailedPath
35+
The path where mails that could repeatedly not be sent are moved to.
3436
3537
.PARAMETER DaemonUser
3638
The user to grant permissions needed to function as the Daemon account.
@@ -42,6 +44,12 @@
4244
4345
.PARAMETER MailSentRetention
4446
The time to keep successfully sent emails around.
47+
48+
.PARAMETER MailAbandonThreshold
49+
How long we attempt to send an email before abandoning it and moving it to -FailedPath.
50+
51+
.PARAMETER MailFailedRetention
52+
How long we keep an abandoned email around before removing it entirely.
4553
4654
.PARAMETER SmtpServer
4755
The mailserver to use for sending emails.
@@ -57,6 +65,13 @@
5765
.PARAMETER RecipientDefault
5866
Default email address to send the email to, if the individual script queuing the email does not specify one.
5967
68+
.PARAMETER UseSSL
69+
Use SSL for sending emails.
70+
71+
.PARAMETER NoLogging
72+
Disables logging.
73+
Unless specified, this setup step will also prepare the windows eventlog by creating a dedicated eventlog for MailDaemon.
74+
6075
.EXAMPLE
6176
PS C:\> Install-MDDaemon -ComputerName DC1, DC2, DC3 -TaskUser $cred -DaemonUser "DOMAIN\MailDaemon" -SmtpServer 'mail.domain.org' -SenderDefault 'daemon@domain.org' -RecipientDefault 'helpdesk-t2@domain.org'
6277
@@ -83,6 +98,9 @@
8398

8499
[string]
85100
$SentPath,
101+
102+
[string]
103+
$FailedPath,
86104

87105
[string]
88106
$DaemonUser,
@@ -92,6 +110,12 @@
92110

93111
[Timespan]
94112
$MailSentRetention,
113+
114+
[Timespan]
115+
$MailAbandonThreshold,
116+
117+
[Timespan]
118+
$MailFailedRetention,
95119

96120
[string]
97121
$SmtpServer,
@@ -103,11 +127,16 @@
103127
$SenderCredential,
104128

105129
[string]
106-
$RecipientDefault
130+
$RecipientDefault,
131+
132+
[switch]
133+
$UseSSL,
134+
135+
[switch]
136+
$NoLogging
107137
)
108138

109-
begin
110-
{
139+
begin {
111140
#region Repetitions (ugly)
112141
# Specifying repetitions directly in the commandline is ugly.
113142
# It ignores explicit settings and requires copying the repetition object from another task.
@@ -155,9 +184,9 @@
155184
#endregion Repetitions (ugly)
156185

157186
#region Setup Task Configuration
158-
if (-not $NoTask)
159-
{
187+
if (-not $NoTask) {
160188
$action = New-ScheduledTaskAction -Execute powershell.exe -Argument "-NoProfile -Command Invoke-MDDaemon"
189+
if ($NoLogging) { $action = New-ScheduledTaskAction -Execute powershell.exe -Argument "-NoProfile -Command Invoke-MDDaemon -NoLogging" }
161190
$triggers = @()
162191
$triggers += New-ScheduledTaskTrigger -AtStartup -RandomDelay "00:15:00"
163192
$triggers += New-ScheduledTaskTrigger -At "00:00:00" -Daily
@@ -173,21 +202,15 @@
173202
TaskName = 'MailDaemon'
174203
InputObject = $taskItem
175204
}
176-
if ($TaskUser)
177-
{
205+
if ($TaskUser) {
178206
$parametersRegister["User"] = $TaskUser.UserName
179207
$parametersRegister["Password"] = $TaskUser.GetNetworkCredential().Password
180208
}
181209
}
182210
#endregion Setup Task Configuration
183211

184212
#region Preparing Parameters
185-
$parameters = @{ }
186-
foreach ($key in $PSBoundParameters.Keys)
187-
{
188-
if ($key -notin 'PickupPath', 'SentPath', 'MailSentRetention', 'SmtpServer', 'SenderDefault', 'RecipientDefault') { continue }
189-
$parameters[$key] = $PSBoundParameters[$key]
190-
}
213+
$parameters = $PSBoundParameters | ConvertTo-PSFHashtable -Include 'PickupPath', 'SentPath', 'FailedPath', 'MailSentRetention', 'MailAbandonThreshold', 'MailFailedRetention', 'SmtpServer', 'SenderDefault', 'RecipientDefault', 'UseSSL'
191214

192215
$paramMainInstallCall = @{
193216
ArgumentList = $parameters
@@ -217,8 +240,7 @@
217240
#endregion The Main Setup Scriptblock
218241
}
219242

220-
process
221-
{
243+
process {
222244
#region Ensure Modules are installed
223245
$testResults = Test-Module -ComputerName $ComputerName -Credential $Credential -Module @{
224246
MailDaemon = $script:ModuleVersion
@@ -227,11 +249,9 @@
227249

228250
$failedTests = $testResults | Where-Object Success -EQ $false
229251

230-
if ($failedTests)
231-
{
252+
if ($failedTests) {
232253
$grouped = $failedTests | Group-Object Name
233-
foreach ($groupSet in $grouped)
234-
{
254+
foreach ($groupSet in $grouped) {
235255
Copy-Module -ModuleName (Get-Module $groupSet.Name).ModuleBase -ToComputer $groupSet.Group.ComputerName
236256
}
237257
}
@@ -242,33 +262,45 @@
242262
Invoke-PSFCommand @paramMainInstallCall
243263

244264
#region Securely store credentials
245-
if ($PSBoundParameters.ContainsKey('SenderCredential'))
246-
{
265+
if ($PSBoundParameters.ContainsKey('SenderCredential')) {
247266
$parametersSave = @{
248-
ComputerName = $ComputerName
249-
Credential = $SenderCredential
250-
Path = 'C:\ProgramData\PowerShell\MailDaemon\senderCredentials.clixml'
267+
ComputerName = $ComputerName
268+
TargetCredential = $SenderCredential
269+
Path = 'C:\ProgramData\PowerShell\MailDaemon\senderCredentials.clixml'
251270
}
271+
if ($Credential) { $parametersSave['Credential'] = $Credential }
252272
if ($TaskUser) { $parametersSave['AccessAccount'] = $TaskUser }
253273
Save-MDCredential @parametersSave
254274

255-
$parametersInvoke = @{ $parametersInvoke['ComputerName'] = $ComputerName }
275+
$parametersInvoke = @{ ComputerName = $ComputerName }
276+
if ($Credential) { $parametersInvoke['Credential'] = $Credential }
256277
Invoke-PSFCommand @parametersInvoke -ScriptBlock {
257278
Set-MDDaemon -SenderCredentialPath "C:\ProgramData\PowerShell\MailDaemon\senderCredentials.clixml"
258279
}
259280
}
260281
#endregion Securely store credentials
282+
283+
#region Setup Logging
284+
if (-not $NoLogging) {
285+
Invoke-PSFCommand @parametersInvoke -ScriptBlock {
286+
if ($PSVersionTable.PSVersion.Major -gt 5 -and -not $IsWindows) { return }
287+
Set-PSFLoggingProvider -Name eventlog -InstanceName MailDaemonInvoke -LogName MailDaemon -Source MailDaemon -Enabled $true -Wait
288+
Write-PSFMessage -Message "Setting up MailDaemon logging"
289+
Disable-PSFLoggingProvider -Name eventlog -InstanceName MailDaemonInvoke
290+
}
291+
}
292+
#endregion Setup Logging
261293

262294
#region Setup Task
263-
if (-not $NoTask)
264-
{
265-
foreach ($computerObject in $ComputerName)
266-
{
267-
if ($ComputerName.Type -like 'CimSession') { $parametersRegister["CimSession"] = $computerObject.InputObject }
268-
elseif (-not $ComputerName.IsLocalhost) { $parametersRegister["CimSession"] = $ComputerName }
269-
270-
$null = Register-ScheduledTask @parametersRegister
271-
}
295+
if (-not $NoTask) {
296+
Invoke-PSFCommand @parametersInvoke -ScriptBlock {
297+
param ($ParametersRegister)
298+
299+
$taskObject = Get-ScheduledTask -TaskName $ParametersRegister.TaskName -ErrorAction Ignore
300+
if ($taskObject) { $taskObject | Unregister-ScheduledTask }
301+
302+
$null = Register-ScheduledTask @ParametersRegister
303+
} -ArgumentList $parametersRegister
272304
}
273305
#endregion Setup Task
274306
}

0 commit comments

Comments
 (0)