Compare commits

..

24 Commits

Author SHA1 Message Date
312e4e713f docker refresh 2026-03-25 14:01:26 +01:00
7d5d3dc0c8 script német verzio 2026-03-25 11:51:13 +01:00
8167a3ffff neue script, check file age 2026-03-25 11:34:33 +01:00
3e68e96c8a script de verzio 2026-03-25 10:18:00 +01:00
3b9b7f8789 1 2026-03-25 10:09:23 +01:00
62f739344c . 2026-03-25 10:09:04 +01:00
9b913a48bb képek sharepointhoz pl 2026-03-25 08:31:57 +01:00
c1f1b48f6b . 2026-03-24 16:17:51 +01:00
acd7daf36f dokument update 2026-03-24 15:56:24 +01:00
36ac72ec82 neu diabetes dokument 2026-03-24 14:49:43 +01:00
440ce4d688 doku für APS-SFTP01 2026-03-24 10:39:41 +01:00
99b400cbc1 conf file aktualizäläs 2026-03-23 14:04:26 +01:00
d78c846898 . 2026-03-23 10:00:50 +01:00
e44480505e sauber machen 2026-03-20 14:39:23 +01:00
625d2fc6bf putzen 2026-03-19 14:46:37 +01:00
324c1b7735 . 2026-03-18 14:53:07 +01:00
4a028aab5f sftp 2026-03-18 14:21:34 +01:00
95cc7edba5 . 2026-03-18 14:10:32 +01:00
f5802c9be3 . 2026-03-18 14:07:58 +01:00
d77bdac13f sharepoint 2026-03-17 08:29:02 +01:00
40fa971f06 . 2026-03-16 12:31:44 +01:00
78a88900d8 postfix 2026-03-16 12:13:07 +01:00
e91094e344 update 2026-03-16 11:28:18 +01:00
d7c6577ec1 . 2026-03-16 08:46:30 +01:00
56 changed files with 1641 additions and 801 deletions

View File

@@ -0,0 +1,56 @@
# Systemdokumentation: APS-SFTP01 Datenaustausch-Server
Dieses Dokument beschreibt die Funktionsweise, das Berechtigungssystem und die Zugriffspfade des Servers **APS-SFTP01 (10.102.1.202)**. Der Server dient zwei getrennten Importprozessen.
## 1. Systemübersicht
Der Server fungiert als zentraler Datenaustauschpunkt für die Systeme Bremen und Amondis:
1. **Bremen-Mave Import:** Empfang externer Daten über SFTP.
2. **Amondis-Mave Import:** Empfang externer Daten über SMB (Samba), und import nach Mave mit SFTP Protokolle.
## 2. Benutzer und Zugriff
┌──────────────────┬──────────────┬───────────────┬─────────────────┬─────────────────────────────┐
│ Benutzer │ Prozess │ Typ │ Shell │ Aufgabe │
├──────────────────┼──────────────┼───────────────┼─────────────────┼─────────────────────────────┤
│ mave-sftp │ Bremen-Mave │ Nur SFTP │ /sbin/nologin │ Import von Bremen-Daten │
│ mave-amondis │ Amondis-Mave │ SFTP & SMB │ /sbin/nologin │ Import von Amondis-Daten │
└──────────────────┴──────────────┴───────────────┴─────────────────┴─────────────────────────────┘
*Hinweis: Keiner der Benutzer ist für eine interaktive SSH-Anmeldung (Terminal) berechtigt.*
## 3. Verzeichnisstruktur und Berechtigungen
### Bremen-Mave Import (mave-sftp)
┌────────────────────────────────────────┬─────────────────────┬──────────────┬──────────────────────────────────┐
│ Pfad │ Besitzer │ Berechtigung │ Rolle │
├────────────────────────────────────────┼─────────────────────┼──────────────┼──────────────────────────────────┤
│ /home/mave-sftp │ root:root │ 755 │ SFTP Chroot-Gefängnis │
│ /home/mave-sftp/Schnittstellen/Bremen │ mave-sftp:mave-sftp │ 775 │ Beschreibbarer Ordner für Bremen │
└────────────────────────────────────────┴─────────────────────┴──────────────┴──────────────────────────────────┘
### Amondis-Mave Import (mave-amondis)
┌───────────────────────────────────────────────┬───────────────────────────┬──────────────┬─────────────────────────────┐
│ Pfad │ Besitzer │ Berechtigung │ Rolle │
├───────────────────────────────────────────────┼───────────────────────────┼──────────────┼─────────────────────────────┤
│ /home/mave-amondis │ root:root │ 755 │ SFTP Home (nicht schreibbar)|
│ /home/mave-amondis/Schnittstellen │ root:root │ 755 │ SFTP Chroot-Gefängnis │
│ /home/mave-amondis/Schnittstellen/Amondis/APO │ mave-amondis:mave-amondis │ 775 │ Beschreibbares Verzeichnis │
└───────────────────────────────────────────────┴───────────────────────────┴──────────────┴─────────────────────────────┘
## 4. Netzwerkzugriff
### SMB (Windows Freigabe)
* **Amondis-Pfad:** `\\10.102.1.202\mave-amondis\Schnittstellen\Amondis\APO`
* **Funktionsweise:** Samba verwendet die Einstellung `force user = mave-amondis`, um Berechtigungskonflikte zu vermeiden.
### SFTP (Secure FTP)
* **Bremen-Verbindung:** `sftp://mave-sftp@10.102.1.202` (sieht nach der Anmeldung den Ordner `mave-amondis\Schnittstellen\Bremen`).
* **Amondis-Verbindung:** `sftp://mave-amondis@10.102.1.202` (sieht nach der Anmeldung den Ordner `Amondis\APO`).
## 5. Automatische Benachrichtigungen (Monitoring)
Bei jeder erfolgreichen Anmeldung (für beide Benutzer) wird eine E-Mail-Benachrichtigung an den Administrator gesendet (`i.meszely@antares-apo.de`).
* **Script-Speicherort:** `/usr/local/sbin/sftp-notify.sh`
* **Funktionsweise:** Das Script wird durch das PAM-System (Pluggable Authentication Modules) bei jedem `open_session`-Ereignis aufgerufen. Es unterscheidet zwischen SFTP (eingeschränkt) und interaktiven SSH-Anmeldungen anhand der Benutzer-Shell und versendet die Details (Benutzer, Remote-IP, Zeitstempel) per E-Mail.
* **Logdatei:** `/tmp/sftp-notify.log` (für das Debugging).
---
*Aktualisiert am: 25. März 2026*

View File

@@ -0,0 +1,56 @@
# Rendszerdokumentáció: APS-SFTP01 Adatcsere Szerver
Ez a dokumentum az **APS-SFTP01 (10.102.1.202)** szerver működését, jogosultsági rendszerét és elérési útjait foglalja össze. A szerver két elkülönített import folyamatot szolgál ki.
## 1. Rendszer Áttekintés
A szerver központi adatcsere pontként funkcionál a Bremen és az Amondis rendszerek felé:
1. **Bremen-Mave Import:** Külső adatok fogadása SFTP-n keresztül.
2. **Amondis-Mave Import:** Belső és külső adatcsere SMB (Samba) és SFTP protokollokon.
## 2. Felhasználók és Hozzáférés
┌──────────────────┬──────────────┬───────────────┬─────────────────┬───────────────────────────┐
│ Felhasználó │ Folyamat │ Típus │ Shell │ Feladat │
├──────────────────┼──────────────┼───────────────┼─────────────────┼───────────────────────────┤
│ mave-sftp │ Bremen-Mave │ Csak SFTP │ /sbin/nologin │ Bremen adatok importálása │
│ mave-amondis │ Amondis-Mave │ SFTP & SMB │ /sbin/nologin │ Amondis adatok kezelése │
└──────────────────┴──────────────┴───────────────┴─────────────────┴───────────────────────────┘
*Megjegyzés: Egyik felhasználó sem jogosult interaktív SSH (terminál) belépésre.*
## 3. Könyvtárstruktúra és Jogosultságok
### Bremen-Mave Import (mave-sftp)
┌────────────────────────────┬─────────────────────┬─────────────┬─────────────────────────────────┐
│ Elérési út │ Tulajdonos │ Jogosultság │ Szerep │
├────────────────────────────┼─────────────────────┼─────────────┼─────────────────────────────────┤
│ /home/mave-sftp │ root:root │ 755 │ SFTP Chroot Börtön │
│ /home/mave-sftp/feltoltes │ mave-sftp:mave-sftp │ 775 │ Írható mappa a Bremen adatoknak │
└────────────────────────────┴─────────────────────┴─────────────┴─────────────────────────────────┘
### Amondis-Mave Import (mave-amondis)
┌───────────────────────────────────────────┬───────────────────────────┬─────────────┬────────────────────────┐
│ Elérési út │ Tulajdonos │ Jogosultság │ Szerep │
├───────────────────────────────────────────┼───────────────────────────┼─────────────┼────────────────────────┤
│ /home/mave-amondis │ root:root │ 755 │ SFTP Home (nem írható) │
│ /home/mave-amondis/Schnittstellen │ root:root │ 755 │ SFTP Chroot Börtön │
│ /home/mave-amondis/Schnittstellen/Amondis │ mave-amondis:mave-amondis │ 775 │ Írható munkakönyvtár │
└───────────────────────────────────────────┴───────────────────────────┴─────────────┴────────────────────────┘
## 4. Hálózati Elérések
### SMB (Windows Megosztás)
* **Amondis Útvonal:** `\\10.102.1.202\mave-amondis\Schnittstellen\Amondis\APO`
* **Működés:** A Samba a `force user = mave-amondis` beállítást használja a jogosultsági hibák elkerülése érdekében.
### SFTP (Biztonságos FTP)
* **Bremen Kapcsolat:** `sftp://mave-sftp@10.102.1.202` (belépéskor a `feltoltes` mappát látja).
* **Amondis Kapcsolat:** `sftp://mave-amondis@10.102.1.202` (belépéskor az `Amondis` mappát látja).
## 5. Automatikus Értesítések (Monitoring)
Minden sikeres bejelentkezéskor (mindkét felhasználó esetén) e-mail értesítés érkezik az adminisztrátornak (`i.meszely@antares-apo.de`).
* **Script helye:** `/usr/local/sbin/sftp-notify.sh`
* **Működés:** A scriptet a PAM (Pluggable Authentication Modules) rendszer hívja meg minden `open_session` eseménynél. A script megkülönbözteti az SFTP (korlátozott) és az interaktív SSH belépéseket a felhasználó shellje alapján, majd elküldi az adatokat (felhasználó, távoli IP, időpont) e-mailben.
* **Log fájl:** `/tmp/sftp-notify.log` (hibakereséshez).
---
*Frissítve: 2026. március 24.*

View File

@@ -0,0 +1,80 @@
# Konfiguration eines SFTP-Servers auf Fedora Linux
Diese Anleitung beschreibt die Einrichtung eines sicheren SFTP-Servers unter Verwendung von OpenSSH. Der Fokus liegt auf Sicherheit durch die Einschränkung des Benutzerzugriffs (Chroot) und die Deaktivierung des Shell-Zugriffs.
## 1. Benutzer anlegen
Zuerst erstellen wir einen dedizierten Benutzer für den SFTP-Zugriff. Um die Sicherheit zu erhöhen, deaktivieren wir den normalen SSH-Terminal-Zugriff (`/sbin/nologin`).
```bash
# Benutzer erstellen (ohne Shell-Zugriff)
sudo useradd -m -s /sbin/nologin sftpuser
# Passwort für den Benutzer festlegen
sudo passwd sftpuser
```
## 2. Firewall-Konfiguration
SFTP läuft über das SSH-Protokoll (Port 22). Dieser muss in der Firewall freigegeben werden.
```bash
# SSH-Dienst in der Firewall erlauben
sudo firewall-cmd --permanent --add-service=ssh
# Konfiguration neu laden
sudo firewall-cmd --reload
```
## 3. SSH-Konfiguration (Einschränkungen)
Um den Benutzer in seinem Home-Verzeichnis zu isolieren (Chroot) und nur SFTP zu erlauben, muss die Datei `/etc/ssh/sshd_config` angepasst werden.
1. Öffnen Sie die Konfigurationsdatei: `sudo nano /etc/ssh/sshd_config`
2. Fügen Sie am Ende der Datei folgende Zeilen hinzu:
```text
Match User sftpuser
ForceCommand internal-sftp
PasswordAuthentication yes
ChrootDirectory %h
AllowTcpForwarding no
X11Forwarding no
```
* **Match User:** Wendet die Regeln nur auf diesen Benutzer an.
* **ForceCommand internal-sftp:** Erlaubt nur SFTP-Befehle, keinen interaktiven Shell-Zugriff.
* **ChrootDirectory %h:** Sperrt den Benutzer in sein Home-Verzeichnis ein.
## 4. Verzeichnisberechtigungen (Wichtig für Chroot)
Damit der `Chroot`-Mechanismus funktioniert, muss das Home-Verzeichnis dem Benutzer `root` gehören und darf für andere nicht schreibbar sein.
```bash
# Besitzer auf root setzen
sudo chown root:root /home/sftpuser
sudo chmod 755 /home/sftpuser
# Einen Unterordner für Uploads erstellen, in dem der Benutzer schreiben darf
sudo mkdir /home/sftpuser/uploads
sudo chown sftpuser:sftpuser /home/sftpuser/uploads
```
## 5. SELinux-Anpassungen (Fedora-spezifisch)
Auf Fedora verhindert SELinux standardmäßig, dass der SSH-Dienst in Chroot-Umgebungen Schreibzugriff auf Home-Verzeichnisse hat. Dies muss explizit erlaubt werden.
```bash
# Schreibzugriff für SFTP-Chroot in SELinux aktivieren
sudo setsebool -P ssh_chroot_rw_homedirs on
```
## 6. Dienst neu starten und testen
Nachdem alle Änderungen vorgenommen wurden, muss der SSH-Dienst neu gestartet werden.
```bash
# SSH-Dienst neu starten
sudo systemctl restart sshd
```
### Testen des Zugriffs:
Von einem entfernten Rechner oder lokal:
```bash
sftp sftpuser@<IP-ADRESSE-DES-SERVERS>
```
*Hinweis: Ein Login via normalem SSH (`ssh sftpuser@...`) sollte nun automatisch abgelehnt werden.*

View File

