This commit is contained in:
beo3000 2026-03-18 18:30:52 +01:00
parent fcc24167db
commit 1ab99402b6
5 changed files with 315 additions and 1 deletions

View File

@ -12,7 +12,10 @@ PowerShell-based automation that reads emails via Microsoft Graph API and files
```
scripts/
Process-MailRules.ps1 # Main entry point — processes emails against rules
Process-MailRules.ps1 # Main entry point -- processes emails against rules
Run-ServiceLoop.ps1 # Service wrapper -- infinite loop calling Process-MailRules
Install-Service.ps1 # Registers Windows service via NSSM (run as Admin)
Uninstall-Service.ps1 # Removes Windows service via NSSM (run as Admin)
Test-SharePointUpload.ps1 # Manual test script for SharePoint upload
Test-Connection.ps1 # Connection/auth test
GraphHelper.psm1 # Graph API auth + mail operations

View File

@ -116,6 +116,62 @@
"unreadOnly": false
},
"actions": {
"onSuccess": {
"markAsRead": true,
"moveToFolder": "deleteditems"
}
}
},
{
"id": "sfuserconnector-results-loeschen",
"enabled": true,
"name": "SFUserConnector Connector Results loeschen",
"description": "SFUserConnector Connector Results von SuccessFactors in den Papierkorb verschieben",
"match": {
"from": "learning@successfactors.eu",
"subject": "SFUserConnector - Connector Results",
"unreadOnly": false
},
"actions": {
"onSuccess": {
"markAsRead": true,
"moveToFolder": "deleteditems"
}
}
},
{
"id": "sap-user-zaduser-loeschen",
"enabled": true,
"name": "SAP-User nicht in ZADUSER loeschen",
"description": "Automatische SAP-User-nicht-in-ZADUSER-Mails von noreply@krah-gruppe.de in den Papierkorb verschieben",
"match": {
"from": "noreply@krah-gruppe.de",
"subject": "SAP-User nicht in ZADUSER",
"unreadOnly": false
},
"actions": {
"onSuccess": {
"markAsRead": true,
"moveToFolder": "deleteditems"
}
}
},
{
"id": "ebnerstolz-newsletter-loeschen",
"enabled": true,
"name": "Ebner Stolz Newsletter loeschen",
"description": "Newsletter von Ebner Stolz in den Papierkorb verschieben",
"match": {
"from": "newsletter@newsletter.ebnerstolz.de",
"unreadOnly": false
},
"actions": {
"onSuccess": {
"markAsRead": true,

100
scripts/Install-Service.ps1 Normal file
View File

@ -0,0 +1,100 @@
#Requires -Version 5.1
#Requires -RunAsAdministrator
<#
.SYNOPSIS
Installs the MailOrganizer Windows service via NSSM.
.DESCRIPTION
Registers a Windows service that runs Run-ServiceLoop.ps1 via NSSM.
NSSM must be available in PATH or specified via -NssmPath.
.PARAMETER ServiceName
Name of the Windows service (default: MailOrganizer)
.PARAMETER NssmPath
Path to nssm.exe (default: looks in PATH, then tools\nssm.exe)
.EXAMPLE
.\Install-Service.ps1
.\Install-Service.ps1 -ServiceName "MailOrganizer-Test" -NssmPath "C:\tools\nssm.exe"
#>
param(
[string]$ServiceName = "MailOrganizer",
[string]$NssmPath
)
$ErrorActionPreference = "Stop"
# --- Locate NSSM ---
if ($NssmPath -and (Test-Path $NssmPath)) {
$nssm = $NssmPath
}
elseif (Get-Command nssm -ErrorAction SilentlyContinue) {
$nssm = (Get-Command nssm).Source
}
else {
$toolsPath = Join-Path (Split-Path $PSScriptRoot -Parent) "tools\nssm.exe"
if (Test-Path $toolsPath) {
$nssm = $toolsPath
}
else {
Write-Host "ERROR: NSSM not found. Provide -NssmPath, add to PATH, or place in tools\nssm.exe" -ForegroundColor Red
exit 1
}
}
Write-Host "Using NSSM: $nssm"
# --- Check if service already exists ---
$existing = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($existing) {
Write-Host "ERROR: Service '$ServiceName' already exists (Status: $($existing.Status)). Uninstall first." -ForegroundColor Red
exit 1
}
# --- Paths ---
$scriptDir = $PSScriptRoot
$projectRoot = Split-Path $scriptDir -Parent
$loopScript = Join-Path $scriptDir "Run-ServiceLoop.ps1"
$logDir = Join-Path $projectRoot "logs"
if (-not (Test-Path $logDir)) {
New-Item -ItemType Directory -Path $logDir -Force | Out-Null
}
$powershell = Join-Path $env:SystemRoot "System32\WindowsPowerShell\v1.0\powershell.exe"
# --- Install service ---
Write-Host "Installing service '$ServiceName'..."
& $nssm install $ServiceName $powershell "-ExecutionPolicy Bypass -NoProfile -File `"$loopScript`""
if ($LASTEXITCODE -ne 0) { throw "NSSM install failed" }
# Configure working directory
& $nssm set $ServiceName AppDirectory $scriptDir
# Configure logging
$stdoutLog = Join-Path $logDir "service_stdout.log"
$stderrLog = Join-Path $logDir "service_stderr.log"
& $nssm set $ServiceName AppStdout $stdoutLog
& $nssm set $ServiceName AppStderr $stderrLog
& $nssm set $ServiceName AppStdoutCreationDisposition 4
& $nssm set $ServiceName AppStderrCreationDisposition 4
& $nssm set $ServiceName AppRotateFiles 1
& $nssm set $ServiceName AppRotateOnline 1
& $nssm set $ServiceName AppRotateBytes 5242880
# Set startup type to Automatic
& $nssm set $ServiceName Start SERVICE_AUTO_START
# Set description
& $nssm set $ServiceName Description "Mail-Organizer: Processes emails and files attachments to SharePoint"
Write-Host ""
Write-Host "Service '$ServiceName' installed successfully." -ForegroundColor Green
Write-Host " Stdout log: $stdoutLog"
Write-Host " Stderr log: $stderrLog"
Write-Host ""
Write-Host "To start: Start-Service $ServiceName"
Write-Host "To check: Get-Service $ServiceName"

