Windows 10 PE über PXE EFI

Ich möchte gerne Windows 10 über das Netzwerk installieren. Die Laptops haben ein Biospasswort was ich nicht kenne und starten nur im EFI Modus und mit SECURE BOOT enabled.

So hab ichs gelöst. Wir brauchen das Windows ADK in der für die aktuelle Windows 10 Version passenden Version (z.B. ist für 1909 das ADK 1903 das richtige) https://docs.microsoft.com/en-us/windows-hardware/get-started/adk-install

Eine aktuelle Version von tftpd32 (gerne in der 64 Bit Version) http://www.tftpd64.com/

Ausserdem ein Windows 10 ISO (MEDIA CREATION TOOL)

Wir halten uns lose an diese Anleitung von Microsoft, auch wenn die eigentlich für LEGACY BIOS Boot ausgelegt ist (auch wenn das da nicht steht) https://docs.microsoft.com/de-de/windows/deployment/configure-a-pxe-server-to-load-windows-pe

Wir installieren die Umgebung für die Bereitstellungs- und Imageerstellung des ADK.

Danach starten wir diese ALS ADMIN. Mit dem folgenden Befehl erstellen wir uns ein Windows PE für 64 BIT

copype.cmd amd64 C:\winpe_amd64

Anschließend laden wir das boot.wim, welches das eigentlich zu startende Windows enthält, in ein Verzeichnis ( C:\winpe_amd64\mount ) und stellen die Sprache um (ungetestet von hier )

Dism /mount-image /imagefile:c:\winpe_amd64\media\sources\boot.wim /index:1 /mountdir:C:\winpe_amd64\mount

dism /image:C:\winpe_amd64\mount /set-inputlocale:de-de;en-us

Wir entpacken nur TFTPD32 nach C:/tftpd32 und sehen zu, dass alle Dateien in diesem Ordner liegen und nicht in einem Unterordner. Anschließend erstellen wir im Ordner tftpd32 den Ordner TFTPDRoot (sodass wir den Ordner C:/tftpd32/tftpdroot erstellt haben). Diesen Ordner geben wir nun schreibend im Netzwerk frei. Das ist offensichtlich für Produktivumgebungen nicht so KLUK, aber für uns reichts.

Wir testen anschließend, ob wir uns mit diesem Laufwerk Verbinden können

net use y: \\PCNAME\TFTPDroot

Jetzt sollte unser Laufwerk Y: den Inhalt des Ordners TFTPDRoot anzeigen (in dem zur Zeit noch nichts drin ist.) Erstellen wir also schnell einen Ordner Boot. Anschließend kopieren wir einen Schwung Dateien aus dem Windows PE Verzeichnis in das TFTPDRoot/Boot und speichern die Änderung der Sprache in die boot.wim

copy c:\winpe_amd64\mount\windows\boot\pxe\*.* y:\Boot
copy c:\winpe_amd64\mount\windows\boot\EFI\bootmgfw.efi y:\Boot

dism /unmount-wim /mountdir:C:\winpe_amd64\mount /commit

copy C:\winpe_amd64\media\boot\boot.sdi y:\Boot
copy C:\winpe_amd64\media\Boot\Fonts y:\Boot\Fonts
copy C:\winpe_amd64\media\sources\boot.wim y:\Boot

Jetzt müssen wir den BCD Eintrag erstellen:

bcdedit /createstore c:\BCD
bcdedit /store c:\BCD /create {ramdiskoptions} /d "Ramdisk options" 
bcdedit /store c:\BCD /set {ramdiskoptions} ramdisksdidevice boot bcdedit /store c:\BCD /set {ramdiskoptions} ramdisksdipath \Boot\boot.sdi 
bcdedit /store c:\BCD /create /d "winpe boot Image efi" /application osloader

Der letzte Befehl gibt eine GUID zurück, z.B. {215fe947-3616-11ea-a770-d850e6d1308f}. Ihr müsst im folgenden Codeblock alle {GUID} durch EURE GUID ersetzen.

bcdedit /store c:\BCD /set {GUID} device ramdisk=[boot]\Boot\boot.wim,{ramdiskoptions} 

bcdedit /store c:\BCD /set {GUID} path \windows\system32\winload.efi 

bcdedit /store c:\BCD /set {GUID} osdevice ramdisk=[boot]\Boot\boot.wim,{ramdiskoptions} 

bcdedit /store c:\BCD /set {GUID} systemroot \windows

bcdedit /store c:\BCD /set {GUID} detecthal Yes

bcdedit /store c:\BCD /set {GUID} winpe Yes

bcdedit /store c:\BCD /create {bootmgr} /d "boot manager"

bcdedit /store c:\BCD /set {bootmgr} timeout 30 

bcdedit /store c:\BCD -displayorder {GUID} -addlast

Anschließend müssen wir die BCD Datei über das Netzwerk in den Bootordner kopieren

copy c:\BCD \\PCNAME\TFTPDRoot\Boot\BCD