@@ -0,0 +1,45 @@
1. Felhasználó létrehozása
Hozzunk létre egy felhasználót (pl. sftpuser), de tiltsuk le neki a shell hozzáférést, hogy ne tudjon belépni a terminálba, csak fájlokat másolni:
1 sudo useradd -m -s /sbin/nologin sftpuser
2 sudo passwd sftpuser
2. Tűzfal (Firewall) beállítása
Fedora alatt a firewalld fut. Engedélyezni kell az SSH-t (ami az SFTP-t is viszi):
1 sudo firewall-cmd --permanent --add-service=ssh
2 sudo firewall-cmd --reload
3. Az SFTP korlátozása (Opcionális, de ajánlott)
Ha azt szeretnéd, hogy a felhasználó csak az SFTP-t használhassa, és ne lásson bele a teljes szerver fájlrendszerébe, módosítsd az SSH konfigurációt:
1. Nyisd meg: sudo nano /etc/ssh/sshd_config
2. Menj a fájl végére és add hozzá:
1 Match User sftpuser
2 ForceCommand internal-sftp
3 PasswordAuthentication yes
4 ChrootDirectory %h
5 AllowTcpForwarding no
6 X11Forwarding no
Megjegyzés: A ChrootDirectory %h bezárja a felhasználót a saját home mappájába.
3. Fontos: Ha ChrootDirectory-t használsz, a home mappa tulajdonosának a root-nak kell lennie:
1 sudo chown root:root /home/sftpuser
2 sudo chmod 755 /home/sftpuser
3 # Hozz létre egy mappát, amibe írhat is:
4 sudo mkdir /home/sftpuser/feltoltes
5 sudo chown sftpuser:sftpuser /home/sftpuser/feltoltes
4. Indítsd újra az SSH-t:
1 sudo systemctl restart sshd
4. SELinux (A Fedora "lelke")
Mivel Fedora alatt dolgozunk, az SELinux alapértelmezés szerint blokkolhatja az SFTP írási jogokat, ha nem a szokványos módon használod. Engedélyezd az SFTP írást a home mappákba:
1 sudo setsebool -P ssh_chroot_rw_homedirs on
(Ha nem használsz Chroot-ot, akkor is érdemes ezt futtatni, ha hiba van.)
Összegzés:
* Ha csak gyorsan kell: useradd + passwd + firewall-cmd -> KÉSZ.
* Ha biztonságosan kell: Használd a Match User részt az sshd_config-ban, hogy ne tudjon "mászkálni" a szerveren.

View File

@@ -0,0 +1,62 @@
# Samba (SMB) Megosztás Beállítása - APS-SFTP01 (mave-amondis)
Ez a leírás a `mave-amondis` felhasználó home könyvtárának megosztását mutatja be, aki **kizárólag SMB** hozzáféréssel rendelkezik (nem használ SFTP-t).
## 1. Előfeltételek (Rendszerfelhasználó)
Ellenőrizzük, hogy a felhasználó létezik-e, és a saját mappája az övé:
```bash
# Ha még nincs felhasználó:
# sudo useradd -m -s /sbin/nologin mave-amondis
# Jogosultságok ellenőrzése (Samba eléréshez 0700 vagy 0755 javasolt)
sudo chown mave-amondis:mave-amondis /home/mave-amondis
sudo chmod 700 /home/mave-amondis
```
## 2. Samba jelszó beállítása
A Samba saját adatbázist használ, így meg kell adni egy jelszót a felhasználónak:
```bash
sudo smbpasswd -a mave-amondis
```
## 3. Samba konfiguráció (/etc/samba/smb.conf)
Add hozzá a fájl végéhez az alábbi részt:
```ini
[mave-amondis]
comment = Mave Amondis SMB Share
path = /home/mave-amondis
valid users = mave-amondis
public = no
writable = yes
browsable = yes
guest ok = no
create mask = 0644
directory mask = 0755
force user = mave-amondis
```
## 4. SELinux és Tűzfal (Fedora / RHEL esetén kötelező!)
A Fedora alapértelmezésben tiltja a Home könyvtárak megosztását és a Samba forgalmat.
```bash
# SELinux: Home könyvtárak engedélyezése Sambához
sudo setsebool -P samba_enable_home_dirs on
# Tűzfal: Samba szolgáltatás engedélyezése
sudo firewall-cmd --permanent --add-service=samba
sudo firewall-cmd --reload
```
## 5. Szolgáltatások indítása
```bash
sudo systemctl enable --now smb nmb
sudo systemctl restart smb
```
## 6. Csatlakozás (Windows)
Windows Intézőben:
`\\APS-SFTP01\mave-amondis`
---
*Megjegyzés: Mivel ez a felhasználó nem használ SFTP-t, nem ütközünk a ChrootDirectory (root-owner) korlátozásaiba.*

View File

@@ -0,0 +1,45 @@
#!/bin/bash
# Locale beállítása, hogy a mail parancs ne hibázzon karakterkódolás miatt
export LC_ALL=C.UTF-8
export LANG=C.UTF-8
# Log fájl a hibakereséshez (adj rá írási jogot: chmod 666 /tmp/sftp-notify.log)
LOGFILE="/tmp/sftp-notify.log"
# Csak a sikeres bejelentkezésekről (open_session) küldünk értesítést
if [ "$PAM_TYPE" = "open_session" ]; then
# Környezet mentése logba
echo "--- $(/usr/bin/date): Login attempt for $PAM_USER from $PAM_RHOST ---" >> "$LOGFILE"
# Felhasználó shelljének ellenőrzése
USER_SHELL=$(/usr/bin/getent passwd "$PAM_USER" | /usr/bin/cut -d: -f7)
# Típus meghatározása
if [[ "$USER_SHELL" == *"/nologin" ]] || [[ "$USER_SHELL" == *"/false" ]]; then
LOGIN_TYPE="SFTP (Restricted)"
else
LOGIN_TYPE="SSH (Interactive)"
fi
MESSAGE="Login értesítés ($PAM_SERVICE):
Típus: $LOGIN_TYPE
Felhasználó: $PAM_USER
Távoli gép: $PAM_RHOST
Shell: $USER_SHELL
Időpont: $(/usr/bin/date)
Host: $(/usr/bin/hostname)"
# Email küldés (abszolút útvonallal)
# Ellenőrizd, hogy a 'mail' parancs a /usr/sbin/mail helyen van-e!
echo "$MESSAGE" | /usr/sbin/mail -s "$LOGIN_TYPE: $PAM_USER" i.meszely@antares-apo.de >> "$LOGFILE" 2>&1
if [ $? -eq 0 ]; then
echo "Siker: Email elküldve." >> "$LOGFILE"
else
echo "HIBA: Az email küldés sikertelen volt! (Exit code: $?)" >> "$LOGFILE"
fi
fi
exit 0

View File

@@ -0,0 +1,45 @@
#!/bin/bash
# Locale-Einstellungen, damit der Mail-Befehl keine Zeichenkodierungsfehler verursacht
export LC_ALL=C.UTF-8
export LANG=C.UTF-8
# Logdatei für das Debugging (Schreibrechte setzen: chmod 666 /tmp/sftp-notify.log)
LOGFILE="/tmp/sftp-notify.log"
# Benachrichtigung nur bei erfolgreichen Anmeldungen (open_session)
if [ "$PAM_TYPE" = "open_session" ]; then
# Umgebung in Log speichern
echo "--- $(/usr/bin/date): Anmeldeversuch für $PAM_USER von $PAM_RHOST ---" >> "$LOGFILE"
# Überprüfung der Benutzer-Shell
USER_SHELL=$(/usr/bin/getent passwd "$PAM_USER" | /usr/bin/cut -d: -f7)
# Bestimmung des Typs
if [[ "$USER_SHELL" == *"/nologin" ]] || [[ "$USER_SHELL" == *"/false" ]]; then
LOGIN_TYPE="SFTP (Eingeschränkt)"
else
LOGIN_TYPE="SSH (Interaktiv)"
fi
MESSAGE="Anmeldebenachrichtigung ($PAM_SERVICE):
Typ: $LOGIN_TYPE
Benutzer: $PAM_USER
Remote-Host: $PAM_RHOST
Shell: $USER_SHELL
Zeitpunkt: $(/usr/bin/date)
Host: $(/usr/bin/hostname)"
# E-Mail-Versand (mit absolutem Pfad)
# Prüfen, ob der 'mail'-Befehl unter /usr/sbin/mail verfügbar ist!
echo "$MESSAGE" | /usr/sbin/mail -s "$LOGIN_TYPE: $PAM_USER" i.meszely@antares-apo.de >> "$LOGFILE" 2>&1
if [ $? -eq 0 ]; then
echo "Erfolg: E-Mail gesendet." >> "$LOGFILE"
else
echo "FEHLER: E-Mail-Versand fehlgeschlagen! (Exit code: $?)" >> "$LOGFILE"
fi
fi
exit 0

View File

@@ -0,0 +1,11 @@
[mave-amondis]
comment = Mave Amondis SMB Share
path = /home/mave-amondis
valid users = mave-amondis
public = no
writable = yes
browsable = yes
guest ok = no
create mask = 0644
directory mask = 0755
force user = mave-amondis

View File

@@ -0,0 +1,13 @@
useradd -M -s /sbin/nologin n8nuser
passwd n8nuser
sudo postconf -e 'relayhost = [10.102.1.201]'
sudo postconf -e 'myorigin = antares-apo.de'
sudo postconf -e 'smtp_generic_maps = hash:/etc/postfix/generic'
echo "apslinux@aps-sftp01.localdomain sftp-alert@antares-apo.de" | sudo tee /etc/postfix/generic
sudo postmap /etc/postfix/generic
sudo systemctl restart postfix

View File

@@ -0,0 +1,71 @@
# SOP: Konfiguration Postfix SMTP Relay (APS-SMTP01)
## 1. Zweck & Übersicht
Diese Dokumentation beschreibt die Konfiguration des zentralen Postfix Mail-Relays (**APS-SMTP01**). Das System dient als Brücke, um internen Geräten (Druckern, Scannern) und automatisierten IT-Skripten den E-Mail-Versand über unseren offiziellen Provider zu ermöglichen.
**System-Details:**
* **Server:** Linux (Ubuntu/Fedora basierend)
* **Hostname:** `aps-smtp01.aps.local`
* **IP-Adresse:** [Bitte interne IP ergänzen]
* **Dienst:** Postfix (MTA - Mail Transfer Agent)
## 2. Zentrale Konfigurationsdateien
Die gesamte Konfiguration befindet sich im Verzeichnis `/etc/postfix/`. Die wichtigsten Dateien sind:
* **`/etc/postfix/main.cf`**: Die Hauptkonfigurationsdatei mit den globalen Parametern.
* **`/etc/postfix/sasl_passwd`**: Enthält die Zugangsdaten für den externen Relay-Host (verschlüsselt via postmap).
* **`/etc/aliases`**: Definiert E-Mail-Weiterleitungen für lokale Benutzer.
## 3. Konfigurations-Ausschnitt (main.cf)
Die folgenden Parameter sind für den Betrieb als Relay entscheidend:
```bash
# Beispiel-Konfiguration für Relay mit Authentifizierung
relayhost = [smtp.dein-provider.de]:587
mynetworks = 127.0.0.0/8, 192.168.1.0/24 [Hier interne Subnetze erlauben]
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_tls_security_level = may
header_size_limit = 4096000
```
## 4. Administrative Befehle & Wartung
Nach Änderungen an der Konfiguration müssen folgende Schritte durchgeführt werden:
### Konfiguration prüfen und laden:
```bash
# Syntax-Check der main.cf
postfix check
# Konfiguration neu laden (ohne Neustart des Dienstes)
systemctl reload postfix
```
### Passwort-Datenbank aktualisieren:
Wenn die `sasl_passwd` geändert wurde, muss die Datenbank neu generiert werden:
```bash
postmap /etc/postfix/sasl_passwd
systemctl restart postfix
```
### Überprüfung der Logs (Fehlersuche):
```bash
# Echtzeit-Überwachung der Mail-Logs
tail -f /var/log/mail.log
# Alternativ via journalctl
journalctl -u postfix -f
```
## 5. Testen des E-Mail-Versands
Um die Funktionalität des Relays direkt auf dem Server zu testen:
```bash
echo "Testmail von APS-SMTP01" | mail -s "Testbetreff" de@deine-domain.de
```
## 6. Bekannte Probleme (Troubleshooting)
* **Relay access denied:** Prüfen Sie den Parameter `mynetworks`. Die IP des sendenden Geräts muss dort erlaubt sein.
* **Connection timed out (Port 25/587):** Prüfen Sie die Firewall-Regeln auf dem Server und im Netzwerk (Ausgehende Verbindung zum Provider).
---
*Erstellt für die IT-Dokumentation - Projekt: IT Internal Repository*

View File

@@ -0,0 +1,6 @@
docker compose pull
docker compose up -d
docker image prune -f

View File

@@ -0,0 +1,43 @@
alias_database = hash:/etc/aliases
alias_maps = hash:/etc/aliases
command_directory = /usr/bin
compatibility_level = 3.10
daemon_directory = /usr/libexec/postfix
data_directory = /var/lib/postfix
debug_peer_level = 2
debugger_command = PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin ddd $daemon_directory/$process_name $process_id & sleep 5
html_directory = no
inet_interfaces = all
inet_protocols = all
mail_owner = postfix
mailq_path = /usr/bin/mailq.postfix
manpage_directory = /usr/share/man
meta_directory = /etc/postfix
mydestination = $myhostname, localhost.$mydomain, localhost
mynetworks = 127.0.0.0/8, 10.102.9.0/24, 10.101.0.0/16, 10.102.1.0/24
newaliases_path = /usr/bin/newaliases.postfix
queue_directory = /var/spool/postfix
readme_directory = /usr/share/doc/postfix/README_FILES
#relayhost = apshh-de0i.mail.protection.outlook.com
#relayhost = [apshh.mail.protection.outlook.com]:25
relayhost = [aps-exch01.aps.local]:25
#relayhost =
sample_directory = /usr/share/doc/postfix/samples
sendmail_path = /usr/bin/sendmail.postfix
setgid_group = postdrop
shlib_directory = /usr/lib64/postfix
#smtp_sasl_auth_enable = no
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
broken_sasl_auth_clients = yes
smtp_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt
smtp_tls_CApath = /etc/pki/tls/certs
smtp_tls_security_level = may
smtpd_tls_cert_file = /etc/pki/tls/certs/postfix.pem
smtpd_tls_key_file = /etc/pki/tls/private/postfix.key
smtpd_tls_security_level = may
unknown_local_recipient_reject_code = 550
myhostname = antares-apo.local
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination

