Sonntag, 23. Juni 2019

Fehlende Gruppenrichtlinien für Windows Update & Store

Aktualisierung Juni 2021:
Eine Offizielle Version dieser Richtlinie wird nicht erscheinen, da dies alle Updates für Windows generell abdreht. Ich (J. Albani) werde sie in meiner Schule so nicht umsetzen sondern die Zwangsupdates zulassen und dann gegebenenfalls Nacharbeiten durchführen. Für die Windows 10 Version 2004 gibt es eine Anleitung von Herrn Rosenfelder bei der paedML Hotline. 

Anmerkung: Die Einstellungen zu den Updates wurden bisher durch das Opsi-Produkt config-win10 durchgeführt. Da Microsoft vergangene Woche (Ende Juni 2019) ihre Updatepolitik für Windows 10 änderte, kann es sein, dass diese Einstellungen nun nicht mehr ausreichend sind. Das LMZ wird die hier vorgeschlagenen Richtlinien prüfen und gegebenenfalls offizielle Richtlinien veröffentlichen. Bis dahin ist die Verwendung dieses Blog Eintrages ohne Gewähr.
Johannes Albani


In der paedML Linux 7.1 fehlen nach aktuellem Stand wichtige Gruppenrichtlinien, um Windows Update richtig zu kontrollieren.
Ohne diese Gruppenrichtlinien verbinden sich alle PCs an der paedML vorbei zum Windows Update-Server bei Microsoft und lassen womöglich die komplette Internetverbindung einbrechen.

Gut nachvollzogen werden kann dies in der access.log des Squidmoduls auf dem paedML Server.

Insgesamt betrifft es bei Windows 10 folgende Module:

- Insider Preview
- Microsoft Store
- Windows Defender Antivirus, bzw. dessen Definitionsupdates
- Windows Update

Der Windows Defender Antivirus sollte natürlich nur deaktiviert werden, sofern ein anderes Anti-Virenprogramm zum Einsatz kommt.

Folgende Gruppenrichtlinien unterbinden alle betroffene Verbindungen zu Microsoft:

Donnerstag, 2. Mai 2019

Installationsprobleme älterer Hardwareklassen in OPSI 4.1

Das Bootimage des OPSI 4.1, basierend auf Ubuntu 18.04, hat ein Problem bei der Installation von älteren Hardwareklassen, festgestellt an HP Elite 8200 PCs.

Hier kommt es beim Ausführen der opsi-local-image-Produkte sporadisch zum Fehler "Login failed: getrandom() initialization failed. (_ssl.c:726)".

Die Abhilfe dagegen:

1) Per putty auf die "abgestürzten" Geräte verbinden, Benutzer: root Passwort: linux123
2) /usr/sbin/rngd -b -r /dev/urandom -o /dev/random eingeben
3) master.py eingeben

Danach läuft das oli-Produkt weiter.

Je nach Situation müssen obige Befehle pro oli-Produkt ausgeführt werden, bei einer Windows-Installation dementsprechend ein Mal für -prepare und ein Mal für -win10x64.

Die Befehle werden mit dem nächsten Bootimage-Release integriert, aktuell befindet sich dieses Bootimage noch im testing-Repository.

Quelle: https://forum.opsi.org/viewtopic.php?f=25&t=10931



Maximale Länge der Rechnernamen

Durch Zufall bin ich letztens auf einen Fehler in der Windows-Installation in Bezug auf die maximale Länge der Rechnernamen gestoßen.

Sobald der Rechnername mehr, als 14 Zeichen hat, endet die Windows-Installation in einem Problem mit der unattend.xml-Datei.



Der Fehler kommt allerdings erst kurz bevor die eigentliche Windows-Installation endet und in die Installation des OPSI-Client-Agent übergeht. Das heißt, je nach Rechnergeschwindigkeit sind bis dahin schon 30 bis 45 Minuten vergangen, was dann etwas ärgerlich ist.

Dokumentiert wurde das Problem bei UIB hier schon vor einiger Zeit https://forum.uib.de/viewtopic.php?f=7&t=1243&sid=6f365afb81aaabfd24e07014d28dd9d0&start=10

Powershell und Windows-Images

