Files
KDS-Install-Agent/web/index.html
T
MrBlakeandClaude Opus 5.5 f4c2a16612 KDS Install Agent: Grundversion
PowerShell-HTTP-Server mit Web-/Desktop-Oberflaeche: Programme (winget/Store),
Office-ODT-Konfigurator, Desktop-Icons, System/Sicherheit, Energie, BitLocker,
Windows-/Treiber-Updates, Profile und Job-Queue.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 15:48:11 +02:00

351 lines
18 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>KDS Install Agent</title>
<link rel="stylesheet" href="style.css">
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><rect width='16' height='16' rx='3' fill='%230a64d6'/><path d='M4 8l3 3 5-6' stroke='white' stroke-width='2' fill='none'/></svg>">
</head>
<body>
<aside class="side">
<div class="brand">KDS <span>Install Agent</span></div>
<nav id="nav">
<a data-tab="overview" class="active">Übersicht</a>
<a data-tab="apps">Programme</a>
<a data-tab="office">Office</a>
<a data-tab="shortcuts">Desktop-Icons</a>
<a data-tab="system">System &amp; Sicherheit</a>
<a data-tab="power">Energie</a>
<a data-tab="bitlocker">BitLocker</a>
<a data-tab="updates">Updates &amp; Treiber</a>
<a data-tab="profiles">Profile</a>
<a data-tab="jobs">Aufgaben <b id="jobBadge" class="badge hidden">0</b></a>
</nav>
<div class="side-foot">
<div id="profileName" class="muted">Profil: (ungespeichert)</div>
<button class="ghost" id="btnShutdown">Agent beenden</button>
</div>
</aside>
<main>
<!-- Übersicht -->
<section id="tab-overview" class="tab active">
<h1>Übersicht</h1>
<div id="sysinfo" class="grid4"></div>
<div class="card">
<h2>Komplette Einrichtung mit einem Klick</h2>
<p class="muted">Führt die Einstellungen aus allen Tabs in sinnvoller Reihenfolge aus. Vorher in den Tabs konfigurieren oder ein Profil laden.</p>
<div class="checks" id="steps">
<label><input type="checkbox" value="system" checked> System</label>
<label><input type="checkbox" value="security" checked> Sicherheit</label>
<label><input type="checkbox" value="power" checked> Energie</label>
<label><input type="checkbox" value="apps" checked> Programme</label>
<label><input type="checkbox" value="office" checked> Office</label>
<label><input type="checkbox" value="shortcuts" checked> Desktop-Icons</label>
<label><input type="checkbox" value="drivers"> Hersteller-Treiber</label>
<label><input type="checkbox" value="updates" checked> Windows Update</label>
<label><input type="checkbox" value="bitlocker"> BitLocker</label>
</div>
<div id="summary" class="summary"></div>
<button class="primary big" id="btnRunAll">▶ Einrichtung starten</button>
</div>
</section>
<!-- Programme -->
<section id="tab-apps" class="tab">
<h1>Programme</h1>
<div class="cols">
<div>
<div class="card">
<h2>Suche in öffentlichen Bibliotheken</h2>
<div class="row">
<input id="appSearch" placeholder="z.B. firefox, acrobat, teamviewer …">
<select id="appSource"><option value="winget">winget (Community-Repo)</option><option value="msstore">Microsoft Store</option></select>
<button id="btnSearch">Suchen</button>
</div>
<div id="searchResults" class="list"></div>
</div>
<div class="card">
<h2>Schnellauswahl</h2>
<div id="catalog"></div>
</div>
<div class="card">
<h2>Eigene Installer vom Stick <span class="muted small">(Ordner <code>installers\</code>)</span></h2>
<div class="row">
<select id="localFile"></select>
<input id="localArgs" placeholder="Silent-Parameter, z.B. /S oder /quiet">
<button id="btnAddLocal">Hinzufügen</button>
</div>
</div>
</div>
<div>
<div class="card sticky">
<h2>Ausgewählt <span id="appCount" class="badge">0</span></h2>
<div id="selectedApps" class="list"></div>
<button class="primary" id="btnInstallApps">Jetzt installieren</button>
<button id="btnUpgradeAll">Alle installierten Programme aktualisieren</button>
</div>
</div>
</div>
</section>
<!-- Office -->
<section id="tab-office" class="tab">
<h1>Microsoft Office</h1>
<div class="cols">
<div class="card">
<h2>Konfiguration</h2>
<label class="f">Produkt<select id="officeProduct" data-bind="office.product"></select></label>
<label class="f">Update-Kanal<select id="officeChannel" data-bind="office.channel"></select></label>
<label class="f">Architektur
<select data-bind="office.arch"><option value="64">64-Bit (empfohlen)</option><option value="32">32-Bit</option></select></label>
<label class="f">Lizenzschlüssel (nur Volumenlizenz/MAK)<input data-bind="office.pidKey" placeholder="XXXXX-XXXXX-XXXXX-XXXXX-XXXXX"></label>
<label class="f">Firmenname<input data-bind="office.company" placeholder="optional"></label>
<h3>Sprachen</h3>
<div class="checks" data-bind-list="office.languages">
<label><input type="checkbox" value="de-de"> Deutsch</label>
<label><input type="checkbox" value="en-us"> Englisch</label>
<label><input type="checkbox" value="fr-fr"> Französisch</label>
<label><input type="checkbox" value="it-it"> Italienisch</label>
<label><input type="checkbox" value="es-es"> Spanisch</label>
<label><input type="checkbox" value="nl-nl"> Niederländisch</label>
<label><input type="checkbox" value="pl-pl"> Polnisch</label>
<label><input type="checkbox" value="tr-tr"> Türkisch</label>
<label><input type="checkbox" value="MatchOS"> Wie Windows</label>
</div>
<h3>Apps <span class="muted small">(abgewählte werden nicht installiert)</span></h3>
<div class="checks" id="officeApps"></div>
<h3>Zusatzprodukte</h3>
<div class="checks" id="officeExtras"></div>
<h3>Optionen</h3>
<div class="checks col">
<label><input type="checkbox" data-bind="office.updates"> Automatische Updates</label>
<label><input type="checkbox" data-bind="office.removeMsi"> Alte MSI-Office-Versionen entfernen</label>
<label><input type="checkbox" data-bind="office.migrateArch"> Architektur einer vorhandenen Installation migrieren</label>
<label><input type="checkbox" data-bind="office.sharedComputer"> Aktivierung für gemeinsam genutzte Computer (RDS)</label>
<label><input type="checkbox" data-bind="office.disableVba"> Makros aus dem Internet blockieren</label>
<label><input type="checkbox" data-bind="office.ooxmlDefault"> Erststart-Dialog unterdrücken</label>
<label><input type="checkbox" data-bind="office.showUi"> Installationsfortschritt anzeigen</label>
</div>
</div>
<div>
<div class="card">
<h2>Generierte configuration.xml</h2>
<pre id="officeXml" class="code"></pre>
<div class="row">
<button id="btnXmlDownload">XML herunterladen</button>
<button id="btnXmlCopy">Kopieren</button>
</div>
</div>
<div class="card">
<h2>Ausführen</h2>
<label class="f">Modus
<select data-bind="officeMode">
<option value="online">Online installieren (direkt von Microsoft)</option>
<option value="download">Nur Build erstellen (Dateien auf den Stick laden)</option>
<option value="offline">Vom Stick installieren (Build wird bei Bedarf erstellt)</option>
</select></label>
<p class="muted small">setup.exe des Office Deployment Tools wird bei Bedarf automatisch von Microsoft geladen und unter <code>office\</code> abgelegt. Builds liegen in <code>office\source\</code>.</p>
<div id="officeBuilds" class="muted small"></div>
<button class="primary" id="btnOffice">Ausführen</button>
</div>
</div>
</div>
</section>
<!-- Desktop-Icons -->
<section id="tab-shortcuts" class="tab">
<h1>Desktop-Icons für alle Benutzer</h1>
<div class="cols">
<div>
<div class="card">
<h2>Neue Verknüpfung</h2>
<label class="f">Typ<select id="scType"><option value="url">Webseite (URL)</option><option value="lnk">Programm / Datei / Ordner</option></select></label>
<label class="f">Name<input id="scName" placeholder="z.B. Intranet"></label>
<label class="f">Ziel<input id="scTarget" placeholder="https://… oder %ProgramFiles%\…\app.exe"></label>
<label class="f lnkonly">Argumente<input id="scArgs"></label>
<label class="f">Icon <span class="muted small">(Ordner <code>icons\</code> auf dem Stick oder Pfad)</span>
<input id="scIcon" list="iconList" placeholder="optional"></label>
<datalist id="iconList"></datalist>
<div class="row">
<button class="primary" id="btnScCreate">Sofort anlegen</button>
<button id="btnScPlan">Zum Profil hinzufügen</button>
</div>
</div>
<div class="card">
<h2>Vorlagen</h2>
<div id="scPresets" class="chips"></div>
</div>
</div>
<div>
<div class="card">
<h2>Im Profil geplant</h2>
<div id="scPlanned" class="list"></div>
<button class="primary" id="btnScApplyAll">Alle geplanten jetzt anlegen</button>
</div>
<div class="card">
<h2>Aktuell auf dem öffentlichen Desktop <button class="small ghost" id="btnScRefresh">↻</button></h2>
<div id="scCurrent" class="list"></div>
</div>
</div>
</div>
</section>
<!-- System & Sicherheit -->
<section id="tab-system" class="tab">
<h1>System &amp; Sicherheit</h1>
<div class="cols">
<div class="card">
<h2>System</h2>
<label class="f">Computername <span class="muted small">(leer = unverändert, max. 15 Zeichen)</span><input data-bind="system.computerName" maxlength="15"></label>
<label class="f">Zeitzone<select id="tzSelect" data-bind="system.timeZone"><option value="">unverändert</option></select></label>
<div class="checks col">
<label><input type="checkbox" data-bind="system.showExtensions"> Dateiendungen anzeigen (auch für neue Benutzer)</label>
<label><input type="checkbox" data-bind="system.disableConsumer"> Werbe-Apps / Consumer-Features deaktivieren</label>
</div>
<button class="primary" data-run="system">Systemeinstellungen anwenden</button>
</div>
<div class="card">
<h2>Sicherheit</h2>
<div class="checks col">
<label><input type="checkbox" data-bind="security.defender"> Defender: Echtzeit-, Cloud- &amp; PUA-Schutz</label>
<label><input type="checkbox" data-bind="security.firewall"> Firewall für alle Profile aktivieren</label>
<label><input type="checkbox" data-bind="security.smartScreen"> SmartScreen aktivieren</label>
<label><input type="checkbox" data-bind="security.uac"> UAC auf höchste Stufe</label>
<label><input type="checkbox" data-bind="security.disableSmb1"> SMBv1 deaktivieren</label>
<label><input type="checkbox" data-bind="security.disableAutorun"> Autorun / Autoplay deaktivieren</label>
<label><input type="checkbox" data-bind="security.lsaProtection"> LSA-Schutz (Credential-Diebstahl erschweren)</label>
<label><input type="checkbox" data-bind="security.telemetryMin"> Telemetrie minimieren</label>
</div>
<label class="f">Remotedesktop
<select data-bind="security.rdp"><option value="keep">unverändert</option><option value="enable">aktivieren (mit NLA)</option><option value="disable">deaktivieren</option></select></label>
<h3>Lokales Admin-Konto <span class="muted small">(optional)</span></h3>
<div class="row">
<input data-bind="security.localAdminName" placeholder="Benutzername">
<input data-bind="security.localAdminPassword" type="password" placeholder="Kennwort" autocomplete="new-password">
</div>
<p class="muted small">Hinweis: Das Kennwort wird beim Speichern im Profil im Klartext abgelegt.</p>
<button class="primary" data-run="security">Sicherheitseinstellungen anwenden</button>
</div>
</div>
</section>
<!-- Energie -->
<section id="tab-power" class="tab">
<h1>Energie</h1>
<div class="card">
<div id="powerState" class="muted small"></div>
<label class="f">Energieplan
<select data-bind="power.plan"><option value="">unverändert</option><option value="balanced">Ausbalanciert</option><option value="high">Höchstleistung</option><option value="ultimate">Ultimative Leistung</option></select></label>
<table class="ptable">
<tr><th></th><th>Netzbetrieb 🔌</th><th>Akku 🔋</th></tr>
<tr><td>Bildschirm aus nach (Min., 0 = nie)</td><td><input type="number" min="0" data-bind="power.monitorAc"></td><td><input type="number" min="0" data-bind="power.monitorDc"></td></tr>
<tr><td>Energiesparmodus nach</td><td><input type="number" min="0" data-bind="power.sleepAc"></td><td><input type="number" min="0" data-bind="power.sleepDc"></td></tr>
<tr><td>Ruhezustand nach</td><td><input type="number" min="0" data-bind="power.hibernateAc"></td><td><input type="number" min="0" data-bind="power.hibernateDc"></td></tr>
<tr><td>Deckel schließen</td><td><select data-bind="power.lidAc" class="act"></select></td><td><select data-bind="power.lidDc" class="act"></select></td></tr>
<tr><td>Netzschalter</td><td><select data-bind="power.buttonAc" class="act"></select></td><td><select data-bind="power.buttonDc" class="act"></select></td></tr>
</table>
<div class="row">
<label class="f">Ruhezustand<select data-bind="power.hibernate"><option value="">unverändert</option><option value="on">ein</option><option value="off">aus</option></select></label>
<label class="f">Schnellstart<select data-bind="power.fastStartup"><option value="">unverändert</option><option value="on">ein</option><option value="off">aus (empfohlen für Updates)</option></select></label>
</div>
<button class="primary" data-run="power">Energieeinstellungen anwenden</button>
</div>
</section>
<!-- BitLocker -->
<section id="tab-bitlocker" class="tab">
<h1>BitLocker</h1>
<div class="cols">
<div class="card">
<h2>Status <button class="small ghost" id="btnBlRefresh">↻</button></h2>
<div id="blStatus">Lade …</div>
</div>
<div class="card">
<h2>Aktivieren</h2>
<label class="f">Verschlüsselung<select data-bind="bitlocker.method"><option value="XtsAes256">XTS-AES 256 (empfohlen)</option><option value="XtsAes128">XTS-AES 128</option></select></label>
<div class="checks col">
<label><input type="checkbox" data-bind="bitlocker.usedSpaceOnly"> Nur belegten Speicher verschlüsseln (schnell, für neue Geräte)</label>
<label><input type="checkbox" data-bind="bitlocker.skipHardwareTest"> Hardwaretest überspringen (sofort starten)</label>
<label><input type="checkbox" data-bind="bitlocker.usePin"> Start-PIN zusätzlich zum TPM</label>
<label><input type="checkbox" data-bind="bitlocker.backupAad"> Schlüssel in Entra ID (Azure AD) sichern</label>
<label><input type="checkbox" data-bind="bitlocker.backupAd"> Schlüssel im Active Directory sichern</label>
</div>
<label class="f pinonly">PIN (6–20 Ziffern)<input data-bind="bitlocker.pin" type="password" inputmode="numeric"></label>
<p class="muted small">Der Wiederherstellungsschlüssel wird immer auf dem Stick unter <code>bitlocker-keys\</code> abgelegt (Computername + Seriennummer).</p>
<div class="row">
<button class="primary" data-bl="enable">BitLocker aktivieren</button>
<button data-bl="savekey">Schlüssel erneut sichern</button>
<button class="danger" data-bl="disable">Deaktivieren</button>
</div>
</div>
</div>
</section>
<!-- Updates -->
<section id="tab-updates" class="tab">
<h1>Updates &amp; Treiber</h1>
<div class="card">
<div class="row wrap">
<button class="primary" data-scan="Software">Windows-Updates suchen</button>
<button class="primary" data-scan="Driver">Treiber-Updates suchen</button>
<button data-scan="all">Alles suchen</button>
<span class="sep"></span>
<button id="btnVendor">Hersteller-Tool (Dell/Lenovo/HP)</button>
<button id="btnWingetUpg">Programme aktualisieren (winget)</button>
<button id="btnWinget">winget reparieren</button>
<span class="sep"></span>
<button class="danger" id="btnReboot">Neustart</button>
</div>
</div>
<div class="card">
<h2>Gefundene Updates <span id="updCount" class="badge">0</span></h2>
<div id="updList" class="list"><p class="muted">Noch keine Suche durchgeführt.</p></div>
<div class="row">
<button class="primary" id="btnUpdSel">Ausgewählte installieren</button>
<button id="btnUpdAll">Alle installieren</button>
</div>
</div>
</section>
<!-- Profile -->
<section id="tab-profiles" class="tab">
<h1>Profile</h1>
<div class="cols">
<div class="card">
<h2>Gespeicherte Profile <span class="muted small">(Ordner <code>profiles\</code>)</span></h2>
<div id="profileList" class="list"></div>
</div>
<div class="card">
<h2>Aktuelle Konfiguration speichern</h2>
<div class="row"><input id="profileSaveName" placeholder="z.B. Buero-Standard"><button class="primary" id="btnProfileSave">Speichern</button></div>
<h3>Import / Export</h3>
<div class="row">
<button id="btnExport">Als JSON exportieren</button>
<label class="button">Importieren<input type="file" id="importFile" accept=".json" hidden></label>
<button class="ghost" id="btnReset">Zurücksetzen</button>
</div>
</div>
</div>
</section>
<!-- Jobs -->
<section id="tab-jobs" class="tab">
<h1>Aufgaben</h1>
<div class="cols jobs">
<div class="card"><div id="jobList" class="list"></div></div>
<div class="card">
<h2 id="jobTitle">Protokoll</h2>
<pre id="jobLog" class="code log"></pre>
<div class="row"><button class="danger hidden" id="btnJobStop">Abbrechen</button></div>
</div>
</div>
</section>
</main>
<div id="toast"></div>
<script src="app.js"></script>
</body>
</html>