Update 4.0 - Zusammenfuehrung AD/Local, Config-Datei, Ntfy-Support
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
27
LICENSE
27
LICENSE
@@ -1,11 +1,28 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 scriptos
|
||||
Copyright ©
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
Name: Patrick Asmus (scriptos)
|
||||
Email: support@techniverse.net
|
||||
Website: https://www.patrick-asmus.de
|
||||
Blog: https://www.cleveradmin.de
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
---
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
Patrick Asmus | www.media-techport.de
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
49
README.md
49
README.md
@@ -1,23 +1,40 @@
|
||||
# Benachrichtigungsmail bei Anmeldung per Remote Desktop Protokoll
|
||||
<p align="center">
|
||||
<a href="https://techniverse.net">
|
||||
<img src="https://assets.techniverse.net/f1/git/graphics/repo-techniverse-logo.png" alt="Techniverse Community" height="70" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<h1 align="center">RDP Login Notifier</h1>
|
||||
|
||||
**1. Skript: rdp-access-mail-notification.v3.ad.ps1**
|
||||
<h4 align="center">
|
||||
Versendet Benachrichtigungen (E-Mail und/oder Ntfy Push) wenn sich jemand per RDP auf einem Windows-System anmeldet.
|
||||
</h4>
|
||||
|
||||
- **Beschreibung:** Dieses Skript sendet eine E-Mail-Benachrichtigung an alle Mitglieder einer Sicherheitsgruppe, wenn sich jemand per Remote Desktop Protocol (RDP) auf einem Windows-System anmeldet. Es extrahiert Informationen aus dem Ereignisprotokoll und informiert die Benutzer über die Anmeldung, einschließlich Datum, Uhrzeit, Domäne, Benutzer und IP-Adresse des Clients.
|
||||
<h6 align="center">
|
||||
<a href="https://www.cleveradmin.de">🏰 Website</a>
|
||||
·
|
||||
<a href="https://techniverse.net">📰 Community</a>
|
||||
·
|
||||
<a href="https://social.techniverse.net/@donnerwolke">🐘 Mastodon</a>
|
||||
·
|
||||
<a href="https://matrix.to/#/#support:techniverse.net">💬 Support</a>
|
||||
</h6>
|
||||
<br><br>
|
||||
|
||||
**Voraussetzung:**
|
||||
Folgendes Modul muss auf allen Systemen, auf denen das Script läuft, installiert sein:
|
||||
## Schnellstart
|
||||
|
||||
Dies kann man einfach per Powershell machen:
|
||||
1. [Voraussetzungen](docs/prerequisites.md) pruefen (RSAT-Modul bei AD-Modus installieren)
|
||||
2. `rdp-access-notification.ps1`, `config.conf` und `rdp-access-notification.xml` nach `C:\scripts\rdp-login-notifier` kopieren
|
||||
3. `config.conf` anpassen — siehe [Konfiguration](docs/configuration.md)
|
||||
4. Task-Scheduler-Aufgabe einrichten — siehe [Task-Scheduler](docs/task-scheduler.md)
|
||||
|
||||
Install-WindowsFeature RSAT-AD-PowerShell
|
||||
<br><br>
|
||||
<p align="center">
|
||||
<img src="https://assets.techniverse.net/f1/git/graphics/gray0-catonline.svg" alt="">
|
||||
</p>
|
||||
|
||||
|
||||
**2. Skript: rdp-access-mail-notification.v3.local.ps1**
|
||||
|
||||
- **Beschreibung:** Dieses Skript sendet eine E-Mail-Benachrichtigung, wenn sich jemand per Remote Desktop Protocol (RDP) auf einem Windows-System anmeldet. Es verwendet Informationen aus dem Ereignisprotokoll, um die Benutzer über die Anmeldung zu informieren, einschließlich Datum, Uhrzeit, Domäne, Benutzer und IP-Adresse des Clients. Die Benachrichtigung geht an eine vordefinierte Empfängeradresse.
|
||||
|
||||
|
||||
Das ganze könnte dann so aussehen:
|
||||
|
||||