Zur Zeit beschäftige ich mich etwas mehr mit Windows Images. Zum einen, weil ich das OPS-VHD Produkt teste und auch schon einsetze (und noch mehr damit geplant habe, mehr dazu hoffentlich in kürze), zum anderen, weil beim opsi-local-image-wim-capture immer wieder Fehlermeldungen erscheinen, wenn das Windows etwas länger eingeschaltet war, bevor es gecaptured wurde. Diesen Problemen versuchen wir auch auf die Schliche zu kommen.

Hier ersteinmal eine Sammlung praktischer Powershell Befehle für die Images:
Ach ja, man muss die Powershell als Administrator ausführen um mit Images arbeiten zu können!
Get-WindowsImage -ImagePath \\backup\opsi_depot_rw\opsi-local-image-win10-x64-capture\installfiles\install.wim
gibt die verschiedenen Images des Capture-Produkts aus. Der Pfad kann an die verschiedenen Capture Produkte angepasst werden. 

Um eine Version von Windows aus dem Installer zu entfernen könnt ihr mit dem vorigen Befehl die Indes Nummer des Zieles herausfinden, mit 
Remove-WindowsImage -ImagePath \\backup\opsi_depot_rw\opsi-local-image-win10-x64-capture\installfiles\install.wim -Index 3 -CheckIntegrity
kann man z.B. das Image an Stelle 3 löschen. 
(Dies dauert ein paar Minuten)

Wenn man aus einer Sammlung von Windows Installationsdateien ein Image aus dem Verbund exportieren wollt geht das mit:
Export-WindowsImage -SourceImagePath  \\backup\opsi_depot_rw\opsi-local-image-win10-x64-capture\installfiles\install.wim -SourceIndex 1 -DestinationImagePath  \\backup\opsi_depot_rw\opsi-local-image-win10-x64-capture\installfiles\export.wim
Um das Exportierte Image (index 1) in eine andere Wim Datei zu verschieben muss das exportierte Image in einen Ordner (Hier C:\winmount) gemountet werden. 
Mount-WindowsImage -ImagePath \\backup\opsi_depot_rw\opsi-local-image-win10-x64-capture\installfiles\export.wim -ReadOnly -Index 1 -Path C:\winmount
Danach kann es zu einer anderen install.wim hinzugefügt werden. 
Add-WindowsImage -ImagePath \\backup\opsi_depot_rw\opsi-local-image-win10-x64-capture\installfiles\install.wim -CapturePath C:\winmount -Name "Name_des_neuen_Images"

Dienstag, 12. Februar 2019

paedML Linux 7.1

Hallo!
Das Update der paedML Linux für Version 7.1 steht in den Startlöchern. Es werden vor allem viele Detailverbesserungen enthalten sein, z.B. das Single Sign-On für die Schulkonsole.

