argumentum Posted July 8 Posted July 8 (edited) I'd like a VM that I can just copy from the host PC to another PC and keep running it. The defaults are paths are that the "Virtual Hard Disks" goes somewhere and the setting elsewhere. And I find myself exporting the newly created VM to a set folder, deleting the VM to then import the VM just to have it all in one place. If I want to move the VM from the current hardware to another hardware, all I have to do ( via this way ) is to copy the folder where the exported ( and registered in place ) is at to the other PC. Easy-peasy Do I need help ?, nope. But I coded a "do it for me" so is easier/faster to get done, that to me is not an example script, not even in quality of code, but it gets the job done. The code is down in the next post, so that I can mark it as solved Edited July 8 by argumentum English ioa747 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
Solution argumentum Posted July 8 Author Solution Posted July 8 (edited) expandcollapse popup#NoTrayIcon #RequireAdmin #include <File.au3> #include <_RunWaitEx.au3> ; https://www.autoitscript.com/forum/index.php?showtopic=212643 #include <Date.au3> #include <ButtonConstants.au3> #include <ComboConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #Region ### START Koda GUI section ### Form= Global $g_ini = StringTrimRight(@ScriptFullPath, 4) & ".ini" Global $hForm = 0, $idLog = 0, $g_sGetVMHost Exit gui() Func gui() Local $hTimer = TimerInit() Local $sFormTitle = "Hyper-V - CreateNewVM", $iW = 600, $iH = 400, $iTop = 10, $iLabelWidth = 120, $iInputWidth = 340 $hForm = GUICreate($sFormTitle, $iW, $iH, -1, -1, BitOR($GUI_SS_DEFAULT_GUI,$WS_MAXIMIZEBOX,$WS_SIZEBOX,$WS_THICKFRAME,$WS_TABSTOP)) GUISetIcon(StringTrimRight(@ScriptFullPath, 4) & ".ico") GUISetFont(10) ;~ GUISetBkColor(0x303030) ; for my dark mode theme GUICtrlCreateLabel("VM name: ", 10, $iTop, $iLabelWidth, 19, $SS_RIGHT);, $WS_EX_STATICEDGE) GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKTOP+$GUI_DOCKWIDTH+$GUI_DOCKHEIGHT) $idVmName = GUICtrlCreateInput("vm-Temp01", $iLabelWidth + 8, $iTop - 1, $iInputWidth, 23, -1, BitOR($WS_EX_CLIENTEDGE, $WS_EX_STATICEDGE)) GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKRIGHT+$GUI_DOCKTOP+$GUI_DOCKHEIGHT) $iTop += 27 GUICtrlCreateLabel("VM Version: ", 10, $iTop, $iLabelWidth, 19, $SS_RIGHT);, $WS_EX_STATICEDGE) GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKTOP+$GUI_DOCKWIDTH+$GUI_DOCKHEIGHT) $idVmVersion = GUICtrlCreateCombo("", $iLabelWidth + 8, $iTop - 2, $iInputWidth - 100, 25, BitOR($CBS_DROPDOWNLIST, $CBS_AUTOHSCROLL), $WS_EX_STATICEDGE) GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKRIGHT+$GUI_DOCKTOP+$GUI_DOCKHEIGHT) GUICtrlSetState($idVmVersion, $GUI_DISABLE) $idVmVersionHelp = GUICtrlCreateButton("Help", $iW - 110 - 100, $iTop, 80, 23) GUICtrlSetTip($idVmVersionHelp, "About virtual machine versions") GUICtrlSetResizing(-1, $GUI_DOCKRIGHT+$GUI_DOCKTOP+$GUI_DOCKHEIGHT+$GUI_DOCKWIDTH) $idGenerateVm = GUICtrlCreateButton("Generate VM", $iW - 110, $iTop, 100, 25) GUICtrlSetResizing(-1, $GUI_DOCKRIGHT+$GUI_DOCKTOP+$GUI_DOCKHEIGHT+$GUI_DOCKWIDTH) GUICtrlSetState($idVmVersion, $GUI_DISABLE) $iTop += 27 GUICtrlCreateLabel("VM Generation: ", 10, $iTop, $iLabelWidth, 19, $SS_RIGHT);, $WS_EX_STATICEDGE) GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKTOP+$GUI_DOCKWIDTH+$GUI_DOCKHEIGHT) $Combo = GUICtrlCreateCombo("", $iLabelWidth + 8, $iTop - 2, $iInputWidth, 25, BitOR($CBS_DROPDOWNLIST, $CBS_AUTOHSCROLL), $WS_EX_STATICEDGE) GUICtrlSetData(-1, "1|2", "2") GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKRIGHT+$GUI_DOCKTOP+$GUI_DOCKHEIGHT) $iTop += 27 GUICtrlCreateLabel("SwitchName: ", 10, $iTop, $iLabelWidth, 19, $SS_RIGHT);, $WS_EX_STATICEDGE) GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKTOP+$GUI_DOCKWIDTH+$GUI_DOCKHEIGHT) $idSwitchName = GUICtrlCreateCombo("", $iLabelWidth + 8, $iTop - 2, $iInputWidth, 25, BitOR($CBS_DROPDOWNLIST, $CBS_AUTOHSCROLL), $WS_EX_STATICEDGE) GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKRIGHT+$GUI_DOCKTOP+$GUI_DOCKHEIGHT) GUICtrlSetState($idSwitchName, $GUI_DISABLE) $iTop += 27 GUICtrlCreateLabel("HDD size (GB): ", 10, $iTop, $iLabelWidth, 19, $SS_RIGHT, $WS_EX_STATICEDGE) GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKTOP+$GUI_DOCKWIDTH+$GUI_DOCKHEIGHT) $idVmHddSize = GUICtrlCreateInput(Int(IniRead($g_ini, "Defaults", "VmHddSize", "127")), $iLabelWidth + 8, $iTop - 1, $iInputWidth, 23, -1, BitOR($WS_EX_CLIENTEDGE, $WS_EX_STATICEDGE)) GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKRIGHT+$GUI_DOCKTOP+$GUI_DOCKHEIGHT) $iTop += 27 GUICtrlCreateLabel("Import VMs path: ", 10, $iTop, $iLabelWidth, 19, $SS_RIGHT, $WS_EX_STATICEDGE) GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKTOP+$GUI_DOCKWIDTH+$GUI_DOCKHEIGHT) $idVmExportsPath = GUICtrlCreateInput(IniRead($g_ini, "Defaults", "VmExportsPath", "C:\Make\A\Path\For\ExportImport"), $iLabelWidth + 8, $iTop - 1, $iW - $iLabelWidth - 20 , 23, -1, BitOR($WS_EX_CLIENTEDGE, $WS_EX_STATICEDGE)) GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKRIGHT+$GUI_DOCKTOP+$GUI_DOCKHEIGHT) $iTop += 27 $idLog = GUICtrlCreateEdit("", 0, $iTop, $iW, $iH - $iTop) GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM) GUICtrlSetFont($idLog, 10, 800) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### GUICtrlSetData($idLog, "... please wait ...") AdlibRegister(AdlibAddDot, 300) $iRet = _RunWaitEx('powershell "Get-VMHost | Select-Object VirtualHardDiskPath, VirtualMachinePath, SupportedVmVersions, InternalNetworkAdapters | ConvertTo-Json | Out-File ''' & @TempDir & '\output-' & $hTimer & '.json''"', @TempDir, @SW_HIDE) $g_sGetVMHost = FileRead(@TempDir & '\output-' & $hTimer & '.json') FileDelete(@TempDir & '\output-' & $hTimer & '.json') ;~ ConsoleWrite(@CRLF & $g_sGetVMHost & @CRLF) GuiPopulate_idVmVersion($idVmVersion) GuiPopulate_idSwitchName($idSwitchName) AdlibUnRegister(AdlibAddDot) GUICtrlSetData($idLog, "Ready") GUICtrlSetState($idVmVersion, $GUI_ENABLE) GUICtrlSetState($idSwitchName, $GUI_ENABLE) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE GUISetState(@SW_HIDE) IniWrite($g_ini, "Defaults", "VmVersion", GUICtrlRead($idVmVersion)) IniWrite($g_ini, "Defaults", "SwitchName", GUICtrlRead($idSwitchName)) IniWrite($g_ini, "Defaults", "VmHddSize", GUICtrlRead($idVmHddSize)) IniWrite($g_ini, "Defaults", "VmExportsPath", GUICtrlRead($idVmExportsPath)) GUIDelete() Exit Case $idVmVersionHelp ShellExecute("https://learn.microsoft.com/en-us/windows-server/virtualization/hyper-v/deploy/upgrade-virtual-machine-version-in-hyper-v-on-windows-or-windows-server") Case $idGenerateVm $sNewVmName = GUICtrlRead($idVmName) $sNewVmHddSize = GUICtrlRead($idVmHddSize) $sNewVmExportsPath = GUICtrlRead($idVmExportsPath) GUICtrlSetState($idGenerateVm, $GUI_DISABLE) GUICtrlSetData($idLog, "... running ...") AdlibRegister(AdlibAddDot, 1000) $sRet = NewVmAsImport($sNewVmName, $sNewVmHddSize, $sNewVmExportsPath) AdlibUnRegister(AdlibAddDot) GUICtrlSetData($idLog, $sRet) If _RunWaitEx_LastExtended() Then GUICtrlSetData($idLog, @CRLF & @CRLF & _RunWaitEx_LastStdout() & @CRLF & _RunWaitEx_LastStderr() & @CRLF, 1) GUICtrlSetState($idGenerateVm, $GUI_ENABLE) EndSwitch WEnd EndFunc ;==>gui Func GuiPopulate_idVmVersion($idVmVersion) Local $sTemp, $sDefault, $aArray = StringSplit($g_sGetVMHost, "[]", 0) For $n = 1 To UBound($aArray) - 2 If StringInStr($aArray[$n], '"SupportedVmVersions"') Then $sTemp = StringReplace(StringStripWS(StringReplace($aArray[$n + 1], ",", "|"), 8), '"', '') $sDefault = StringLeft($sTemp, StringInStr($sTemp, "|") - 1) ExitLoop EndIf Next ; https://learn.microsoft.com/en-us/windows-server/virtualization/hyper-v/deploy/upgrade-virtual-machine-version-in-hyper-v-on-windows-or-windows-server $sDefault = IniRead($g_ini, "Defaults", "VmVersion", "8.0") If Not StringInStr('|' & $sTemp & '|', '|' & $sDefault & '|') Then $sDefault = "" GUICtrlSetData($idVmVersion, $sTemp, $sDefault) EndFunc Func GuiPopulate_idSwitchName($idSwitchName) Local $sTemp = "", $sDefault = "", $aTemp, $aArray = StringSplit($g_sGetVMHost, "[]", 0) For $n = 1 To UBound($aArray) - 2 If StringInStr($aArray[$n], '"InternalNetworkAdapters"') Then $aTemp = StringSplit($aArray[$n + 1], @CRLF, 1) ExitLoop EndIf Next For $n = 1 To UBound($aTemp) - 2 If StringInStr($aTemp[$n], '"SwitchName":') Then If StringLen($sTemp) Then $sTemp &= "|" $sTemp &= GetTheJsonValue($aTemp[$n]) If $sDefault = "" Then $sDefault = $sTemp EndIf Next $sDefault = IniRead($g_ini, "Defaults", "SwitchName", $sDefault) If Not StringInStr('|' & $sTemp & '|', '|' & $sDefault & '|') Then $sDefault = "" GUICtrlSetData($idSwitchName, $sTemp, $sDefault) EndFunc Func GetTheJsonValue($sStr) Local $aArray = StringSplit($sStr, '"') Return $aArray[$aArray[0] - 1] EndFunc Func AdlibAddDot() GUICtrlSetData($idLog, ".", 1) EndFunc Func GetMe($sJson, $sStr, $sNext = Default) Local $iPos1 = StringInStr($sJson, '"' & $sStr & '"') If $sNext = Default Then Local $iPos2 = StringInStr($sJson, '"', 0, 1, $iPos1 + StringLen($sStr) + 3) Local $iPos3 = StringInStr($sJson, '"', 0, 1, $iPos2 + 1) Return StringReplace(StringReplace(StringMid($sJson, $iPos2, $iPos3 - $iPos2 + 1), '"', ''), '\\', '\') EndIf Return StringInStr($sJson, ' "' & $sNext & '"') ; meh =/ EndFunc ;==>GetMe Func NewVmAsImport($sNewVmName = Default, $sNewVmHddSize = Default, $sNewVmExportsPath = Default) If Not IsAdmin() Then Return SetError(1, @ScriptLineNumber, "This script RequireAdmin !") Local $iRunEm = 1, $iRet, $sRun, $sVmName = "MyTestVM" Local $sRunDir = @TempDir Local $sRunShow = @SW_HIDE Local $sVmVersion = "8.0" Local $sSwitchName = "External 10G" Local $sVmGeneration = 2 Local $hTimer = TimerInit() If FileExists($sNewVmExportsPath & "\" & $sNewVmName) Then Return SetError(1, @ScriptLineNumber, "VmName """ & $sNewVmName & """ exists in importPath """ & $sNewVmExportsPath & """ !") $iRet = _RunWaitEx('powershell "Get-VMHost | Select-Object VirtualHardDiskPath, VirtualMachinePath, SupportedVmVersions, InternalNetworkAdapters | ConvertTo-Json | Out-File ''' & $sRunDir & '\output-' & $hTimer & '.json''"', $sRunDir, $sRunShow) Local $sJson = FileRead(@TempDir & '\output-' & $hTimer & '.json') FileDelete(@TempDir & '\output-' & $hTimer & '.json') If $iRunEm And @extended Then Return SetError(1, @ScriptLineNumber, "Get-VMHost failed") $sJson = $g_sGetVMHost Local $sVirtualHardDiskPath = GetMe($sJson, "VirtualHardDiskPath") ; D:\\HV-defaults\\Virtual Hard Disks If Not FileExists($sVirtualHardDiskPath) Then Return SetError(1, @ScriptLineNumber, "VirtualHardDiskPath """ & $sVirtualHardDiskPath & """ don't exist ?!") Local $sVirtualMachinePath = GetMe($sJson, "VirtualMachinePath") ; D:\\HV-defaults\\Hyper-V If Not GetMe($sJson, "SupportedVmVersions", $sVmVersion) Then Return SetError(2, @ScriptLineNumber, "Bad Version !") If Not GetMe($sJson, "InternalNetworkAdapters", $sSwitchName) Then Return SetError(2, @ScriptLineNumber, "Bad SwitchName !") If $sNewVmName <> Default Then $sVmName = $sNewVmName If $sVmName = "" Then Return SetError(2, @ScriptLineNumber, "Needs a VM name !") Local $sVmHddSize = "127GB" If $sNewVmHddSize <> Default Then If Int($sNewVmHddSize) < 1 Then Return SetError(2, @ScriptLineNumber, "Wrong a VM HDD size !") $sVmHddSize = $sNewVmHddSize & "GB" EndIf Local $sVmExportsPath = "D:\HV-defaults\FreshExport" If $sNewVmExportsPath <> Default Then $sVmExportsPath = $sNewVmExportsPath Local $sVmID = "" Local $aArray = _FileListToArrayRec($sVmExportsPath & "\" & $sVmName, "*.vmcx", 1, 1) For $n = 1 To UBound($aArray) - 1 $sVmID = $sVmExportsPath & "\" & $sVmName & "\" & $aArray[$n] ConsoleWrite('>' & $sVmExportsPath & "\" & $sVmName & "\" & $aArray[$n] & '<' & @CRLF) ExitLoop Next If $sVmID <> "" Then Return SetError(3, 0, "VM already exists") If Not FileExists($sVmExportsPath) Then Return SetError(4, @ScriptLineNumber, "VM export folder don't exists") $sRun = "powershell ""New-VM -Name '" & $sVmName & "' -MemoryStartupBytes 4GB -NewVHDPath '" & $sVmName & ".vhdx' -NewVHDSizeBytes " & $sVmHddSize & _ " -Generation " & $sVmGeneration & " -SwitchName '" & $sSwitchName & "' -Version " & $sVmVersion & " " If $iRunEm Then $iRet = _RunWaitEx($sRun, $sRunDir, $sRunShow) ConsoleWrite($sRun & @CRLF & '$iRet = ' & $iRet & ' - @error = ' & @error & ' - @extended = ' & @extended & @CRLF & @CRLF) If $iRunEm And @extended Then Return SetError(11, @ScriptLineNumber, "VM: New-VM failed") $sRun = "powershell ""Set-VM -VMName '" & $sVmName & "' -CheckpointType Production""" If $iRunEm Then $iRet = _RunWaitEx($sRun, $sRunDir, $sRunShow) ConsoleWrite($sRun & @CRLF & '$iRet = ' & $iRet & ' - @error = ' & @error & ' - @extended = ' & @extended & @CRLF & @CRLF) $sRun = "powershell ""Set-VM -VMName '" & $sVmName & "' -AutomaticStartDelay 120""" ; https://virtualizationdojo.com/hyper-v/customize-vm-powershell/ If $iRunEm Then $iRet = _RunWaitEx($sRun, $sRunDir, $sRunShow) ConsoleWrite($sRun & @CRLF & '$iRet = ' & $iRet & ' - @error = ' & @error & ' - @extended = ' & @extended & @CRLF & @CRLF) $sRun = "powershell ""Set-VM -VMName '" & $sVmName & "' -AutomaticCheckpointsEnabled $False""" If $iRunEm Then $iRet = _RunWaitEx($sRun, $sRunDir, $sRunShow) ConsoleWrite($sRun & @CRLF & '$iRet = ' & $iRet & ' - @error = ' & @error & ' - @extended = ' & @extended & @CRLF & @CRLF) $sRun = "powershell ""Set-VM -VMName '" & $sVmName & "' -Notes 'Created with \""" & StringTrimRight(@ScriptName, 4) & "\"" on " & _NowCalc() & "'" If $iRunEm Then $iRet = _RunWaitEx($sRun, $sRunDir, $sRunShow) ConsoleWrite($sRun & @CRLF & '$iRet = ' & $iRet & ' - @error = ' & @error & ' - @extended = ' & @extended & @CRLF & @CRLF) $sRun = "powershell ""Export-VM -Name '" & $sVmName & "' -Path '" & $sVmExportsPath & "'""" If $iRunEm Then $iRet = _RunWaitEx($sRun, $sRunDir, $sRunShow) ConsoleWrite($sRun & @CRLF & '$iRet = ' & $iRet & ' - @error = ' & @error & ' - @extended = ' & @extended & @CRLF & @CRLF) If $iRunEm And @extended Then Return SetError(12, @ScriptLineNumber, "VM: Export-VM failed") $sRun = "powershell ""Remove-VM -Name '" & $sVmName & "' -Force""" If $iRunEm Then $iRet = _RunWaitEx($sRun, $sRunDir, $sRunShow) ConsoleWrite($sRun & @CRLF & '$iRet = ' & $iRet & ' - @error = ' & @error & ' - @extended = ' & @extended & @CRLF & @CRLF) If $iRunEm And @extended Then Return SetError(13, @ScriptLineNumber, "VM: Remove-VM failed") $aArray = _FileListToArrayRec($sVmExportsPath & "\" & $sVmName, "*.vmcx", 1, 1) For $n = 1 To UBound($aArray) - 1 $sVmID = $sVmExportsPath & "\" & $sVmName & "\" & $aArray[$n] ConsoleWrite('>' & $sVmExportsPath & "\" & $sVmName & "\" & $aArray[$n] & '<' & @CRLF) ExitLoop Next $sRun = "powershell ""Import-VM -Path '" & $sVmID & "'""" If $iRunEm Then $iRet = _RunWaitEx($sRun, $sRunDir, $sRunShow) ConsoleWrite($sRun & @CRLF & '$iRet = ' & $iRet & ' - @error = ' & @error & ' - @extended = ' & @extended & @CRLF & @CRLF) If $iRunEm And @extended Then Return SetError(14, @ScriptLineNumber, "VM: Import-VM failed") If FileGetSize($sVirtualHardDiskPath & "\" & $sVmName & ".vhdx") = 4194304 Then ; .vhdx is new (4,194,304 bytes) FileDelete($sVirtualHardDiskPath & "\" & $sVmName & ".vhdx") EndIf Return SetError(0, @ScriptLineNumber, $sVmName & " is ready.") EndFunc ;==>NewVmAsImport Edited July 8 by argumentum Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now