# Intune Manager – Web Edition Modernes Web-Frontend fuer den Intune Manager. PowerShell startet einen lokalen HTTP-Server, der das Frontend ausliefert und die Microsoft Graph-Aufrufe ausfuehrt. ## Voraussetzungen - Windows mit PowerShell 5.1 oder PowerShell 7+ - Modul `Microsoft.Graph.Authentication` (wird beim ersten Connect benoetigt): ```powershell Install-Module Microsoft.Graph.Authentication -Scope CurrentUser -Force ``` - Browser (Edge, Chrome, Firefox) ## Start ```powershell .\Start.ps1 ``` Optionen: | Parameter | Standard | Beschreibung | |---------------|----------|-----------------------------------------------------------| | `-Port` | `8077` | Port des lokalen HTTP-Servers | | `-TenantId` | — | Ueberschreibt Tenant-ID aus Settings (nur dieser Start) | | `-ClientId` | — | Ueberschreibt Client-ID aus Settings (nur dieser Start) | | `-NoBrowser` | aus | Browser nicht automatisch oeffnen | Beispiele: ```powershell .\Start.ps1 -Port 8088 .\Start.ps1 -NoBrowser ``` Beenden: `Ctrl+C` im Terminal. --- ## Verbindungsmodus (Read/Write vs. Read-Only) Der Server probiert beim Verbinden **zuerst die Read/Write-App-ID** (`clientId`). Schlaegt diese fehl, wird automatisch auf die **Read-Only-App-ID** (`clientIdRo`) zurueckgefallen. | Modus | Anmelde-Ergebnis | Verhalten im Frontend | |-------------|------------------------------------------|------------------------------------------------| | Read/Write | Normale Verbindung | Alle Funktionen verfuegbar | | Read-Only | Fallback auf `clientIdRo` | Schreib-Buttons/Tabs werden ausgeblendet | ### Was wird im Read-Only-Modus ausgeblendet? - App-Zuweisung (Required / Available hinzufuegen und entfernen) - Gruppen erstellen und loeschen - Tab „Benutzer hinzufuegen" im Group Management - Tab „CSV-Import" im Group Management - Session-Ausfuehren-Button - Alle Rename-/Delete-Buttons ### Konfiguration in den Einstellungen ``` Settings → Verbindung Client-ID (Read/Write): Client-ID (Read-Only): (optional) Scopes RW: DeviceManagementApps.ReadWrite.All ... Scopes RO: DeviceManagementApps.Read.All ... ``` ### Benoetigt Graph-Berechtigungen | Funktion | Benoetigt | |----------------------------------|----------------------------------------------| | Apps anzeigen | `DeviceManagementApps.Read.All` | | Gruppen anzeigen / Mitglieder | `GroupMember.Read.All` | | User suchen | `User.Read.All` | | Zuweisungen aendern | `DeviceManagementApps.ReadWrite.All` | | Gruppen-Mitglieder aendern | `GroupMember.ReadWrite.All` | | App-Installationszaehler (Report)| `DeviceManagementManagedDevices.Read.All` ⚠ | | Geraete-Exportliste pro App | `DeviceManagementManagedDevices.Read.All` ⚠ | > ⚠ Ohne `DeviceManagementManagedDevices.Read.All` zeigt der App-Report nur > Zaehler = 0 und der Geraete-Export liefert keine Eintraege. --- ## Navigation (Tabs) | Tab | Beschreibung | |--------------------|-------------------------------------------------------------| | App Management | Haupt-Ansicht: Apps laden, Gruppen zuweisen / entfernen | | Group Management | Mitglieder anzeigen, exportieren, Benutzer hinzufuegen, CSV-Import | | App Report | Installationszaehler pro App, Geraete-Export als CSV | | Geräte | Geraete suchen, Detail-Panel, Aktionen (Sync, Wipe, …) | | Policies | Policies exportieren (JSON-Download) und importieren (Neuanlage) | --- ## Group Management ### Mitglieder & Export - Gruppe links suchen und auswaehlen - Mitgliederliste (inkl. verschachtelte Gruppen) wird geladen - Filter zum Einschraenken der Anzeige - **Als CSV exportieren** laedt alle Mitglieder als `members--.csv` ### Benutzer hinzufuegen *(nur Read/Write)* - Benutzer per Name, UPN oder E-Mail suchen - Mehrere Benutzer auswaehlen und gemeinsam hinzufuegen ### CSV-Import *(nur Read/Write)* Massenhaftes Hinzufuegen von Benutzern zu einer Gruppe per CSV-Datei. **Ablauf:** 1. Gruppe links auswaehlen 2. CSV hochladen **oder** UPNs/E-Mails direkt einfuegen (eine pro Zeile) 3. **„Benutzer aufloesen"** – Graph-Lookup via UPN/Mail → Vorschau mit ✓/✗ 4. **„Gefundene importieren"** – fuegt alle gefundenen Benutzer zur Gruppe hinzu **CSV-Format:** Die erste Zeile wird als optionaler Header erkannt. Spalte mit dem Namen `UserPrincipalName`, `Mail` oder `Email` wird automatisch ausgewaehlt. Ohne Header: erste Spalte mit `@` wird verwendet. ```csv DisplayName,UserPrincipalName,Mail Max Mustermann,max.mustermann@firma.de,max.mustermann@firma.de Erika Muster,erika.muster@firma.de, ``` Oder einfach eine UPN pro Zeile: ``` max.mustermann@firma.de erika.muster@firma.de ``` **Ergebnis-Anzeige nach Import:** | Chip / Status | Bedeutung | |--------------------|------------------------------------------------| | ✔ Gruen | Erfolgreich hinzugefuegt | | ≈ Gelb | Bereits Mitglied (kein Fehler) | | ✗ Rot | Fehler (Meldung in der Tabelle) | | Grau | UPN nicht in Graph gefunden (nicht importiert) | --- ## App Report - **Neu laden**: laedt Installationszaehler fuer alle Apps (kann 1–2 Min. dauern) - Tabelle sortierbar per Klick auf Spaltenheader - Suche filtert nach App-Name, Publisher, Typ - **Als CSV exportieren**: exportiert die gefilterte Tabelle - **Geraete-Export** (pro Zeile): laedt alle Geraete mit Installationsstatus fuer diese App --- ## Policies (Export / Import) Sichert Intune-Policies als JSON und legt sie in einem (ggf. anderen) Tenant neu an. Unterstuetzte Typen: | Typ | Graph-Collection | |-------------------------|-----------------------------| | Settings Catalog | `configurationPolicies` | | Compliance Policies | `deviceCompliancePolicies` | | Konfigurationsprofile | `deviceConfigurations` | ### Export - Tabelle laedt alle drei Typen; Suche + Typ-Filter grenzen ein - Policies per Checkbox auswaehlen → **Export** - **1 Policy** → eine JSON-Datei - **mehrere** → eine gebündelte JSON-Datei (`intune-policies_.json`) - Zusaetzlich wird jeder Export server-seitig unter `%APPDATA%\IntuneAppManager-Web\policy-exports` archiviert ### Import *(nur Read/Write)* - **Import…** → eine oder mehrere JSON-Dateien waehlen (einzeln oder Bundle) - Import legt die Policies **immer als neue Policy** an — bestehende Policies werden nie ueberschrieben - Ergebnis-Toast meldet Erfolg/Fehler pro Policy > Beim Anlegen entfernt der Import instanzgebundene / schreibgeschuetzte Felder > (`id`, Zeitstempel, `version`, Zuweisungen, Status). Compliance-Policies > bekommen bei Bedarf einen Default-`scheduledActionsForRule`-Block, den Graph > beim Anlegen zwingend verlangt. ### Benoetigt Graph-Berechtigung `DeviceManagementConfiguration.ReadWrite.All` (Import) bzw. `DeviceManagementConfiguration.Read.All` (nur Export). Der Scope wird beim Start automatisch zur Verbindung ergaenzt — in der Azure-App-Registration muss die Berechtigung aber vorhanden und (Admin-)zugestimmt sein. --- ## Architektur ``` Intune Manager/ ├── Start.ps1 Entry Point, Config, State ├── README.md diese Datei ├── src/ │ ├── Models.ps1 Settings-Schema und Defaults │ ├── Graph.ps1 Microsoft Graph API Helpers │ ├── Server.ps1 HTTP-Server (HttpListener) │ ├── Router.ps1 Request-Routing │ ├── Api.ps1 REST-API-Endpoints │ └── PolicyIO.ps1 Policy Export/Import (Compliance, Config, Settings Catalog) └── www/ ├── index.html SPA-Shell ├── styles.css Dark Theme, Read-Only-Regeln └── app.js Frontend-Logik (Vanilla JS) ``` --- ## REST-API (intern) | Methode | Pfad | Rechte | Zweck | |---------|-------------------------------------------|-----------|------------------------------------------| | GET | `/api/status` | — | Verbindungsstatus + ReadOnly-Flag | | POST | `/api/connect` | — | Microsoft Graph verbinden | | POST | `/api/disconnect` | — | Trennen | | GET | `/api/groups` | Read | Abteilungs-Gruppen (`abt-hm-*`) | | GET | `/api/groups/rpa` | Read | 3 vordefinierte RPA-Gruppen | | GET | `/api/groups/search?q=` | Read | Gruppen suchen | | POST | `/api/groups` | **Write** | Neue Required-Gruppe erstellen | | POST | `/api/groups/check` | Read | Gruppen-Name pruefen | | POST | `/api/groups/resolve-upns` | Read | UPN-Liste → UserId + DisplayName | | GET | `/api/groups/{id}/members` | Read | Mitglieder einer Gruppe | | GET | `/api/groups/{id}/members/export` | Read | Mitglieder als CSV | | POST | `/api/groups/{id}/members` | **Write** | Benutzer zur Gruppe hinzufuegen | | DELETE | `/api/groups/{id}/members/{uid}` | **Write** | Benutzer aus Gruppe entfernen | | GET | `/api/users?q=` | Read | Benutzer suchen | | GET | `/api/apps` | Read | Apps laden (cached) | | POST | `/api/apps/refresh` | Read | Apps neu laden | | GET | `/api/apps/report` | Read+MDM | Installationszaehler alle Apps | | GET | `/api/apps/devicestatus?appId=` | Read+MDM | Geraete-Installationsstatus einer App | | GET | `/api/membership?targets=&groupId=` | Read | Mitgliedschafts-Status pruefen | | POST | `/api/membership/bulk` | Read | Mehrere Mitgliedschaften pruefen | | POST | `/api/assignments/apply` | **Write** | Geplante Zuweisungen ausfuehren | | GET | `/api/policies/settingscatalog` | Read+Cfg | Settings-Catalog-Policies auflisten | | GET | `/api/policies/compliance` | Read+Cfg | Compliance-Policies auflisten | | GET | `/api/policies/configuration` | Read+Cfg | Konfigurationsprofile auflisten | | POST | `/api/policies/export` | Read+Cfg | Ausgewaehlte Policies als JSON exportieren | | GET | `/api/policies/exports` | — | Server-Archiv der Exporte auflisten | | POST | `/api/policies/import` | **Write** | Policies als Neuanlage importieren | > **Read+MDM** = benoetigt zusaetzlich `DeviceManagementManagedDevices.Read.All` > **Read+Cfg** = benoetigt `DeviceManagementConfiguration.Read.All` (Export) bzw. `.ReadWrite.All` (Import) --- ## Hinweise - **Single-User-App** – der lokale HTTP-Server ist fuer einen Benutzer ausgelegt. - **Auth lebt im PowerShell-Prozess** – Disconnect oder Schliessen des Terminals beendet die Session. - **Cache** – Apps werden im Serverprozess gecacht. Refresh-Knopf laedt neu. - **Port-Konflikt** – laeuft bereits eine Instanz, beendet `Start.ps1` sie automatisch (per CommandLine-Matching). Bei PID-4-Konflikt (http.sys) anderen Port waehlen: `.\Start.ps1 -Port 8088`.