View File

@@ -0,0 +1,37 @@
alias_database = hash:/etc/aliases
alias_maps = hash:/etc/aliases
command_directory = /usr/bin
compatibility_level = 3.10
daemon_directory = /usr/libexec/postfix
data_directory = /var/lib/postfix
debug_peer_level = 2
debugger_command = PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin ddd $daemon_directory/$process_name $process_id & sleep 5
html_directory = no
inet_interfaces = all
inet_protocols = all
mail_owner = postfix
mailq_path = /usr/bin/mailq.postfix
manpage_directory = /usr/share/man
meta_directory = /etc/postfix
mydestination = $myhostname, localhost.$mydomain, localhost
mynetworks = 127.0.0.0/8, 10.102.9.0/24, 10.101.0.0/16, 10.102.1.0/24
newaliases_path = /usr/bin/newaliases.postfix
queue_directory = /var/spool/postfix
readme_directory = /usr/share/doc/postfix/README_FILES
#relayhost = apshh-de0i.mail.protection.outlook.com
#relayhost = [apshh.mail.protection.outlook.com]:25
relayhost = [aps-exch01.aps.local]:25
#relayhost =
sample_directory = /usr/share/doc/postfix/samples
sendmail_path = /usr/bin/sendmail.postfix
setgid_group = postdrop
shlib_directory = /usr/lib64/postfix
smtp_sasl_auth_enable = no
smtp_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt
smtp_tls_CApath = /etc/pki/tls/certs
smtp_tls_security_level = may
smtpd_tls_cert_file = /etc/pki/tls/certs/postfix.pem
smtpd_tls_key_file = /etc/pki/tls/private/postfix.key
smtpd_tls_security_level = may
unknown_local_recipient_reject_code = 550
myhostname = antares-apo.local

View File

@@ -0,0 +1,151 @@
#
# Postfix master process configuration file. For details on the format
# of the file, see the master(5) manual page (command: "man 5 master" or
# on-line: https://www.postfix.org/master.5.html).
#
# Do not forget to execute "postfix reload" after editing this file.
#
# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (no) (never) (100)
# ==========================================================================
smtp inet n - n - - smtpd
#smtp inet n - n - 1 postscreen
#smtpd pass - - n - - smtpd
#dnsblog unix - - n - 0 dnsblog
#tlsproxy unix - - n - 0 tlsproxy
# Choose one: enable submission for loopback clients only, or for any client.
#127.0.0.1:submission inet n - n - - smtpd
#submission inet n - n - - smtpd
# -o syslog_name=postfix/submission
# -o smtpd_forbid_unauth_pipelining=no
# -o smtpd_tls_security_level=encrypt
# -o smtpd_sasl_auth_enable=yes
# -o smtpd_tls_auth_only=yes
# -o local_header_rewrite_clients=static:all
# -o smtpd_hide_client_session=yes
# -o smtpd_reject_unlisted_recipient=no
# Instead of specifying complex smtpd_<xxx>_restrictions here,
# specify "smtpd_<xxx>_restrictions=$mua_<xxx>_restrictions"
# here, and specify mua_<xxx>_restrictions in main.cf (where
# "<xxx>" is "client", "helo", "sender", "relay", or "recipient").
# -o smtpd_client_restrictions=
# -o smtpd_helo_restrictions=
# -o smtpd_sender_restrictions=
# -o smtpd_relay_restrictions=
# -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
# -o milter_macro_daemon_name=ORIGINATING
# Choose one: enable submissions for loopback clients only, or for any client.
#127.0.0.1:submissions inet n - n - - smtpd
#submissions inet n - n - - smtpd
# -o syslog_name=postfix/submissions
# -o smtpd_forbid_unauth_pipelining=no
# -o smtpd_tls_wrappermode=yes
# -o smtpd_sasl_auth_enable=yes
# -o local_header_rewrite_clients=static:all
# -o smtpd_hide_client_session=yes
# -o smtpd_reject_unlisted_recipient=no
# Instead of specifying complex smtpd_<xxx>_restrictions here,
# specify "smtpd_<xxx>_restrictions=$mua_<xxx>_restrictions"
# here, and specify mua_<xxx>_restrictions in main.cf (where
# "<xxx>" is "client", "helo", "sender", "relay", or "recipient").
# -o smtpd_client_restrictions=
# -o smtpd_helo_restrictions=
# -o smtpd_sender_restrictions=
# -o smtpd_relay_restrictions=
# -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
# -o milter_macro_daemon_name=ORIGINATING
#628 inet n - n - - qmqpd
pickup unix n - n 60 1 pickup
cleanup unix n - n - 0 cleanup
qmgr unix n - n 300 1 qmgr
#qmgr unix n - n 300 1 oqmgr
tlsmgr unix - - n 1000? 1 tlsmgr
rewrite unix - - n - - trivial-rewrite
bounce unix - - n - 0 bounce
defer unix - - n - 0 bounce
trace unix - - n - 0 bounce
verify unix - - n - 1 verify
flush unix n - n 1000? 0 flush
proxymap unix - - n - - proxymap
proxywrite unix - - n - 1 proxymap
smtp unix - - n - - smtp
relay unix - - n - - smtp
-o syslog_name=${multi_instance_name?{$multi_instance_name}:{postfix}}/$service_name
# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
showq unix n - n - - showq
error unix - - n - - error
retry unix - - n - - error
discard unix - - n - - discard
local unix - n n - - local
virtual unix - n n - - virtual
lmtp unix - - n - - lmtp
anvil unix - - n - 1 anvil
scache unix - - n - 1 scache
postlog unix-dgram n - n - 1 postlogd
#
# ====================================================================
# Interfaces to non-Postfix software. Be sure to examine the manual
# pages of the non-Postfix software to find out what options it wants.
#
# Many of the following services use the Postfix pipe(8) delivery
# agent. See the pipe(8) man page for information about ${recipient}
# and other message envelope options.
# ====================================================================
#
# maildrop. See the Postfix MAILDROP_README file for details.
# Also specify in main.cf: maildrop_destination_recipient_limit=1
#
#maildrop unix - n n - - pipe
# flags=DRXhu user=vmail argv=/usr/local/bin/maildrop -d ${recipient}
#
# ====================================================================
#
# Recent Cyrus versions can use the existing "lmtp" master.cf entry.
#
# Specify in cyrus.conf:
# lmtp cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4
#
# Specify in main.cf one or more of the following:
# mailbox_transport = lmtp:inet:localhost
# virtual_transport = lmtp:inet:localhost
#
# ====================================================================
#
# Cyrus 2.1.5 (Amos Gouaux)
# Also specify in main.cf: cyrus_destination_recipient_limit=1
#
#cyrus unix - n n - - pipe
# flags=DRX user=cyrus argv=/usr/lib/cyrus-imapd/deliver -e -r ${sender} -m ${extension} ${user}
#
# ====================================================================
#
# Old example of delivery via Cyrus.
#
#old-cyrus unix - n n - - pipe
# flags=R user=cyrus argv=/usr/lib/cyrus-imapd/deliver -e -m ${extension} ${user}
#
# ====================================================================
#
# See the Postfix UUCP_README file for configuration details.
#
#uucp unix - n n - - pipe
# flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
#
# ====================================================================
#
# Other external delivery methods.
#
#ifmail unix - n n - - pipe
# flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
#
#bsmtp unix - n n - - pipe
# flags=Fq. user=bsmtp argv=/usr/local/sbin/bsmtp -f $sender $nexthop $recipient
#
#scalemail-backend unix - n n - 2 pipe
# flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store
# ${nexthop} ${user} ${extension}
#
#mailman unix - n n - - pipe
# flags=FRX user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
# ${nexthop} ${user}

View File

@@ -0,0 +1,8 @@
Username: mave-sftp
Password : asdWFWF45mfEGGEwf
Server : 10.102.1.202
Server : aps-sftp01
User kann schrieben unten die Schnittstellen/Bremen/ Ordner

View File

@@ -18,3 +18,20 @@ https://www.tc-telefon.de/Kontakt/
Kosten aps - Continia - kosten.aps.7739934@cdc.continiaonline.com
Einkauf aps - Continia - einkauf.aps.7739934@cdc.continiaonline.com
Informationstechnologie
Software
tv-token api
297eca2e0221361646d3aa88f4b00e6f
curl -H 'X-Auth-Token: 297eca2e0221361646d3aa88f4b00e6f' https://10.102.1.201/api/v0
jasmin gresen
PG19 : Officin
15454
ilka banemann - laptop - outlook (profile)
inten im Officein drucker von Iphone

BIN
Doc/Bilders/Development.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 877 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 789 KiB

BIN
Doc/Bilders/Scripts.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 760 KiB

View File

@@ -9,11 +9,15 @@ Wifi: a494052388958b494052388958
Wifi: ASR22Antares
KP: MuVD9Zcc4HK0jDQ4HzMt
Sftp : mave-sftp : asdWFWF45mfEGGEwf
SMB : mave-amondis : asdWFasdas43fEGGCf
Smtp : mdmuser : Q8ZdNSEFCPwDCpoPsage
Smtp : n8nuser : Q8ZdNSEFCPwDCpoPsage
Smtp : drucker : Q8ZdNSrFCpwdCPoPsAge
Smtp : elpro : Q8ZwerrRTHwdDfoPsAge
Smtp : maveuser: Q8456rrRgwegwDoRGSRQ
Smtp : useralert : Q845Rr345gwDoRsdRQ
monitor - GNYOJTPFASNEEICPSV
@@ -172,3 +176,10 @@ RCPT TO:<istvan@meszely.eu>
00:08:7B:25:DD:F3
Kapelou2025
Schliesinger mail:
wegner@

View File

@@ -0,0 +1,49 @@
# SOP: Export von Druckprotokollen in MySQL (drucklog_export_v.0.1.ps1)
## 1. Zweck des Skripts
Dieses PowerShell-Skript dient der zentralen Erfassung von Druckvorgängen auf Windows-Servern oder Workstations. Es liest das Ereignisprotokoll `Microsoft-Windows-PrintService/Operational` (Event ID 307) aus und überträgt die Details (Benutzer, Dokumentname, Seitenanzahl, Drucker) in eine MySQL-Datenbank (`drucklog`).
**Nutzen:** Ermöglicht die langfristige Analyse des Druckaufkommens und die Erstellung von Reports für die IT-Administration.
## 2. Voraussetzungen & Installation
Damit das Skript ordnungsgemäß ausgeführt werden kann, müssen folgende Voraussetzungen erfüllt sein:
* **MySQL Connector NET:** Das Skript erwartet die `MySql.Data.dll` im Pfad:
`C:\Program Files (x86)\MySQL\MySQL Connector NET 9.4\MySql.Data.dll`
* **PrintService Log:** Das "Operational"-Protokoll im Windows Event Viewer muss **aktiviert** sein.
* **MySQL Datenbank:** Eine Datenbank namens `drucklog` mit der entsprechenden Tabellenstruktur muss auf dem Host `10.102.1.65` vorhanden sein.
## 3. Zentrale Konfiguration (Skript-Header)
Die Verbindungsparameter sind im Skript wie folgt definiert:
* **MySQL-Host:** `10.102.1.65`
* **Datenbank-Benutzer:** `svc.druckerlog`
* **Datenbank-Passwort:** (Im Skript hinterlegt)
* **Ziel-Datenbank:** `drucklog`
* **Log-Pfad:** `C:\Tools\drucklog_task.log` (Überprüfung der Skriptausführung)
## 4. Ausführung & Automatisierung
Das Skript kann manuell oder über die **Windows Aufgabenplanung (Task Scheduler)** ausgeführt werden.
### Manueller Test (PowerShell):
```powershell
# In das Verzeichnis wechseln und ausführen
.\drucklog_export_v.0.1.ps1
```
### Empfohlene Automatisierung (Task Scheduler):
* **Trigger:** Täglich, Wiederholung alle 1 Stunde.
* **Aktion:** `powershell.exe`
* **Argumente:** `-ExecutionPolicy Bypass -File "C:\Scripts\drucklog_export_v.0.1.ps1"`
## 5. Monitoring & Protokollierung
Das Skript schreibt bei jedem Durchlauf einen Zeitstempel in die lokale Datei:
`C:\Tools\drucklog_task.log`
Bei Fehlern in der Datenbankverbindung prüfen Sie bitte, ob der MySQL-Host `10.102.1.65` vom lokalen System aus erreichbar ist (Port 3306).
## 6. Sicherheitshinweis
**Achtung:** Das Skript enthält Datenbank-Zugangsdaten im Klartext. Stellen Sie sicher, dass die NTFS-Berechtigungen auf dem Windows-Server so gesetzt sind, dass nur das IT-Team Zugriff auf das Skriptverzeichnis hat.
---
*Erstellt für die IT-Dokumentation - Projekt: IT Internal Repository*

24
Doc/Microsoft o365 URL.md Normal file
View File

@@ -0,0 +1,24 @@
1. Kulcsfontosságú URL-ek (FQDN-ek)
A login és az outlook mellett a következőket is engedélyezni kell (jellemzően a 443-as porton):
* Bejelentkezés és Hitelesítés:
* *.microsoftonline.com
* *.microsoft.com
* *.msftauth.net
* *.msauth.net
* Outlook/OWA és Kapcsolódó szolgáltatások:
* *.office.com
* *.office365.com
* *.outlook.com
* Statikus tartalom és CDN (nélkülük lassú vagy szétesik az oldal):
* *.msedge.net
* *.msecnd.net
* *.res.office365.com
*.outlook.office.com
*.office.com
*.microsoftonline.com
*.msftauth.net
https://learn.microsoft.com/en-us/microsoft-365/enterprise/urls-and-ip-address-ranges?view=o365-worldwide

View File

