Dieses Script setzt optional die Execution Policy, vertraut PSGallery, installiert die wichtigsten Module für die Schulcomputer-Administration und kann auf Wunsch auch gleich die Anmeldung an Microsoft Graph starten.

Inhalt

Das Skript installiert moderne Module wie Microsoft.Graph, Microsoft.Graph.DeviceManagement, Microsoft.Graph.DeviceManagement.Administration, ExchangeOnlineManagement, MicrosoftTeams, Microsoft.Online.SharePoint.PowerShell und IntuneEndpointTools, weil diese für Intune-, M365- und Schul-PC-Verwaltung sinnvoll sind. Veraltete Module wie AzureAD und MSOnline sind nicht standardmäßig enthalten und werden nur per Schalter ergänzt, weil sie nur noch für Altskripte gedacht sind.

Verwendung

Normale Ausführung für den aktuellen Benutzer:

.\Schuladmin-PowerShell-Setup.ps1

Systemweit für alle Benutzer:

.\Schuladmin-PowerShell-Setup.ps1 -AllUsers

Mit alten AzureAD/MSOnline-Modulen für Legacy-Skripte:

.\Schuladmin-PowerShell-Setup.ps1 -IncludeLegacyAzureAD

Optional

Mit direkter Graph-Anmeldung:

.\Schuladmin-PowerShell-Setup.ps1 -ConnectGraph

Testlauf ohne Änderungen:

.\Schuladmin-PowerShell-Setup.ps1 -WhatIf

Hinweis

Das Skript ist so gebaut, dass es auch unter Windows PowerShell 5.1 lauffähig bleibt, gleichzeitig aber moderne Graph-/Intune-Module bevorzugt. Für neue Admin-Skripte auf Schulgeräten ist PowerShell 7 meist die bessere Zielplattform, aber für manche Altlasten bleibt 5.1 relevant.

Skript

Das folgende Skript als Schuladmin-PowerShell-Setup.ps1 abspeichern.

#requires -Version 5.1
[CmdletBinding(SupportsShouldProcess = $true)]
param(
    [switch]$AllUsers,
    [switch]$IncludeLegacyAzureAD,
    [switch]$SkipExecutionPolicy,
    [switch]$SkipRepositoryTrust,
    [switch]$ConnectGraph,
    [string[]]$GraphScopes = @('DeviceManagementManagedDevices.ReadWrite.All','Group.ReadWrite.All')
)

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

function Write-Info {
    param([string]$Message)
    Write-Host "[INFO] $Message" -ForegroundColor Cyan
}

function Write-WarnMsg {
    param([string]$Message)
    Write-Host "[HINWEIS] $Message" -ForegroundColor Yellow
}

function Install-RequiredModule {
    param(
        [Parameter(Mandatory)] [string]$Name,
        [string]$MinimumVersion,
        [switch]$AllowClobber
    )

    $installParams = @{
        Name  = $Name
        Force = $true
    }

    if ($AllUsers) {
        $installParams['Scope'] = 'AllUsers'
    }
    else {
        $installParams['Scope'] = 'CurrentUser'
    }

    if ($MinimumVersion) {
        $installParams['MinimumVersion'] = $MinimumVersion
    }

    if ($AllowClobber) {
        $installParams['AllowClobber'] = $true
    }

    $installed = Get-Module -ListAvailable -Name $Name | Sort-Object Version -Descending | Select-Object -First 1

    if ($installed -and (-not $MinimumVersion -or $installed.Version -ge [version]$MinimumVersion)) {
        Write-Info "$Name ist bereits installiert (Version $($installed.Version))."
        return
    }

    if ($PSCmdlet.ShouldProcess($Name, 'Install-Module')) {
        Write-Info "Installiere Modul: $Name"
        Install-Module @installParams
    }
}

Write-Info "Starte PowerShell-Grundeinrichtung für die Verwaltung von Schulcomputern."
Write-Info "PowerShell-Version: $($PSVersionTable.PSVersion)"
Write-Info "Installationsziel: $(if ($AllUsers) { 'AllUsers' } else { 'CurrentUser' })"

