diff --git a/windows/welcome/src/SilverOS.Welcome.Core/Apply/BitLockerService.cs b/windows/welcome/src/SilverOS.Welcome.Core/Apply/BitLockerService.cs index d6e0e1c..2551ccd 100644 --- a/windows/welcome/src/SilverOS.Welcome.Core/Apply/BitLockerService.cs +++ b/windows/welcome/src/SilverOS.Welcome.Core/Apply/BitLockerService.cs @@ -14,6 +14,11 @@ public sealed class BitLockerService(IProcessRunner runner) : IBitLockerService // 3. Remove any TPM-only protector (only once a TPM+PIN protector is confirmed present) // so the device actually requires the PIN at pre-boot. var script = string.Concat( + // Eject optical install media first — BitLocker -TpmAndPinProtector refuses to enroll + // while bootable CD/DVD media is present ("detected bootable media in the computer"). + "try { $s=New-Object -ComObject Shell.Application; ", + "$s.Namespace(17).Items() | Where-Object { $_.Type -match 'CD|DVD' } | ForEach-Object { try { $_.InvokeVerb('Eject') } catch {} } } catch {}; ", + "Start-Sleep -Seconds 3; ", "$fve='HKLM:\\SOFTWARE\\Policies\\Microsoft\\FVE'; ", "New-Item -Path $fve -Force | Out-Null; ", "New-ItemProperty -Path $fve -Name UseAdvancedStartup -Value 1 -PropertyType DWord -Force | Out-Null; ", diff --git a/windows/welcome/tests/SilverOS.Welcome.Tests/ApplyServicesTests.cs b/windows/welcome/tests/SilverOS.Welcome.Tests/ApplyServicesTests.cs index 133f2b2..8bf4a0f 100644 --- a/windows/welcome/tests/SilverOS.Welcome.Tests/ApplyServicesTests.cs +++ b/windows/welcome/tests/SilverOS.Welcome.Tests/ApplyServicesTests.cs @@ -81,6 +81,9 @@ public class ApplyServicesTests // Removes any TPM-only protector so the device requires the PIN at pre-boot. run.Verify(r => r.RunAsync("powershell.exe", It.Is(s => s.Contains("Remove-BitLockerKeyProtector")), It.IsAny())); + // Ejects optical install media first (BitLocker refuses to enroll with bootable media present). + run.Verify(r => r.RunAsync("powershell.exe", It.Is(s => + s.Contains("Shell.Application") && s.Contains("Eject")), It.IsAny())); } [Fact]