Nach dem Update werden ein paar Tricks meines Blogs jedoch obsolet:

  1. die Anmeldung als Administrator funktioniert nur noch mit paedml-linux\Administrator, die Abkürzungen. z.B. p\Administrator werden nicht mehr klappen.
     
  2. Der im Blog beschriebene Trick mit dem Ausblenden des Opsi-Statusfensters muss rückgängig gemacht werden. Das paedml-login Opsi-Paket ersetzt viele der Login-Skripte (Icons kopieren, Informationen über Benutzer anzeigen usw. ) Diese werden von diesem Opsi-Statusfenster aufgerufen.
    Falls Sie meine Änderungen durchgeführt haben, setzen Sie für die Clients und das Depot "Host-Parameter" --> "opsiclientd" -->"opsiclientd.event.user_login.active" wieder auf "true" und rollen Sie den client-agent neu aus, wie in der Anleitung ausführlich beschrieben wurde.
     
  3. Einige meiner Druckeranmelde Tipps und Tricks wurden im Update umgesetzt. Zur Verteilung können Sie nun zusätzlich und optional die Gruppenrichtlinie paedMLL_Druckerverbinden nutzen. Dazu müssen Sie im Ordner \\backup\opsi_depot_rw\update71 das Powershell-Skript DruckerGPO.ps1 ausführen. Dadurch wird eine Gruppenrichtlinie mit ihrer aktuellen Druckerkonfiguration erzeugt. Sobald Sie Änderungen an den Drucker-Zuordnungen durchführen, muss das Skript erneut gestartet werden, damit die Richtlinie aktualisiert wird.
    Ich empfehle für Schüler und Lehrer jeweils eine Verknüpfung "Drucker reparieren" anzulegen, welche ein gpupdate durchführt. Dadurch können die Benutzer bei Bedarf die Drucker neu installieren lassen.
    Rechtsklick auf dem Desktop --> Neu --> Verknüpfung
    Als Pfad wählen Sie C:\Windows\System32\gpupdate.exe, als Icon können Sie in der Standardbibliothek SHELL32.dll ein passendes Icon auswählen. 
    Verteilen können Sie dieses Icon über aproflehrer und aprofschueler.
  4. Bei der paedML-Linux 7.1 wurde die Anmeldung überarbeitet. Es kann nach dem Update jedoch passieren, dass nicht der Standard-Hintergrund geladen wird. Für diesen Fall können Sie folgenden Skript verwenden. Es löscht abweichende Hintergrundbilder aus den Ordnern der SuS:

    $sus = Get-ChildItem "\\server\Home-Verzeichnisse Schueler\"
    foreach( $s in $sus){
        if (Test-Path  "\\server\Home-Verzeichnisse Schueler\$s\AppData\Microsoft\Windows\Themes\TranscodedWallpaper" ){
            if(
            ((Get-Item "\\server\Home-Verzeichnisse Schueler\$s\AppData\Microsoft\Windows\Themes\TranscodedWallpaper").Length -gt 240000) -or ((Get-Item "\\server\Home-Verzeichnisse Schueler\$s\AppData\Microsoft\Windows\Themes\TranscodedWallpaper").Length -le 220000)){
                Remove-Item –path "\\server\Home-Verzeichnisse Schueler\$s\AppData\Microsoft\Windows\Themes" –recurse
                write-host "Der Schüleraccount von $s wurde bereinigt." -ForegroundColor Green
            }
        }
    }
  5. Der Samba Bug, der das Verwenden des Klassenorder _klassen verhinderte, ist mit der paedML Linux 7.1 natürlich behoben. D.h. meine Anleitung  für einen Ersatz ist damit praktisch obsolet. 

                    Weitere Änderungen werde ich hier im Artikel aufführen. 

                    Montag, 3. Dezember 2018

                    Kyocera Treiber

                    Da Kyocera Treiber veröffentlicht, welche nicht von Samba akzeptiert werden bleibt oft nur ein abändern der Treiber (Wie auch hier im Blog beschrieben).
                    Ein freundlicher Mensch hat einen Kyocera Treiber passend abgeändert und danach Microsoft Zertifiziert.
                    Bei Kyocera-Druckern eine absolute Empfehlung:
                    https://downloads.van-belle.nl/samba4/Kyocera/KyoClassicUniversalPCL5_v3.0_Samba_WHQL.zip

                    Donnerstag, 15. November 2018

                    Drucker anmelden per Gruppenrichtlinie

                    Da die Druckerzuweisung an den Clients nicht so zuverlässig funktioniert wie ich es mir wünsche habe ich ein neues Skript geschrieben, welches die Druckereinstellungen der Schulkonsole als Gruppenrichtlinie anlegt. Diese Richtlinie läuft in meiner Schule nun parallel zum herkömmlichen Drucker Anmeldeskript. Außerdem habe ich für Notfälle auf den Desktop eine Verknüpfung "Drucker reparieren" angelegt, welche gpupdate.exe startet.

                    Bisher habe ich keine Drucker-Anmeldeprobleme mehr feststellen können, aber falls doch Probleme auftreten sollten löst ein gpupdate dieses nun direkt. 

                    Wichtig: Mit dem Skript wird die printers.xml aus einer Gruppenrichtlinie bearbeitet. Dazu müssen einzigartige GUID-Schlüssel erzeugt werden. Diese gibt es erst ab Powershell 5! Bitte gegebenenfalls updaten oder das Skript auf einem Windows 10 Rechner starten. 

                    Leider braucht das Skript eine Vorhandene GPO als Vorlage. Auf anfrage kann ich diese gerne versenden. Ihr könnt euch aber auch selbst eine Richtlinie basteln. Die Anleitung dazu folgt in kürze. 

                    Und hier geht es los:

                    $zielGPO = "paedMLL_Druckerverbinden"
                    #Wenn Force = $true ist wird die GPO bei jedem Durchlauf aktualisiert, sonst nur bei neuen Printerlist Dateien oder fehlender GPO. 
                    $force = $false

                    #Hilfsfunktion. Dank an den Author Adam Bell
                    function Get-SID{
                        Param ($DSIdentity)
                    $ID = new-object System.Security.Principal.NTAccount($DSIdentity)
                    return $ID.Translate( [System.Security.Principal.SecurityIdentifier] ).toString()
                    # From Adam Bell http://www.leadfollowmove.com/archives/powershell/security-identifiers-sids-and-nt-account-name
                    }

                    #Alle printer-assignment Dateien werden eingelesen
                    $a= Import-Csv -Header A,B,C -Delimiter ":" -Path  (Get-ChildItem -Path "\\server\netlogon\univention-printer-assignment\" -Filter '*.printerlist').FullName# | % -begin {$i=0} -process {$_.B=$i; $i++ }
                    $i=0
                    #Druckerreiheinfolge wird vor dem Sortieren gesichert
                    foreach($as in $a){
                        $as.B = $i
                        $i++
                    }

                    #Doppenungen werden entfernt und Daten aufbereitet
                    # Danke an https://stackoverflow.com/questions/31343752/how-can-you-select-unique-objects-based-on-two-properties-of-an-object-in-powers
                    $csvDataUnique = $a |   Group-Object 'A','C' |   %{ $_.Group | Select 'A','C','B' -First 1} |   Sort 'C'
                    $csvDataUnique | foreach{$_.C=$_.C.Split(",")[0].Split("=")[1]}
                    $backup = $csvDataUnique
                    $GPOListe = $csvDataUnique |   Group-Object 'C' |   %{ $_.Group | Select 'C' -First 1} |   Sort 'C'
                    $GPOListe=$GPOListe.C

                    #Liste aller Räume und deren Drucker wird erstellt.
                    $DruckerListe=@()
                    foreach($GPO in $GPOListe){
                        $sammlung=@()
                        foreach($zuordnung in $csvDataUnique){
                            if($GPO -eq $zuordnung.C){
                                $item = New-Object -TypeName psobject
                                $item | Add-Member -MemberType NoteProperty -Name DruckerName -Value $zuordnung.A
                                $item | Add-Member -MemberType NoteProperty -Name DruckerReihenfolge -Value $zuordnung.B
                                $item | Add-Member -MemberType NoteProperty -Name DruckerNummer -Value 0
                                $sammlung+=$item
                                }        
                        }
                        $DruckerAdd = New-Object -TypeName psobject
                        $DruckerAdd | Add-Member -MemberType NoteProperty -Name Name -Value $GPO
                        $DruckerAdd | Add-Member -MemberType NoteProperty -Name Server -Value "\\SERVER\"
                        $DruckerAdd | Add-Member -MemberType NoteProperty -Name GruppenName -Value ("PAEDML-LINUX\$GPO")
                        $DruckerAdd | Add-Member -MemberType NoteProperty -Name GruppenSID -Value (Get-SID $GPO)
                        $DruckerAdd | Add-Member -MemberType NoteProperty -Name Id -Value ""
                        $DruckerAdd | Add-Member -MemberType NoteProperty -Name DruckerZuordnung -Value $sammlung
                        $DruckerListe+=$DruckerAdd
                    }
                    #Drucker werden wieder in Reihenfolge gebracht.
                    foreach($GPO in $DruckerListe){
                        $GPO.DruckerZuordnung = $GPO.DruckerZuordnung | Sort-Object -Property DruckerReihenfolge
                        $i=0
                        while($i -le $GPO.DruckerZuordnung.Count-1){
                            $GPO.DruckerZuordnung[$i].DruckerNummer = $i
                            $i++
                        }
                    }
                    #Es wird geprüft, ob die GPO bereits existiert. Sonst wird Sie importiert und mit der OU Schule verknüpft. 
                    try{
                        $ignore = Get-GPO -Name $zielGPO -ErrorAction Stop}
                    catch{
                        $result = import-gpo -BackupId 13F02EBD-2DAA-44B9-B31F-743FC7E91F4E -TargetName $zielGPO -path "\\backup\opsi_depot_rw\DruckerSetup" -CreateIfNeeded
                        New-GPLink -name $zielGPO -target "ou=schule,dc=paedml-linux,dc=lokal" -LinkEnabled Yes -ErrorAction SilentlyContinue
                        $force=$true
                    }
                    $Id=(Get-GPO -Name $zielGPO).Id
                    $file = '\\BACKUP\opsi_depot_rw\DruckerSetup\{13F02EBD-2DAA-44B9-B31F-743FC7E91F4E}\DomainSysvol\GPO\User\Preferences\Printers\Printers.xml'
                    $target = '\\Server\sysvol\paedml-linux.lokal\Policies\{'+$Id+'}\User\Preferences\Printers\Printers.xml'

                    [xml]$xdoc = Get-Content ($file)
                    foreach($Raum in $DruckerListe){
                    #Für jeden Raum werden nun die Drucker Aktionen hinzugefügt. 
                        $Raum.Id=$result.Id
                        $server=$Raum.server
                        #Alle Drucker aus der Schulkonsole werde ersteinmal entfernt, so werden falsche zuordnungen oder Probleme mit der Druckersperre gelöst. 
                        foreach($Drucker in $Raum.DruckerZuordnung){
                            $BranchToClone = @($xdoc.Printers.SharedPrinter)[1].Clone()
                            $BranchToClone.Properties.path= $server+$Drucker.DruckerName
                            $BranchToClone.name= $Drucker.DruckerName
                            $BranchToClone.status=$Drucker.DruckerName
                            $newguid = [System.Guid]::NewGuid().toString()
                            $BranchToClone.uid= "{" + "$newguid" + "}"
                            $CurrentDateTime = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
                            $BranchToClone.Changed = "$CurrentDateTime"
                            $ignore = $xdoc.Printers.AppendChild($BranchToClone)
                        }
                        #Nun werden alle Drucker angelegt, jeweils mit einer Zielgruppenadressierung für den jeweiligen Raum. 
                        foreach($Drucker in $Raum.DruckerZuordnung){
                            $BranchToClone = @($xdoc.Printers.SharedPrinter)[2].Clone()
                            $newguid = [System.Guid]::NewGuid().toString()
                            $BranchToClone.uid= "{" + "$newguid" + "}"
                            $CurrentDateTime = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
                            $BranchToClone.Changed = "$CurrentDateTime"
                            $BranchToClone.name=$Drucker.DruckerName
                            $BranchToClone.status=$Drucker.DruckerName
                            $BranchToClone.Filters.FilterGroup.name = $Raum.GruppenName
                            $BranchToClone.Filters.FilterGroup.sid = $Raum.GruppenSID
                            if($Drucker.DruckerNummer-eq 0){$BranchToClone.Properties.default="1"}
                            $BranchToClone.Properties.path=$server+$Drucker.DruckerName
                            $ignore = $xdoc.Printers.AppendChild($BranchToClone)
                        }
                    }
                    #Die ersten 3 Knoten sind die Vorlagen-Knoten aus der Vorlage GPO
                    $nodedelete = $xdoc.Printers.SharedPrinter[0]
                    $ignore = $xdoc.Printers.RemoveChild($nodedelete)
                    $nodedelete = $xdoc.Printers.SharedPrinter[0]
                    $ignore = $xdoc.Printers.RemoveChild($nodedelete)
                    $nodedelete = $xdoc.Printers.SharedPrinter[0]
                    $ignore = $xdoc.Printers.RemoveChild($nodedelete)

                    #Änderungen werden nur angewendet, wenn Univention Printerlist Dateien vorliegen oder die GPO nicht vorhanden war. 
                    try{if($force -or ((Get-ChildItem "\\server\netlogon\univention-printer-assignment\" | Foreach {$_.LastWriteTime} | sort)[(Get-ChildItem "\\server\netlogon\univention-printer-assignment\" | Foreach {$_.LastWriteTime} | sort).Count-1] -gt (Get-Item $target| Foreach {$_.LastWriteTime}))){
                            Write-Host "Neue Druckereinstellungen werden installiert."
                            $xdoc.Save($target)
                        }
                        else{
                            Write-Host "Keine neuen Druckereinstellungen gefunden."
                        }
                    }
                    catch{
                        Write-Host "Neue Druckereinstellungen werden installiert."
                        $xdoc.Save($target)
                    }