Create New-VHD via PowerShell or GUI
How To: Create New-VHD via PowerShell or GUI and attach to existing VM
If you prefer video over written format the corresponding video for this write-up can be viewed below:
Here is all the PowerShell code required for the creation of a new VHD. The code below can be used to prompt for all needed settings to fully setup and configure a new .vhd/.vhdx and will attach it to the VM you specify. This is a fully functional script that could be easily modified to automate a wide range of tasks involving the creation of additional .vhd(s)/.vhdx(s). A full write-up with examples for the GUI can also be found below.
Create New-VHD with PowerShell
#----------------------Variables Used---------------------------------------- [string]$vmName = $null [string]$vhdName = $null [string]$vhdType = $null [string]$path = $null [string]$vhdPath = $null [int64]$vhdSize = $null [string]$dynamic = $null [string]$confirm = $null #--------------------END Variables Used-------------------------------------- #----------------------USER PROMPTS------------------------------------------ $vmName = Read-Host "Enter name of VM to create new VHD for" #check to ensure VM actually exists on the local Hyp $vms = Get-VM | Select-Object -ExpandProperty Name if($vmName -like $vms){ #vm was found, we can continue with questions $vhdName = Read-Host "Enter name of new .vhdx file (Ex VMNameDisk4)" $path = Read-Host "Enter path where .vhdx will reside (Ex E:\VHD\)" $vhdPath = $path+$vhdName+".vhdx" $vhdSize = Read-Host "Enter VHDSize (GB)" $vhdSize = [math]::round($vhdSize *1Gb, 3) #converts GB to bytes while("yes","no" -notcontains $dynamic){ $dynamic = Read-Host "Will this new VHD be dynamic? (yes/no)" } if($dynamic -eq "yes"){ $vhdType = "Dynamic" } else{ $vhdType = "Fixed" } #-------------------END USER PROMPTS------------------------------------------ #-----------------CONFIRM CREATE NEW VHD---------------- Write-Host "Creating new VHD:" $vhdPath "(size:" $vhdSize "),"` "`n VHD Type:" $vhdType ` "`n Attaching this new VHD to:" $vmName ` -ForegroundColor Cyan while("yes","no" -notcontains $confirm){ $confirm = Read-Host "Proceed? (yes/no)" } #---------------END CONFIRM CREATE NEW VHD-------------- if($confirm -eq "yes"){ #-------------NEW VHD CREATION---------------------- #create either a fixed or dynamic vhd depending on user choice try{ if($dynamic -eq "yes"){ New-VHD -SizeBytes $vhdSize –Path $vhdPath -Dynamic -Confirm:$false } else{ Write-Host "Creating fixed .vhdx - this could take some time..." -ForegroundColor Cyan New-VHD -SizeBytes $vhdSize –Path $vhdPath -Fixed -Confirm:$false } } catch{ Write-Host "There was an error creating the new VHD" -ForegroundColor Red Write-Error $_ } #----------END NEW VHD CREATION--------------------- #--------------ATTACH NEW VHD ---------------------- try{ Add-VMHardDiskDrive -VMName $vmName -Path $vhdPath } catch{ Write-Host "There was an error attaching the new VHD to" $vmName -ForegroundColor Red Write-Error $_ } #------------END ATTACH NEW VHD -------------------- #now show all VHDs that are attached to the specified VM: Write-Host "Final Results:" -ForegroundColor Cyan Write-Host "--------------" -ForegroundColor Cyan $vm = Get-VM -Name $vmName Get-VHD -VMId $vm.ID | select Path } else{ Exit } } else{ #vm was not found Write-Host "The VM you specified was not located - therefore you cannot add a VHD to it" -ForegroundColor Yellow }
Create New-VHD with GUI
1. Access VM Settings for the VM you wish to add a VHD drive for
Open Hyper-V Manager – virtmgmt.msc – right click your VM – Settings…
2. Add Hardware
Depending on your generation type being Generation 1 / Generation 2 you may see the option to add an IDE or SCSI Controller. The example below demonstrates a Generation 2 VM selecting a SCSI Controller.
3. Add Hard Drive
4. Specify New drive to launch New Virtual Hard Disk Wizard
The first choice you will be prompted to make will be the Disk Type. This should be chosen with great consideration. Here is a short breakdown on disk types:
Fixed: The VHDs provision the entire disk size as it is created. If you create a 500GB fixed VHD, it will consume 500GB of space on your storage medium regardless of how much data is actually contained within the VHD. Fixed VHDs can take a long time to create depending on how large they will be. These are known to perform slightly better than dynamic VHDs but that gap is closing.
Dynamic: Expanding disks that consume only as much space as is actually inside the VHD. If you create a 500GB dynamic VHD, it will likely only be a few MB in size initially, and will grow as data is added to the VHD.
Differencing: a VHD associated with another virtual hard disk that you select when you create the differencing disk. Used primarily to isolate changes to a virtual hard disk or the guest operating system by storing them in a separate file.
If you need additional information I suggest you check out the following articles:
Aidan Finn’s article on Choosing Between Disk Types
Technet’s article on Using differencing disks
Choose a location on where you would like your new VHD to be stored:
Determine the size of your new VHD keeping in mind that fixed VHDs will take some time to create:
Confirm all settings:
hi, i’m french, so scuse me for my bad english 😉
i ll try to explain my issue :
$vms = Get-VM | Select-Object -ExpandProperty Name
(when i play $vms after this line to see result, prompt list all my vms perfectly)
but after, the $vms variable doest retrieve my value? so script go to end (and says “The VM you specified was not located – therefore you cannot add a VHD to it” 😦
i made a test , remplacing $vms by my value like this :
if($vmName -eq “CL31-1”) (CL31-1 is one of my Virtual Machines, i have 7 VMs)
And it’s ok !
So how to modifie script to play well?
Hey, haven`t done poweshell in a while and now i had to do a simple script to make a batch of vhd`s. I`ve been bashing my head trying to figure out how to make it take the size var…your example with “$vhdSize = [math]::round($vhdSize *1Gb, 3) #converts GB to bytes” was perfect. Thanks. Example of my script:
[int]$n=read-host “Number of VHDD`s”
[array]$nd=1..($n)
$loc=read-host “Location to create VHDD`s”
[int]$size=read-host “Size in gb”
$path=$loc+$file+”.vhdx”
$vhdsize = [math]::round($size *1Gb, 3)
foreach ( $file in $nd ) {$path=$loc+$file+”.vhdx”;New-VHD -Path $path -SizeBytes $vhdsize}