Skip to content

Instantly share code, notes, and snippets.

@lawndoc
Last active February 20, 2025 14:53
Show Gist options
  • Save lawndoc/ea03e2ee0f4d64162669d1b5e997ec77 to your computer and use it in GitHub Desktop.
Save lawndoc/ea03e2ee0f4d64162669d1b5e997ec77 to your computer and use it in GitHub Desktop.
Scripted Dev Drive Setup
<#
.SYNOPSIS
Script to create a new Dev Drive
.DESCRIPTION
This script will create a new Dev Drive on a Windows system. By default, it will create a 100GB dynamically sized VHDX file located in C:\ProgramData\Custom Dev Drive\drive.vhdx that will be mounted to the V: letter drive. For more information about Dev Drives, please see https://learn.microsoft.com/en-us/windows/dev-drive/
.EXAMPLE
.\New-DevDrive.ps1
or
.\New-DevDrive.ps1 -DrivePath "C:\Temp\testing" -DriveSize 200GB -DriveLetter "T"
.PARAMETER Drive Path
This optional parameter specifies the path that the VHDX file will be saved to. A default path of 'C:\ProgramData\Custom Dev Drive' is provided.
.PARAMETER Drive Letter
This optional parameter defines the drive letter that the Dev Drive will be mounted to. A default letter of 'V' is provided.
.PARAMETER Drive Size
This optional parameter defines the maximum size of the Dev Drive's dynamically sized volume. A default size of '100GB' is provided.
#>
param([string]$DrivePath = "C:\ProgramData\Custom Dev Drive",
[string]$DriveSize = "100GB",
[string]$DriveLetter = "B"
)
function Convert-ToMegabytes {
param (
[string]$sizeString
)
$number = [double]($sizeString -replace '[^\d.]+')
switch -Regex ($sizeString) {
'MB' {
$numberInMB = $number
break
}
'GB' {
$numberInMB = $number * 1024
break
}
'TB' {
$numberInMB = $number * 1024 * 1024
break
}
default {
throw "Unsupported unit. Please use MB, GB, or TB."
}
}
return $numberInMB
}
$SizeInMB = Convert-ToMegabytes -sizeString $DriveSize
if (Test-Path "$DrivePath\drive.vhdx") {
Write-Warning "ERROR: $DrivePath\drive.vhdx already exists! Aborting..."
exit 1
}
if (Test-Path "${DriveLetter}:") {
Write-Warning "ERROR: Drive letter ${DrivePath}: is already in use! Aborting..."
exit 1
}
Write-Output "[*] Setting disk configuration settings..."
Write-Output "create vdisk file='${DrivePath}\drive.vhdx' maximum=$SizeInMB type=expandable" | Out-File -Encoding ascii -FilePath C:\Temp\diskpart_devdrive.txt
Write-Output "select vdisk file='${DrivePath}\drive.vhdx'" | Out-File -Encoding ascii -Append -FilePath C:\Temp\diskpart_devdrive.txt
Write-Output "attach vdisk" | Out-File -Encoding ascii -Append -FilePath C:\Temp\diskpart_devdrive.txt
Write-Output "create partition primary" | Out-File -Encoding ascii -Append -FilePath C:\Temp\diskpart_devdrive.txt
Write-Output "format fs=refs label='Dev Drive' quick" | Out-File -Encoding ascii -Append -FilePath C:\Temp\diskpart_devdrive.txt
Write-Output "assign letter=${DriveLetter}" | Out-File -Encoding ascii -Append -FilePath C:\Temp\diskpart_devdrive.txt
Write-Output "[*] Creating Dev Drive..."
if (!(Test-Path "$DrivePath")) {
mkdir $DrivePath
}
diskpart /s C:\Temp\diskpart_devdrive.txt
Format-Volume -DriveLetter $DriveLetter -DevDrive
if (!(Test-Path "${DriveLetter}:")) {
Write-Warning "ERROR: Failed to create ReFS vdisk for Dev Drive..."
exit 1
}
Write-Output "[*] Verifying Dev Drive trust..."
fsutil devdrv query ${DriveLetter}:
cd ${DriveLetter}:
label Dev Drive
# dev drive doesn't re-mount after reboots without a scheduled task
$Script = "diskpart.exe /s '$DrivePath\devdrivetask.txt' > '$DrivePath\tasklog.txt'"
Write-Output "select vdisk file='$DrivePath\drive.vhdx'" | Out-File -Encoding ascii -FilePath $DrivePath\devdrivetask.txt
Write-Output "attach vdisk" | Out-File -Encoding ascii -Append -FilePath $DrivePath\devdrivetask.txt
Write-Output $Script | Out-File -Encoding ascii -FilePath $DrivePath\devdrivetask.ps1
Write-Output "cd ${DriveLetter}:" | Out-File -Encoding ascii -Append -FilePath $DrivePath\devdrivetask.ps1
Write-Output "label Dev Drive" | Out-File -Encoding ascii -Append -FilePath $DrivePath\devdrivetask.ps1
$taskname = "Mount Dev Drive"
$taskdescription = "Make sure Dev Drive is mounted after reboots"
$taskTrigger = New-ScheduledTaskTrigger -AtStartup
$taskAction = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-ExecutionPolicy Bypass .\devdrivetask.ps1" -WorkingDirectory $DrivePath
$taskSettings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
Register-ScheduledTask -TaskName $taskname -Description $taskdescription -Action $taskAction -Trigger $taskTrigger -Settings $taskSettings -User "System"
Write-Output "[*] Cleaning up..."
Remove-Item C:\Temp\diskpart_devdrive.txt
Write-Output "[*] Done."
@lawndoc
Copy link
Author

lawndoc commented Feb 19, 2025

To change the drive letter of the Dev Drive:

$OldLetter = "B"
$NewLetter = "V"
$FileName = "C:\Temp\diskpart_devdrive.txt"
Write-Output "select volume $OldLetter" | Out-File -Encoding ascii -FilePath $FileName
Write-Output "assign letter=$NewLetter" | Out-File -Encoding ascii -Append -FilePath $FileName
diskpart /s $FileName
(Get-Content -Path 'C:\ProgramData\Custom Dev Drive\devdrivetask.ps1' -Raw) -replace "cd $OldLetter", "cd $NewLetter" | Set-Content -Path "C:\ProgramData\Custom Dev Drive\devdrivetask.ps1"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment