generalize: assign the data-disk letter every boot, and heal a temp profile
The relocated profile went temporary on the target and stayed that way. The cause was not the profile: the image ships with ProfilesDirectory set to D:\Users but with no drive letter for the data disk. generalize strips MountedDevices, and the specialize pass that re-asserts the letter runs only in the build VM, never on the target -- so the zvol boots letterless, the first autologon cannot find D:\Users\sagar (event 1511), and Windows falls back to a temporary profile, renames the real ProfileList key to .bak, and the fault sticks on every later logon. Confirmed by reading the shipped image offline: ProfileList has the SID at D:\Users\TEMP with a .bak sibling at D:\Users\sagar, MountedDevices carries no \DosDevices\D:, and the sagar hive on the zvol is intact -- so nothing was wrong but the letter. An onstart SYSTEM task now runs the existing (idempotent) data-disk init, whose diskpart assign writes MountedDevices and so makes D: persistent for every later boot. Only the first boot is exposed to the race; if it left a .bak, a small PowerShell heal puts the key back, drops the temp profile, and reboots once -- after which D: is persistent and the real profile loads. Same onstart / SYSTEM mechanism the static address already uses. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117qMyjpuXsjpVAcpJbFD8g
This commit is contained in:
parent
6a62a649bd
commit
d94c576df2
1 changed files with 55 additions and 1 deletions
|
|
@ -143,6 +143,49 @@ in
|
|||
:done
|
||||
'';
|
||||
|
||||
# PowerShell in its own file, so neither cmd quoting nor Nix's '' need to be
|
||||
# fought. If the account's real profile got backed up to a .bak key (the
|
||||
# temporary-profile fallback), put it back: drop the temp key, rename .bak to
|
||||
# the live SID, remove the temp directory, and drop a flag so the caller
|
||||
# knows to reboot.
|
||||
healProfileScript = pkgs.writeText "vmix-heal-profile.ps1" ''
|
||||
$pl = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList'
|
||||
$bak = Get-ChildItem $pl -ErrorAction SilentlyContinue | Where-Object {
|
||||
$_.PSChildName -like '*.bak' -and
|
||||
(Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue).ProfileImagePath -eq '${profilesDirectory}\${username}'
|
||||
} | Select-Object -First 1
|
||||
if ($bak) {
|
||||
$sid = $bak.PSChildName -replace '\.bak$'
|
||||
Remove-Item (Join-Path $pl $sid) -Recurse -Force -ErrorAction SilentlyContinue
|
||||
Rename-Item $bak.PSPath $sid -ErrorAction SilentlyContinue
|
||||
Remove-Item '${profilesDirectory}\TEMP' -Recurse -Force -ErrorAction SilentlyContinue
|
||||
New-Item -Path C:\Windows\Temp\vmix-profile-healed -ItemType File -Force | Out-Null
|
||||
}
|
||||
'';
|
||||
|
||||
# Ensures D: exists on every boot and heals a profile that went temporary.
|
||||
#
|
||||
# generalize strips MountedDevices, so the shipped image carries no drive
|
||||
# letter for the data disk, and the specialize pass that would re-assert it
|
||||
# runs only in the build, not on the target. The zvol therefore boots
|
||||
# letterless, the first autologon cannot find its relocated profile at
|
||||
# ${profilesDirectory}\${username} (event 1511) and falls back to a temporary
|
||||
# one, backing the real key up as .bak and making the fault stick.
|
||||
#
|
||||
# diskpart assign writes MountedDevices, so once this has run once D: is
|
||||
# persistent for every later boot. Only the first boot is exposed, and if it
|
||||
# left a .bak the heal puts it back and reboots -- the next boot, D: now
|
||||
# persistent and ProfileList clean, logs straight into the real profile.
|
||||
bootDataProfileScript = pkgs.writeText "vmix-data-profile.cmd" ''
|
||||
@echo off
|
||||
call C:\vmix-init-data-disk.cmd
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -File C:\vmix-heal-profile.ps1 > C:\Windows\Temp\vmix-data-profile.log 2>&1
|
||||
if exist C:\Windows\Temp\vmix-profile-healed (
|
||||
del /q C:\Windows\Temp\vmix-profile-healed
|
||||
shutdown /r /t 5 /c "vmix: repaired relocated profile, restarting"
|
||||
)
|
||||
'';
|
||||
|
||||
folderLocationsXml = lib.optionalString (profilesDirectory != null) ''
|
||||
<!-- Profiles live on the data disk, so the OS disk stays disposable
|
||||
and rebuilding it does not take the profile along -->
|
||||
|
|
@ -247,6 +290,13 @@ in
|
|||
schtasks /create /tn "vmix-static-ip" /tr "C:\vmix-static-ip.cmd" /sc onstart /ru SYSTEM /rl HIGHEST /f > nul 2>&1
|
||||
''}
|
||||
|
||||
${lib.optionalString (dataDisk != null) ''
|
||||
:: Ensures D: is assigned on every boot -- the image ships without a
|
||||
:: persisted letter for the data disk -- and heals a profile that went
|
||||
:: temporary before D: was ready. Onstart / SYSTEM, like the address task.
|
||||
schtasks /create /tn "vmix-data-profile" /tr "C:\vmix-data-profile.cmd" /sc onstart /ru SYSTEM /rl HIGHEST /f > nul 2>&1
|
||||
''}
|
||||
|
||||
${lib.optionalString (writeFilter != null) ''
|
||||
:: Install the feature now, but defer configuring it: uwfmgr does not exist
|
||||
:: until this has been through a reboot, and the swapfile belongs on the
|
||||
|
|
@ -357,7 +407,11 @@ in {
|
|||
{ source = oobeXml; dest = "/oobe-unattend.xml"; }
|
||||
{ source = postOobeScript; dest = "/post-oobe.cmd"; }
|
||||
{ source = masScript; dest = "/MAS_AIO.cmd"; }
|
||||
] ++ lib.optional (dataDisk != null) { source = initDataDiskScript; dest = "/vmix-init-data-disk.cmd"; }
|
||||
] ++ lib.optionals (dataDisk != null) [
|
||||
{ source = initDataDiskScript; dest = "/vmix-init-data-disk.cmd"; }
|
||||
{ source = healProfileScript; dest = "/vmix-heal-profile.ps1"; }
|
||||
{ source = bootDataProfileScript; dest = "/vmix-data-profile.cmd"; }
|
||||
]
|
||||
++ lib.optional (writeFilter != null) { source = uwfConfigScript; dest = "/vmix-uwf-config.cmd"; }
|
||||
++ lib.optional (staticIP != null) { source = staticIPScript; dest = "/vmix-static-ip.cmd"; };
|
||||
# delayOobeRun: sysprep + shutdown — OOBE runs on real hardware
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue