Windows: Sysprep ohne OOBE

Sysprep ist eine feine Sache, um eine Master-Windows-Installation für die Verteilung vorzubereiten.

Mit am wichtigsten ist dabei, das eine neue SID (Sicherheitskennung) für das System generiert wird, damit es später in der Domäne, im WSUS und mehr keine Schwierigkeiten gibt.

Ein Nachteil von Sysprep kann sein, das nach dessen Ausführung man das gesamte OOBE (Out-of-the-Box Experience) durchlaufen muss. Es erscheinen also die ganzen Abfragen nach Sprache, WLAN, Cloud-Anbindung bzw. lokalen Benutzer anlegen, usw.

Mitunter ist das allerdings gar nicht gewünscht oder notwendig und man möchte den bei der Erst-Einrichtung angelegten Benutzer (samt Profil) sogar behalten.

Mit einer kleinen Antwortdatei kann man das alles umgehen:

<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
 <settings pass="oobeSystem">
  <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <OOBE>
    <HideEULAPage>true</HideEULAPage>
    <HideLocalAccountScreen>true</HideLocalAccountScreen>
    <HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
    <HideOnlineAccountScreens>true</HideOnlineAccountScreens>
    <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
    <NetworkLocation>Other</NetworkLocation>
    <ProtectYourPC>3</ProtectYourPC>
    <SkipMachineOOBE>true</SkipMachineOOBE>
    <SkipUserOOBE>true</SkipUserOOBE>
    <UnattendEnableRetailDemo>false</UnattendEnableRetailDemo>
   </OOBE>
  </component>
 </settings>
</unattend>

Gestartet wird Sysprep dann mit folgendem Aufruf:

C:\Windows\System32\Sysprep\sysprep.exe /generalize /shutdown /oobe /unattend:C:\Sysprep\deploy.xml

Nachdem das System heruntergefahren ist, kann man die Antwortdatei entfernen und das Laufwerk klonen bzw. ein Image für die Verteilung erstellen.

Quelle

Bart Simons – Sysprep generalize Windows image without OOBE

Microsoft – Docs – Generalisieren einer Windows-Installation (Systemvorbereitung)

7 Kommentare

  1. Martin Kuras

    … hier eine Stolperfalle:

    Die Disk GUID wird von sysprep aber nicht geändert, was dazu führt, dass sich nicht zwei von diesem Image abgeleitete virtuelle Disks z.B. gleichzeitig mounten lassen, was viele Backup Programme tun.

    Diese Powershell Zeilen ändern die GPT Disk-GUID von C: (idealerweise direkt beim Ausrollen):

    # neue GUID’s vergeben und Bootmanager anpassen:
    Get-Disk | Select Guid
    $newguid = [GUID]::NewGuid()
    $guid = [string]$newguid
    Set-Disk -Number 0 -Guid “{$guid}”
    bcdedit /set “{current}” device partition=C:
    bcdedit /set “{current}” osdevice partition=C:
    bcdedit /default “{current}”
    Get-Disk | Select Guid

  2. Andy

    “/mode:vm” ist bei Sysprep das passende bei Generalisieren einer VHD(X) zur Verwendung auf dem gleichen Hyper-V bzw. Host:

    Sysprep Command-Line-Optionen – /mode:vm

  3. Martin Kuras

    … das weiß ich auch…. funktioniert nur nicht. Ich hatte ´ne Menge Probleme dadurch, das nachträgliche ändern der GUID ist Gott sei Dank kein Problem.

    Wenn man die VMs per Powershell anlegt, kann man das auch dabei gleich erledigen:

    [..]

    # leitet VHDx aus der Vorlage ab, mounten in Anwesenheit des Templates um wegen Disksignaturfehler neue GUID zu erzwingen
    New-Item “$VMPath$VMNameVirtual Hard Disks” –Type Directory
    Copy-Item $TemplateVHDX “$VMPath$VMNameVirtual Hard Disks$VMName.vhdx” -PassThru
    Set-VHD -Path “$VMPath$VMNameVirtual Hard Disks$VMName.vhdx” -ResetDiskIdentifier -Force -Passthru
    Mount-VHD -Path “$VMPath$VMNameVirtual Hard Disks$VMName.vhdx” -NoDriveLetter -PassThru

    $guid = [GUID]::NewGuid()
    $connecthost = $env:COMPUTERNAME
    $uniqueIds = Invoke-Command -Computername $connecthost {Get-Disk}
    ForEach ($uniqueId in $uniqueIds)
    {
    If ($uniqueId.FriendlyName -like “Msft Virtual Disk”)
    {
    $disknumber = $uniqueId.Number
    $cmds = “`”SELECT DISK $disknumber`””,
    “`”UNIQUEID DISK ID=$guid`””
    $scriptblock = [string]::Join(“,”,$cmds)
    $diskpart =$ExecutionContext.InvokeCommand.NewScriptBlock(“$scriptblock | DISKPART”)
    Invoke-Command -ComputerName $connecthost -ScriptBlock $diskpart
    }
    }

    Dismount-VHD -Path “$VMPath$VMNameVirtual Hard Disks$VMName.vhdx” -PassThru

    [..]

  4. Andy

    > … das weiß ich auch…. funktioniert nur nicht.

    Ah ok, verstehe, dieser Kontext fehlte mir im vorigen Kommentar.
    Gut zu Wissen, das man die Sache (nachträglich) korrigieren kann.

    Vielen Dank für dein Feedback.

  5. Bernd

    Hallo geehrte Forenmitglieder,

    habe nur Geräte ohne Domäne und Internet-Zugang.
    Gibt es eine Möglichkeit die XML ohne:
    xmlns:wcm=”http://schemas.microsoft.com/WMIConfig/2002/State” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
    zu verwenden?

    Vielen Dank,
    Bernd

  6. Andy

    Die genannten Zeilen deklarieren glaube ich nur einen Namespace, eine Internetverbindung ist vmtl. nicht zwingend notwendig, außer man verwendet die neueste Windows 11-Ausgabe (das hat da allerdings nichts mit Sysprep und OOBE zutun).

  7. Leo

    Windows 10
    Nach dem
    C:WindowsSystem32Sysprepsysprep.exe /generalize /shutdown /oobe /unattend:C:Sysprepdeploy.xml
    mit der deploy.xml von oben bekomme ich leider beim Login als Administrator:
    Your Account has been disabled. Please see your system administrator.
    Haben Sie vielleicht eine Idee woran es liegen kann?

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

© 2024 Andy's Blog

Theme von Anders NorénHoch ↑