@@ -0,0 +1,38 @@
# SOP: Bereinigung alter Datensätze (delete_old_records.py)
## 1. Zweck des Skripts
Dieses Python-Skript dient der automatischen Bereinigung (Housekeeping) unserer MySQL-Datenbanken. Es entfernt veraltete Datensätze, die eine definierte Aufbewahrungsfrist (Retention Period) überschritten haben, um die Datenbankgröße zu kontrollieren und die Abfragegeschwindigkeit zu optimieren.
## 2. Voraussetzungen
* **Python Version:** Mindestens Python 3.8.
* **Bibliotheken:** `mysql-connector-python`, `python-dotenv`.
* **Datenbankzugriff:** Das Skript benötigt einen Benutzer mit `DELETE`-Berechtigungen auf die entsprechenden Tabellen.
## 3. Konfiguration
Die Steuerung des Skripts erfolgt über eine `.env`-Datei oder direkt im Skript-Header:
* **DB_HOST:** IP des Datenbankservers (z. B. `10.102.1.65`).
* **RETENTION_DAYS:** Anzahl der Tage, nach denen Daten gelöscht werden (Standard: X Tage).
* **DRY_RUN:** Wenn auf `True` gesetzt, zeigt das Skript nur an, was gelöscht würde, ohne die Datenbank tatsächlich zu verändern.
## 4. Ausführung
Es wird empfohlen, das Skript regelmäßig als Cronjob (Linux) oder Task Scheduler (Windows) auszuführen.
### Testlauf (Dry-Run):
```bash
python3 delete_old_records.py --mode dry-run
```
### Scharfe Ausführung:
```bash
python3 delete_old_records.py --mode execute
```
## 5. Monitoring & Logs
Alle Löschvorgänge werden in der Standardausgabe und optional in einer Log-Datei protokolliert. Prüfen Sie regelmäßig die Anzahl der gelöschten Datensätze, um sicherzustellen, dass die Logik korrekt arbeitet.
## 6. Sicherheitshinweis
**Achtung:** Gelöschte Daten können nicht ohne Backup wiederhergestellt werden. Führen Sie vor größeren Änderungen an der Aufbewahrungslogik immer ein Datenbank-Backup durch.
---
*Erstellt für die IT-Dokumentation - Projekt: IT Internal Repository*

View File

@@ -0,0 +1,31 @@
# SOP: Behebung winmail.dat Anhang-Fehler (Office 365)
## Problembeschreibung
Wenn E-Mails an externe Empfänger gesendet werden, werden Anhänge (z. B. PDF-Dateien) nicht korrekt angezeigt, sondern sind in einer einzigen `winmail.dat`-Datei verpackt. Dies wird durch das Outlook-eigene **TNEF (Transport Neutral Encapsulation Format)** verursacht, das andere E-Mail-Clients nicht interpretieren können.
## Lösungsmöglichkeiten
### 1. Globale Lösung (Exchange Online Admin) - EMPFOHLEN
Diese Einstellung gilt für die gesamte Organisation und deaktiviert die TNEF-Codierung auf Serverebene für externe Empfänger.
1. Melden Sie sich im **Exchange Admin Center** an.
2. Navigieren Sie zu: **Mail flow** (Nachrichtenfluss) -> **Remote domains** (Remote-Domänen).
3. Wählen Sie die Domäne **Default** (*) aus.
4. Suchen Sie die Einstellung **Use Table Neutral Encapsulation Format (TNEF)**.
5. Setzen Sie den Wert auf **Never** (Niemals).
6. Speichern Sie die Änderungen.
### 2. PowerShell-Lösung (Schnellere Administration)
Führen Sie den folgenden Befehl im Exchange Online PowerShell-Modul aus:
```powershell
Set-RemoteDomain -Identity Default -TNEFEnabled $false
```
### 3. Einzelne Benutzerlösung (Outlook Client)
Wenn die Korrektur nur an einem PC erfolgen soll:
1. **Datei -> Optionen -> E-Mail**.
2. Im Abschnitt **Nachrichtenformat**: *"Beim Senden von Nachrichten im Rich-Text-Format an externe Empfänger"* -> Auf **In HTML-Format konvertieren** umstellen.
---
*Erstellt am: 24. März 2026*

View File

@@ -0,0 +1,31 @@
# SOP: winmail.dat csatolmány hiba javítása (Office 365)
## Probléma leírása
Külső címzetteknek küldött e-mailek esetén a csatolmányok (például PDF fájlok) nem megfelelően érkeznek meg, hanem egyetlen `winmail.dat` fájlba csomagolva látszanak. Ezt az Outlook saját **TNEF (Transport Neutral Encapsulation Format)** kódolása okozza, amit más levelezőrendszerek nem tudnak értelmezni.
## Megoldási lehetőségek
### 1. Globális megoldás (Exchange Online Admin) - JAVASOLT
Ez a beállítás az egész szervezetre vonatkozik, és szerver szinten tiltja le a TNEF kódolást a külső címzettek felé.
1. Lépj be az **Exchange Admin Center** felületre.
2. Navigálj ide: **Mail flow** (Üzenetküldés) -> **Remote domains** (Távoli tartományok).
3. Válaszd ki a **Default** (*) tartományt.
4. Keresd meg a **Use Table Neutral Encapsulation Format (TNEF)** beállítást.
5. Állítsd az értékét **Never** (Soha) típusra.
6. Mentsd el a módosításokat.
### 2. PowerShell megoldás (Gyorsabb adminisztráció)
Futtasd az alábbi parancsot az Exchange Online PowerShell modulban:
```powershell
Set-RemoteDomain -Identity Default -TNEFEnabled $false
```
### 3. Egyéni felhasználói megoldás (Outlook kliens)
Ha csak egy gépen kell javítani:
1. **Fájl -> Beállítások -> Posta**.
2. Az **Üzenetformátum** résznél: *"Üzenetek küldése RTF formátumban külső címzetteknek"* -> Állítsd át **Konvertálás HTML formátumra** értékre.
---
*Készült: 2026. március 24.*

View File

@@ -0,0 +1,41 @@
# SOP: Automatisierter PDF-Import aus O365 (import_pdf_from_o365_de.v2.2.py)
## 1. Zweck des Skripts
Dieses Python-Skript automatisiert den Import von PDF-Dokumenten aus der Microsoft 365-Umgebung (z.B. Outlook-Postfächer oder SharePoint) in das lokale IT-Dateisystem. Es dient zur effizienten Digitalisierung von Dokumenten, die als E-Mail-Anhänge eingehen.
## 2. Voraussetzungen & Bibliotheken
Um das Skript auszuführen, sind folgende Module notwendig:
* **Python:** Version 3.8+
* **Module:** `pip install O365 requests python-dotenv`
* **Infrastruktur:** Eine registrierte Anwendung in Azure AD (Entra ID) mit den entsprechenden API-Berechtigungen (`Mail.Read`, `Files.Read`).
## 3. Zentrale Konfiguration
Das Skript benötigt eine `.env`-Datei mit folgenden Zugangsdaten:
* **CLIENT_ID:** Die ID der registrierten Azure-App.
* **CLIENT_SECRET:** Das zugehörige Client-Secret für die Authentifizierung.
* **TARGET_FOLDER:** Der lokale Pfad, in dem die PDF-Dateien gespeichert werden sollen.
* **MAILBOX:** Die E-Mail-Adresse des zu überwachenden Postfachs.
## 4. Ausführung & Betrieb
Das Skript kann sowohl manuell als auch automatisiert über einen Dienst oder Cronjob gestartet werden.
### Manueller Start:
```bash
# Skript manuell aufrufen
python3 import_pdf_from_o365_de.v2.2.py
```
### Fehlerbehebung (Troubleshooting):
* **Authentifizierungsfehler:** Prüfen Sie, ob das Client-Secret abgelaufen ist oder die Berechtigungen in Azure AD korrekt gesetzt sind.
* **Download-Fehler:** Stellen Sie sicher, dass das Zielverzeichnis vorhanden ist und Schreibrechte bestehen.
## 5. Monitoring
Die Ausführung des Skripts wird standardmäßig protokolliert. Bei erfolgreichem Import werden die entsprechenden Log-Einträge erstellt, die den Dateinamen und den Zeitstempel enthalten.
## 6. Sicherheitshinweis
Bewahren Sie die `.env`-Datei sicher auf und geben Sie das **Client-Secret** niemals an unbefugte Personen weiter. Es wird empfohlen, die Secret-Rotation gemäß IT-Sicherheitsrichtlinien regelmäßig durchzuführen.
---
*Erstellt für die IT-Dokumentation - Projekt: IT Internal Repository*

View File

@@ -1,41 +0,0 @@
+ Angel
+ Aalbek
+ Beek
Donau
+ Eider
+ Elbe
+ Emmer
+ Ems
Enz
+ Fintau
+ Flottbek
+ Goldbach
+ Hamme
+ Hellbach
+ Jasenitz
+ Juemme
+ Linde
+ Orthbrookgraben
+ Lottbek
+ Bille
+ Iller
Ahr_Struensee-Haus
+ Müritz
+ Weser
+ Radegast
+ Seseke
+ Siede
+ Zorge
Elbe 01 - Stuensee - Haus
Auf Elbe:
+ Elena Rattelmüller
+ Gloria Blewussi
+ Sarah Bidar
+ Kevin Vischer
+ Saskia Koiteck
+ Tamara Look
+ Marie Kopte
+ Vanessa Mettenbrink
+ Anne Häusler

View File

@@ -1,12 +0,0 @@
Liebe Kolleginnen und Kollegen,
auf dem Drucker Elbe im Erste Etage stehen folgende E-Mail-Adressen für „Senden als E-Mail“ zur Verfügung:
Kosten aps Continia
kosten.aps.7739934@cdc.continiaonline.com
Einkauf aps Continia
einkauf.aps.7739934@cdc.continiaonline.com
Viele Grüße
IT Team

View File

@@ -87,6 +87,7 @@ services:
- DB_USER=librenms
- DB_PASSWORD=${MYSQL_PASSWORD}
- REDIS_HOST=redis
- LIBRENMS_ALLOW_LOGIN_GET=true
- DISPATCHER_NODE_ID=dispatcher1
- SIDECAR_DISPATCHER=1
restart: always

View File

@@ -34,6 +34,7 @@ A kedvenc programozási nyelvem a Python.
Weboldalak amiket hasznälni szoktunk:
mermaid.live
Általában fedora linux alatt dolgozunk.
Második leggyakrabban használt linux az Ubuntu alapu.
Virtualizácionk Proxmox VE
Általában szerver oldalon Fedora Linux alatt dolgozunk.
A második leggyakrabban használt linux az Ubuntu alapú (szintén szerver).
Kliens oldalon (munkaállomás) Windows 11-et vagy macOS-t használunk.
Virtualizációnk Proxmox VE.

View File

@@ -5,47 +5,37 @@ Egy központi, felhőalapú (O365) platform létrehozása az IT részleg összes
## 2. Webhely Típusa
- **Típus:** SharePoint Team Site (**Privát**)
- **Név javaslat:** `IT Internal Repository`
- **Hozzáférés:** Kizárólag az IT csapat tagjai számára.
- **Név:** `IT Internal Repository`
- **Hozzáférés:** Kizárólag az IT csapat tagjai számára (Tulajdonosok és Tagok).
## 3. Javasolt Struktúra (Dokumentumtárak)
A meglévő helyi struktúra alapján az alábbi könyvtárakat hozzuk létre:
## 3. Végleges Struktúra (Dokumentumtárak)
A SharePoint felületen kialakított mappaszerkezet:
- **01_Infrastructure (Infrastruktúra):**
- Switch konfigok (`Conf/Switch/`), szerver beállítások (`Conf/aps.local/`), hálózati rajzok.
- *Metaadat javaslat:* Eszköz típusa, Gyártó.
- **02_Development_Projects (Projektek):**
- Docker fájlok, n8n munkafolyamatok, Python fejlesztések (`Dev/`).
- *Cél:* Fejlesztési dokumentáció és kódminták.
- **03_Knowledge_Base (Wiki / SOP):**
- Telepítési útmutatók, hibajegy-megoldások, folyamatleírások (`Doc/`).
- *Formátum:* SharePoint Pages vagy Markdown.
- **04_Automation_Scripts (Szkriptek):**
- Bash, PowerShell, Python szkriptek gyűjteménye (`Scripts/`).
- *Előny:* Felhőből bárhonnan elérhető kódminták.
- **05_Archive (Archívum):**
- Régi backupok, kifutott projektek (`Backup/`).
- **01_Infrastructure:** Postfix konfigok, Switch beállítások, hálózati rajzok.
- **02_Software:** Telepítőfájlok (.zip, .exe), szoftveres dokumentációk.
- **03_Knowledge_Base:** Általános IT útmutatók és Markdown (.md) dokumentumok.
- **04_Automation_Scripts:** Python és Bash szkriptek gyűjteménye.
- **05_Archive:** Régi mentések és logok.
## 4. Technikai Funkciók (IT Fókusz)
- **Verziókezelés:** Minden fájl módosítása visszakövethető (SharePoint Version History).
- **OneDrive Sync:** A fájlok helyi (Windows/Linux) szerkesztése és automatikus szinkronizációja (VS Code ajánlott).
- **Markdown és Plain Text (.txt) Stratégia:**
- A technikai dokumentáció (.md) és a nyers konfigurációk (.txt, .conf, .sh) eredeti formátumban maradnak.
- A switch konfigok (.txt) közvetlenül olvashatók és kereshetők a SharePoint webes felületén.
- A verziókövetés lehetővé teszi a konfigurációk közötti különbségek követését.
- A képek megjelenítése miatt a komplex dokumentációhoz a helyi szerkesztés (VS Code + OneDrive) ajánlott.
- **SOP (Wiki) Oldalak:** Modern SharePoint oldalakat használunk a folyamatok leírására (német nyelven a kollégáknak).
- **Code Snippets:** A kódminták szintaxis-kiemeléssel jelennek meg az oldalakon.
- **Verziókezelés:** Minden fájl módosítása visszakövethető.
- **OneDrive Sync:** Windows/WSL környezetből való kényelmes feltöltés és szinkronizáció.
- **Teams Integráció:**
- A SharePoint webhelyhez kapcsolódó Teams csapat automatikusan létrejön.
- A dokumentumtárak (Libraries) külön fülként (Tab) hozzáadhatók a Teams csatornákhoz.
- Gyors elérés: Fájlok megtekintése és alapvető szerkesztése közvetlenül a Teams felületén.
- Központi keresés: A Teams keresője megtalálja a SharePointon tárolt konfigokat és leírásokat is.
## 5. Következő Lépések (Teendők)
## 5. Elvégzett és Következő Lépések
- [x] Célközönség meghatározása (Csak IT).
- [ ] Üres SharePoint Site létrehozása (Privát Team Site).
- [ ] Dokumentumtárak (Libraries) létrehozása a fenti struktúra szerint.
- [ ] Kezdeti adatok feltöltése (OneDrive szinkronizációval).
- [x] Privát SharePoint Team Site létrehozása.
- [x] Dokumentumtárak (Libraries) kialakítása (01-05).
- [x] Kezdőlap (Dashboard) testreszabása (Hero, Schnelllinks).
- [x] Első SOP (Wiki) oldalak létrehozása (Német nyelven).
- [ ] Teljes adatkészlet feltöltése (OneDrive szinkronizáció befejezése).
- [ ] Teams integráció véglegesítése (Tab-ok hozzáadása).
## 6. Megvalósított SOP Oldalak (2026.03.16)
- **SOP: Automatisierter PDF-Import aus O365 (v2.2)**
- **SOP: Bereinigung alter Datensätze (delete_old_records.py)**
- **SOP: Konfiguration Postfix SMTP Relay (APS-SMTP01)**
---
*Ez a dokumentum a Gemini CLI segítségével készült, és a projekt aktuális állapotát tükrözi.*