if (-not $SkipExecutionPolicy) {
    if ($PSCmdlet.ShouldProcess('CurrentUser', 'Set-ExecutionPolicy RemoteSigned')) {
        Write-Info 'Setze die Ausführungsrichtlinie für den aktuellen Benutzer auf RemoteSigned.'
        Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser -Force
    }
}
else {
    Write-WarnMsg 'Ausführungsrichtlinie wurde übersprungen.'
}

if (-not $SkipRepositoryTrust) {
    if ($PSCmdlet.ShouldProcess('PSGallery', 'Set-PSRepository Trusted')) {
        Write-Info 'Markiere PSGallery als vertrauenswürdiges Repository.'
        Set-PSRepository -Name 'PSGallery' -InstallationPolicy Trusted
    }
}
else {
    Write-WarnMsg 'PSGallery-Vertrauensstellung wurde übersprungen.'
}

$modules = @(
    @{ Name = 'PowerShellGet'; AllowClobber = $true; Beschreibung = 'Verwaltet die Installation weiterer Module.' },
    @{ Name = 'Microsoft.Graph'; AllowClobber = $true; Beschreibung = 'Zentrale Schnittstelle zu Microsoft 365 und Intune.' },
    @{ Name = 'Microsoft.Graph.DeviceManagement'; AllowClobber = $true; Beschreibung = 'Cmdlets für Geräteverwaltung in Intune.' },
    @{ Name = 'Microsoft.Graph.DeviceManagement.Administration'; AllowClobber = $true; Beschreibung = 'Erweiterte Intune-Verwaltung und Auswertung.' },
    @{ Name = 'Microsoft.Online.SharePoint.PowerShell'; AllowClobber = $true; Beschreibung = 'Verwaltung von SharePoint Online.' },
    @{ Name = 'ExchangeOnlineManagement'; AllowClobber = $true; Beschreibung = 'Verwaltung von Exchange Online.' },
    @{ Name = 'MicrosoftTeams'; AllowClobber = $true; Beschreibung = 'Verwaltung von Microsoft Teams.' },
    @{ Name = 'IntuneEndpointTools'; AllowClobber = $true; Beschreibung = 'Hilft bei Diagnose und lokalen Intune-Aktionen auf Clients.' }
)

if ($PSVersionTable.PSVersion.Major -ge 7) {
    $modules += @{ Name = 'Microsoft.Graph.Intune'; AllowClobber = $true; Beschreibung = 'Älteres Intune-Graph-Modul; nur bei Bedarf für vorhandene Skripte.' }
}
else {
    Write-WarnMsg 'Microsoft.Graph.Intune wird hier nicht automatisch ergänzt; für neue Skripte ist Microsoft.Graph vorzuziehen.'
}

if ($IncludeLegacyAzureAD) {
    Write-WarnMsg 'Legacy-Module AzureAD und MSOnline gelten als veraltet und sollten nur für Alt-Skripte genutzt werden.'
    $modules += @(
        @{ Name = 'AzureAD'; AllowClobber = $true; Beschreibung = 'Veraltetes AzureAD-Modul für ältere Skripte.' },
        @{ Name = 'MSOnline'; AllowClobber = $true; Beschreibung = 'Sehr altes Modul für Altumgebungen.' }
    )
}

foreach ($module in $modules) {
    Write-Info "$($module.Name): $($module.Beschreibung)"
    Install-RequiredModule -Name $module.Name -AllowClobber:([bool]$module.AllowClobber)
}

Write-Info 'Installierte Modulpfade in dieser PowerShell-Umgebung:'
$env:PSModulePath -split [IO.Path]::PathSeparator | ForEach-Object { Write-Host " - $_" }

if ($ConnectGraph) {
    if (Get-Module -ListAvailable -Name Microsoft.Graph.Authentication) {
        Write-Info "Starte Anmeldung an Microsoft Graph mit Scopes: $($GraphScopes -join ', ')"
        Connect-MgGraph -Scopes $GraphScopes
    }
    else {
        Write-WarnMsg 'Microsoft.Graph.Authentication wurde nicht gefunden; Anmeldung wird übersprungen.'
    }
}
else {
    Write-Info "Für die Anmeldung an Microsoft Graph später ausführen: Connect-MgGraph -Scopes '$($GraphScopes -join "','")'"
}

Write-Info 'Fertig. Prüfe die verfügbaren Module mit: Get-Module -ListAvailable'