Hello,
I had to recreate a vm often with a virtual hard disk, because exporting a vm was quite long
So i started storing my virtual disk on a removable usb3 drive
Since hyperv is a service, I needed to recreate the vm on any computer to work with
Only the hard disk was important to restart the vm on another computer quickly
I found code in powershell on internet and adapted it to my needs
I added powershell code references at the end for futur use
2019-08-03 added the state of hyper-v service
################# powershell ####################
# create a vm from a vistual disk
# windows or maybe anything
# 2 cpu
# 4 gig ram
# windows 7
# Set-ExecutionPolicy RemoteSigned
# windows 10
# Set-ExecutionPolicy -scope currentuser RemoteSigned
$test01 = 0
#$test01 = 0
# logfile
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$scriptname = split-path -leaf $MyInvocation.MyCommand.Definition
$Logfilename = $scriptname + "_log.txt"
$logfile = $scriptPath + "\" + $Logfilename
$logall = 1
$msg01 = "START hyper-v vm creation from disk image with same name"
write-host $msg01
if ($logall=1) {(Get-Date -Format "yyyy-MM-dd HH:mm:ss") + " " + $msg01 | Out-File $logfile}
# error management object
$error01 = New-Object PsObject
$error01 | Add-Member NoteProperty -Name number -value ''
$error01 | Add-Member NoteProperty -Name description -value ''
$error01 | Add-Member NoteProperty -Name error02 -value ''
function error_display($error01)
{
write-host "===== " $error01.description
write-host "===== " $error01.error02
write-host "===== " $error01.error02.InvocationInfo.PositionMessage
if ($logall=1) {(Get-Date -Format "yyyy-MM-dd HH:mm:ss") + "===== " + $error01.description | Out-File $logfile -append}
if ($logall=1) {(Get-Date -Format "yyyy-MM-dd HH:mm:ss") + "===== " + $error01.error02 | Out-File $logfile -append}
if ($logall=1) {(Get-Date -Format "yyyy-MM-dd HH:mm:ss") + "===== " + $error01.error02.InvocationInfo.PositionMessage | Out-File $logfile -append}
#if ($logall=1) {(Get-Date -Format "yyyy-MM-dd HH:mm:ss") + " error02.Exception.itemname: " + $error01.error02.Exception.itemname | Out-File $filnamfull_log01 -append}
#if ($logall=1) {(Get-Date -Format "yyyy-MM-dd HH:mm:ss") + " error02.InvocationInfo.MyCommand.Name: " + $error01.error02.InvocationInfo.MyCommand.Name | Out-File $filnamfull_log01 -append}
#if ($logall=1) {(Get-Date -Format "yyyy-MM-dd HH:mm:ss") + " error02.ErrorDetails.Message : " + $error01.error02.ErrorDetails.Message | Out-File $filnamfull_log01 -append}
#if ($logall=1) {(Get-Date -Format "yyyy-MM-dd HH:mm:ss") + " error02.InvocationInfo.PositionMessage: " + $error01.error02.InvocationInfo.PositionMessage | Out-File $filnamfull_log01 -append}
#if ($logall=1) {(Get-Date -Format "yyyy-MM-dd HH:mm:ss") + " error02.CategoryInfo.ToString: " + $error01.error02.CategoryInfo.ToString() | Out-File $filnamfull_log01 -append}
#if ($logall=1) {(Get-Date -Format "yyyy-MM-dd HH:mm:ss") + " error02.FullyQualifiedErrorId: " + $error01.error02.FullyQualifiedErrorId | Out-File $filnamfull_log01 -append}
}
# hyper-v requis
# Windows 10 Enterprise, Pro, or Education
# 64-bit Processor with Second Level Address Translation (SLAT).
# CPU support for VM Monitor Mode Extension (VT-c on Intel CPUs).
# Minimum of 4 GB memory.
# The Hyper-V role cannot be installed on Windows 10 Home.
#Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
#Install-WindowsFeature -Name Hyper-V -IncludeManagementTools -Restart
#Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
# check if hyper-v optionnal feature is installed
cls
write-host ""
write-host "Checking if hyper-v is installed..."
$features01 = Get-WindowsOptionalFeature -online
[string[]]$arr_optionnal_feature = "Microsoft-Hyper-V-All" #State : Enabled
$arr_optionnal_feature+= "Microsoft-Hyper-V"
$arr_optionnal_feature+= "Microsoft-Hyper-V-Tools-All"
$arr_optionnal_feature+= "Microsoft-Hyper-V-Management-PowerShell"
$arr_optionnal_feature+= "Microsoft-Hyper-V-Hypervisor"
$arr_optionnal_feature+= "Microsoft-Hyper-V-Services"
$arr_optionnal_feature+= "Microsoft-Hyper-V-Management-Clients"
$found01 = 0
foreach ($feature01 in $features01)
{
if ($feature01.FeatureName -eq $arr_optionnal_feature[0])
{
if ($feature01.State.tostring() -eq "Enabled")
{
#write-host $arr_optionnal_feature[1]
$found01 = 1
$feature01.FeatureName
$feature01.State
}
else
{
$feature01.FeatureName
$feature01.State
}
}
}
if($found01 -eq 1)
{
write-host "--> OK hyper-v is installed"
####################################################
# disk path to create vm from with same name
####################################################
write-host ""
write-host "Getting all virtual disk in current folder..."
# scan file in this folder
$filelist01 = Get-ChildItem -Path $scriptPath -Filter "*.vhd*"
[System.Int32]$i_max = ( $filelist01 | Measure-Object ).Count + 1
write-host ""
write-host "Liste des disques virtuels dans le dossier actuel: "
write-host ""
for($i=1; $i -lt $i_max; $i++)
{
write-host ($i) ($filelist01[$i-1].name)
}
write-host ""
$choice01 = Read-Host -Prompt 'Entrez le choix du disque virtuel'
if (($choice01 -gt 0) -and ($choice01 -lt ($i_max)))
{
write-host ""
$msg01 = "--> Choice: " + $choice01 + " " + $filelist01[$choice01 -1]
if ($logall=1) {(Get-Date -Format "yyyy-MM-dd HH:mm:ss") + " " + $msg01 | Out-File $logfile -append}
write-host $msg01
$filename01 = $filelist01[$choice01 -1]
$vhd_path01 = $scriptPath + "\" + $filename01
# extract vm name from disk image name (we want it to be the same)
$vm_name_arr01 = $vhd_path01.split("\")
$vm_name01 = $vm_name_arr01[$vm_name_arr01.GetUpperBound(0)]
# remove extension after .
$vm_name01 = $vm_name01.Substring(0,$vm_name01.LastIndexOf('.'))
write-host ""
write-host "virtual disk full path: " $vhd_path01
write-host "virtual machine name..: " $vm_name01
if ($vm_name01.length -gt 0)
{
$vm01 = Get-VM| where {$_.name -eq $vm_name01}
if ($vm01.count -eq 0)
{
write-host ""
write-host "Getting switch list, finding any external switch... (so we can patch windows on internet)"
$switchs01 = Get-VMSwitch
$found01 = 0
$switch_name01 = ""
foreach ($switch01 in $switchs01)
{
if ($switch01.switchtype.tostring().tolower() -eq "external")
{
write-host "External switch found: " $switch01.name
$switch_name01 = $switch01.name
$found01 = 1 # caca
}
}
if($found01 -eq 0)
{
################################
# create external v-switch
################################
$netadapters01 = Get-NetAdapter
$found01 = 0
foreach($netadapter01 in $netadapters01)
{
if($netadapter01.name.tostring().tolower() -eq "ethernet")
{
write-host "found ethernet"
$found01 = 1
}
}
if($found01 -eq 1)
{
$switch_name01 = "external01"
$msg01 = "Creating external switch, network might get disrupted"
write-host $msg01
if ($logall=1) {(Get-Date -Format "yyyy-MM-dd HH:mm:ss") + " " + $msg01 | Out-File $logfile -append}
New-VMSwitch -name $switch_name01 -NetAdapterName Ethernet -AllowManagementOS $true
}
}
else
{
# an external v-switch was found
# we dont create one
}
############################## futur dev ############################
## futur multiple vm creation from array
#[string[]]$arr_vmname = ""
#[string[]]$arr_vmMemoryStartupBytes = 2147483648*2
#[string[]]$arr_Generation = 1
#[string[]]$arr_VHDPath = $vhd_path01
#[string[]]$arr_NewVHDSizeBytes = 120687091200
#[string[]]$arr_BootDevice = "VHD"
#[string[]]$arr_path = Path = $scriptPath + "\" + $vm_name01
#[string[]]$arr_SwitchName = "Nouveau commutateur virtuel"
## parameter number 2 to inputbox
#$arr_vmname += "vm2"
#$arr_vmMemoryStartupBytes += 2147483648*2
#$arr_Generation += $vhd_path01
#$arr_VHDPath += "textbox"
#$arr_NewVHDSizeBytes += 120687091200
#$arr_BootDevice += "VHD"
#$arr_path += $scriptPath + "\" + $vm_name01
#$arr_SwitchName += "Nouveau commutateur virtuel"
# array of parameters
#=== vm parameters
#https://docs.microsoft.com/en-us/powershell/module/hyper-v/set-vm?view=win10-ps
$VM = @{
Name = $vm_name01
MemoryStartupBytes = 2147483648*2
Generation = 1
VHDPath = $vhd_path01
#NewVHDSizeBytes = 53687091200
BootDevice = "VHD"
Path = $scriptPath
SwitchName = $switch_name01 #(Get-VMSwitch).Name
}
try
{
$error01.number = 0
New-VM @VM | out-null
$msg01 = "creating vm: " + $vm_name01
if ($logall=1) {(Get-Date -Format "yyyy-MM-dd HH:mm:ss") + " " + $msg01 | Out-File $logfile -append}
}
catch
{
$error01.number = 1
$error01.description = "ERROR " + $msg01
$error01.error02 = $_
}
if ($error01.number -eq 0)
{
$msg01 = "vm created: " + $vm_name01
write-host $msg01
if ($logall=1) {(Get-Date -Format "yyyy-MM-dd HH:mm:ss") + " " + $msg01 | Out-File $logfile -append}
try
{
$error01.number = 0
set-vmprocessor -vmname $vm_name01 -count 2
$msg01 = "vm processors set to 2: " + $vm_name01
write-host $msg01
if ($logall=1) {(Get-Date -Format "yyyy-MM-dd HH:mm:ss") + " " + $msg01 | Out-File $logfile -append}
}
catch
{
$error01.number = 1
$error01.description = "ERROR " + $msg01
$error01.error02 = $_
}
if ($error01.number -eq 0)
{
# checkpoints off
$msg01 = "vm checkpoints: disabled"
write-host $msg01
if ($logall=1) {(Get-Date -Format "yyyy-MM-dd HH:mm:ss") + " " + $msg01 | Out-File $logfile -append}
set-vm -vmname $vm_name01 -CheckpointType disabled
}
else
{
error_display($error01)
}
###############################
# start hyper-v manager
###############################
& (Get-Command "$($env:systemroot)\system32\mmc.exe") @("$($env:systemroot)\System32\virtmgmt.msc")
}
else
{
error_display($error01)
}
#Set-VMNetworkAdapterVlan -VMName vmfrompowershell1 -Access -VlanId 121
}
else
{
$error01.number = 1
$error01.description = "ERROR vm already exist, name: " + $vm_name01
$error01.error02 = ""
error_display($error01)
###############################
# start hyper-v manager
###############################
& (Get-Command "$($env:systemroot)\system32\mmc.exe") @("$($env:systemroot)\System32\virtmgmt.msc")
}
}
else
{
$error01.number = 1
$error01.description = "ERROR vm_name01 empty"
$error01.error02 = ""
error_display($error01)
}
}
else
{
$error01.number = 1
$error01.description = "ERROR bad choice"
$error01.error02 = ""
error_display($error01)
}
write-host ""
$msg01 = "END hyper-v vm creation from disk image"
write-host $msg01
if ($logall=1) {(Get-Date -Format "yyyy-MM-dd HH:mm:ss") + " " + $msg01 | Out-File $logfile -append}
#ref code:
#& (Get-Command "$($env:systemroot)\system32\robocopy.exe") @("$($folder_source_c_01)", "$($folder_destination_here_01)", '/XJ', '/s', '/e', '/R:0', '/W:0', $log01)
# check if it's already existing
# reference:
# vm details
# Get-VM -Name VMWEB01 | Format-List *
# vm disks
#(Get-VM –VMName VMTest | Select-Object VMId | Get-VHD).Path
# vm memory
#Set-VMMemory "VMTest" -DynamicMemoryEnabled $true -MaximumBytes 1GB
# vm start
# Start-VM -name VMTest
#vm stop forced (not gracefull)
# Stop-VM -name VMTest -Force
# vm add checkpoint
# Get-VM -Name VMTest | Checkpoint-VM -SnapshotName “Before Upgrade”
# vm get checkpoints
# Remove-VMCheckpoint -VMName VMTest -Name "Before Upgrade"
# vm list all checkpoints
#Get-VM | Get-VMCheckpoint
#######################
# vm backup
#######################
## Backup Folder
#$Backup = "C:\Backup"
## Get VMs Name
#$VMs = Get-VM | select name
# vm backuo Delete Backup Folder and create it again
## Backup Folder
#$Backup = "C:\Backup"
## Get VMs Name
#$VMs = Get-VM | select name
#if((Test-Path -Path $Backup)){
# Remove-Item $Backup -force -recurse -erroraction:SilentlyContinue
#} else {
# New-Item $Backup -type directory
#}
## Export all the VMs
#foreach ($VM in $VMs)
#{
# Export-VM -Name $VM.Name -Path $Backup
#}
# vm backup schedule
#$trigger = New-JobTrigger -Weekly -DaysOfWeek Sunday -WeeksInterval 2 -At 12:00AM
#$options = New-ScheduledJobOption -RunElevated
#############################################
# vmsnapshot
#############################################
#get-VMSnapshot forea-demox-win10-avantage
#Remove-VMSnapshot
##################################################
# vm management advanced (server)
##################################################
#scvmm console commands
# https://docs.microsoft.com/en-us/powershell/module/virtualmachinemanager/?view=systemcenter-ps-2019
#Import-Module -Name "virtualmachinemanager"
# scvmm
# add console
#SCVMM Management console
# load pssnapin
#Add-PSSnapin Microsoft.SystemCenter.VirtualMachineManager
}
else
{
$error01.number = 1
$error01.description = "ERROR Hyper-v is not installed"
$error01.error02 = ""
error_display($error01)
write-host ""
$choice01 = Read-Host -Prompt "Do you want to install all hyper-v features? (y = yes, n=no, you will have to reboot if it was not installed)"
if($choice01.ToString().ToLower() -eq "y")
{
write-host ""
write-host "Installting all hyper-v features online"
write-host "Executing: Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All..."
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
}
else
{
write-host "ok bye!"
}
}