View File

@ -0,0 +1,93 @@
#Requires -Version 5.1
<#
.SYNOPSIS
Service loop wrapper -- runs Process-MailRules.ps1 at a configurable interval.
.DESCRIPTION
Designed to be launched by NSSM as a Windows service. Runs Process-MailRules.ps1
in an infinite loop, sleeping ServiceIntervalMinutes between runs.
Handles graceful shutdown via Ctrl+C / console close events.
.PARAMETER ConfigPath
Path to config directory (default: ..\config relative to script)
.EXAMPLE
.\Run-ServiceLoop.ps1
.\Run-ServiceLoop.ps1 -ConfigPath "C:\work\mail-organizer\config"
#>
param(
[string]$ConfigPath = (Join-Path $PSScriptRoot "..\config")
)
# --- Load Logger ---
Import-Module (Join-Path $PSScriptRoot "Logger.psm1") -Force
$logDir = Join-Path (Split-Path $ConfigPath -Parent) "logs"
Initialize-Logger -LogDirectory $logDir -Level "Info"
# --- Read interval from settings ---
$settingsFile = Join-Path $ConfigPath "settings.json"
if (-not (Test-Path $settingsFile)) {
Write-Log "Settings not found: $settingsFile" -Level Error
exit 1
}
$settings = Get-Content $settingsFile -Raw | ConvertFrom-Json
$intervalMinutes = if ($settings.ServiceIntervalMinutes) { $settings.ServiceIntervalMinutes } else { 5 }
# --- Graceful shutdown flag ---
$script:Running = $true
$cancelHandler = {
$script:Running = $false
Write-Log "Shutdown signal received, stopping after current run..." -Level Warn
}
# Register Ctrl+C / console close handler
try {
[Console]::TreatControlCAsInput = $false
$null = Register-EngineEvent -SourceIdentifier PowerShell.Exiting -Action $cancelHandler -ErrorAction SilentlyContinue
} catch {
# Ignore if not supported in this host
}
trap {
$script:Running = $false
Write-Log "Service loop terminated by signal" -Level Warn
break
}
# --- Main loop ---
$processScript = Join-Path $PSScriptRoot "Process-MailRules.ps1"
if (-not (Test-Path $processScript)) {
Write-Log "Process-MailRules.ps1 not found: $processScript" -Level Error
exit 1
}
Write-Log "Service loop started (interval: $intervalMinutes min)"
while ($script:Running) {
Write-Log "Running Process-MailRules.ps1..."
try {
& $processScript -ConfigPath $ConfigPath
Write-Log "Process-MailRules.ps1 completed successfully"
}
catch {
Write-Log "Process-MailRules.ps1 failed: $_" -Level Error
}
if (-not $script:Running) { break }
Write-Log "Waiting $intervalMinutes minute(s) until next run..."
# Sleep in 1-second intervals for responsive shutdown
$sleepSeconds = $intervalMinutes * 60
for ($i = 0; $i -lt $sleepSeconds; $i++) {
if (-not $script:Running) { break }
Start-Sleep -Seconds 1
}
}
Write-Log "Service loop stopped"

View File

@ -0,0 +1,62 @@
#Requires -Version 5.1
#Requires -RunAsAdministrator
<#
.SYNOPSIS
Stops and removes the MailOrganizer Windows service via NSSM.
.PARAMETER ServiceName
Name of the Windows service (default: MailOrganizer)
.PARAMETER NssmPath
Path to nssm.exe (default: looks in PATH, then tools\nssm.exe)
.EXAMPLE
.\Uninstall-Service.ps1
.\Uninstall-Service.ps1 -ServiceName "MailOrganizer-Test"
#>
param(
[string]$ServiceName = "MailOrganizer",
[string]$NssmPath
)
$ErrorActionPreference = "Stop"
# --- Locate NSSM ---
if ($NssmPath -and (Test-Path $NssmPath)) {
$nssm = $NssmPath
}
elseif (Get-Command nssm -ErrorAction SilentlyContinue) {
$nssm = (Get-Command nssm).Source
}
else {
$toolsPath = Join-Path (Split-Path $PSScriptRoot -Parent) "tools\nssm.exe"
if (Test-Path $toolsPath) {
$nssm = $toolsPath
}
else {
Write-Host "ERROR: NSSM not found. Provide -NssmPath, add to PATH, or place in tools\nssm.exe" -ForegroundColor Red
exit 1
}
}
# --- Check if service exists ---
$existing = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if (-not $existing) {
Write-Host "Service '$ServiceName' not found. Nothing to uninstall." -ForegroundColor Yellow
exit 0
}
# --- Stop service if running ---
if ($existing.Status -eq "Running") {
Write-Host "Stopping service '$ServiceName'..."
& $nssm stop $ServiceName
Start-Sleep -Seconds 2
}
# --- Remove service ---
Write-Host "Removing service '$ServiceName'..."
& $nssm remove $ServiceName confirm
if ($LASTEXITCODE -ne 0) { throw "NSSM remove failed" }
Write-Host "Service '$ServiceName' removed successfully." -ForegroundColor Green