Binary file not shown.

2
Personal/Films.md Normal file
View File

@@ -0,0 +1,2 @@
https://www.imdb.com/de/title/tt30923123/

View File

@@ -1,2 +0,0 @@
useradd -M -s /sbin/nologin n8nuser
passwd n8nuser

View File

@@ -0,0 +1,37 @@
#!/bin/bash
# ----------------------------------------------------------------
# SSH Login Alert Script (DE)
# Dieses Skript sendet eine E-Mail an eine angegebene Adresse,
# wenn sich ein Benutzer über SSH anmeldet.
# ----------------------------------------------------------------
# Geben Sie hier die E-Mail-Adresse ein, an die die Benachrichtigung gesendet werden soll.
RECIPIENT_EMAIL="ihre_email_adresse@example.com"
# Betreff der E-Mail. Der Befehl `hostname` fügt den Servernamen ein.
SUBJECT="SSH-Anmeldung: $USER auf Server $(hostname -f)"
# Extrahiere nur die IP-Adresse aus der SSH_CLIENT-Variablen.
# Z. B. "1.2.3.4 56789 22" -> "1.2.3.4"
CLIENT_IP=${SSH_CLIENT%% *}
# E-Mail-Inhalt. 'cat << EOF' ist eine elegante Art, mehrzeiligen Text zu verarbeiten.
BODY=$(cat << EOF
Eine SSH-Anmeldung ist auf dem Server $(hostname -f) erfolgt.
Details:
Benutzer: $USER
IP-Adresse: $CLIENT_IP
Zeitpunkt: $(date +"%Y-%m-%d %H:%M:%S")
--- Aktuell angemeldete Benutzer ---
$(who)
EOF
)
# E-Mail mit dem 'mail'-Befehl senden.
# Nur senden, wenn die Variable SSH_CLIENT existiert (d. h. es handelt sich um eine SSH-Verbindung).
if [ -n "$SSH_CLIENT" ]; then
echo "$BODY" | mail -s "$SUBJECT" "$RECIPIENT_EMAIL"
fi

View File

@@ -1,47 +0,0 @@
$events = Get-WinEvent -LogName "Microsoft-Windows-PrintService/Operational" -MaxEvents 500 |
Where-Object { $_.Id -eq 307 }
$logList = @()
foreach ($event in $events) {
$message = $event.Message
$user = ""
$document = ""
$printer = ""
$pages = ""
# Felhasználó (pl. L.Vogt auf APS-NB072)
if ($message -match "im Besitz von (.+?) wurde auf") {
$user = $matches[1].Trim()
}
# Nyomtató neve (pl. Jasenitz)
if ($message -match "wurde auf (.+?) über Port") {
$printer = $matches[1].Trim()
}
# Oldalszám (pl. Gedruckte Seiten: 1)
if ($message -match "Gedruckte Seiten:\s+(\d+)") {
$pages = $matches[1]
}
# Dokumentum sorszám (pl. Dokument 62) jobb híján
if ($message -match "^Dokument\s+(\d+)") {
$document = "Dokument " + $matches[1]
}
$logList += [PSCustomObject]@{
Datum = $event.TimeCreated
Benutzer = $user
Dokument = $document
Drucker = $printer
Seiten = $pages
}
}
# Exportálás CSV-be
$exportPfad = "$env:USERPROFILE\Desktop\drucklog_export.csv"
$logList | Export-Csv -Path $exportPfad -NoTypeInformation -Encoding UTF8
Write-Host "Exportálás kész: $exportPfad"

View File

@@ -1,54 +0,0 @@
$events = Get-WinEvent -LogName "Microsoft-Windows-PrintService/Operational" -MaxEvents 500 |
Where-Object { $_.Id -eq 307 }
$logList = @()
foreach ($event in $events) {
$message = $event.Message
$user = ""
$computer = ""
$document = ""
$printer = ""
$pages = ""
# Felhasználó és gép különválasztása
if ($message -match "im Besitz von (.+?) wurde auf") {
$fullUser = $matches[1].Trim()
if ($fullUser -match "^(.+?) auf (.+)$") {
$user = $matches[1].Trim()
$computer = $matches[2].Trim()
} else {
$user = $fullUser
}
}
# Nyomtató neve (pl. Jasenitz)
if ($message -match "wurde auf (.+?) über Port") {
$printer = $matches[1].Trim()
}
# Oldalszám (pl. Gedruckte Seiten: 1)
if ($message -match "Gedruckte Seiten:\s+(\d+)") {
$pages = $matches[1]
}
# Dokument sorszám (pl. Dokument 62)
if ($message -match "^Dokument\s+(\d+)") {
$document = "Dokument " + $matches[1]
}
$logList += [PSCustomObject]@{
Datum = $event.TimeCreated
Benutzer = $user
Computer = $computer
Dokument = $document
Drucker = $printer
Seiten = $pages
}
}
# Exportálás CSV-be
$exportPfad = "$env:USERPROFILE\Desktop\drucklog_export.csv"
$logList | Export-Csv -Path $exportPfad -NoTypeInformation -Encoding UTF8
Write-Host "Exportálás kész: $exportPfad"

View File

@@ -1,75 +0,0 @@
# Printer Log Report 0.3
#
# Get-WinEvent on Englische Windows : Get-WinEvent -LogName "Microsoft-Windows-PrintService/Operational"
# Get-WinEvent on Deutsche Windows : Get-WinEvent -LogName "Microsoft-Windows-PrintService/Betriebsbereit"
$events = Get-WinEvent -LogName "Microsoft-Windows-PrintService/Operational" -MaxEvents 500 |
Where-Object { $_.Id -eq 307 }
$logList = @()
foreach ($event in $events) {
$message = $event.Message
$user = ""
$computer = ""
$document = ""
$printer = ""
$pages = 0
# Felhasználó és gép különválasztása
if ($message -match "im Besitz von (.+?) wurde auf") {
$fullUser = $matches[1].Trim()
if ($fullUser -match "^(.+?) auf (.+)$") {
$user = $matches[1].Trim()
$computer = $matches[2].Trim()
} else {
$user = $fullUser
}
}
# Nyomtató neve (pl. Jasenitz)
if ($message -match "wurde auf (.+?) über Port") {
$printer = $matches[1].Trim()
}
# Oldalszám (pl. Gedruckte Seiten: 1)
if ($message -match "Gedruckte Seiten:\s+(\d+)") {
$pages = [int]$matches[1]
}
# Dokument sorszám (pl. Dokument 62)
if ($message -match "^Dokument\s+(\d+)") {
$document = "Dokument " + $matches[1]
}
$logList += [PSCustomObject]@{
Datum = $event.TimeCreated
Benutzer = $user
Computer = $computer
Dokument = $document
Drucker = $printer
Seiten = $pages
}
}
# Export részletes lista
$exportPfad = "$env:USERPROFILE\Desktop\drucklog_export.csv"
$logList | Export-Csv -Path $exportPfad -NoTypeInformation -Encoding UTF8
# ✅ Összesítés felhasználónként
$summary = $logList | Group-Object -Property Benutzer | ForEach-Object {
$userGroup = $_.Group
[PSCustomObject]@{
Benutzer = $_.Name
Anzahl_Dokumente = $userGroup.Count
Gesamt_Seiten = ($userGroup | Measure-Object -Property Seiten -Sum).Sum
}
}
# Export összesítés
$summaryPfad = "$env:USERPROFILE\Desktop\drucklog_summary.csv"
$summary | Export-Csv -Path $summaryPfad -NoTypeInformation -Encoding UTF8
Write-Host "Exportálás kész:"
Write-Host "- Részletes lista: $exportPfad"
Write-Host "- Felhasználónkénti összesítés: $summaryPfad"

View File

@@ -1,152 +0,0 @@
# Printer Log Report 0.3
#
# Get-WinEvent on Englische Windows : Get-WinEvent -LogName "Microsoft-Windows-PrintService/Operational"
# Get-WinEvent on Deutsche Windows : Get-WinEvent -LogName "Microsoft-Windows-PrintService/Betriebsbereit"
$events = Get-WinEvent -LogName "Microsoft-Windows-PrintService/Operational" -MaxEvents 2000 |
Where-Object { $_.Id -eq 307 }
$logList = @()
foreach ($event in $events) {
$message = $event.Message
$user = ""
$computer = ""
$document = ""
$printer = ""
$pages = 0
if ($message -match "im Besitz von (.+?) wurde auf") {
$fullUser = $matches[1].Trim()
if ($fullUser -match "^(.+?) auf (.+)$") {
$user = $matches[1].Trim()
$computer = $matches[2].Trim()
} else {
$user = $fullUser
}
}
if ($message -match "wurde auf (.+?) über Port") {
$printer = $matches[1].Trim()
}
if ($message -match "Gedruckte Seiten:\s+(\d+)") {
$pages = [int]$matches[1]
}
if ($message -match "^Dokument\s+(\d+)") {
$document = "Dokument " + $matches[1]
}
$logList += [PSCustomObject]@{
Datum = $event.TimeCreated
Tag = $event.TimeCreated.Date.ToString("yyyy-MM-dd")
Woche = Get-Date $event.TimeCreated -UFormat "%Y-W%V"
Benutzer = $user
Computer = $computer
Dokument = $document
Drucker = $printer
Seiten = $pages
}
}
# 🔹 Export részletes lista
$exportPfad = "$env:USERPROFILE\Desktop\drucklog_export.csv"
$logList | Export-Csv -Path $exportPfad -NoTypeInformation -Encoding UTF8
# 🔸 Összesítés felhasználónként (teljes)
$summary = $logList | Group-Object -Property Benutzer | ForEach-Object {
$userGroup = $_.Group
[PSCustomObject]@{
Benutzer = $_.Name
Anzahl_Dokumente = $userGroup.Count
Gesamt_Seiten = ($userGroup | Measure-Object -Property Seiten -Sum).Sum
}
}
$summary | Export-Csv -Path "$env:USERPROFILE\Desktop\drucklog_summary.csv" -NoTypeInformation -Encoding UTF8
# 🔸 Napi összesítés felhasználónként
$dailySummary = $logList | Group-Object -Property Tag, Benutzer | ForEach-Object {
$day = $_.Group[0].Tag
$user = $_.Group[0].Benutzer
$pages = ($_.Group | Measure-Object -Property Seiten -Sum).Sum
$docs = $_.Count
[PSCustomObject]@{
Datum = $day
Benutzer = $user
Dokumente = $docs
Seiten = $pages
}
}
$dailySummary | Export-Csv -Path "$env:USERPROFILE\Desktop\drucklog_daily.csv" -NoTypeInformation -Encoding UTF8
# 🔸 Heti összesítés felhasználónként (ISO hét formátum: pl. 2025-W30)
$weeklySummary = $logList | Group-Object -Property Woche, Benutzer | ForEach-Object {
$week = $_.Group[0].Woche
$user = $_.Group[0].Benutzer
$pages = ($_.Group | Measure-Object -Property Seiten -Sum).Sum
$docs = $_.Count
[PSCustomObject]@{
Woche = $week
Benutzer = $user
Dokumente = $docs
Seiten = $pages
}
}
$weeklySummary | Export-Csv -Path "$env:USERPROFILE\Desktop\drucklog_weekly.csv" -NoTypeInformation -Encoding UTF8
Write-Host "Exportálás kész:"
Write-Host "- Részletes lista: drucklog_export.csv"
Write-Host "- Összesítés: drucklog_summary.csv"
Write-Host "- Napi összesítés: drucklog_daily.csv"
Write-Host "- Heti összesítés: drucklog_weekly.csv"
# 🔸 Nyomtatónkénti összesítés
$printerSummary = $logList | Group-Object -Property Drucker | ForEach-Object {
$printer = $_.Name
$pages = ($_.Group | Measure-Object -Property Seiten -Sum).Sum
$docs = $_.Count
[PSCustomObject]@{
Drucker = $printer
Dokumente = $docs
Seiten = $pages
}
}
$printerSummary | Export-Csv -Path "$env:USERPROFILE\Desktop\drucklog_by_printer.csv" -NoTypeInformation -Encoding UTF8
# 🔸 Napi összesítés nyomtatónként
$dailyPrinterSummary = $logList | Group-Object -Property Tag, Drucker | ForEach-Object {
$day = $_.Group[0].Tag
$printer = $_.Group[0].Drucker
$pages = ($_.Group | Measure-Object -Property Seiten -Sum).Sum
$docs = $_.Count
[PSCustomObject]@{
Datum = $day
Drucker = $printer
Dokumente = $docs
Seiten = $pages
}
}
$dailyPrinterSummary | Export-Csv -Path "$env:USERPROFILE\Desktop\drucklog_daily_by_printer.csv" -NoTypeInformation -Encoding UTF8
# 🔸 Heti összesítés nyomtatónként
$weeklyPrinterSummary = $logList | Group-Object -Property Woche, Drucker | ForEach-Object {
$week = $_.Group[0].Woche
$printer = $_.Group[0].Drucker
$pages = ($_.Group | Measure-Object -Property Seiten -Sum).Sum
$docs = $_.Count
[PSCustomObject]@{
Woche = $week
Drucker = $printer
Dokumente = $docs
Seiten = $pages
}
}
$weeklyPrinterSummary | Export-Csv -Path "$env:USERPROFILE\Desktop\drucklog_weekly_by_printer.csv" -NoTypeInformation -Encoding UTF8

