upd
This commit is contained in:
parent
fcc24167db
commit
1ab99402b6
|
|
@ -12,7 +12,10 @@ PowerShell-based automation that reads emails via Microsoft Graph API and files
|
||||||
|
|
||||||
```
|
```
|
||||||
scripts/
|
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-SharePointUpload.ps1 # Manual test script for SharePoint upload
|
||||||
Test-Connection.ps1 # Connection/auth test
|
Test-Connection.ps1 # Connection/auth test
|
||||||
GraphHelper.psm1 # Graph API auth + mail operations
|
GraphHelper.psm1 # Graph API auth + mail operations
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,62 @@
|
||||||
"unreadOnly": false
|
"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": {
|
"actions": {
|
||||||
"onSuccess": {
|
"onSuccess": {
|
||||||
"markAsRead": true,
|
"markAsRead": true,
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
@ -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"
|
||||||
|
|
@ -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
|
||||||
Loading…
Reference in New Issue