How to install Windows 10 on NVMe SSD on old PC? Since old computers don't load NVMe SSD drives when

New Contributor

How to install Windows 10 on NVMe SSD on old PC? Since old computers don't load NVMe SSD drives when they start up, the way I think about it is to load them during BCDBoot? But I don't know how.


Because the hardware of the old computer is not configured with NVMe SSD OPROM or EFI driver, but I found that win10 installation disk can load NVMe SSD and normal use of NVMe SSD, which indicates that in the process of win10 startup can still be joined by software NVMe SSD driver and use this hardware device, Hardware can be loaded at operating system boot, just as the SCSI card driver was previously loaded when installing the Windows operating system.


3 Replies


I've done this before actually, it does work but it's complex (be warned.) It's like network booting, but instead your SSD will have a virtual image within the drive itself. It's smarter to set this up in a VM on an HDD, and then copy the image, leaving a certain percentage of free space available for wear leveling / TRIM / garbage collection purposes, as to extend the lifespan of the drive.)


Here's an example of some random things I use specifically for this:

wsl --install
DISM /Online /Enable-Feature /All /Norestart /featurename:Microsoft-Windows-Subsystem-Linux
DISM /Online /Enable-Feature /All /Norestart /featurename:VirtualMachinePlatform
DISM /Online /Enable-Feature /All /Norestart /FeatureName:HypervisorPlatform

bcdedit /v

bcdedit /enum {current}

bcdedit /set {current} bootlog no
bcdedit /set {current} bootmenupolicy Legacy
bcdedit /set {current} quietboot on
bcdedit /set {current} disableelamdrivers yes
bcdedit /set {current} nx AlwaysOn
bcdedit /set {current} disabledynamictick no
bcdedit /set {current} pciexpress default
bcdedit /set {current} tpmbootentropy ForceEnable
bcdedit /set {current} tscsyncpolicy Enhanced
bcdedit /set {current} usefirmwarepcisettings yes
bcdedit /set {current} uselegacyapicmode no
bcdedit /set {current} highestmode on

"bcdedit" ->
"BCDEdit Options Reference" ->
"4-Gigabyte Tuning: BCDEdit and Boot.ini" ->
"Bootsect Command-Line Options" ->
"BCDBoot Command-Line Options" ->
"Boot to a virtual hard disk: Add a VHDX or VHD to the boot menu" ->
"[MS-VHDX]: Virtual Hard Disk v2 (VHDX) File Format" ->

For additional types that apply to the boot manager, memory diagnostic
application, windows OS loader, or the resume application, run
"bcdedit /? TYPES <apptype>", where <apptype> is one of the following:

    BOOTMGR    The boot manager.
    MEMDIAG    The memory diagnostic application.
    OSLOADER   The Windows OS loader.
    RESUME     The resume application.

"Boot Settings" ->

"Manufacturing Windows Engineering Guide (WEG)" ->
"Compact OS Size comparisons" ->
"/Optimize-Image" ->
"Oscdimg Command-Line Options" ->
"Create an ISO image for UEFI platforms for a Windows PE CD-ROM" ->
"Installing Windows to an EFI-Based Computer" ->
"Device and OSDevice Settings" ->
"Secure Boot" ->
"WIM vs. VHD vs. FFU: comparing image file formats" ->

"Sample scripts" ->

bcdboot C:\Windows /s S: /f UEFI



