Neuaufbau, viele neue Funktionen, verbesserte Fehlerbehandlung, optimierte Logik, erweiterte Benachrichtigungsoptionen, Winget-Integration, History-Export in CSV/XLSX, Pre/Post Hooks, Reboot-Kontrolle und mehr.
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
config.ini
|
||||
28
LICENSE
28
LICENSE
@@ -1,9 +1,29 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 scriptos
|
||||
---
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
Copyright © Patrick Asmus (scriptos)
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
Website: https://www.patrick-asmus.de
|
||||
Blog: https://www.cleveradmin.de
|
||||
Email: support@techniverse.net
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
---
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
112
README.md
112
README.md
@@ -1,11 +1,109 @@
|
||||
# Windows Updates per Powershell installieren
|
||||
<p align="center">
|
||||
<a href="https://techniverse.net">
|
||||
<img src="https://assets.techniverse.net/f1/git/graphics/repo-techniverse-logo.png" alt="Techniverse Community" height="70" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
Dieses Script lädt das Modul PSWindowsUpdate lokal in Powershell, installiert anschließend Windows Updates und startet den Rechner neu, falls notwendig.
|
||||
Alternativ hab ich noch ein kleines PS-Script mit rein, welches das Modul online installieren kann.
|
||||
Das eigentliche Script ist jedoch darauf ausgelegt das Modul aus dem Repo zu verwenden, weil lokal.
|
||||
<h1 align="center">Windows Updater</h1>
|
||||
|
||||
<h4 align="center">
|
||||
Automatisiertes Windows Update Management per PowerShell. Installiert Windows Updates, optional Winget-Pakete, und benachrichtigt per ntfy und/oder E-Mail.
|
||||
</h4>
|
||||
|
||||
<h6 align="center">
|
||||
<a href="https://www.cleveradmin.de">🏰 Website</a>
|
||||
·
|
||||
<a href="https://techniverse.net">📰 Community</a>
|
||||
·
|
||||
<a href="https://social.techniverse.net/@donnerwolke">🐘 Mastodon</a>
|
||||
·
|
||||
<a href="https://matrix.to/#/#support:techniverse.net">💬 Support</a>
|
||||
</h6>
|
||||
<br><br>
|
||||
|
||||
|
||||
## Weiterführende Links/Quellen:
|
||||
https://de.minitool.com/datentraegerverwaltung/powershell-windows-updaten.html
|
||||
**Repository:** [https://git.techniverse.net/scriptos/windows-updater](https://git.techniverse.net/scriptos/windows-updater)
|
||||
|
||||
https://www.powershellgallery.com/packages/PSWindowsUpdate
|
||||
## Features
|
||||
|
||||
- **Windows Updates** automatisch installieren via PSWindowsUpdate-Modul
|
||||
- **Winget-Updates** optional (`winget upgrade --all`), automatische Erkennung der Verfügbarkeit
|
||||
- **Benachrichtigungen** via ntfy und/oder E-Mail (inkl. HTML-Report mit Ergebnis-Tabelle)
|
||||
- **Dry-Run Modus** zum Prüfen verfügbarer Updates ohne Installation
|
||||
- **Update-Ausschlüsse** für bestimmte KBs oder Treiber-Updates
|
||||
- **Retry-Logik** für fehlgeschlagene Updates (konfigurierbare Anzahl)
|
||||
- **Log-Rotation** mit einer Datei pro Tag und konfigurierbarer Aufbewahrung
|
||||
- **Update-History** als XLSX (mit ImportExcel-Modul) oder CSV-Fallback
|
||||
- **WSUS-Erkennung** automatisch, inkl. Anzeige des WSUS-Servers
|
||||
- **Reboot-Management** mit drei Modi: sofort, verzögert, oder zu bestimmter Uhrzeit
|
||||
- **Pre-/Post-Update Hooks** für eigene Scripts vor und nach dem Update-Vorgang
|
||||
- **OS-Erkennung** für Windows 10/11, Server 2016/2019/2022/2025
|
||||
|
||||
## Unterstützte Betriebssysteme
|
||||
|
||||
| OS | Windows Updates | Winget |
|
||||
|---|---|---|
|
||||
| Windows 10 | Ja | Ja (wenn installiert) |
|
||||
| Windows 11 | Ja | Ja |
|
||||
| Windows Server 2016 | Ja | Nein* |
|
||||
| Windows Server 2019 | Ja | Nein* |
|
||||
| Windows Server 2022 | Ja | Nein* |
|
||||
| Windows Server 2025 | Ja | Nein* |
|
||||
|
||||
*Winget ist auf Servern standardmäßig nicht verfügbar. Wird es manuell installiert, erkennt das Script dies automatisch.
|
||||
|
||||
## Schnellstart
|
||||
|
||||
### 1. Repository klonen / Dateien kopieren
|
||||
|
||||
```powershell
|
||||
git clone https://git.techniverse.net/scriptos/windows-updater.git C:\scripts\windows-updater
|
||||
```
|
||||
|
||||
### 2. Konfiguration erstellen
|
||||
|
||||
```powershell
|
||||
Copy-Item C:\scripts\windows-updater\config.example.ini C:\scripts\windows-updater\config.ini
|
||||
```
|
||||
|
||||
Danach `config.ini` mit einem Texteditor öffnen und die gewünschten Werte anpassen. Siehe [Konfiguration](docs/configuration.md) für alle Optionen.
|
||||
|
||||
### 3. Script ausführen (als Administrator)
|
||||
|
||||
```powershell
|
||||
powershell.exe -ExecutionPolicy Bypass -File "C:\scripts\windows-updater\windows-updater.ps1"
|
||||
```
|
||||
|
||||
### 4. Optional: Aufgabenplanung einrichten
|
||||
|
||||
Für automatische Ausführung per Windows Aufgabenplanung siehe [Aufgabenplanung einrichten](docs/task-scheduler.md).
|
||||
|
||||
## Exit-Codes
|
||||
|
||||
| Code | Bedeutung |
|
||||
|---|---|
|
||||
| 0 | Erfolg (Updates installiert, keine Updates verfügbar, oder Dry-Run) |
|
||||
| 1 | Fehler (Modul-Fehler, Config fehlt, Updates fehlgeschlagen) |
|
||||
| 2 | Neustart erforderlich, aber Auto-Reboot ist deaktiviert |
|
||||
|
||||
## PSWindowsUpdate-Modul
|
||||
|
||||
Das Script versucht zuerst, das [PSWindowsUpdate](https://github.com/mgajda83/PSWindowsUpdate)-Modul online von der PowerShell Gallery zu installieren. Falls das nicht möglich ist (kein Internet, Firewall), wird automatisch die im Repository enthaltene Offline-Kopie verwendet.
|
||||
|
||||
## Dokumentation
|
||||
|
||||
- [Konfiguration](docs/configuration.md) - Alle INI-Optionen im Detail
|
||||
- [Benachrichtigungen](docs/notifications.md) - ntfy und E-Mail einrichten
|
||||
- [Aufgabenplanung](docs/task-scheduler.md) - Windows Task Scheduler Setup
|
||||
- [Problembehandlung](docs/troubleshooting.md) - Häufige Fehler und Lösungen
|
||||
|
||||
<br><br>
|
||||
<p align="center">
|
||||
<img src="https://assets.techniverse.net/f1/git/graphics/gray0-catonline.svg" alt="">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<sub>
|
||||
© Patrick Asmus · Techniverse Network · <a href="./LICENSE">Lizenz</a>
|
||||
</sub>
|
||||
</p>
|
||||
@@ -1,50 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-16"?>
|
||||
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
|
||||
<RegistrationInfo>
|
||||
<Date>2023-10-21T22:57:08.4089431</Date>
|
||||
<Author>SYSTEM</Author>
|
||||
<URI>\Windows Updates mit AutoReboot</URI>
|
||||
</RegistrationInfo>
|
||||
<Triggers>
|
||||
<CalendarTrigger>
|
||||
<StartBoundary>2023-11-29T04:00:00</StartBoundary>
|
||||
<Enabled>true</Enabled>
|
||||
<ScheduleByDay>
|
||||
<DaysInterval>1</DaysInterval>
|
||||
</ScheduleByDay>
|
||||
</CalendarTrigger>
|
||||
</Triggers>
|
||||
<Principals>
|
||||
<Principal id="Author">
|
||||
<UserId>S-1-5-18</UserId>
|
||||
<RunLevel>LeastPrivilege</RunLevel>
|
||||
</Principal>
|
||||
</Principals>
|
||||
<Settings>
|
||||
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
|
||||
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
|
||||
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
|
||||
<AllowHardTerminate>true</AllowHardTerminate>
|
||||
<StartWhenAvailable>false</StartWhenAvailable>
|
||||
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
|
||||
<IdleSettings>
|
||||
<StopOnIdleEnd>true</StopOnIdleEnd>
|
||||
<RestartOnIdle>false</RestartOnIdle>
|
||||
</IdleSettings>
|
||||
<AllowStartOnDemand>true</AllowStartOnDemand>
|
||||
<Enabled>true</Enabled>
|
||||
<Hidden>false</Hidden>
|
||||
<RunOnlyIfIdle>false</RunOnlyIfIdle>
|
||||
<DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
|
||||
<UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>
|
||||
<WakeToRun>false</WakeToRun>
|
||||
<ExecutionTimeLimit>PT1H</ExecutionTimeLimit>
|
||||
<Priority>7</Priority>
|
||||
</Settings>
|
||||
<Actions Context="Author">
|
||||
<Exec>
|
||||
<Command>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</Command>
|
||||
<Arguments>-executionpolicy bypass -command "C:\scripts\windows-updater\windows-updater.ps1"</Arguments>
|
||||
</Exec>
|
||||
</Actions>
|
||||
</Task>
|
||||
78
config.example.ini
Normal file
78
config.example.ini
Normal file
@@ -0,0 +1,78 @@
|
||||
###############################################
|
||||
# Windows Updater - Configuration
|
||||
# Lines starting with # or ; are comments
|
||||
# Copy this file to config.ini and adjust values
|
||||
###############################################
|
||||
|
||||
[General]
|
||||
# Path for log files (one file per day)
|
||||
LogPath = C:\logs\windows-updater
|
||||
# Number of days to keep log files (default: 365)
|
||||
LogRetentionDays = 365
|
||||
# Dry-run mode: scan and report only, do not install (true/false)
|
||||
DryRun = false
|
||||
|
||||
[WindowsUpdate]
|
||||
# Use Microsoft Update (includes Office, .NET, drivers) instead of Windows Update only
|
||||
UseMicrosoftUpdate = true
|
||||
# Exclude specific KB articles (comma-separated, e.g. KB1234567,KB7654321)
|
||||
ExcludeKBs =
|
||||
# Exclude driver updates (true/false)
|
||||
ExcludeDrivers = false
|
||||
# Number of retry attempts for failed updates (default: 3)
|
||||
RetryCount = 3
|
||||
|
||||
[Winget]
|
||||
# Enable winget upgrade --all (true/false, default: false)
|
||||
# Only works on Windows 10/11 with winget installed, auto-skipped if unavailable
|
||||
Enabled = false
|
||||
|
||||
[Reboot]
|
||||
# Enable automatic reboot after updates if required (true/false)
|
||||
Enabled = false
|
||||
# Reboot mode: immediate, delayed, scheduled
|
||||
Mode = immediate
|
||||
# Delay in minutes before reboot (only for Mode = delayed)
|
||||
DelayMinutes = 5
|
||||
# Time to reboot at in HH:mm format (only for Mode = scheduled, e.g. 03:00)
|
||||
ScheduledTime = 03:00
|
||||
|
||||
[Notification]
|
||||
# --- ntfy ---
|
||||
NtfyEnabled = false
|
||||
# ntfy server URL (e.g. https://ntfy.sh or your self-hosted instance)
|
||||
NtfyUrl = https://ntfy.sh
|
||||
# ntfy topic name
|
||||
NtfyTopic = windows-updates
|
||||
# ntfy access token (leave empty if not required)
|
||||
NtfyToken =
|
||||
# ntfy priority: min, low, default, high, urgent
|
||||
NtfyPriority = default
|
||||
|
||||
# --- Email ---
|
||||
EmailEnabled = false
|
||||
SmtpServer = smtp.example.com
|
||||
SmtpPort = 587
|
||||
SmtpUseSsl = true
|
||||
SmtpUsername =
|
||||
SmtpPassword =
|
||||
EmailFrom = updater@example.com
|
||||
# Multiple recipients comma-separated (e.g. admin@example.com,ops@example.com)
|
||||
EmailTo = admin@example.com
|
||||
# Send HTML formatted report with update table (true/false)
|
||||
EmailHtmlReport = true
|
||||
|
||||
[Hooks]
|
||||
# Path to PowerShell script to execute BEFORE updates (leave empty to disable)
|
||||
PreUpdateScript =
|
||||
# Abort update process if pre-hook script fails (true/false)
|
||||
AbortOnPreHookFailure = false
|
||||
# Path to PowerShell script to execute AFTER updates (leave empty to disable)
|
||||
PostUpdateScript =
|
||||
|
||||
[History]
|
||||
# Enable persistent update history tracking (true/false)
|
||||
Enabled = false
|
||||
# Path for the history file
|
||||
# Uses .xlsx format if ImportExcel module is available, otherwise falls back to .csv
|
||||
HistoryPath = C:\logs\windows-updater\update-history
|
||||
175
docs/configuration.md
Normal file
175
docs/configuration.md
Normal file
@@ -0,0 +1,175 @@
|
||||
# Konfiguration
|
||||
|
||||
Alle Einstellungen werden in der Datei `config.ini` vorgenommen, die sich im selben Verzeichnis wie das Script befindet. Als Vorlage dient `config.example.ini`.
|
||||
|
||||
## Übersicht aller Optionen
|
||||
|
||||
### [General]
|
||||
|
||||
| Option | Typ | Standard | Beschreibung |
|
||||
|---|---|---|---|
|
||||
| `LogPath` | String | `C:\logs\windows-updater` | Verzeichnis für Log-Dateien (eine Datei pro Tag) |
|
||||
| `LogRetentionDays` | Integer | `365` | Anzahl Tage, nach denen alte Log-Dateien gelöscht werden |
|
||||
| `DryRun` | Boolean | `false` | Nur prüfen welche Updates verfügbar sind, ohne zu installieren |
|
||||
|
||||
### [WindowsUpdate]
|
||||
|
||||
| Option | Typ | Standard | Beschreibung |
|
||||
|---|---|---|---|
|
||||
| `UseMicrosoftUpdate` | Boolean | `true` | Microsoft Update verwenden (inkl. Office, .NET, Treiber). Bei `false` nur Windows Update |
|
||||
| `ExcludeKBs` | String | *(leer)* | Kommagetrennte Liste von KB-Artikeln die übersprungen werden sollen (z.B. `KB1234567,KB7654321`) |
|
||||
| `ExcludeDrivers` | Boolean | `false` | Treiber-Updates ausschließen |
|
||||
| `RetryCount` | Integer | `3` | Anzahl Wiederholungsversuche für fehlgeschlagene Updates |
|
||||
|
||||
### [Winget]
|
||||
|
||||
| Option | Typ | Standard | Beschreibung |
|
||||
|---|---|---|---|
|
||||
| `Enabled` | Boolean | `false` | Winget-Updates aktivieren (`winget upgrade --all`). Wird automatisch übersprungen, wenn winget nicht verfügbar ist |
|
||||
|
||||
### [Reboot]
|
||||
|
||||
| Option | Typ | Standard | Beschreibung |
|
||||
|---|---|---|---|
|
||||
| `Enabled` | Boolean | `false` | Automatischen Neustart nach Updates aktivieren |
|
||||
| `Mode` | String | `immediate` | Neustart-Modus: `immediate` (sofort), `delayed` (verzögert), `scheduled` (geplante Uhrzeit) |
|
||||
| `DelayMinutes` | Integer | `5` | Verzögerung in Minuten (nur bei `Mode = delayed`) |
|
||||
| `ScheduledTime` | String | `03:00` | Uhrzeit im Format HH:mm (nur bei `Mode = scheduled`). Liegt die Uhrzeit in der Vergangenheit, wird der nächste Tag verwendet |
|
||||
|
||||
### [Notification]
|
||||
|
||||
#### ntfy
|
||||
|
||||
| Option | Typ | Standard | Beschreibung |
|
||||
|---|---|---|---|
|
||||
| `NtfyEnabled` | Boolean | `false` | ntfy-Benachrichtigungen aktivieren |
|
||||
| `NtfyUrl` | String | `https://ntfy.sh` | URL des ntfy-Servers |
|
||||
| `NtfyTopic` | String | `windows-updates` | ntfy-Topic-Name |
|
||||
| `NtfyToken` | String | *(leer)* | Zugangs-Token (leer lassen wenn nicht benötigt) |
|
||||
| `NtfyPriority` | String | `default` | Priorität: `min`, `low`, `default`, `high`, `urgent` |
|
||||
|
||||
#### E-Mail
|
||||
|
||||
| Option | Typ | Standard | Beschreibung |
|
||||
|---|---|---|---|
|
||||
| `EmailEnabled` | Boolean | `false` | E-Mail-Benachrichtigungen aktivieren |
|
||||
| `SmtpServer` | String | *(leer)* | SMTP-Server Adresse |
|
||||
| `SmtpPort` | Integer | `587` | SMTP-Port |
|
||||
| `SmtpUseSsl` | Boolean | `true` | SSL/TLS für SMTP verwenden |
|
||||
| `SmtpUsername` | String | *(leer)* | SMTP-Benutzername (leer für anonyme Authentifizierung) |
|
||||
| `SmtpPassword` | String | *(leer)* | SMTP-Passwort |
|
||||
| `EmailFrom` | String | *(leer)* | Absender-Adresse |
|
||||
| `EmailTo` | String | *(leer)* | Empfänger-Adresse(n), kommagetrennt |
|
||||
| `EmailHtmlReport` | Boolean | `true` | HTML-formatierten Report mit Update-Tabelle senden |
|
||||
|
||||
### [Hooks]
|
||||
|
||||
| Option | Typ | Standard | Beschreibung |
|
||||
|---|---|---|---|
|
||||
| `PreUpdateScript` | String | *(leer)* | Pfad zu einem PowerShell-Script, das VOR den Updates ausgeführt wird |
|
||||
| `AbortOnPreHookFailure` | Boolean | `false` | Update-Prozess abbrechen wenn das Pre-Hook-Script fehlschlägt |
|
||||
| `PostUpdateScript` | String | *(leer)* | Pfad zu einem PowerShell-Script, das NACH den Updates ausgeführt wird |
|
||||
|
||||
### [History]
|
||||
|
||||
| Option | Typ | Standard | Beschreibung |
|
||||
|---|---|---|---|
|
||||
| `Enabled` | Boolean | `false` | Update-History-Tracking aktivieren |
|
||||
| `HistoryPath` | String | `C:\logs\windows-updater\update-history` | Basispfad für die History-Datei (Dateiendung wird automatisch gewählt: `.xlsx` wenn ImportExcel verfügbar, sonst `.csv`) |
|
||||
|
||||
## Boolean-Werte
|
||||
|
||||
Folgende Werte werden als `true` erkannt (Groß-/Kleinschreibung egal):
|
||||
- `true`, `1`, `yes`
|
||||
|
||||
Alles andere wird als `false` interpretiert.
|
||||
|
||||
## Beispiel-Konfigurationen
|
||||
|
||||
### Minimal (nur Windows Updates)
|
||||
|
||||
```ini
|
||||
[General]
|
||||
LogPath = C:\logs\windows-updater
|
||||
DryRun = false
|
||||
|
||||
[WindowsUpdate]
|
||||
UseMicrosoftUpdate = true
|
||||
```
|
||||
|
||||
### Mit E-Mail Benachrichtigung
|
||||
|
||||
```ini
|
||||
[General]
|
||||
LogPath = C:\logs\windows-updater
|
||||
DryRun = false
|
||||
|
||||
[WindowsUpdate]
|
||||
UseMicrosoftUpdate = true
|
||||
ExcludeDrivers = true
|
||||
|
||||
[Notification]
|
||||
EmailEnabled = true
|
||||
SmtpServer = smtp.example.com
|
||||
SmtpPort = 587
|
||||
SmtpUseSsl = true
|
||||
SmtpUsername = user@example.com
|
||||
SmtpPassword = geheim123
|
||||
EmailFrom = updater@example.com
|
||||
EmailTo = admin@example.com
|
||||
EmailHtmlReport = true
|
||||
|
||||
[Reboot]
|
||||
Enabled = true
|
||||
Mode = delayed
|
||||
DelayMinutes = 10
|
||||
```
|
||||
|
||||
### Vollständig mit ntfy und History
|
||||
|
||||
```ini
|
||||
[General]
|
||||
LogPath = C:\logs\windows-updater
|
||||
LogRetentionDays = 365
|
||||
DryRun = false
|
||||
|
||||
[WindowsUpdate]
|
||||
UseMicrosoftUpdate = true
|
||||
ExcludeKBs = KB1234567,KB7654321
|
||||
ExcludeDrivers = true
|
||||
RetryCount = 3
|
||||
|
||||
[Winget]
|
||||
Enabled = true
|
||||
|
||||
[Reboot]
|
||||
Enabled = true
|
||||
Mode = scheduled
|
||||
ScheduledTime = 03:00
|
||||
|
||||
[Notification]
|
||||
NtfyEnabled = true
|
||||
NtfyUrl = https://ntfy.mein-server.de
|
||||
NtfyTopic = windows-updates
|
||||
NtfyToken = tk_mein_token
|
||||
NtfyPriority = default
|
||||
|
||||
EmailEnabled = true
|
||||
SmtpServer = smtp.example.com
|
||||
SmtpPort = 587
|
||||
SmtpUseSsl = true
|
||||
SmtpUsername = user@example.com
|
||||
SmtpPassword = geheim123
|
||||
EmailFrom = updater@example.com
|
||||
EmailTo = admin@example.com,ops@example.com
|
||||
EmailHtmlReport = true
|
||||
|
||||
[Hooks]
|
||||
PreUpdateScript = C:\scripts\pre-update.ps1
|
||||
AbortOnPreHookFailure = true
|
||||
PostUpdateScript = C:\scripts\post-update.ps1
|
||||
|
||||
[History]
|
||||
Enabled = true
|
||||
HistoryPath = C:\logs\windows-updater\update-history
|
||||
```
|
||||
134
docs/notifications.md
Normal file
134
docs/notifications.md
Normal file
@@ -0,0 +1,134 @@
|
||||
# Benachrichtigungen einrichten
|
||||
|
||||
Das Script unterstützt zwei unabhängige Benachrichtigungskanäle, die einzeln oder gleichzeitig genutzt werden können.
|
||||
|
||||
## ntfy
|
||||
|
||||
[ntfy](https://ntfy.sh) ist ein einfacher Push-Notification-Dienst. Es kann die öffentliche Instanz (`ntfy.sh`) oder ein selbst gehosteter Server verwendet werden.
|
||||
|
||||
### Einrichtung
|
||||
|
||||
1. **Topic wählen** - Ein Topic-Name ist wie ein Kanal, auf den man Nachrichten sendet (z.B. `windows-updates-meinserver`)
|
||||
|
||||
2. **App installieren** (optional) - ntfy-App für [Android](https://play.google.com/store/apps/details?id=io.heckel.ntfy), [iOS](https://apps.apple.com/app/ntfy/id1625396347) oder [Web](https://ntfy.sh) öffnen und das Topic abonnieren
|
||||
|
||||
3. **Token erstellen** (optional) - Wenn der ntfy-Server Authentifizierung erfordert, einen Access Token erstellen
|
||||
|
||||
4. **Config anpassen:**
|
||||
|
||||
```ini
|
||||
[Notification]
|
||||
NtfyEnabled = true
|
||||
NtfyUrl = https://ntfy.sh
|
||||
NtfyTopic = windows-updates-meinserver
|
||||
NtfyToken =
|
||||
NtfyPriority = default
|
||||
```
|
||||
|
||||
### Prioritäten
|
||||
|
||||
| Wert | Bedeutung |
|
||||
|---|---|
|
||||
| `min` | Keine Vibration, kein Sound |
|
||||
| `low` | Keine Vibration |
|
||||
| `default` | Standard-Verhalten |
|
||||
| `high` | Hohe Priorität mit Sound |
|
||||
| `urgent` | Höchste Priorität, durchbricht "Nicht stören" |
|
||||
|
||||
Das Script verwendet automatisch `high` für Fehler und Reboot-Benachrichtigungen.
|
||||
|
||||
### Selbst gehosteter ntfy-Server
|
||||
|
||||
Bei einem eigenen ntfy-Server die URL entsprechend anpassen:
|
||||
|
||||
```ini
|
||||
NtfyUrl = https://ntfy.mein-server.de
|
||||
NtfyToken = tk_mein_zugangstoken
|
||||
```
|
||||
|
||||
## E-Mail
|
||||
|
||||
### Einrichtung
|
||||
|
||||
1. **SMTP-Zugangsdaten beschaffen** - Diese bekommt man vom E-Mail-Provider oder dem eigenen Mailserver
|
||||
|
||||
2. **Config anpassen:**
|
||||
|
||||
```ini
|
||||
[Notification]
|
||||
EmailEnabled = true
|
||||
SmtpServer = smtp.example.com
|
||||
SmtpPort = 587
|
||||
SmtpUseSsl = true
|
||||
SmtpUsername = user@example.com
|
||||
SmtpPassword = mein-passwort
|
||||
EmailFrom = updater@example.com
|
||||
EmailTo = admin@example.com
|
||||
EmailHtmlReport = true
|
||||
```
|
||||
|
||||
### Mehrere Empfänger
|
||||
|
||||
Kommagetrennt in `EmailTo`:
|
||||
|
||||
```ini
|
||||
EmailTo = admin@example.com,ops@example.com,chef@example.com
|
||||
```
|
||||
|
||||
### HTML-Report
|
||||
|
||||
Wenn `EmailHtmlReport = true` gesetzt ist, enthält die E-Mail nach der Update-Installation eine formatierte HTML-Tabelle mit:
|
||||
|
||||
- Hostname und Betriebssystem
|
||||
- Datum und Uhrzeit
|
||||
- Anzahl erfolgreicher und fehlgeschlagener Updates
|
||||
- Tabelle mit allen Updates (KB, Titel, Größe, Ergebnis)
|
||||
- Farbcodierung: Grün für Erfolg, Rot für Fehler
|
||||
|
||||
Bei `EmailHtmlReport = false` wird stattdessen eine einfache Text-E-Mail gesendet.
|
||||
|
||||
### Häufige SMTP-Einstellungen
|
||||
|
||||
| Provider | Server | Port | SSL |
|
||||
|---|---|---|---|
|
||||
| Microsoft 365 | `smtp.office365.com` | 587 | true |
|
||||
| Gmail | `smtp.gmail.com` | 587 | true |
|
||||
| Eigener Server | `mail.example.com` | 587 oder 465 | true |
|
||||
| Lokaler Relay | `localhost` | 25 | false |
|
||||
|
||||
**Hinweis:** Bei Gmail wird ein App-spezifisches Passwort benötigt, kein normales Kontopasswort.
|
||||
|
||||
### E-Mail ohne Authentifizierung
|
||||
|
||||
Bei einem lokalen SMTP-Relay ohne Authentifizierung:
|
||||
|
||||
```ini
|
||||
SmtpServer = mailrelay.local
|
||||
SmtpPort = 25
|
||||
SmtpUseSsl = false
|
||||
SmtpUsername =
|
||||
SmtpPassword =
|
||||
```
|
||||
|
||||
## Benachrichtigungs-Ereignisse
|
||||
|
||||
Das Script sendet Benachrichtigungen bei folgenden Ereignissen:
|
||||
|
||||
| Ereignis | Priorität | Beschreibung |
|
||||
|---|---|---|
|
||||
| Keine Updates | default | Keine Updates verfügbar |
|
||||
| Dry-Run Report | default | Liste der verfügbaren Updates (ohne Installation) |
|
||||
| Updates OK | default | Zusammenfassung aller erfolgreich installierten Updates |
|
||||
| Updates mit Fehlern | high | Zusammenfassung inkl. fehlgeschlagener Updates |
|
||||
| Modul-Fehler | high | PSWindowsUpdate konnte nicht geladen werden |
|
||||
| Pre-Hook fehlgeschlagen | high | Pre-Update Script ist fehlgeschlagen, Updates abgebrochen |
|
||||
| Neustart steht an | high | System wird neugestartet (mit Modus und Zeitpunkt) |
|
||||
| Neustart erforderlich | high | Neustart nötig, aber Auto-Reboot ist deaktiviert |
|
||||
|
||||
## Sicherheitshinweis
|
||||
|
||||
Die `config.ini` enthält möglicherweise Zugangsdaten (SMTP-Passwort, ntfy-Token). Stelle sicher, dass:
|
||||
|
||||
- Die Datei `config.ini` in `.gitignore` eingetragen ist (ist standardmäßig der Fall)
|
||||
- Die Dateiberechtigungen auf dem Server eingeschränkt sind (nur Administratoren)
|
||||
- Das SMTP-Passwort idealerweise ein App-spezifisches Passwort ist, nicht das Hauptpasswort
|
||||
149
docs/task-scheduler.md
Normal file
149
docs/task-scheduler.md
Normal file
@@ -0,0 +1,149 @@
|
||||
# Aufgabenplanung (Task Scheduler)
|
||||
|
||||
Das Script kann über die Windows Aufgabenplanung automatisch ausgeführt werden, z.B. täglich zu einer bestimmten Uhrzeit.
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
- Das Script muss als **Administrator** (bzw. **SYSTEM**) ausgeführt werden
|
||||
- Eine `config.ini` muss im Script-Verzeichnis vorhanden sein
|
||||
- PowerShell 5.1 muss verfügbar sein (auf allen unterstützten OS standardmäßig vorhanden)
|
||||
|
||||
## Aufgabe per PowerShell erstellen (empfohlen)
|
||||
|
||||
Folgende Befehle in einer **administrativen PowerShell** ausführen:
|
||||
|
||||
### Täglich um 04:00 Uhr
|
||||
|
||||
```powershell
|
||||
$action = New-ScheduledTaskAction `
|
||||
-Execute "powershell.exe" `
|
||||
-Argument "-ExecutionPolicy Bypass -NoProfile -File `"C:\scripts\windows-updater\windows-updater.ps1`""
|
||||
|
||||
$trigger = New-ScheduledTaskTrigger -Daily -At "04:00"
|
||||
|
||||
$principal = New-ScheduledTaskPrincipal `
|
||||
-UserId "SYSTEM" `
|
||||
-RunLevel Highest `
|
||||
-LogonType ServiceAccount
|
||||
|
||||
$settings = New-ScheduledTaskSettingsSet `
|
||||
-AllowStartIfOnBatteries `
|
||||
-DontStopIfGoingOnBatteries `
|
||||
-StartWhenAvailable `
|
||||
-ExecutionTimeLimit (New-TimeSpan -Hours 2)
|
||||
|
||||
Register-ScheduledTask `
|
||||
-TaskName "Windows Updater" `
|
||||
-Action $action `
|
||||
-Trigger $trigger `
|
||||
-Principal $principal `
|
||||
-Settings $settings `
|
||||
-Description "Automatische Windows Updates mit Benachrichtigung"
|
||||
```
|
||||
|
||||
### Wöchentlich (z.B. Sonntags um 03:00 Uhr)
|
||||
|
||||
```powershell
|
||||
$trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Sunday -At "03:00"
|
||||
```
|
||||
|
||||
Den Rest wie oben, nur den Trigger austauschen.
|
||||
|
||||
### Bestehende Aufgabe ändern
|
||||
|
||||
```powershell
|
||||
# Uhrzeit ändern
|
||||
$trigger = New-ScheduledTaskTrigger -Daily -At "02:00"
|
||||
Set-ScheduledTask -TaskName "Windows Updater" -Trigger $trigger
|
||||
|
||||
# Aufgabe deaktivieren
|
||||
Disable-ScheduledTask -TaskName "Windows Updater"
|
||||
|
||||
# Aufgabe aktivieren
|
||||
Enable-ScheduledTask -TaskName "Windows Updater"
|
||||
|
||||
# Aufgabe löschen
|
||||
Unregister-ScheduledTask -TaskName "Windows Updater" -Confirm:$false
|
||||
```
|
||||
|
||||
### Aufgabe manuell starten (zum Testen)
|
||||
|
||||
```powershell
|
||||
Start-ScheduledTask -TaskName "Windows Updater"
|
||||
```
|
||||
|
||||
## Aufgabe per GUI erstellen
|
||||
|
||||
1. `taskschd.msc` öffnen (oder "Aufgabenplanung" im Startmenü suchen)
|
||||
2. Rechtsklick auf "Aufgabenplanungsbibliothek" → "Aufgabe erstellen..."
|
||||
3. Reiter **Allgemein**:
|
||||
- Name: `Windows Updater`
|
||||
- "Mit höchsten Privilegien ausführen" aktivieren
|
||||
- "Unabhängig von der Benutzeranmeldung ausführen" wählen
|
||||
- Benutzer auf `SYSTEM` ändern
|
||||
4. Reiter **Trigger**:
|
||||
- Neuer Trigger → Täglich → Startzeit z.B. 04:00
|
||||
5. Reiter **Aktionen**:
|
||||
- Neue Aktion → "Programm starten"
|
||||
- Programm: `powershell.exe`
|
||||
- Argumente: `-ExecutionPolicy Bypass -NoProfile -File "C:\scripts\windows-updater\windows-updater.ps1"`
|
||||
6. Reiter **Einstellungen**:
|
||||
- "Aufgabe so schnell wie möglich nach einem verpassten Start ausführen" aktivieren
|
||||
- "Aufgabe beenden, falls sie länger ausgeführt wird als:" 2 Stunden
|
||||
|
||||
## Wichtige Hinweise
|
||||
|
||||
### SYSTEM-Kontext
|
||||
|
||||
Das Script läuft als `SYSTEM`-Benutzer. Beachte dabei:
|
||||
|
||||
- **Netzlaufwerke** sind nicht verfügbar (SYSTEM hat keine zugeordneten Laufwerke)
|
||||
- **Umgebungsvariablen** wie `%USERPROFILE%` zeigen auf `C:\Windows\system32\config\systemprofile`
|
||||
- **winget** muss ggf. über den vollen Pfad aufgerufen werden (das Script behandelt dies automatisch)
|
||||
- **Log-Dateien** müssen in einem Verzeichnis liegen, auf das SYSTEM Schreibrechte hat (z.B. `C:\logs\`)
|
||||
|
||||
### Execution Policy
|
||||
|
||||
Das Script wird mit `-ExecutionPolicy Bypass` aufgerufen, damit es ohne vorherige Änderung der systemweiten Execution Policy läuft. Dies ist sicher, da nur dieses spezifische Script betroffen ist.
|
||||
|
||||
### Timeout
|
||||
|
||||
Die Standard-Ausführungszeitbegrenzung ist auf 2 Stunden gesetzt. Bei Servern mit vielen Updates kann dies ggf. erhöht werden:
|
||||
|
||||
```powershell
|
||||
$settings = New-ScheduledTaskSettingsSet `
|
||||
-ExecutionTimeLimit (New-TimeSpan -Hours 4)
|
||||
Set-ScheduledTask -TaskName "Windows Updater" -Settings $settings
|
||||
```
|
||||
|
||||
### Log prüfen
|
||||
|
||||
Nach der ersten automatischen Ausführung die Logs prüfen:
|
||||
|
||||
```powershell
|
||||
# Heutiges Log anzeigen
|
||||
$today = Get-Date -Format "yyyy-MM-dd"
|
||||
Get-Content "C:\logs\windows-updater\windows-updater_$today.log"
|
||||
|
||||
# Letzten Lauf in der Aufgabenplanung prüfen
|
||||
Get-ScheduledTaskInfo -TaskName "Windows Updater" | Select-Object LastRunTime, LastTaskResult
|
||||
```
|
||||
|
||||
### Exit-Codes in der Aufgabenplanung
|
||||
|
||||
| Task Result | Bedeutung |
|
||||
|---|---|
|
||||
| 0 | Erfolg |
|
||||
| 1 | Fehler (Details im Log) |
|
||||
| 2 | Neustart erforderlich (Auto-Reboot deaktiviert) |
|
||||
| 0x1 | Allgemeiner Fehler |
|
||||
| 0x41301 | Aufgabe läuft gerade |
|
||||
|
||||
## Empfohlene Zeitplanung
|
||||
|
||||
| Szenario | Empfehlung |
|
||||
|---|---|
|
||||
| Arbeitsstation | Täglich, 12:00 (Mittagspause) mit DryRun, Manuelles Update später |
|
||||
| Server (nicht-kritisch) | Täglich, 03:00-05:00 mit Auto-Reboot |
|
||||
| Server (kritisch/Produktion) | Wöchentlich Sonntag, 03:00 mit DryRun. Manuell nach Prüfung |
|
||||
| Testumgebung | Täglich, 02:00 mit Auto-Reboot |
|
||||
225
docs/troubleshooting.md
Normal file
225
docs/troubleshooting.md
Normal file
@@ -0,0 +1,225 @@
|
||||
# Problembehandlung
|
||||
|
||||
## PSWindowsUpdate-Modul lässt sich nicht laden
|
||||
|
||||
### Symptom
|
||||
```
|
||||
[ERROR] Failed to load PSWindowsUpdate module from any source
|
||||
```
|
||||
|
||||
### Lösungen
|
||||
|
||||
**Online-Installation schlägt fehl:**
|
||||
1. Prüfen ob TLS 1.2 verfügbar ist:
|
||||
```powershell
|
||||
[Net.ServicePointManager]::SecurityProtocol
|
||||
```
|
||||
2. NuGet-Provider manuell installieren:
|
||||
```powershell
|
||||
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
|
||||
```
|
||||
3. PSGallery als vertrauenswürdige Quelle setzen:
|
||||
```powershell
|
||||
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
|
||||
```
|
||||
4. Proxy prüfen (falls vorhanden):
|
||||
```powershell
|
||||
[System.Net.WebRequest]::DefaultWebProxy
|
||||
```
|
||||
|
||||
**Offline-Fallback schlägt fehl:**
|
||||
- Prüfen ob der Ordner `Modules\PSWindowsUpdate` im Script-Verzeichnis existiert
|
||||
- Prüfen ob die DLL-Datei vorhanden ist: `Modules\PSWindowsUpdate\2.2.1.2\PSWindowsUpdate.dll`
|
||||
|
||||
## Keine Updates gefunden
|
||||
|
||||
### Mögliche Ursachen
|
||||
|
||||
1. **WSUS blockiert Updates:**
|
||||
- Script zeigt "WSUS server detected" im Log
|
||||
- WSUS-Server hat möglicherweise keine Updates freigegeben
|
||||
- Lösung: WSUS-Administrator kontaktieren oder `UseMicrosoftUpdate = true` setzen (funktioniert nur ohne WSUS-GPO)
|
||||
|
||||
2. **Windows Update Service gestoppt:**
|
||||
```powershell
|
||||
Get-Service wuauserv | Select-Object Status
|
||||
# Falls gestoppt:
|
||||
Start-Service wuauserv
|
||||
```
|
||||
|
||||
3. **Updates bereits installiert:**
|
||||
- Das Script zeigt "No updates available" — alle Updates sind aktuell
|
||||
|
||||
## E-Mail wird nicht gesendet
|
||||
|
||||
### Checkliste
|
||||
|
||||
1. **SMTP-Server erreichbar?**
|
||||
```powershell
|
||||
Test-NetConnection -ComputerName smtp.example.com -Port 587
|
||||
```
|
||||
|
||||
2. **Zugangsdaten korrekt?** Im Log nach folgender Meldung suchen:
|
||||
```
|
||||
[WARN] Failed to send email: ...
|
||||
```
|
||||
|
||||
3. **App-Passwort bei Gmail/Microsoft 365:**
|
||||
- Normales Passwort funktioniert oft nicht
|
||||
- App-spezifisches Passwort in den Kontoeinstellungen erstellen
|
||||
|
||||
4. **Firewall:** Port 587 (oder 465/25) muss ausgehend offen sein
|
||||
|
||||
5. **SSL/TLS:** `SmtpUseSsl = true` für Port 587/465, `false` für Port 25 (lokal)
|
||||
|
||||
## ntfy-Benachrichtigung kommt nicht an
|
||||
|
||||
### Checkliste
|
||||
|
||||
1. **Server erreichbar?**
|
||||
```powershell
|
||||
Invoke-RestMethod -Uri "https://ntfy.sh/test-topic" -Method Post -Body "Test"
|
||||
```
|
||||
|
||||
2. **Topic korrekt?** Topic-Name muss in Config und App identisch sein
|
||||
|
||||
3. **Token korrekt?** Falls Authentifizierung konfiguriert:
|
||||
```powershell
|
||||
$headers = @{ "Authorization" = "Bearer tk_mein_token" }
|
||||
Invoke-RestMethod -Uri "https://ntfy.mein-server.de/test" -Method Post -Body "Test" -Headers $headers
|
||||
```
|
||||
|
||||
4. **App abonniert?** In der ntfy-App prüfen ob das Topic abonniert ist
|
||||
|
||||
## Winget wird nicht erkannt
|
||||
|
||||
### Auf Client-Systemen (Windows 10/11)
|
||||
|
||||
1. **Winget installiert?**
|
||||
```powershell
|
||||
Get-Command winget
|
||||
# oder
|
||||
Get-AppxPackage -Name Microsoft.DesktopAppInstaller
|
||||
```
|
||||
|
||||
2. **Winget aktualisieren:**
|
||||
- Microsoft Store öffnen → "App-Installer" aktualisieren
|
||||
|
||||
3. **Im SYSTEM-Kontext:** Winget ist eine per-User MSIX-App. Das Script versucht automatisch den Pfad über `Get-AppxPackage -AllUsers` zu finden.
|
||||
|
||||
### Auf Server-Systemen
|
||||
|
||||
Winget ist auf Windows Server standardmäßig **nicht verfügbar**. Es kann manuell installiert werden:
|
||||
|
||||
1. Aktuelle Version von [GitHub](https://github.com/microsoft/winget-cli/releases) herunterladen
|
||||
2. `.msixbundle` installieren (erfordert ggf. zusätzliche Abhängigkeiten)
|
||||
|
||||
Das Script erkennt automatisch ob winget verfügbar ist und überspringt die Funktion wenn nicht.
|
||||
|
||||
## ImportExcel / XLSX-Export funktioniert nicht
|
||||
|
||||
### Symptom
|
||||
```
|
||||
[WARN] ImportExcel not available, falling back to CSV for history export
|
||||
```
|
||||
|
||||
### Lösungen
|
||||
|
||||
1. **Manuell installieren:**
|
||||
```powershell
|
||||
Install-Module -Name ImportExcel -Force -Scope AllUsers
|
||||
```
|
||||
|
||||
2. **Kein Internet:** Das Script versucht automatisch das Modul zu installieren. Ohne Internet wird automatisch CSV als Fallback verwendet.
|
||||
|
||||
3. **CSV statt XLSX:** Funktioniert immer, keine zusätzlichen Module nötig. Die History-Datei wird dann als `.csv` statt `.xlsx` gespeichert.
|
||||
|
||||
## Script bricht mit "must be run as Administrator" ab
|
||||
|
||||
Das Script erfordert Administrator-Rechte für:
|
||||
- Installation von Windows Updates
|
||||
- Installation von PowerShell-Modulen
|
||||
- Zugriff auf Windows Update COM-Objekte
|
||||
|
||||
### Lösung
|
||||
- PowerShell als Administrator starten (Rechtsklick → "Als Administrator ausführen")
|
||||
- In der Aufgabenplanung: "Mit höchsten Privilegien ausführen" aktivieren und als `SYSTEM` ausführen
|
||||
|
||||
## Updates schlagen wiederholt fehl
|
||||
|
||||
### Mögliche Ursachen
|
||||
|
||||
1. **Speicherplatz:** Windows Updates benötigen freien Speicher
|
||||
```powershell
|
||||
Get-PSDrive C | Select-Object Used, Free
|
||||
```
|
||||
|
||||
2. **Windows Update Komponenten zurücksetzen:**
|
||||
```powershell
|
||||
# PSWindowsUpdate bietet dafür ein Cmdlet
|
||||
Reset-WUComponents -Verbose
|
||||
```
|
||||
|
||||
3. **Bestimmte KB ausschließen:** Falls ein spezifisches Update immer fehlschlägt:
|
||||
```ini
|
||||
[WindowsUpdate]
|
||||
ExcludeKBs = KB1234567
|
||||
```
|
||||
|
||||
4. **Retry-Count erhöhen:** Manchmal hilft ein weiterer Versuch:
|
||||
```ini
|
||||
[WindowsUpdate]
|
||||
RetryCount = 5
|
||||
```
|
||||
|
||||
## Log-Dateien werden nicht erstellt
|
||||
|
||||
1. **Verzeichnis-Berechtigungen prüfen:**
|
||||
```powershell
|
||||
# SYSTEM muss Schreibrechte haben
|
||||
icacls "C:\logs\windows-updater"
|
||||
```
|
||||
|
||||
2. **Verzeichnis erstellen:**
|
||||
```powershell
|
||||
New-Item -ItemType Directory -Path "C:\logs\windows-updater" -Force
|
||||
```
|
||||
|
||||
3. **LogPath in config.ini prüfen** — Pfad muss ohne Anführungszeichen angegeben werden
|
||||
|
||||
## Hook-Scripts werden nicht ausgeführt
|
||||
|
||||
1. **Pfad korrekt?** Absoluter Pfad verwenden, keine Umgebungsvariablen
|
||||
2. **Script vorhanden?** `Test-Path` auf den konfigurierten Pfad prüfen
|
||||
3. **Execution Policy:** Hook-Scripts werden mit `-ExecutionPolicy Bypass` aufgerufen
|
||||
4. **Exit-Code:** Hook muss mit `exit 0` enden für Erfolg, jeder andere Code gilt als Fehler
|
||||
|
||||
## Allgemeine Diagnose
|
||||
|
||||
### Log-Ausgabe im Detail prüfen
|
||||
|
||||
```powershell
|
||||
# Heutiges Log anzeigen
|
||||
$today = Get-Date -Format "yyyy-MM-dd"
|
||||
Get-Content "C:\logs\windows-updater\windows-updater_$today.log"
|
||||
|
||||
# Nach Fehlern suchen
|
||||
Select-String -Path "C:\logs\windows-updater\windows-updater_*.log" -Pattern "\[ERROR\]"
|
||||
```
|
||||
|
||||
### Script manuell mit Ausgabe testen
|
||||
|
||||
```powershell
|
||||
# In einer Admin-PowerShell ausführen
|
||||
powershell.exe -ExecutionPolicy Bypass -File "C:\scripts\windows-updater\windows-updater.ps1"
|
||||
```
|
||||
|
||||
### Dry-Run zum Testen
|
||||
|
||||
In `config.ini` setzen:
|
||||
```ini
|
||||
[General]
|
||||
DryRun = true
|
||||
```
|
||||
|
||||
Dies prüft alle Funktionen (Logging, Benachrichtigungen, Modulladung) ohne tatsächlich Updates zu installieren.
|
||||
@@ -1,25 +0,0 @@
|
||||
# Script Name: pswindowsupdate-installer.ps1
|
||||
# Beschreibung: Installiert das Modul 'PSWindowsUpdate' und alle anderen Voraussetzungen per Internet
|
||||
# Lauffähig unter Windows Server 2016, 2019 und 2022
|
||||
# Aufruf: -
|
||||
# Autor: Patrick Asmus
|
||||
# Web: https://www.media-techport.de
|
||||
# Git-Reposit.: https://git.media-techport.de/scriptos/PSWindowsUpdate.git
|
||||
# Version: 1.0
|
||||
# Datum: 29.11.2023
|
||||
# Modifikation: Erste Veröffentlichung
|
||||
#####################################################
|
||||
|
||||
# Setze TLS 1.2 als Sicherheitsprotokoll
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
|
||||
# Überprüfe, ob das PowerShellGet-Modul vorhanden ist. Falls nicht, installiere es.
|
||||
if (-not (Get-Module -Name PowerShellGet -ListAvailable)) {
|
||||
Install-Module -Name PowerShellGet -Force -AllowClobber
|
||||
}
|
||||
|
||||
# Installiere PSWindowsUpdate-Modul
|
||||
Install-Module -Name PSWindowsUpdate -Force
|
||||
|
||||
# Zeige installiertes PSWindowsUpdate-Modul an
|
||||
Get-Package -Name PSWindowsUpdate
|
||||
1143
windows-updater.ps1
1143
windows-updater.ps1
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user