View File

@@ -1,98 +0,0 @@
# Drucklog_Export.ps1
# Nyomtatási napló beolvasása Event Log-ból, feldolgozása és mentése SQLite adatbázisba duplikációk nélkül
# Fontos modul SQLite feldolgozäshoz
# Install-Module -Name SQLite -Scope CurrentUser
# Import-Module SQLite
# --- Beállítások ---
$logName = "Microsoft-Windows-PrintService/Operational"
$dbPath = "$env:USERPROFILE\Desktop\drucklog_APS-PRINT01.db"
# $dbPath = "$env:USERPROFILE\Desktop\drucklog_APS-PRINT02.db"
# --- SQLite kapcsolat ---
# Add-Type -Path "C:\Tools\SQLite\System.Data.SQLite.dll"
$connectionString = "Data Source=$dbPath;Version=3;"
$connection = New-Object System.Data.SQLite.SQLiteConnection($connectionString)
$connection.Open()
# --- Tábla létrehozása, ha nem létezik ---
$createTableCmd = $connection.CreateCommand()
$createTableCmd.CommandText = @"
CREATE TABLE IF NOT EXISTS drucklog (
id INTEGER PRIMARY KEY AUTOINCREMENT,
event_id INTEGER UNIQUE,
datum TEXT,
tag TEXT,
woche TEXT,
benutzer TEXT,
computer TEXT,
dokument TEXT,
drucker TEXT,
seiten INTEGER
);
"@
$createTableCmd.ExecuteNonQuery()
# --- Események lekérdezése ---
$events = Get-WinEvent -LogName $logName -ErrorAction SilentlyContinue | Where-Object { $_.Id -eq 307 }
# --- Adatok feldolgozása ---
$logList = foreach ($event in $events) {
$msg = $event.Message
if ($msg -match "im Besitz von (.+?) auf (.+?) wurde auf (.+?) über Port") {
$benutzer = $matches[1]
$computer = $matches[2]
$drucker = $matches[3]
}
else {
continue
}
$dokument = if ($msg -match "Dokument (.+?), Dokument drucken") { $matches[1] } else { "Unbekannt" }
$seiten = if ($msg -match "Gedruckte Seiten: (\d+)") { [int]$matches[1] } else { 0 }
$calendar = [System.Globalization.CultureInfo]::CurrentCulture.Calendar
$weekRule = [System.Globalization.CalendarWeekRule]::FirstFourDayWeek
$firstDay = [System.DayOfWeek]::Monday
$woche = $calendar.GetWeekOfYear($event.TimeCreated, $weekRule, $firstDay)
[PSCustomObject]@{
Id = $event.RecordId
Datum = $event.TimeCreated.ToString("yyyy-MM-dd HH:mm:ss")
Tag = $event.TimeCreated.ToString("yyyy-MM-dd")
Woche = $woche
Benutzer = $benutzer
Computer = $computer
Dokument = $dokument
Drucker = $drucker
Seiten = $seiten
}
}
# --- Adatok mentése adatbázisba, duplikáció nélkül ---
foreach ($row in $logList) {
$checkCmd = $connection.CreateCommand()
$checkCmd.CommandText = "SELECT COUNT(*) FROM drucklog WHERE event_id = @id"
$checkCmd.Parameters.AddWithValue("@id", $row.Id)
$exists = $checkCmd.ExecuteScalar()
if ($exists -eq 0) {
$insertCmd = $connection.CreateCommand()
$insertCmd.CommandText = "INSERT INTO drucklog (event_id, datum, tag, woche, benutzer, computer, dokument, drucker, seiten)
VALUES (@id, @datum, @tag, @woche, @benutzer, @computer, @dokument, @drucker, @seiten)"
$insertCmd.Parameters.AddWithValue("@id", $row.Id)
$insertCmd.Parameters.AddWithValue("@datum", $row.Datum)
$insertCmd.Parameters.AddWithValue("@tag", $row.Tag)
$insertCmd.Parameters.AddWithValue("@woche", $row.Woche)
$insertCmd.Parameters.AddWithValue("@benutzer", $row.Benutzer)
$insertCmd.Parameters.AddWithValue("@computer", $row.Computer)
$insertCmd.Parameters.AddWithValue("@dokument", $row.Dokument)
$insertCmd.Parameters.AddWithValue("@drucker", $row.Drucker)
$insertCmd.Parameters.AddWithValue("@seiten", $row.Seiten)
$insertCmd.ExecuteNonQuery()
}
}
$connection.Close()
Write-Host "Sikeresen frissítve: $($logList.Count) esemény feldolgozva."

View File

@@ -1,101 +0,0 @@
# Drucklog_Export.ps1
# Nyomtatási napló beolvasása Event Log-ból, feldolgozása és mentése SQLite adatbázisba duplikációk nélkül
# Fontos modul SQLite feldolgozäshoz
# Install-Module -Name SQLite -Scope CurrentUser
# Import-Module SQLite
# --- Beállítások ---
$logName = "Microsoft-Windows-PrintService/Operational"
$dbPath = "$env:USERPROFILE\Desktop\drucklog_APS-PRINT01.db"
# $dbPath = "$env:USERPROFILE\Desktop\drucklog_APS-PRINT02.db"
# --- SQLite kapcsolat ---
# Add-Type -Path "C:\Tools\SQLite\System.Data.SQLite.dll"
$connectionString = "Data Source=$dbPath;Version=3;"
$connection = New-Object System.Data.SQLite.SQLiteConnection($connectionString)
$connection.Open()
# --- Tábla létrehozása, ha nem létezik ---
$createTableCmd = $connection.CreateCommand()
$createTableCmd.CommandText = @"
CREATE TABLE IF NOT EXISTS drucklog (
id INTEGER PRIMARY KEY AUTOINCREMENT,
event_id INTEGER UNIQUE,
datum TEXT,
tag TEXT,
woche TEXT,
benutzer TEXT,
computer TEXT,
dokument TEXT,
drucker TEXT,
seiten INTEGER
);
"@
$createTableCmd.ExecuteNonQuery()
# --- Események lekérdezése ---
$events = Get-WinEvent -LogName $logName -ErrorAction SilentlyContinue | Where-Object { $_.Id -eq 307 }
# --- Adatok feldolgozása ---
$logList = foreach ($event in $events) {
$msg = $event.Message
if ($msg -match "im Besitz von (.+?) auf (.+?) wurde auf (.+?) über Port") {
$benutzer = $matches[1]
$computer = $matches[2]
$drucker = $matches[3]
}
else {
continue
}
$dokument = if ($msg -match "Dokument (.+?), Dokument drucken") { $matches[1] } else { "Unbekannt" }
$seiten = if ($msg -match "Gedruckte Seiten: (\d+)") { [int]$matches[1] } else { 0 }
$calendar = [System.Globalization.CultureInfo]::CurrentCulture.Calendar
$weekRule = [System.Globalization.CalendarWeekRule]::FirstFourDayWeek
$firstDay = [System.DayOfWeek]::Monday
$woche = $calendar.GetWeekOfYear($event.TimeCreated, $weekRule, $firstDay)
[PSCustomObject]@{
Id = $event.RecordId
Datum = $event.TimeCreated.ToString("yyyy-MM-dd HH:mm:ss")
Tag = $event.TimeCreated.ToString("yyyy-MM-dd")
Woche = $woche
Benutzer = $benutzer
Computer = $computer
Dokument = $dokument
Drucker = $drucker
Seiten = $seiten
}
}
# --- Adatok mentése adatbázisba, duplikáció nélkül ---
$ujBejegyzesek = 0
foreach ($row in $logList) {
$checkCmd = $connection.CreateCommand()
$checkCmd.CommandText = "SELECT COUNT(*) FROM drucklog WHERE event_id = @id"
$checkCmd.Parameters.AddWithValue("@id", $row.Id)
$exists = $checkCmd.ExecuteScalar()
if ($exists -eq 0) {
$insertCmd = $connection.CreateCommand()
$insertCmd.CommandText = "INSERT INTO drucklog (event_id, datum, tag, woche, benutzer, computer, dokument, drucker, seiten)
VALUES (@id, @datum, @tag, @woche, @benutzer, @computer, @dokument, @drucker, @seiten)"
$insertCmd.Parameters.AddWithValue("@id", $row.Id)
$insertCmd.Parameters.AddWithValue("@datum", $row.Datum)
$insertCmd.Parameters.AddWithValue("@tag", $row.Tag)
$insertCmd.Parameters.AddWithValue("@woche", $row.Woche)
$insertCmd.Parameters.AddWithValue("@benutzer", $row.Benutzer)
$insertCmd.Parameters.AddWithValue("@computer", $row.Computer)
$insertCmd.Parameters.AddWithValue("@dokument", $row.Dokument)
$insertCmd.Parameters.AddWithValue("@drucker", $row.Drucker)
$insertCmd.Parameters.AddWithValue("@seiten", $row.Seiten)
$insertCmd.ExecuteNonQuery()
$ujBejegyzesek++
}
}
$connection.Close()
Write-Host "Sikeresen frissítve: $($logList.Count) esemény feldolgozva."
Write-Host "Új bejegyzések az adatbázisban: $ujBejegyzesek"

View File

@@ -1,81 +0,0 @@
# Drucklog_MySQL.ps1
# Install-Module MySQLCmdlets
# Nyomtatási napló export MySQL adatbázisba
# Aufgabeplannung: Taglich um 8.00 Uhr
# Name: Drucklog_MySQL_0.1.ps1
# powershell.exe -ExecutionPolicy Bypass -File "-ExecutionPolicy Bypass -File "C:\Tools\drucklog_export_0.1.ps1"
# Beállítások
$logName = "Microsoft-Windows-PrintService/Operational"
$mysqlHost = "10.101.0.82"
$mysqlUser = "druckloguser"
$mysqlPassword = "Test123#"
$mysqlDatabase = "drucklog"
$quelleServer = $env:COMPUTERNAME # vagy: "Szerver01"
# MySQL .NET csomag betöltése (előzetesen szükséges: MySql.Data.dll)
# Add-Type -Path "C:\Tools\MySql.Data.dll"
# Add-Type -Path "C:\Program Files (x86)\MySQL\MySQL Connector NET 9.4\MySql.Data.dll"
[Reflection.Assembly]::LoadFrom("C:\Program Files (x86)\MySQL\MySQL Connector NET 9.4\MySql.Data.dll") | Out-Null
# Kapcsolódás
$connectionString = "server=$mysqlHost;user id=$mysqlUser;password=$mysqlPassword;database=$mysqlDatabase;SslMode=none"
$connection = New-Object MySql.Data.MySqlClient.MySqlConnection($connectionString)
$connection.Open()
# Lekérés a logból
$events = Get-WinEvent -LogName $logName -ErrorAction SilentlyContinue | Where-Object { $_.Id -eq 307 }
# Kulturális beállítás a heti számításhoz
$calendar = [System.Globalization.CultureInfo]::CurrentCulture.Calendar
$weekRule = [System.Globalization.CalendarWeekRule]::FirstFourDayWeek
$firstDay = [System.DayOfWeek]::Monday
$ujBejegyzes = 0
foreach ($event in $events) {
$msg = $event.Message
if ($msg -match "im Besitz von (.+?) auf (.+?) wurde auf (.+?) über Port") {
$benutzer = $matches[1]
$computer = $matches[2]
$drucker = $matches[3]
} else {
continue
}
$dokument = if ($msg -match "Dokument (.+?), Dokument drucken") { $matches[1] } else { "Unbekannt" }
$seiten = if ($msg -match "Gedruckte Seiten: (\d+)") { [int]$matches[1] } else { 0 }
$woche = $calendar.GetWeekOfYear($event.TimeCreated, $weekRule, $firstDay)
$datum = $event.TimeCreated.ToString("yyyy-MM-dd HH:mm:ss")
$tag = $event.TimeCreated.ToString("yyyy-MM-dd")
$id = $event.RecordId
# Duplikáció ellenőrzés
$checkCmd = $connection.CreateCommand()
$checkCmd.CommandText = "SELECT COUNT(*) FROM drucklog WHERE event_id = @id AND quelle_server = @qs"
$checkCmd.Parameters.AddWithValue("@id", $id)
$checkCmd.Parameters.AddWithValue("@qs", $quelleServer)
$exists = $checkCmd.ExecuteScalar()
if ($exists -eq 0) {
$insertCmd = $connection.CreateCommand()
$insertCmd.CommandText = "INSERT INTO drucklog (event_id, datum, tag, woche, benutzer, computer, dokument, drucker, seiten, quelle_server)
VALUES (@id, @datum, @tag, @woche, @benutzer, @computer, @dokument, @drucker, @seiten, @qs)"
$insertCmd.Parameters.AddWithValue("@id", $id)
$insertCmd.Parameters.AddWithValue("@datum", $datum)
$insertCmd.Parameters.AddWithValue("@tag", $tag)
$insertCmd.Parameters.AddWithValue("@woche", $woche)
$insertCmd.Parameters.AddWithValue("@benutzer", $benutzer)
$insertCmd.Parameters.AddWithValue("@computer", $computer)
$insertCmd.Parameters.AddWithValue("@dokument", $dokument)
$insertCmd.Parameters.AddWithValue("@drucker", $drucker)
$insertCmd.Parameters.AddWithValue("@seiten", $seiten)
$insertCmd.Parameters.AddWithValue("@qs", $quelleServer)
$insertCmd.ExecuteNonQuery()
$ujBejegyzes++
}
}
$connection.Close()
Write-Host "Feldolgozott események: $($events.Count) | Új bejegyzés: $ujBejegyzes"

View File