Another example of what it might look like in diskpart (it's not that different on nix btw, especially if you want partition alignment, advanced format disk or another type (512e vs 4k sectors I mean,) it's basically like using a raid calculator.

1TB   = 1048576 (MB) -> 2^20 * 1
500GB = 512001 (MB) -> 500 * 1024 + 1
250GB = 256001 (MB) -> 250 * 1024 + 1
150GB = 153601 (MB) -> 150 * 1024 + 1
100GB = 102401 (MB) -> 100 * 1024 + 1
50GB  = 51201 (MB) -> 50 * 1024 + 1

NTFS -> (Size in GB * 1024) + 1
FAT32 (up to 32GB) -> (Size in GB * 1024) + 12

Minimum page file size: Varies based on page file usage history, amount of RAM (RAM ÷ 8, max 32 GB) and crash dump settings.

Maximum page file size: 3 × RAM or 4 GB, whichever is larger. This is then limited to the volume size ÷ 8. However, it can grow to within 1 GB of free space on the volume if required for crash dump settings.

58369 (57GB NTFS)
16385 (16GB NTFS)
1025 (1GB NTFS)

Old PC Pagefile: MIN 128 MAX 3075 (MAX > 2560 = 1/8th of 20GB Volume)
New PC Pagefile: MIN 2048 MAX 49155 (MAX > 19200 = 1/8th of 150GB Volume | MAX > 7296 = 1/8th of 57GB Volume )

51073 = 58369 - 7296 (Virtual Drive File Size = System Drive Size - Swap File Size)

DISKPART> help create vdisk

    Creates a virtual disk file. Currently only VHD and VHDX format files are
    supported and are specified through the file extensions (.vhd and .vhdx)
    of the virtual disk file.

             [SD=<SDDL string>] [PARENT=<"filename">] [SOURCE=<"filename">]


                Specifies the complete path and filename of the virtual disk
                file.  The file may be on a network share.

    MAXIMUM=<N> The maximum amount of space exposed by the virtual disk, in
                megabytes (MB).


                FIXED specifies a fixed size virtual disk file.  EXPANDABLE
                specifies a virtual disk file that resizes to accommodate
                the allocated data.  The default is FIXED.


                Path to an existing parent virtual disk file to create a
                differencing disk. With the PARENT parameter, MAXIMUM should
                not be specified because the differencing disk gets the size
                from its parent. Also, TYPE should not be specified since only
                EXPANDABLE differencing disks can be created.


                Path to an existing virtual disk file to be used to
                pre-populate the new virtual disk file. When SOURCE is
                specified, data from the input virtual disk file is copied
                block for block from the input virtual disk file to the
                created virtual disk file.  There is no parent-child
                relationship established however.

    NOERR       For scripting only. When an error is encountered, DiskPart
                continues to process commands as if the error did not occur.
                Without the NOERR parameter, an error causes DiskPart to exit
                with an error code.

    CREATE VDISK FILE="c:\test\test.vhd" MAXIMUM=1000
    CREATE VDISK FILE="c:\test\child.vhdx" PARENT="c:\test\test.vhdx"
    CREATE VDISK FILE="c:\test\test.vhd" MAXIMUM=1000 SD="D:P(A;;GA;;;WD)"
    CREATE VDISK FILE="c:\test\new.vhdx" SOURCE="c:\test\test.vhd"

Another example for an EFI / UEFI system in diskpart (you can find similar ones in the sample scripts for MBR partitions. This one is for 150GB obviously, zero-indexed, so it's a perfect 150GB, not more not less. You can set it to whatever you want using the above examples, although MSR is almost always going to be 500MB, and the EFI partition will be something in the range of 100-128MB, depending on bootloader complexity, menu options, if you have a multi-boot setup I mean. Most of the time, 100MB is good enough for the system partition, unless of course you have some type of Unix / Linux multi-boot setup utilizing a complex GRUB 2.x menu with RHEL, Solaris, alongside the Windows 10 / 11 bootloader, etc. I'm sure even then 100mb is probably fine (the example below utilizes binary prefixes.)

list disk
select disk <enter disk number>
list partition
convert gpt
create partition efi size=100
create partition msr size=500
create partition primary size=153601

list volume
select volume <enter volume number>
assign letter=c
format fs=ntfs unit=4096 quick

Comparable Linux / Unix examples:

NEWFS: TB = {[(1099511627776 * Size in TB) + 1048576] / 512}
NEWFS: GB = {[(1073741824 * Size in GB) + 1048576] / 512}

1TB   = 2147485696 sectors = 1048576.0MB ( cyl groups)
500GB = 1048578048 sectors = 512001.0MB ( cyl groups)
250GB = 524289024 sectors = 256001.0MB ( cyl groups)
150GB = 314574848 sectors = 153601.0MB ( cyl groups)
100GB = 209717248 sectors = 102401.0MB ( cyl groups)
50GB  = 104859648 sectors = 51201.0MB ( cyl groups)

newfs -N -b4096 -f512 -i8192 –o space -s104859648 /dev/rdsk/c2t0d0p0

FDISK: 59616 cylinders - Cylinder blocks 131072 - 512 byte blocks (sectors)
1TB   = 16385 cylinders {[(2^40) / (Cylinder Blocks * Sectors)]+1}
500GB = 8001 cylinders {[(2^30 * 500) / (Cylinder Blocks * Sector Size)]+1}
250GB = 4001 cylinders {[(2^30 * 250) / (Cylinder Blocks * Sector Size)]+1}
150GB = 2401 cylinders {[(2^30 * 150) / (Cylinder Blocks * Sector Size)]+1}
100GB = 1601 cylinders {[(2^30 * 100) / (Cylinder Blocks * Sector Size)]+1}
50GB  = 801 cylinders {[(2^30 * 50) / (Cylinder Blocks * Sector Size)]+1}



If you were to use VirtualBox with Windows 10/11 Home [and a Virtual Hard Disk v2 (VHDX) image,] it would look like this, given VirtualBox for some odd reason doesn't recognize VHDX v2 images yet (even though it's an open specification at this point.)

VirtualBox Example:


C:\Users\username\Desktop>wmic diskdrive list brief
Caption                    DeviceID            Model                      Partitions  Size
xxx xxxxxxxxxxxxxxx        \\.\PHYSICALDRIVE0  xxxxxxxxxxxxxxxxxxxxxxxxx  x           xxxxxxxxxxxxx
xxx xxxxxxxxxxxxxxx        \\.\PHYSICALDRIVE1  xxxxxxxxxxxxxxxxxxxxxxxxx  x           xxxxxxxxxxxxx
xxx xxxxxxxxxxxxxxx        \\.\PHYSICALDRIVE2  xxxxxxxxxxxxxxxxxxxxxxxxx  x           xxxxxxxxxxxxx

VBoxManage internalcommands createrawvmdk -filename \VirtualBox\VMs\Win11_64_adk_imaging.vmdk -rawdisk \\.\PHYSICALDRIVE2
VBoxManage storageattach "Windows 11 (64-bit)" --storagectl "AHCI" --port 0 --device 0 --type hdd --medium \VirtualBox\VMs\Win11_64_adk_imaging.vmdk

VBoxManage internalcommands createrawvmdk -filename \VirtualBox\VMs\USB_DRIVE_WIN_64.vmdk -rawdisk \\.\PHYSICALDRIVE2
VBoxManage storageattach "Windows 10 (64-bit)" --storagectl "AHCI" --port 2 --device 0 --type hdd --medium \VirtualBox\VMs\USB_DRIVE_WIN_64.vmdk

"9.7.1. Using a Raw Host Hard Disk From a Guest" ->
"Chapter 8. VBoxManage" ->
"WMI Command-line Tools" ->

The only caveat with this one, is if anything stops working you have to release the image from the VM in VirtualBox, and recreate it all over again via the console (given it's just a link when operating in RAW access mode.) It's better to dismount it in diskpart like this after you mount it, so the host operating system cannot see it (Windows,) but the guest operating system can still access it (the VM itself.)

PS C:\WINDOWS\system32> diskpart

Microsoft DiskPart version

DISKPART> list volume

  Volume ###  Ltr  Label        Fs     Type        Size     Status     Info
  ----------  ---  -----------  -----  ----------  -------  ---------  --------
  Volume 9                             Removable   xxxx MB  Healthy    Offline

DISKPART> select volume 9

Volume 9 is the selected volume.

DISKPART> assign

DiskPart successfully assigned the drive letter or mount point.

DISKPART> automount disable

Automatic mounting of new volumes disabled.

DISKPART> list volume

  Volume ###  Ltr  Label        Fs     Type        Size     Status     Info
  ----------  ---  -----------  -----  ----------  -------  ---------  --------
* Volume 9     F                RAW    Removable   xxxx MB  Healthy

DISKPART> remove letter=f dismount

DiskPart successfully removed the drive letter or mount point.

DiskPart successfully dismounted and offlined the volume.


Leaving DiskPart...
PS C:\WINDOWS\system32>

Good Luck! Happy New Year as well! (Year of the Kitten.)