Jetzt können wir prüfen ob wir alles richtig gemacht haben und uns den Inhalt der BCD Datei anzeigen lassen, z.B. mit

bcdedit /store C:\tftpd\tftpdroot\Boot\BCD /enum all
Windows Boot Manager
 identifier              {bootmgr}
 description             boot manager
 displayorder            {215fe947-3616-11ea-a770-d850e6d1308f}
                         
 timeout                 30
 
 Windows Boot Loader
 identifier              {215fe947-3616-11ea-a770-d850e6d1308f}
 device                  ramdisk=[boot]\Boot\boot.wim,{ramdiskoptions}
 path                    \windows\system32\winload.efi
 osdevice                ramdisk=[boot]\Boot\boot.wim,{ramdiskoptions}
 systemroot              \windows
 
 Setup Ramdisk Options
 identifier              {ramdiskoptions}
 description             Ramdisk options
 ramdisksdidevice        boot
 ramdisksdipath          \Boot\boot.sdi

So oder so ähnlich sollte es aussehen.

Dann haben wir es schon fast geschafft. Wir müssen nur noch kurz TFTPD32 starten und einstellen. Wir müssen unserem PC eine feste IP Adresse geben (192.168.123.1) und uns, wenn möglich, vom Internet trennen. Dann kann der zu installierenden Laptop entweder direkt (hat bei mir Probleme verursacht) oder über eine Switch angeschlossen werden.

Die Einstellungen für TFTPD32 sehen wie folgt aus:

Unter Logview und TFTP Server kann der Status der Installation dann verfolgt werden.

Nachdem die Windows PE Version dann gestartet ist, kann das Windows 10 ISO gemountet (Bereitgestellt) werden und dann über das Netzwerk freigegeben werden. Anschließend kann in der Windows PE Version per net use die Freigabe gemountet werden (Credentials werden dort abgefragt, wenn vorhanden) und die Windows Version per Setup.exe gestartet werden. Der Rest der Windowsinstallation ist dann wie gewohnt!

Raspi Kühlersteuerung

Mein Raspi wird ab zu zu warm… um das zu verhindern habe ich einen 5V Lüfter von Noctua erstanden ( https://noctua.at/de/nf-a4x10-5v ). Weiter brauchte ich einen NPN 107B Transistor und einen 650 Ohm Wiederstand.

Ich habe dann mit dem GPIO Pin 21 eine Schaltung gebaut, sodass ich über den Transistor den Lüfter schalten kann. (Berechnung VOrwiederstand Transistor: https://www.mikrocontroller.net/articles/Basiswiderstand ) Das scheint super zu laufen.

Zuerst müssen wir die GPIO Pins aktivieren


#gpio pins für die lüftersteuerung
 echo "21" > /sys/class/gpio/export
 echo "out" > /sys/class/gpio/gpio21/direction
 echo "1" > /sys/class/gpio/gpio21/value

Diese Zeilen habe ich auch der /etc/rc.local angefügt (vor das EXIT ), damit überlegt es wohl auch nen Neustart (yet to prove)

Ich habe das folgende Script geschrieben (/usr/bin/tempdaemon)


#!/bin/bash

while true; do
 # date;
  TC=$(awk '{printf("%.1f\n",$1/1e3)}' /sys/class/thermal/thermal_zone0/temp)
  BIGGER55=$(awk -v a="$TC" -v b="55.0" 'BEGIN{print(a>b)}')
  SMALLER45=$(awk -v a="$TC" -v b="45.0" 'BEGIN{print(a<b)}')

#   echo $TC;
#   echo $BIGGER55;
#   echo $SMALLER45;
  if [  $BIGGER55 == "1" ];  then
#       echo "Mehr als 55, Lüfter an";
        echo "1" > /sys/class/gpio/gpio21/value ;
        sleep 60;
  elif [ $SMALLER45 == "1" ]; then
        #Lüfter aus
#       echo "Lüfter aus";
        echo "0" > /sys/class/gpio/gpio21/value;
 else
#       echo "weder noch, sweetspot?!?";
        sleep 1;
  fi

  sleep 10;
done

Danach habe ich es ausführbar gemacht (sudo chmod +x /usr/bin/tempdaemon)

Anschließend habe ich die Servicedatei dafür geschrieben (sudo nano /etc/systemd/system/tempdaemon.service)


[Unit]
Description=Arnes Lüfterdaemon

[Service]
ExecStart=/usr/bin/tempdaemon
Restart=on-failure

[Install]
WantedBy=multi-user.target

Und dann den Service enabled (damit er nach nem neustart automatisch mitstartet) und ihn einmal von hand gestartet

sudo systemctl enable tempdaemon
sudo systemctl start tempdaemon

Ausserdem habe ich mir zwei aliase in die ~/.bash_alias eingefügt, mit denen ich die aktuelle temperatur und den zustand des lüfters beobachten kann.


alias temp='/opt/vc/bin/vcgencmd measure_temp'
alias lufter='cat /sys/class/gpio/gpio21/value'