|
||||
<p align="center">
|
||||
<sub>
|
||||
© Patrick Asmus · Techniverse Network · <a href="./LICENSE">Lizenz</a>
|
||||
</sub>
|
||||
</p>
|
||||
@@ -1,92 +0,0 @@
|
||||
# Konfigurationsparameter
|
||||
$SMTPServer = "smtp.media-techport.int"
|
||||
$FromName = "Media-Techport.DE | Notification Service"
|
||||
$FromEmail = "noreply@media-techport.de"
|
||||
$SecurityGroupDN = "CN=GG-MailAT_RDP-Access,OU=Benachrichtigungsgruppen,OU=Benutzergruppen,DC=media-techport,DC=int"
|
||||
|
||||
# Überwachung der Ereignisprotokolle
|
||||
$EventLogName = "Security"
|
||||
$EventID = 1149 # Event ID für Anmeldungen
|
||||
|
||||
# Filter für Ereignisse
|
||||
$FilterXML = @"
|
||||
<QueryList>
|
||||
<Query Id="0" Path="Security">
|
||||
<Select Path="Security">
|
||||
*[System[(EventID=$EventID)]]
|
||||
and
|
||||
*[EventData[Data[@Name='LogonType'] and (Data='10')]]
|
||||
and
|
||||
*[EventData[Data[@Name='TargetUserName'] and (Data!='$null')]]
|
||||
and
|
||||
*[EventData[Data[@Name='TargetDomainName'] and (Data='$env:USERDOMAIN')]]
|
||||
</Select>
|
||||
</Query>
|
||||
</QueryList>
|
||||
"@
|
||||
|
||||
# Funktion zum Senden von E-Mails
|
||||
function Send-Email {
|
||||
param(
|
||||
[string]$To,
|
||||
[string]$Subject,
|
||||
[string]$Message,
|
||||
[string]$GivenName,
|
||||
[string]$Surname
|
||||
)
|
||||
$EmailBody = @"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
|
||||
<style>
|
||||
p {
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p><img src="https://assets.media-techport.de/logos/main/LogoSchwarz.png" alt="Logo-Schwarz" width="266" height="81" /></p>
|
||||
<p><span style="font-size: 14pt;"><strong>Hallo $GivenName $Surname,</strong></span></p>
|
||||
<p>$Message</p>
|
||||
</body>
|
||||
</html>
|
||||
"@
|
||||
|
||||
Send-MailMessage -SmtpServer $SMTPServer -From "$FromName <$FromEmail>" -To $To -Subject $Subject -Body $EmailBody -BodyAsHtml -Encoding "UTF8"
|
||||
}
|
||||
|
||||
# Hauptüberwachungsschleife
|
||||
$events = Get-WinEvent -LogName $EventLogName -FilterXPath $FilterXML
|
||||
foreach ($event in $events) {
|
||||
$eventTime = $event.TimeCreated
|
||||
$clientIP = $event.Properties[18].Value # IP-Adresse des Clients
|
||||
$serverIP = $env:COMPUTERNAME # IP-Adresse des Servers
|
||||
$user = $event.Properties[5].Value
|
||||
$domain = $event.Properties[6].Value
|
||||
|
||||
$userEmails = Get-ADGroupMember -Identity $SecurityGroupDN | Where-Object { $_.objectClass -eq "user" } | ForEach-Object {
|
||||
$userDetails = Get-ADUser $_.DistinguishedName -Properties GivenName, Surname, EmailAddress
|
||||
$GivenName = $userDetails.GivenName
|
||||
$Surname = $userDetails.Surname
|
||||
$EmailAddress = $userDetails.EmailAddress
|
||||
[PSCustomObject]@{
|
||||
EmailAddress = $EmailAddress
|
||||
GivenName = $GivenName
|
||||
Surname = $Surname
|
||||
}
|
||||
}
|
||||
|
||||
$emailMessage = @"
|
||||
Es wurde eine Anmeldung per RDP auf dem Windows Server <b>$serverIP</b> registriert.<br><br>
|
||||
<b>Datum:</b> $($eventTime.ToString('dd.MM.yyyy'))<br>
|
||||
<b>Uhrzeit:</b> $($eventTime.ToString('HH:mm:ss'))<br>
|
||||
<b>Domäne:</b> $domain<br>
|
||||
<b>Benutzer:</b> $user<br>
|
||||
<b>IP-Adresse des Clients:</b> $clientIP
|
||||
"@
|
||||
foreach ($userDetail in $userEmails) {
|
||||
Send-Email -To $userDetail.EmailAddress -Subject "RDP-Anmeldung auf $serverIP registriert" -Message $emailMessage -GivenName $userDetail.GivenName -Surname $userDetail.Surname
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
# Konfigurationsparameter
|
||||
$SMTPServer = "smtp.media-techport.int"
|
||||
$FromName = "Media-Techport.DE | Notification Service"
|
||||
$FromEmail = "noreply@media-techport.de"
|
||||
$SecurityGroupDN = "CN=GG-MailAT_RDP-Access,OU=Benachrichtigungsgruppen,OU=Benutzergruppen,DC=media-techport,DC=int"
|
||||
|
||||
# Funktion zum Senden von E-Mails
|
||||
function Send-Email {
|
||||
param(
|
||||
[string]$To,
|
||||
[string]$Subject,
|
||||
[string]$Message
|
||||
)
|
||||
|
||||
Send-MailMessage -SmtpServer $SMTPServer -From "$FromName <$FromEmail>" -To $To -Subject $Subject -Body $Message -BodyAsHtml -Encoding "UTF8"
|
||||
}
|
||||
|
||||
# Parameter aus dem Ereignisprotokoll auslesen
|
||||
$eventID = 1149 # Event ID für RDP-Anmeldungen
|
||||
$eventLogName = "Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational"
|
||||
|
||||
$latestEvent = Get-WinEvent -LogName $eventLogName -FilterXPath "<QueryList><Query Id='0' Path='$eventLogName'><Select Path='$eventLogName'>*[System[(EventID=$eventID)]]</Select></Query></QueryList>" | Select-Object -First 1
|
||||
|
||||
if ($latestEvent) {
|
||||
$xml = [xml]$latestEvent.ToXml()
|
||||
|
||||
if ($xml.Event.UserData) {
|
||||
$user = $xml.Event.UserData.EventXML.Param1
|
||||
$domain = $xml.Event.UserData.EventXML.Param2
|
||||
$clientIP = $xml.Event.UserData.EventXML.Param3
|
||||
|
||||
$eventTime = $latestEvent.TimeCreated
|
||||
$computerName = $latestEvent.MachineName
|
||||
|
||||
$userEmails = Get-ADGroupMember -Identity $SecurityGroupDN | Where-Object { $_.objectClass -eq "user" } | ForEach-Object {
|
||||
Get-ADUser $_.DistinguishedName -Properties EmailAddress | Select-Object -ExpandProperty EmailAddress
|
||||
}
|
||||
|
||||
$emailMessage = @"
|
||||
Es wurde eine Anmeldung per RDP auf dem Windows Server $computerName registriert.<br><br>
|
||||
<b>Datum:</b> $($eventTime.ToString('dd.MM.yyyy'))<br>
|
||||
<b>Uhrzeit:</b> $($eventTime.ToString('HH:mm:ss'))<br>
|
||||
<b>Domäne:</b> $domain<br>
|
||||
<b>Benutzer:</b> $user<br>
|
||||
<b>IP-Adresse des Clients:</b> $clientIP
|
||||
"@
|
||||
|
||||
foreach ($email in $userEmails) {
|
||||
Send-Email -To $email -Subject "RDP-Anmeldung auf $computerName registriert" -Message $emailMessage
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -1,92 +0,0 @@
|
||||
# Script Name: rdp-access-mail-notification.v3.ad.ps1
|
||||
# Beschreibung: Schickt allen Mitgliedern einer GG eine Mail, wenn sich jemand per RDP auf einem System anmeldet
|
||||
# Aufruf: -
|
||||
# Autor: Patrick Asmus
|
||||
# Web: https://www.media-techport.de
|
||||
# Git-Reposit.: https://git.media-techport.de/scriptos/private-script-collection.git
|
||||
# Version: 3.1
|
||||
# Datum: 22.10.2023
|
||||
# Modifikation: Umzug ins neue Repo und damit verbundene Anpassungen
|
||||
#####################################################
|
||||
|
||||
# Konfigurationsparameter
|
||||
$SMTPServer = "smtp.media-techport.int"
|
||||
$FromName = "Media-Techport.DE | Notification Service"
|
||||
$FromEmail = "noreply@media-techport.de"
|
||||
$SecurityGroupDN = "CN=GG-MailAT_RDP-Access,OU=Benachrichtigungsgruppen,OU=Benutzergruppen,DC=media-techport,DC=int"
|
||||
$LogoURL = "https://assets.media-techport.de/logos/main/LogoSchwarz.png"
|
||||
|
||||
# Funktion zum Senden von E-Mails
|
||||
function Send-Email {
|
||||
param(
|
||||
[string]$To,
|
||||
[string]$Subject,
|
||||
[string]$HTMLBody
|
||||
)
|
||||
|
||||
$emailMessage = @"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
|
||||
</head>
|
||||
<body>
|
||||
$HTMLBody
|
||||
</body>
|
||||
</html>
|
||||
"@
|
||||
|
||||
Send-MailMessage -SmtpServer $SMTPServer -From "$FromName <$FromEmail>" -To $To -Subject $Subject -Body $emailMessage -BodyAsHtml -Encoding "UTF8"
|
||||
}
|
||||
|
||||
# Parameter aus dem Ereignisprotokoll auslesen
|
||||
$eventID = 1149 # Event ID für RDP-Anmeldungen
|
||||
$eventLogName = "Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational"
|
||||
|
||||
$latestEvent = Get-WinEvent -LogName $eventLogName -FilterXPath "<QueryList><Query Id='0' Path='$eventLogName'><Select Path='$eventLogName'>*[System[(EventID=$eventID)]]</Select></Query></QueryList>" | Select-Object -First 1
|
||||
|
||||
if ($latestEvent) {
|
||||
$xml = [xml]$latestEvent.ToXml()
|
||||
|
||||
if ($xml.Event.UserData) {
|
||||
$user = $xml.Event.UserData.EventXML.Param1
|
||||
$domain = $xml.Event.UserData.EventXML.Param2
|
||||
$clientIP = $xml.Event.UserData.EventXML.Param3
|
||||
|
||||
$eventTime = $latestEvent.TimeCreated
|
||||
$computerName = $latestEvent.MachineName
|
||||
|
||||
$userEmails = Get-ADGroupMember -Identity $SecurityGroupDN | Where-Object { $_.objectClass -eq "user" } | ForEach-Object {
|
||||
$userDetails = Get-ADUser $_.DistinguishedName -Properties GivenName, Surname, EmailAddress
|
||||
$GivenName = $userDetails.GivenName
|
||||
$Surname = $userDetails.Surname
|
||||
$EmailAddress = $userDetails.EmailAddress
|
||||
[PSCustomObject]@{
|
||||
EmailAddress = $EmailAddress
|
||||
GivenName = $GivenName
|
||||
Surname = $Surname
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($userDetails in $userEmails) {
|
||||
$GivenName = $userDetails.GivenName
|
||||
$Surname = $userDetails.Surname
|
||||
$EmailAddress = $userDetails.EmailAddress
|
||||
|
||||
$HTMLBody = @"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<p><img src="$LogoURL" alt="" width="265" height="81" /></p>
|
||||
<p><strong>Hallo $GivenName $Surname,</strong></p>
|
||||
<p>Es wurde eine Anmeldung per RDP auf der Windows Maschine <strong>$computerName</strong> registriert.<br /><br /><strong>Datum:</strong> $($eventTime.ToString('dd.MM.yyyy'))<br /><strong>Uhrzeit:</strong> $($eventTime.ToString('HH:mm:ss'))<br /><strong>Domäne:</strong> $domain<br /><strong>Benutzer:</strong> $user<br /><strong>IP-Adresse des Clients:</strong> $clientIP</p>
|
||||
</body>
|
||||
</html>
|
||||
"@
|
||||
|
||||
Send-Email -To $EmailAddress -Subject "RDP-Anmeldung auf $computerName registriert" -HTMLBody $HTMLBody
|
||||
}
|
||||
}
|
||||
}
|
||||
26
config.conf
Normal file
26
config.conf
Normal file
@@ -0,0 +1,26 @@
|
||||
# RDP Access Notification - Konfiguration
|
||||
# Dokumentation: docs/configuration.md
|
||||
|
||||
# Modus: ad | local
|
||||
MODE=ad
|
||||
|
||||
# Benachrichtigungsmethoden: email, ntfy oder email,ntfy
|
||||
NOTIFICATION_METHODS=email
|
||||
|
||||
# E-Mail
|
||||
SMTP_SERVER=
|
||||
SMTP_FROM_NAME=
|
||||
SMTP_FROM_EMAIL=
|
||||
|
||||
# AD-Modus (nur bei MODE=ad)
|
||||
AD_SECURITY_GROUP_DN=
|
||||
|
||||
# Local-Modus (nur bei MODE=local, Format: Name,Email;Name,Email)
|
||||
LOCAL_RECIPIENTS=
|
||||
|
||||
# Ntfy (nur wenn ntfy in NOTIFICATION_METHODS)
|
||||
NTFY_SERVER=https://ntfy.sh
|
||||
NTFY_TOPIC=
|
||||
NTFY_PRIORITY=3
|
||||
NTFY_TAGS=warning,computer
|
||||
NTFY_AUTH_TOKEN=
|
||||
92
docs/configuration.md
Normal file
92
docs/configuration.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# Konfiguration
|
||||
|
||||
Alle Einstellungen werden in der `config.conf` vorgenommen, die im selben Verzeichnis wie das Script liegen muss.
|
||||
|
||||
## Modus
|
||||
|
||||
| Wert | Beschreibung |
|
||||
|---|---|
|
||||
| `MODE=ad` | Empfaenger werden aus einer AD-Sicherheitsgruppe gelesen |
|
||||
| `MODE=local` | Empfaenger werden manuell in der Konfiguration definiert |
|
||||
|
||||
**RSAT-Modul installieren (nur fuer AD-Modus):**
|
||||
|
||||
```powershell
|
||||
Install-WindowsFeature RSAT-AD-PowerShell
|
||||
```
|
||||
|
||||
## Benachrichtigungsmethoden
|
||||
|
||||
Kommasepariert — einzeln oder kombiniert:
|
||||
|
||||
```
|
||||
NOTIFICATION_METHODS=email
|
||||
NOTIFICATION_METHODS=ntfy
|
||||
NOTIFICATION_METHODS=email,ntfy
|
||||
```
|
||||
|
||||
## E-Mail
|
||||
|
||||
| Key | Beschreibung |
|
||||
|---|---|
|
||||
| `SMTP_SERVER` | SMTP-Server Adresse |
|
||||
| `SMTP_FROM_NAME` | Anzeigename des Absenders |
|
||||
| `SMTP_FROM_EMAIL` | E-Mail-Adresse des Absenders |
|
||||
|
||||
Beispiel:
|
||||
|
||||
```
|
||||
SMTP_SERVER=smtp.example.com
|
||||
SMTP_FROM_NAME=Notification Service
|
||||
SMTP_FROM_EMAIL=noreply@example.com
|
||||
```
|
||||
|
||||
## AD-Modus
|
||||
|
||||
Nur relevant wenn `MODE=ad`.
|
||||
|
||||
| Key | Beschreibung |
|
||||
|---|---|
|
||||
| `AD_SECURITY_GROUP_DN` | Distinguished Name der AD-Sicherheitsgruppe, deren Mitglieder benachrichtigt werden |
|
||||
|
||||
Beispiel:
|
||||
|
||||
```
|
||||
AD_SECURITY_GROUP_DN=CN=Gruppe,OU=Gruppen,DC=domain,DC=local
|
||||
```
|
||||
|
||||
## Local-Modus
|
||||
|
||||
Nur relevant wenn `MODE=local`. Mehrere Empfaenger mit Semikolon trennen.
|
||||
|
||||
| Key | Beschreibung |
|
||||
|---|---|
|
||||
| `LOCAL_RECIPIENTS` | Empfaengerliste im Format `Name,Email;Name,Email` |
|
||||
|
||||
Beispiel:
|
||||
|
||||
```
|
||||
LOCAL_RECIPIENTS=Max Mustermann,max@example.com;Lisa Mueller,lisa@example.com
|
||||
```
|
||||
|
||||
## Ntfy Push-Benachrichtigung
|
||||
|
||||
Nur relevant wenn `ntfy` in `NOTIFICATION_METHODS` enthalten ist.
|
||||
|
||||
| Key | Beschreibung |
|
||||
|---|---|
|
||||
| `NTFY_SERVER` | URL des Ntfy-Servers |
|
||||
| `NTFY_TOPIC` | Ntfy-Topic |
|
||||
| `NTFY_PRIORITY` | Prioritaet 1-5 (1=min, 3=default, 5=max) |
|
||||
| `NTFY_TAGS` | Kommaseparierte Emoji-Tags |
|
||||
| `NTFY_AUTH_TOKEN` | Bearer-Token (leer lassen wenn nicht benoetigt) |
|
||||
|
||||
Beispiel:
|
||||
|
||||
```
|
||||
NTFY_SERVER=https://ntfy.sh
|
||||
NTFY_TOPIC=rdp-access
|
||||
NTFY_PRIORITY=3
|
||||
NTFY_TAGS=warning,computer
|
||||
NTFY_AUTH_TOKEN=tk_geheim123
|
||||
```
|
||||
51
docs/prerequisites.md
Normal file
51
docs/prerequisites.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Voraussetzungen
|
||||
|
||||
## PowerShell ExecutionPolicy
|
||||
|
||||
Windows blockiert standardmaessig die Ausfuehrung von PowerShell-Scripts. Es gibt zwei Moeglichkeiten, das Script ausfuehrbar zu machen:
|
||||
|
||||
**Variante 1 — Nur fuer die Task-Scheduler-Aufgabe (empfohlen):**
|
||||
|
||||
In der Aufgabe wird `-ExecutionPolicy Bypass` als Argument uebergeben. Das betrifft nur diese eine Ausfuehrung und aendert keine systemweite Einstellung. Details dazu in der [Task-Scheduler-Dokumentation](task-scheduler.md).
|
||||
|
||||
**Variante 2 — Systemweit erlauben:**
|
||||
|
||||
```powershell
|
||||
Set-ExecutionPolicy RemoteSigned -Scope LocalMachine
|
||||
```
|
||||
|
||||
## RSAT ActiveDirectory PowerShell-Modul
|
||||
|
||||
Das AD-Modul wird nur benoetigt, wenn `MODE=ad` in der `config.conf` gesetzt ist. Im Local-Modus (`MODE=local`) kann dieser Abschnitt uebersprungen werden.
|
||||
|
||||
### Windows Server
|
||||
|
||||
```powershell
|
||||
Install-WindowsFeature RSAT-AD-PowerShell
|
||||
```
|
||||
|
||||
Ein Neustart ist in der Regel nicht erforderlich.
|
||||
|
||||
### Windows Client (Windows 10 / 11 Pro oder Enterprise)
|
||||
|
||||
```powershell
|
||||
Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0
|
||||
```
|
||||
|
||||
Alternativ ueber DISM:
|
||||
|
||||
```cmd
|
||||
DISM /Online /Add-Capability /CapabilityName:Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0
|
||||
```
|
||||
|
||||
Nach der Installation pruefen, ob das Modul verfuegbar ist:
|
||||
|
||||
```powershell
|
||||
Get-Module -ListAvailable -Name ActiveDirectory
|
||||
```
|
||||
|
||||
### Wichtige Hinweise zum AD-Modus
|
||||
|
||||
- Das Zielsystem muss Mitglied der Domaene sein.
|
||||
- Das Script laeuft als `SYSTEM` (S-1-5-18) und nutzt das Computerkonto fuer AD-Abfragen. Dafuer sind keine separaten Credentials noetig.
|
||||
- Die Windows Home-Edition unterstuetzt weder RDP-Host noch RSAT und ist daher nicht kompatibel.
|
||||
67
docs/task-scheduler.md
Normal file
67
docs/task-scheduler.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# Task-Scheduler einrichten
|
||||
|
||||
Die Aufgabe wird durch das Windows-Event **1149** im Log `Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational` ausgeloest. Dieses Event wird bei jeder erfolgreichen RDP-Anmeldung geschrieben.
|
||||
|
||||
## Variante 1 — XML importieren (empfohlen)
|
||||
|
||||
Die mitgelieferte Datei `rdp-access-notification.xml` kann direkt importiert werden:
|
||||
|
||||
**Per PowerShell:**
|
||||
|
||||
```powershell
|
||||
Register-ScheduledTask -Xml (Get-Content "C:\scripts\rdp-access-notification.xml" -Raw) -TaskName "RDP Access Notification"
|
||||
```
|
||||
|
||||
**Per Aufgabenplanung (GUI):**
|
||||
|
||||
1. Aufgabenplanung oeffnen (`taskschd.msc`)
|
||||
2. Aktion > Aufgabe importieren
|
||||
3. Die Datei `rdp-access-notification.xml` auswaehlen
|
||||
4. Bei Bedarf den Pfad zum Script unter *Aktionen* anpassen
|
||||
|
||||
## Variante 2 — Manuell anlegen
|
||||
|
||||
### Allgemein
|
||||
|
||||
| Einstellung | Wert |
|
||||
|---|---|
|
||||
| Name | `RDP Access Notification` |
|
||||
| Ausfuehren als | `SYSTEM` |
|
||||
| Unabhaengig von der Benutzeranmeldung ausfuehren | Ja |
|
||||
| Mit hoechsten Privilegien ausfuehren | Nein |
|
||||
|
||||
### Trigger
|
||||
|
||||
| Einstellung | Wert |
|
||||
|---|---|
|
||||
| Trigger-Typ | Bei einem Ereignis |
|
||||
| Protokoll | `Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational` |
|
||||
| Quelle | `Microsoft-Windows-TerminalServices-RemoteConnectionManager` |
|
||||
| Ereignis-ID | `1149` |
|
||||
|
||||
### Aktion
|
||||
|
||||
| Einstellung | Wert |
|
||||
|---|---|
|
||||
| Programm/Script | `C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe` |
|
||||
| Argumente | `-ExecutionPolicy Bypass -File "C:\scripts\rdp-access-notification.ps1"` |
|
||||
|
||||
Der Parameter `-ExecutionPolicy Bypass` sorgt dafuer, dass das Script auch ohne systemweite Aenderung der ExecutionPolicy ausgefuehrt wird. Er gilt nur fuer diesen einen Prozess.
|
||||
|
||||
### Einstellungen
|
||||
|
||||
| Einstellung | Wert |
|
||||
|---|---|
|
||||
| Aufgabe bei Bedarf starten | Ja |
|
||||
| Aufgabe beenden, falls laenger als | 72 Stunden |
|
||||
| Nicht starten, falls im Akkubetrieb | Nein |
|
||||
|
||||
## Aufgabe testen
|
||||
|
||||
Nach dem Anlegen kann die Aufgabe manuell ausgeloest werden:
|
||||
|
||||
```powershell
|
||||
Start-ScheduledTask -TaskName "RDP Access Notification"
|
||||
```
|
||||
|
||||
Oder im Aufgabenplaner per Rechtsklick > *Ausfuehren*.
|
||||
Binary file not shown.
@@ -1,74 +0,0 @@
|
||||
# Script Name: rdp-access-mail-notification.v3.local.ps1
|
||||
# Beschreibung: Versendet eine Mail, wenn sich jemand per RDP auf einem System anmeldet
|
||||
# Aufruf: -
|
||||
# Autor: Patrick Asmus
|
||||
# Web: https://www.media-techport.de
|
||||
# Git-Reposit.: https://git.media-techport.de/scriptos/private-script-collection.git
|
||||
# Version: 3.1
|
||||
# Datum: 22.10.2023
|
||||
# Modifikation: Umzug ins neue Repo und damit verbundene Anpassungen
|
||||
#####################################################
|
||||
|
||||
# Konfigurationsparameter
|
||||
$SMTPServer = "smtp.media-techport.int"
|
||||
$FromName = "Media-Techport.DE | Notification Service"
|
||||
$FromEmail = "noreply@media-techport.de"
|
||||
$LogoURL = "https://assets.media-techport.de/logos/main/LogoSchwarz.png"
|
||||
$ManualRecipient = "system@media-techport.de"
|
||||
|
||||
# Funktion zum Senden von E-Mails
|
||||
function Send-Email {
|
||||
param(
|
||||
[string]$To,
|
||||
[string]$Subject,
|
||||
[string]$HTMLBody
|
||||
)
|
||||
|
||||
$emailMessage = @"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
|
||||
</head>
|
||||
<body>
|
||||
$HTMLBody
|
||||
</body>
|
||||
</html>
|
||||
"@
|
||||
|
||||
Send-MailMessage -SmtpServer $SMTPServer -From "$FromName <$FromEmail>" -To $To -Subject $Subject -Body $emailMessage -BodyAsHtml -Encoding "UTF8"
|
||||
}
|
||||
|
||||
# Parameter aus dem Ereignisprotokoll auslesen
|
||||
$eventID = 1149 # Event ID für RDP-Anmeldungen
|
||||
$eventLogName = "Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational"
|
||||
|
||||
$latestEvent = Get-WinEvent -LogName $eventLogName -FilterXPath "<QueryList><Query Id='0' Path='$eventLogName'><Select Path='$eventLogName'>*[System[(EventID=$eventID)]]</Select></Query></QueryList>" | Select-Object -First 1
|
||||
|
||||
if ($latestEvent) {
|
||||
$xml = [xml]$latestEvent.ToXml()
|
||||
|
||||
if ($xml.Event.UserData) {
|
||||
$user = $xml.Event.UserData.EventXML.Param1
|
||||
$domain = $xml.Event.UserData.EventXML.Param2
|
||||
$clientIP = $xml.Event.UserData.EventXML.Param3
|
||||
|
||||
$eventTime = $latestEvent.TimeCreated
|
||||
$computerName = $latestEvent.MachineName
|
||||
|
||||
$HTMLBody = @"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<p><img src="$LogoURL" alt="" width="265" height="81" /></p>
|
||||
<p><strong>Hallo Patrick Asmus,</strong></p>
|
||||
<p>Es wurde eine Anmeldung per RDP auf der Windows Maschine <strong>$computerName</strong> registriert.<br /><br /><strong>Datum:</strong> $($eventTime.ToString('dd.MM.yyyy'))<br /><strong>Uhrzeit:</strong> $($eventTime.ToString('HH:mm:ss'))<br /><strong>Domäne:</strong> $domain<br /><strong>Benutzer:</strong> $user<br /><strong>IP-Adresse des Clients:</strong> $clientIP</p>
|
||||
</body>
|
||||
</html>
|
||||
"@
|
||||
|
||||
Send-Email -To $ManualRecipient -Subject "RDP-Anmeldung auf $computerName registriert" -HTMLBody $HTMLBody
|
||||
}
|
||||
}
|
||||
225
rdp-access-notification.ps1
Normal file
225
rdp-access-notification.ps1
Normal file
@@ -0,0 +1,225 @@
|
||||
# Script Name: rdp-access-notification.ps1
|
||||
# Beschreibung: Versendet Benachrichtigungen (E-Mail / Ntfy) bei RDP-Anmeldung
|
||||
# Autor: Patrick Asmus
|
||||
# Web: https://www.patrick-asmus.de
|
||||
# Git-Reposit.: https://git.techniverse.net/scriptos/rdp-access-mailbenachrichtigung.git
|
||||
# Version: 4.0
|
||||
# Datum: 26.04.2026
|
||||
# Modifikation: Zusammenfuehrung AD/Local, Config-Datei, Ntfy-Support
|
||||
#####################################################
|
||||
|
||||
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
$configPath = Join-Path $scriptDir "config.conf"
|
||||
|
||||
if (-not (Test-Path $configPath)) {
|
||||
Write-Error "Konfigurationsdatei nicht gefunden: $configPath"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# --- Config parsen ---
|
||||
|
||||
$conf = @{}
|
||||
foreach ($line in Get-Content -Path $configPath) {
|
||||
$line = $line.Trim()
|
||||
if ($line -eq "" -or $line.StartsWith("#")) { continue }
|
||||
$parts = $line -split "=", 2
|
||||
if ($parts.Count -eq 2) {
|
||||
$conf[$parts[0].Trim()] = $parts[1].Trim()
|
||||
}
|
||||
}
|
||||
|
||||
# --- Funktionen ---
|
||||
|
||||
function Send-Email {
|
||||
param(
|
||||
[string]$To,
|
||||
[string]$RecipientName,
|
||||
[string]$Subject,
|
||||
[string]$ComputerName,
|
||||
[string]$EventDate,
|
||||
[string]$EventTime,
|
||||
[string]$Domain,
|
||||
[string]$User,
|
||||
[string]$ClientIP
|
||||
)
|
||||
|
||||
$htmlBody = @"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
|
||||
<style>
|
||||
body { font-family: Segoe UI, Tahoma, Geneva, Verdana, sans-serif; color: #333; margin: 0; padding: 0; background-color: #f4f4f4; }
|
||||
.container { max-width: 600px; margin: 20px auto; background: #ffffff; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
|
||||
.header { background: #2c3e50; color: #ffffff; padding: 20px 30px; font-size: 18px; font-weight: 600; }
|
||||
.content { padding: 25px 30px; line-height: 1.6; }
|
||||
.info-table { width: 100%; border-collapse: collapse; margin-top: 15px; }
|
||||
.info-table td { padding: 8px 12px; border-bottom: 1px solid #eee; }
|
||||
.info-table td:first-child { font-weight: 600; white-space: nowrap; width: 180px; color: #555; }
|
||||
.footer { background: #f8f8f8; padding: 15px 30px; font-size: 12px; color: #999; text-align: center; border-top: 1px solid #eee; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">RDP-Zugriff erkannt</div>
|
||||
<div class="content">
|
||||
<p>Hallo <strong>$RecipientName</strong>,</p>
|
||||
<p>auf der Windows-Maschine <strong>$ComputerName</strong> wurde eine RDP-Anmeldung registriert.</p>
|
||||
<table class="info-table">
|
||||
<tr><td>Datum</td><td>$EventDate</td></tr>
|
||||
<tr><td>Uhrzeit</td><td>$EventTime</td></tr>
|
||||
<tr><td>Domäne</td><td>$Domain</td></tr>
|
||||
<tr><td>Benutzer</td><td>$User</td></tr>
|
||||
<tr><td>IP-Adresse des Clients</td><td>$ClientIP</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="footer">Diese Nachricht wurde automatisch generiert.</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
"@
|
||||
|
||||
if (-not $To) {
|
||||
Write-Warning "Kein Empfaenger fuer E-Mail (Name: $RecipientName) - uebersprungen"
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
Send-MailMessage `
|
||||
-SmtpServer $conf["SMTP_SERVER"] `
|
||||
-From "$($conf["SMTP_FROM_NAME"]) <$($conf["SMTP_FROM_EMAIL"])>" `
|
||||
-To $To `
|
||||
-Subject $Subject `
|
||||
-Body $htmlBody `
|
||||
-BodyAsHtml `
|
||||
-Encoding ([System.Text.Encoding]::UTF8) `
|
||||
-ErrorAction Stop
|
||||
}
|
||||
catch {
|
||||
Write-Error "E-Mail an $To fehlgeschlagen: $_"
|
||||
}
|
||||
}
|
||||
|
||||
function Send-Ntfy {
|
||||
param(
|
||||
[string]$Title,
|
||||
[string]$Message
|
||||
)
|
||||
|
||||
$ntfyUrl = "$($conf["NTFY_SERVER"])/$($conf["NTFY_TOPIC"])"
|
||||
|
||||
$headers = @{
|
||||
"Title" = $Title
|
||||
"Priority" = $conf["NTFY_PRIORITY"]
|
||||
"Tags" = $conf["NTFY_TAGS"]
|
||||
}
|
||||
|
||||
if ($conf["NTFY_AUTH_TOKEN"]) {
|
||||
$headers["Authorization"] = "Bearer $($conf["NTFY_AUTH_TOKEN"])"
|
||||
}
|
||||
|
||||
try {
|
||||
Invoke-RestMethod `
|
||||
-Uri $ntfyUrl `
|
||||
-Method Post `
|
||||
-Headers $headers `
|
||||
-Body ([System.Text.Encoding]::UTF8.GetBytes($Message)) `
|
||||
-ContentType "text/plain; charset=utf-8"
|
||||
}
|
||||
catch {
|
||||
Write-Error "Ntfy-Benachrichtigung fehlgeschlagen: $_"
|
||||
}
|
||||
}
|
||||
|
||||
# --- RDP-Event auslesen ---
|
||||
|
||||
$eventID = 1149
|
||||
$eventLogName = "Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational"
|
||||
|
||||
$latestEvent = Get-WinEvent -LogName $eventLogName -FilterXPath "<QueryList><Query Id='0' Path='$eventLogName'><Select Path='$eventLogName'>*[System[(EventID=$eventID)]]</Select></Query></QueryList>" | Select-Object -First 1
|
||||
|
||||
if (-not $latestEvent) {
|
||||
exit 0
|
||||
}
|
||||
|
||||
$xml = [xml]$latestEvent.ToXml()
|
||||
|
||||
if (-not $xml.Event.UserData) {
|
||||
exit 0
|
||||
}
|
||||
|
||||
$user = $xml.Event.UserData.EventXML.Param1
|
||||
$domain = $xml.Event.UserData.EventXML.Param2
|
||||
$clientIP = $xml.Event.UserData.EventXML.Param3
|
||||
$eventTime = $latestEvent.TimeCreated
|
||||
$computerName = $latestEvent.MachineName
|
||||
|
||||
$eventDate = $eventTime.ToString('dd.MM.yyyy')
|
||||
$eventTimeStr = $eventTime.ToString('HH:mm:ss')
|
||||
$subject = "RDP-Anmeldung auf $computerName registriert"
|
||||
|
||||
# --- Empfaenger ermitteln ---
|
||||
|
||||
$recipients = @()
|
||||
|
||||
switch ($conf["MODE"]) {
|
||||
"ad" {
|
||||
$adMembers = Get-ADGroupMember -Identity $conf["AD_SECURITY_GROUP_DN"] | Where-Object { $_.objectClass -eq "user" }
|
||||
foreach ($member in $adMembers) {
|
||||
$adUser = Get-ADUser $member.DistinguishedName -Properties GivenName, Surname, EmailAddress
|
||||
$recipients += [PSCustomObject]@{
|
||||
Name = "$($adUser.GivenName) $($adUser.Surname)"
|
||||
Email = $adUser.EmailAddress
|
||||
}
|
||||
}
|
||||
}
|
||||
"local" {
|
||||
foreach ($entry in $conf["LOCAL_RECIPIENTS"] -split ";") {
|
||||
$entry = $entry.Trim()
|
||||
if ($entry -eq "") { continue }
|
||||
$parts = $entry -split ",", 2
|
||||
if ($parts.Count -eq 2) {
|
||||
$recipients += [PSCustomObject]@{
|
||||
Name = $parts[0].Trim()
|
||||
Email = $parts[1].Trim()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
default {
|
||||
Write-Error "Unbekannter Modus: $($conf["MODE"]). Erlaubt: 'ad', 'local'"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
# --- Benachrichtigungen versenden ---
|
||||
|
||||
$methods = $conf["NOTIFICATION_METHODS"] -split ","
|
||||
|
||||
if ($methods.Trim() -contains "email") {
|
||||
foreach ($recipient in $recipients) {
|
||||
Send-Email `
|
||||
-To $recipient.Email `
|
||||
-RecipientName $recipient.Name `
|
||||
-Subject $subject `
|
||||
-ComputerName $computerName `
|
||||
-EventDate $eventDate `
|
||||
-EventTime $eventTimeStr `
|
||||
-Domain $domain `
|
||||
-User $user `
|
||||
-ClientIP $clientIP
|
||||
}
|
||||
}
|
||||
|
||||
if ($methods.Trim() -contains "ntfy") {
|
||||
$ntfyMessage = @"
|
||||
Maschine: $computerName
|
||||
Datum: $eventDate
|
||||
Uhrzeit: $eventTimeStr
|
||||
Domaene: $domain
|
||||
Benutzer: $user
|
||||
Client-IP: $clientIP
|
||||
"@
|
||||
|
||||
Send-Ntfy -Title $subject -Message $ntfyMessage
|
||||
}
|
||||
47
rdp-access-notification.xml
Normal file
47
rdp-access-notification.xml
Normal file
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-16"?>
|
||||
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
|
||||
<RegistrationInfo>
|
||||
<Date>2026-04-26T00:00:00</Date>
|
||||
<Author>Administrator</Author>
|
||||
<URI>\Benachrichtigung bei RDP Anmeldung</URI>
|
||||
</RegistrationInfo>
|
||||
<Triggers>
|
||||
<EventTrigger>
|
||||
<Enabled>true</Enabled>
|
||||
<Subscription><QueryList><Query Id="0" Path="Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational"><Select Path="Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational">*[System[Provider[@Name='Microsoft-Windows-TerminalServices-RemoteConnectionManager'] and EventID=1149]]</Select></Query></QueryList></Subscription>
|
||||
</EventTrigger>
|
||||
</Triggers>
|
||||
<Principals>
|
||||
<Principal id="Author">
|
||||
<UserId>S-1-5-18</UserId>
|
||||
<RunLevel>LeastPrivilege</RunLevel>
|
||||
</Principal>
|
||||
</Principals>
|
||||
<Settings>
|
||||
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
|
||||
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
|
||||
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
|
||||
<AllowHardTerminate>true</AllowHardTerminate>
|
||||
<StartWhenAvailable>false</StartWhenAvailable>
|
||||
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
|
||||
<IdleSettings>
|
||||
<StopOnIdleEnd>true</StopOnIdleEnd>
|
||||
<RestartOnIdle>false</RestartOnIdle>
|
||||
</IdleSettings>
|
||||
<AllowStartOnDemand>true</AllowStartOnDemand>
|
||||
<Enabled>true</Enabled>
|
||||
<Hidden>false</Hidden>
|
||||
<RunOnlyIfIdle>false</RunOnlyIfIdle>
|
||||
<DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
|
||||
<UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>
|
||||
<WakeToRun>false</WakeToRun>
|
||||
<ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
|
||||
<Priority>7</Priority>
|
||||
</Settings>
|
||||
<Actions Context="Author">
|
||||
<Exec>
|
||||
<Command>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</Command>
|
||||
<Arguments>-ExecutionPolicy Bypass -File "C:\scripts\rdp-login-notifier\rdp-access-notification.ps1"</Arguments>
|
||||
</Exec>
|
||||
</Actions>
|
||||
</Task>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 32 KiB |
Reference in New Issue
Block a user