@@ -1,12 +1,16 @@
# Drucklog_MySQL.ps1
# Drucklog_MySQL.ps1
# Install-Module MySQLCmdlets
# Nyomtatási napló export MySQL adatbázisba
#Teszt
Add-Content -Path "C:\Tools\drucklog_task.log" -Value "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Script futott"
# Beállítások
$logName = "Microsoft-Windows-PrintService/Operational"
$mysqlHost = "10.101.0.82"
$mysqlUser = "druckloguser"
$mysqlPassword = "Test123#"
$mysqlHost = "10.102.1.65"
$mysqlUser = "svc.druckerlog"
$mysqlPassword = "ctqBirh3eEbakLb96Ks1"
$mysqlDatabase = "drucklog"
$quelleServer = $env:COMPUTERNAME # vagy: "Szerver01"
@@ -15,6 +19,7 @@ $quelleServer = $env:COMPUTERNAME # vagy: "Szerver01"
# Add-Type -Path "C:\Program Files (x86)\MySQL\MySQL Connector NET 9.4\MySql.Data.dll"
[Reflection.Assembly]::LoadFrom("C:\Program Files (x86)\MySQL\MySQL Connector NET 9.4\MySql.Data.dll") | Out-Null
# Kapcsolódás
$connectionString = "server=$mysqlHost;user id=$mysqlUser;password=$mysqlPassword;database=$mysqlDatabase;SslMode=none"
$connection = New-Object MySql.Data.MySqlClient.MySqlConnection($connectionString)

View File

@@ -1,91 +0,0 @@
# Requires -Modules @{ModuleName='Microsoft.Graph.Applications';ModuleVersion='1.19.0'}, @{ModuleName='Microsoft.Graph.Mail';ModuleVersion='1.19.0'}
# ==============================================================================
# KONFIGURÁCIÓ
# ==============================================================================
# Adatok az Azure App Regisztrációból
# Tennant ID : caee3499-03f8-4175-9fa8-a935248d0ece
$TENANT_ID = "caee3499-03f8-4175-9fa8-a935248d0ece"
# Client Id : 3a08b279-1fc3-419f-a77e-31f12a0f65f7
$CLIENT_ID = "3a08b279-1fc3-419f-a77e-31f12a0f65f7"
# Key : Rk-8Q~nJ.sZ-xUiNxtEDdzVgoFFosODLVHX~jdrh (érték, nem Secret ID)
$CLIENT_SECRET = "Rk-8Q~nJ.sZ-xUiNxtEDdzVgoFFosODLVHX~jdrh"
# Figyelt postafiók
$USER_EMAIL = "i.meszely@aps-hh.de"
# Microsoft Graph API végpontok (alapértelmezett, nem kell módosítani)
$GRAPH_API_ENDPOINT = "https://graph.microsoft.com/v1.0"
# Scopes needed for the application
# Mail.ReadWrite for reading, marking as read, and eventually moving emails
$SCOPES = @("Mail.ReadWrite")
# ==============================================================================
# FÜGGVÉNYEK
# ==============================================================================
Function Connect-GraphAPI {
<#
.SYNOPSIS
Csatlakozik a Microsoft Graph API-hoz kliens hitelesítő adatokkal.
.DESCRIPTION
Ez a függvény megpróbál csatlakozni a Microsoft Graph API-hoz az Azure AD alkalmazás regisztrációjában megadott
kliens hitelesítő adatok (Tenant ID, Client ID, Client Secret) segítségével.
Sikeres kapcsolat esetén egy Access Token-t ad vissza. Hiba esetén null-t ad vissza és hibaüzenetet ír ki.
.OUTPUTS
Access Token (String) vagy $null
#>
[CmdletBinding()]
Param()
Write-Host "Graph API-hoz való csatlakozás megkezdése..." -ForegroundColor Cyan
try {
# Ellenőrizzük, hogy a szükséges modulok telepítve vannak-e
$requiredModules = @("Microsoft.Graph.Applications", "Microsoft.Graph.Mail")
foreach ($module in $requiredModules) {
if (-not (Get-Module -ListAvailable -Name $module)) {
Write-Warning "A(z) '$module' PowerShell modul nincs telepítve. Kérjük telepítse futtatás előtt: Install-Module $module"
return $null
}
}
# Csatlakozás a Graph API-hoz kliens hitelesítő adatokkal
# A -Scopes paraméterben az alkalmazásengedélyek neveit kell megadni
$connectResult = Connect-MgGraph -TenantId $TENANT_ID -ClientId $CLIENT_ID -ClientSecret $CLIENT_SECRET -Scopes $SCOPES -ErrorAction Stop
if ($connectResult) {
Write-Host "Sikeresen csatlakozott a Graph API-hoz." -ForegroundColor Green
# Lekérjük az Access Token-t
$token = (Get-MsalToken).AccessToken
return $token
} else {
Write-Error "Nem sikerült csatlakozni a Graph API-hoz."
return $null
}
}
catch {
Write-Error "Hiba történt a Graph API-hoz való csatlakozás során: $($_.Exception.Message)"
Write-Host "Kérjük, ellenőrizze a konfigurációs beállításokat (TENANT_ID, CLIENT_ID, CLIENT_SECRET) és az alkalmazásengedélyeket az Azure AD-ben." -ForegroundColor Yellow
return $null
}
}
# ==============================================================================
# FŐ LOGIKA
# ==============================================================================
function Main {
$accessToken = Connect-GraphAPI
if (-not $accessToken) {
Write-Error "Nem sikerült Access Token-t szerezni. Kilépés."
return
}
Write-Host "Access Token sikeresen lekérve. Kész a Graph API hívásokhoz." -ForegroundColor Green
# Itt fogjuk később implementálni az e-mailek feldolgozását
}
# Fő függvény meghívása
Main

View File

@@ -0,0 +1,92 @@
#!/usr/bin/env python3
"""
Fájl kor ellenőrző script n8n automatizáláshoz.
Használat: python3 check_file_age.py <mappa_utvonal> <max_perc>
Kimenet: JSON formátum (n8n barát)
Exit kód: 0 (ha minden rendben), 1 (ha régi fájlt talált vagy hiba történt)
"""
import os
import time
import sys
import json
def check_files(directory, max_age_minutes=40):
now = time.time()
max_age_seconds = max_age_minutes * 60
too_old_files = []
# Mappa létezésének ellenőrzése
if not os.path.exists(directory):
return {
"status": "error",
"alert": True,
"message": f"A megadott könyvtár nem létezik: {directory}",
"files": []
}
try:
# Fájlok listázása
files_in_dir = os.listdir(directory)
for filename in files_in_dir:
filepath = os.path.join(directory, filename)
# Csak a fájlokat ellenőrizzük (mappákat nem)
if os.path.isfile(filepath):
file_age_seconds = now - os.path.getmtime(filepath)
if file_age_seconds > max_age_seconds:
age_min = round(file_age_seconds / 60, 1)
too_old_files.append({
"file": filename,
"age_minutes": age_min,
"last_modified": time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(os.path.getmtime(filepath)))
})
if too_old_files:
return {
"status": "alert",
"alert": True,
"message": f"Találtam {len(too_old_files)} db fájlt, ami régebbi mint {max_age_minutes} perc!",
"directory": directory,
"limit_minutes": max_age_minutes,
"files": too_old_files
}
return {
"status": "ok",
"alert": False,
"message": "Minden fájl friss.",
"directory": directory,
"files": []
}
except Exception as e:
return {
"status": "error",
"alert": True,
"message": f"Hiba történt az ellenőrzés közben: {str(e)}",
"files": []
}
if __name__ == "__main__":
# Paraméterek átvétele a parancssorból
if len(sys.argv) < 2:
print(json.dumps({"status": "error", "message": "Hiányzó paraméter! Használat: python3 check_file_age.py <mappa> <perc>"}))
sys.exit(1)
dir_to_check = sys.argv[1]
age_limit = int(sys.argv[2]) if len(sys.argv) > 2 else 40
result = check_files(dir_to_check, age_limit)
# JSON kimenet az n8n számára
print(json.dumps(result, indent=2))
# Exit code beállítása az n8n SSH Node számára
if result.get("alert"):
sys.exit(1)
else:
sys.exit(0)

View File

@@ -0,0 +1,92 @@
#!/usr/bin/env python3
"""
Skript zur Überprüfung des Dateialters für n8n-Automatisierung.
Verwendung: python3 check_file_age_de.py <verzeichnispfad> <max_minuten>
Ausgabe: JSON-Format (n8n-freundlich)
Exit-Code: 0 (wenn alles ok), 1 (wenn eine alte Datei gefunden wurde oder ein Fehler auftrat)
"""
import os
import time
import sys
import json
def check_files(directory, max_age_minutes=40):
now = time.time()
max_age_seconds = max_age_minutes * 60
too_old_files = []
# Überprüfung, ob das Verzeichnis existiert
if not os.path.exists(directory):
return {
"status": "error",
"alert": True,
"message": f"Das angegebene Verzeichnis existiert nicht: {directory}",
"files": []
}
try:
# Dateien auflisten
files_in_dir = os.listdir(directory)
for filename in files_in_dir:
filepath = os.path.join(directory, filename)
# Nur Dateien prüfen (keine Verzeichnisse)
if os.path.isfile(filepath):
file_age_seconds = now - os.path.getmtime(filepath)
if file_age_seconds > max_age_seconds:
age_min = round(file_age_seconds / 60, 1)
too_old_files.append({
"file": filename,
"age_minutes": age_min,
"last_modified": time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(os.path.getmtime(filepath)))
})
if too_old_files:
return {
"status": "alert",
"alert": True,
"message": f"{len(too_old_files)} Datei(en) gefunden, die älter als {max_age_minutes} Minuten sind!",
"directory": directory,
"limit_minutes": max_age_minutes,
"files": too_old_files
}
return {
"status": "ok",
"alert": False,
"message": "Alle Dateien sind aktuell.",
"directory": directory,
"files": []
}
except Exception as e:
return {
"status": "error",
"alert": True,
"message": f"Fehler während der Überprüfung aufgetreten: {str(e)}",
"files": []
}
if __name__ == "__main__":
# Parameter aus der Befehlszeile übernehmen
if len(sys.argv) < 2:
print(json.dumps({"status": "error", "message": "Fehlender Parameter! Verwendung: python3 check_file_age_de.py <verzeichnis> <minuten>"}))
sys.exit(1)
dir_to_check = sys.argv[1]
age_limit = int(sys.argv[2]) if len(sys.argv) > 2 else 40
result = check_files(dir_to_check, age_limit)
# JSON-Ausgabe für n8n
print(json.dumps(result, indent=2))
# Exit-Code für den n8n SSH-Node festlegen
if result.get("alert"):
sys.exit(1)
else:
sys.exit(0)

View File

@@ -0,0 +1,70 @@
"""
Használati útmutató / Usage:
1. Telepítés / Installation:
pip install markdown-pdf
2. Futtatás / Execution:
- Aktuális könyvtár bejárása:
python Scripts/python/md_to_pdf_recursive.py
- Konkrét könyvtár megadása:
python Scripts/python/md_to_pdf_recursive.py Dev/APS-SFTP01
A script rekurzívan végigjárja a megadott könyvtárat, és minden .md fájl mellé
létrehoz egy azonos nevű .pdf fájlt. A .git, .venv és __pycache__ könyvtárakat kihagyja.
"""
import os
import sys
from markdown_pdf import Section, MarkdownPdf
def convert_md_to_pdf(root_dir):
"""
Rekurzívan végigjárja a megadott könyvtárat és minden .md fájlból PDF-et készít.
"""
print(f"Keresés indítása a következő könyvtárban: {root_dir}")
# Kizárandó könyvtárak (pl. git, virtuális környezet)
exclude_dirs = {'.git', '.venv', '__pycache__', 'node_modules'}
count = 0
for root, dirs, files in os.walk(root_dir):
# Alkönyvtárak szűrése (helyben módosítva a dirs listát)
dirs[:] = [d for d in dirs if d not in exclude_dirs]
for file in files:
if file.endswith(".md"):
md_path = os.path.join(root, file)
pdf_path = os.path.splitext(md_path)[0] + ".pdf"
print(f"Konvertálás: {md_path} -> {pdf_path}")
try:
# Markdown olvasása
with open(md_path, "r", encoding="utf-8") as f:
md_content = f.read()
# PDF generálása
pdf = MarkdownPdf(toc_level=2)
pdf.add_section(Section(md_content, toc=False))
pdf.save(pdf_path)
count += 1
except Exception as e:
print(f"Hiba a fájl feldolgozása közben ({md_path}): {e}")
print(f"\nKész! Összesen {count} fájl lett konvertálva.")
if __name__ == "__main__":
# Ha nincs megadva útvonal, az aktuális könyvtárat használja
target_path = sys.argv[1] if len(sys.argv) > 1 else "."
# Ellenőrizzük a függőséget
try:
import markdown_pdf
except ImportError:
print("Hiba: A 'markdown-pdf' könyvtár nincs telepítve.")
print("Telepítés: pip install markdown-pdf")
sys.exit(1)
convert_md_to_pdf(target_path)

View File

@@ -0,0 +1,297 @@
import os
import requests
import msal
import base64
import logging
import mysql.connector
import sys
sys.stdout.reconfigure(encoding='utf-8')
# ==============================================================================
# MySQL KONFIGURATION
# ==============================================================================
MYSQL_HOST = "10.102.1.65"
MYSQL_USER = "svc.emailtopdf"
MYSQL_PASSWORD = "zZUHrps62skLKfr9yQwQ"
MYSQL_DATABASE = "emailtopdf"
MYSQL_TABLE = "emailtopdf"
# ==============================================================================
def create_log_table_if_not_exists():
"""Létrehozza a naplótáblát, ha még nem létezik."""
try:
cnx = mysql.connector.connect(
host=MYSQL_HOST,
user=MYSQL_USER,
password=MYSQL_PASSWORD,
database=MYSQL_DATABASE
)
cursor = cnx.cursor()
# A tábla struktúrája
create_table_query = f"""
CREATE TABLE IF NOT EXISTS `{MYSQL_TABLE}` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`timestamp` DATETIME DEFAULT CURRENT_TIMESTAMP,
`level` VARCHAR(10),
`message` TEXT
)
"""
cursor.execute(create_table_query)
cnx.commit()
logging.info(f"MySQL naplótábla '{MYSQL_TABLE}' ellenőrizve/létrehozva.")
except mysql.connector.Error as err:
logging.error(f"Hiba a MySQL naplótábla létrehozásakor/ellenőrzésekor: {err}")
finally:
if 'cnx' in locals() and cnx.is_connected():
cursor.close()
cnx.close()
class MySQLHandler(logging.Handler):
"""Egyéni naplózó kezelő, amely MySQL adatbázisba ír."""
def emit(self, record):
# Szűrjük ki a mysql.connector naplókat, hogy elkerüljük a rekurziót
if record.name.startswith('mysql.connector'):
return
try:
cnx = mysql.connector.connect(
host=MYSQL_HOST,
user=MYSQL_USER,
password=MYSQL_PASSWORD,
database=MYSQL_DATABASE
)
cursor = cnx.cursor()
sql = f"INSERT INTO `{MYSQL_TABLE}` (level, message) VALUES (%s, %s)"
# A rekord szintjének és üzenetének használata
cursor.execute(sql, (record.levelname, self.format(record)))
cnx.commit()
except mysql.connector.Error as err:
# Ne naplózzunk a MySQLHandlerben, hogy elkerüljük a végtelen ciklust
# Helyette printeljük ki a hibát, hogy debuggolható legyen.
print(f"Hiba a MySQL naplóbejegyzés beszúrásakor: {err}")
finally:
if 'cnx' in locals() and cnx.is_connected():
cursor.close()
cnx.close()
# ==============================================================================
# LOGGING KONFIGURATION
# ==============================================================================
LOG_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'import_pdf_from_o365_de.v2.1.log')
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler(LOG_FILE, encoding='utf-8'),
logging.StreamHandler(), # Revert to default StreamHandler, encoding is handled by sys.stdout.reconfigure
MySQLHandler() # Re-enabled MySQLHandler
]
)
# ==============================================================================
# ==============================================================================
# KONFIGURATION
# ==============================================================================
# Daten aus der Azure App-Registrierung
# Tennant ID : caee3499-03f8-4175-9fa8-a935248d0ece
TENANT_ID = "caee3499-03f8-4175-9fa8-a935248d0ece"
# Client Id : 3a08b279-1fc3-419f-a77e-31f12a0f65f7
CLIENT_ID = "3a08b279-1fc3-419f-a77e-31f12a0f65f7"
# Key : 3cd0be8b-e58f-4e0c-9856-5c9788183b2c
CLIENT_SECRET = "Rk-8Q~nJ.sZ-xUiNxtEDdzVgoFFosODLVHX~jdrh" # Der "Wert", nicht die "Secret ID"
# Das zu überwachende Postfach
# USER_EMAIL = "Bestellung-Fax-Eingang@aps-hh.de"
USER_EMAIL = "i.meszely@aps-hh.de"
# Speicherort für heruntergeladene PDFs
# DOWNLOAD_DIR = r"\\aps-nb090\test"
# DOWNLOAD_DIR = r"C:\Users\YourUsername\Downloads\PDFs"
DOWNLOAD_DIR = "C:/Tools/PDF"
# Name des Ordners, in den verarbeitete E-Mails verschoben werden
PROCESSED_FOLDER_NAME = "erledigt"
# ==============================================================================
# Microsoft Graph API Endpunkte
GRAPH_API_ENDPOINT = "https://graph.microsoft.com/v1.0"
AUTHORITY_URL = f"https://login.microsoftonline.com/{TENANT_ID}"
SCOPES = ["https://graph.microsoft.com/.default"]
def get_graph_api_token():
"""Ruft das Zugriffstoken für die Microsoft Graph API ab."""
app = msal.ConfidentialClientApplication(
client_id=CLIENT_ID,
authority=AUTHORITY_URL,
client_credential=CLIENT_SECRET
)
result = app.acquire_token_silent(scopes=SCOPES, account=None)
if not result:
result = app.acquire_token_for_client(scopes=SCOPES)
if "access_token" in result:
logging.info("Graph API-Token erfolgreich abgerufen.")
return result["access_token"]
else:
logging.error("Fehler beim Abrufen des Tokens!")
logging.error(result.get("error"))
logging.error(result.get("error_description"))
return None
def get_folder_id(access_token, folder_name):
"""Sucht die ID eines Ordners anhand seines Namens."""
headers = {"Authorization": f"Bearer {access_token}"}
url = f"{GRAPH_API_ENDPOINT}/users/{USER_EMAIL}/mailFolders"
response = requests.get(url, headers=headers)
response.raise_for_status()
folders = response.json().get("value", [])
for folder in folders:
if folder["displayName"].lower() == folder_name.lower():
return folder["id"]
# Man könnte auch den Fall behandeln, dass der Ordner nicht existiert, und ihn erstellen.
# Vorerst wird einfach ein Fehler ausgelöst.
raise ValueError(f"Der Ordner '{folder_name}' wurde nicht gefunden.")
def main():
"""Hauptverarbeitungsfunktion."""
logging.info("Graph API-Token wird abgerufen...")
access_token = get_graph_api_token()
if not access_token:
logging.error("Kein Zugriffstoken erhalten. Beende das Skript.")
return
headers = {"Authorization": f"Bearer {access_token}"}
try:
logging.info(f"Suche nach der ID für den Ordner '{PROCESSED_FOLDER_NAME}'...")
processed_folder_id = get_folder_id(access_token, PROCESSED_FOLDER_NAME)
logging.info("Ordner-ID erfolgreich abgerufen.")
except requests.exceptions.HTTPError as e:
logging.error(f"Fehler beim Abrufen der Ordner-ID: {e}")
if e.response.status_code == 403:
logging.error("Mögliche Ursache: Fehlende oder unzureichende Graph API-Berechtigungen. Bitte stellen Sie sicher, dass die Anwendung die erforderlichen 'Application Permissions' (z.B. Mail.Read, Mail.ReadWrite) in Azure AD hat und dass der Administrator die Zustimmung erteilt hat.")
return
except ValueError as e:
logging.error(f"Fehler beim Abrufen der Ordner-ID: {e}")
return
# Nur ungelesene E-Mails mit Anhängen abfragen
# $select=id,subject -> Nur die notwendigen Felder für mehr Effizienz abfragen
messages_url = (
f"{GRAPH_API_ENDPOINT}/users/{USER_EMAIL}/mailFolders/inbox/messages?"
f"$filter=isRead eq false and hasAttachments eq true&"
f"$select=id,subject"
)
response = requests.get(messages_url, headers=headers)
response.raise_for_status()
messages = response.json().get("value", [])
if not messages:
logging.info("Keine neuen E-Mails zur Verarbeitung gefunden.")
return
logging.info(f"{len(messages)} neue E-Mail(s) mit Anhängen gefunden.")
for message in messages:
msg_id = message["id"]
subject = message.get("subject", "N/A")
logging.info(f"\n--- In Verarbeitung: '{subject}' (ID: {msg_id}) ---")
attachments_url = f"{GRAPH_API_ENDPOINT}/users/{USER_EMAIL}/messages/{msg_id}/attachments"
response = requests.get(attachments_url, headers=headers)
if response.status_code != 200:
logging.error(f" Fehler beim Abrufen der Anhänge: {response.json()}")
continue
attachments = response.json().get("value", [])
pdf_found = False
for att in attachments:
filename = att.get("name", "unknown")
content_type = att.get("contentType", "")
if filename == "Safe Attachments Scan In Progress" and content_type is None:
logging.info(f" Placeholder melléklet kihagyása: '{filename}'")
continue
if filename.lower().endswith(".pdf") or content_type == "application/pdf":
logging.info(f" PDF-Anhang gefunden: {filename}")
# Der Inhalt des Anhangs befindet sich im Feld 'contentBytes' und ist Base64-kodiert
file_content = base64.b64decode(att["contentBytes"])
# Dateinamen bereinigen
safe_filename = "".join(c if c.isalnum() or c in (" ", ".", "_", "-") else "_" for c in filename)
# Ellenőrizze, hogy a fájl létezik-e, és szükség esetén adjon hozzá sorszámot
base_name, extension = os.path.splitext(safe_filename)
counter = 0
while True:
if counter == 0:
final_filename = safe_filename
else:
final_filename = f"{base_name} ({counter}){extension}"
filepath = os.path.join(DOWNLOAD_DIR, final_filename)
if not os.path.exists(filepath):
break
counter += 1
try:
with open(filepath, "wb") as f:
f.write(file_content)
logging.info(f" PDF erfolgreich gespeichert: {filepath}")
pdf_found = True
except Exception as e:
logging.error(f" Fehler beim Speichern der Datei: {e}")
if pdf_found:
logging.info(f" E-Mail wird in den Ordner '{PROCESSED_FOLDER_NAME}' verschoben...")
move_url = f"{GRAPH_API_ENDPOINT}/users/{USER_EMAIL}/messages/{msg_id}/move"
move_payload = {"destinationId": processed_folder_id}
response = requests.post(move_url, headers=headers, json=move_payload)
if response.status_code == 201:
logging.info(" E-Mail erfolgreich verschoben.")
# Az áthelyezett e-mail új ID-jának lekérése a válaszból
moved_message_id = response.json().get("id")
if moved_message_id:
logging.info(f" E-Mail új ID-ja: {moved_message_id}")
# E-Mail mint olvasottként való megjelölés az új ID-val
logging.info(f" Markiere E-Mail '{subject}' (ID: {moved_message_id}) als gelesen...")
mark_as_read_url = f"{GRAPH_API_ENDPOINT}/users/{USER_EMAIL}/messages/{moved_message_id}"
mark_as_read_payload = {"isRead": True}
mark_response = requests.patch(mark_as_read_url, headers=headers, json=mark_as_read_payload)
if mark_response.status_code == 200:
logging.info(" E-Mail erfolgreich als gelesen markiert.")
else:
logging.error(f" Fehler beim Markieren der E-Mail als gelesen: {mark_response.status_code} - {mark_response.text}")
else:
logging.error(" Hiba: Nem sikerült lekérni az áthelyezett e-mail új ID-ját a válaszból.")
else:
# Für das Verschieben ist die Berechtigung Mail.ReadWrite erforderlich!
logging.error(f" Fehler beim Verschieben der E-Mail: {response.status_code} - {response.text}")
# Az eredeti olvasottként jelölési kód eltávolítva, mivel feljebb már megcsináljuk
logging.info("\nVerarbeitung abgeschlossen.")
if __name__ == "__main__":
logging.info("Skript gestartet.")
create_log_table_if_not_exists() # Call to create table
if not os.path.exists(DOWNLOAD_DIR):
logging.error(f"Fehler: Der Download-Ordner existiert nicht: {DOWNLOAD_DIR}")
else:
main()
logging.info("Skript beendet.")

View File

@@ -105,12 +105,12 @@ CLIENT_SECRET = "Rk-8Q~nJ.sZ-xUiNxtEDdzVgoFFosODLVHX~jdrh" # Der "Wert", nicht d
# Das zu überwachende Postfach
# USER_EMAIL = "Bestellung-Fax-Eingang@aps-hh.de"
USER_EMAIL = "i.meszely@aps-hh.de"
USER_EMAIL = "fax-bestellung@antares-apo.de"
# Speicherort für heruntergeladene PDFs
# DOWNLOAD_DIR = r"\\aps-nb090\test"
# DOWNLOAD_DIR = r"C:\Users\YourUsername\Downloads\PDFs"
DOWNLOAD_DIR = "C:/Tools/PDF"
DOWNLOAD_DIR = r"\\APS-FILE01\Faxe\Austausch"
# Name des Ordners, in den verarbeitete E-Mails verschoben werden
PROCESSED_FOLDER_NAME = "erledigt"

View File

@@ -21,8 +21,44 @@ Für unsere Anforderungen ist eine klassische **SharePoint Team Site** die optim
### 4. Unterstützung technischer Formate
* Die Team Site ermöglicht eine schnelle Vorschau und Suche innerhalb von **Plain-Text-Dateien (.txt)** und **Markdown (.md)** direkt im Browser, was für Switch-Konfigurationen und Anleitungen essenziell ist.
## Fazit
Um die Agilität der IT-Abteilung zu gewährleisten und eine einfache, synchronisierbare Ablage zu schaffen, sollte auf die Erstellung eines Inhaltscenters verzichtet und stattdessen eine **private Team Site** implementiert werden.
---
## Umsetzung & Fortschritt (Stand: 16.03.2026)
Das Projekt wurde erfolgreich gestartet und die Basis-Infrastruktur steht bereit.
### 1. Implementierte Web-Struktur
Der SharePoint wurde als **private Team Site** unter dem Namen `IT Internal Repository` erstellt.
**Verzeichnisstruktur in der Dokumentenbibliothek (Documents):**
* `01_Infrastructure`: Konfigurationen (z. B. Postfix, Switches) und Netzwerkpläne.
* `02_Software`: Installationsdateien, Lizenzschlüssel und Software-Dokumentation.
* `03_Knowledge_Base`: Allgemeine IT-Anleitungen und Knowledge-Base-Artikel (.md).
* `04_Automation_Scripts`: Zentrale Ablage für Python, Bash und PowerShell Skripte.
* `05_Archive`: Veraltete Backups und Protokolle.
### 2. Dashboard & Navigation
Die Startseite wurde als **IT Dashboard** konfiguriert:
* **Hero-Bereich:** Direkte Verlinkung zu Infrastruktur, Software und Wiki.
* **Schnelllinks:** Schnellzugriff auf alle Hauptverzeichnisse (01-05).
* **News/Updates:** Automatische Anzeige der neuesten SOP-Seiten.
### 3. Erstellte Dokumentationen (SOPs)
Folgende Standard Operating Procedures (SOPs) wurden bereits auf SharePoint-Seiten sowie lokal als `.md` Dateien implementiert:
* `SOP: Automatisierter PDF-Import aus O365 (v2.2)`
* `SOP: Bereinigung alter Datensätze (delete_old_records.py)`
* **SOP: Konfiguration Postfix SMTP Relay (APS-SMTP01)**
* **SOP: Export von Druckprotokollen in MySQL (PowerShell)**
### 4. Integrationen
* **Microsoft Teams:** Die SharePoint-Seite ist mit dem Team `Informationstechnologie` (Private Gruppe) verbunden.
* **OneNote:** Das gemeinsame Notizbuch (Notizbuch) wurde integriert und lokale Abschnitte erfolgreich migriert.
* **OneDrive Sync:** Die Synchronisation für die Bearbeitung via Windows Explorer und WSL ist vorbereitet.
### 5. Nächste Schritte
* Vollständiger Upload des Software-Archivs via OneDrive.
* Integration von Switch-Konfigurationen in `01_Infrastructure`.
* Erweiterung der Wissensdatenbank durch das IT-Team.
---
*Erstellt für das IT-Team Projekt: Internal Repository*
*Aktualisiert für das IT-Team Projekt: Internal Repository*