Post by haichen » 15 Sep 2020, 05:53
Hatte vor einiger Zeit ein Gui-Script für so etwas geschrieben.
Es erzeugt den Powershellcode um mehrere VMs zu erzeugen.
Ich habe jetzt schon länger nicht mehr ausprobiert. Ist auch nicht der schönste Code.
Muss im Ordner mit den ISOs laufen.
Ich stelle es hier mal einfach so ein:
Code: Select all
full_command_line := DllCall("GetCommandLine", "str")
if not (A_IsAdmin or RegExMatch(full_command_line, " /restart(?!\S)"))
{
try
{
if A_IsCompiled
Run *RunAs "%A_ScriptFullPath%" /restart
else
Run *RunAs "%A_AhkPath%" /restart "%A_ScriptFullPath%"16
}
ExitApp
}
#NoEnv
#SingleInstance Force
SetWorkingDir %A_ScriptDir%
gosub, GetIsos
gosub, GetSwitches
Gui, Margin, 40, 30
Gui, Add, Tab3,x3 y3 vMyTab, Names|Powershell
Gui, Tab,1
Gui Add, Text, xp-20 ym , Erstellung eines PS-Scripts zur Erzeugung von mehreren VMs in Hyper-V. Im Order mit den Isos ablegen.
Gui, Add, GroupBox, xm-20 yp+40 w900 h300 section, Namen
Gui Add, Text, xm yp+25 w410 h27 +0x200 , Gib die gewünschten Namen der VMs (mit Komma getrennt) ein:
Gui Add, Edit, xm y+2 w860 r4 gMakeNewNames vnames, server,server
Gui Add, Edit, y+20 w100 r1 h32 vprefix gMakeNewNames
Gui Add, CheckBox, x+10 h23 vpcheck gMakeNewNames, Namens-Prefix zB. Fisi_ oder 01_..99_
Gui Add, Edit, x+20 w20 r1 h32 vTrennerS gMakeNewNames,
Gui Add, CheckBox, x+10 h23 vscheck gMakeNewNames, Nummerierung S_01 , S_02
Gui Add, Text, xm y+20 w410 h27 +0x200, neue Namen
Gui Add, Edit, xm y+2 w860 r4 vNewNames disabled ,
Gui, Add, GroupBox, xm-20 y+40 w900 h280 section, VM-Einstellungen
Gui Add, Text, xm ys+40 h23 +0x200, Auswahl der OS Iso Datei
Gui Add, DropDownList, xm y+2 w760 vPS_Iso gMakePS, ||%filelist%
Gui Add, Button, x+20 w80 h23 ggetIsoFolder, Iso-Dir
Gui Add, Text, xm y+20 w124 h32 +0x200, Switche:
Gui Add, DropDownList, xm y+2 w120 vPS_Switch1 gMakePS, unverbunden ||%switches%
Gui Add, DropDownList, x+10 w120 vPS_Switch2 gMakePS, unverbunden ||%switches%
Gui Add, DropDownList, x+10 w120 vPS_Switch3 gMakePS, unverbunden ||%switches%
Gui Add, Text, xm y+20 w61 h23 +0x200, Generation
Gui Add, DropDownList, x+2 w39 +0x200 gMakePS vPS_gen, 1|2||
Gui Add, ComboBox, xm y+20 w60 gMakePS vPS_Ram, 512|1024|2024|3024||6024
Gui Add, Text, x+5 w52 h23 +0x200 , MB Ram
Gui Add, CheckBox, x+20 h23 checked +0x200 gMakePS vPS_DynS, Dynamischer Speicher
Gui Add, Edit, x+20 w100 r1 vPS_HD gMakePS ,127
Gui Add, Text, x+5 h23 +0x200 , GB HD Grösse
Gui, Tab,2
Gui, Add, GroupBox, xm-20 y+40 w900 h500 section, Powershellbefehle
Gui Add, Text, xm yp+20 h32 +0x200 section, Powershell:
Gui Add, Edit, xm y+2 w750 h420 vpowershell
Gui Add, Button, x+20 ys+40 w80 h23 gcopy, Copy
Gui Add, Button, xp ys+80 w80 h23 gsave, Save
Gui Add, Button, xp ys+120 w80 h23 grun, Run
Gui Add, Button, xp ys+160 w80 h23 gtestVHDExist, VHD exist?
Gui Add, Button, xp ys200 w80 h23 gadd, Add some more
Gui Show, , make PS-Script for new VMs in Hyper-v
Return
testVHDExist:
t:=""
GetallVhds="& {Get-VM | select VMID | Get-VHD | ? Path -like "C:\Users\Public\*" | select Path }"
vhdFilelist:=RunWaitOne("powershell.exe -Command " GetallVhds )
Loop, Parse, newnames, `,
if InStr(vhdFilelist, A_LoopField ".vhd")
t.= A_LoopField ".vhd existiert bereits!`n"
else
t.= A_LoopField ".vhd OK`n"
msgbox, % t
return
add:
gui,submit, nohide
addscript :=powershell
guicontrol,,names
GuiControl,choose, MyTab, Names|Powershell
;msgbox, %powershell%
return
copy:
clipboard:=powershell
return
save:
FileSelectFile, savehere , S24, %A_WorkingDir%\MakeVMs.ps1, Prompt, Scriptfiles (*.ps1;*.ahk;*.txt;*.*)
fileappend, %powershell%, %savehere%
return
run:
gui,submit, nohide
;msgbox, % powershell
RunWait *runas PowerShell.exe -Command &{%powershell%} ,,hide
;RunWait *runas PowerShell.exe -NoExit -Command &{%powershell%}
;,, hide
return
getswitches:
gui,submit, nohide
t:=""
i:=0
switches:=RunWaitOne(" powershell -windowstyle hidden -command GET-VMSwitch ")
switches := StrReplace(switches, " Internal ", " (Internal) ")
switches := StrReplace(switches, " External ", " (External) ")
switches := StrReplace(switches, " Private ", " (Private) ")
Loop, parse, switches, `n, `r
{
if InStr(A_LoopField, " (Internal) ") or InStr(A_LoopField, " (External) ") or InStr(A_LoopField, " (Private) ")
{
;i++
s .= SubStr(A_LoopField, 1 , InStr(A_LoopField, ")")) "|"
;s := ++i=1 ? s .="||" : s .="|"
}
}
loop, 3
switches := StrReplace(s, " ", " ")
return
makePS:
gui,submit, nohide
ps_namelist:=StrReplace(newnames, "," , "','")
PS_switch1 :=trim(SubStr(PS_switch1, 1 , InStr(PS_switch1, "(")-1))
PS_switch2 :=trim(SubStr(PS_switch2, 1 , InStr(PS_switch2, "(")-1))
PS_switch3 :=trim(SubStr(PS_switch3, 1 , InStr(PS_switch3, "(")-1))
PS_switchStr:=""
loop,3
if !instr(PS_switch%a_index%, "unverbunden")
PS_switchStr .= PS_switch%a_index% ","
PS_switchStr:=RTrim(trim(PS_switchStr),",")
SW_array:=""
SW_array := StrSplit(PS_switchStr , ",", " `t`n`r")
PS_switch:=""
ps_addswitches:=""
for index, sw in SW_array ; Recommended approach in most cases.
{
if (index=1)
{
PS_switch:="$Switch1= '" sw "'`n"
ps_swname=-SwitchName $switch1
}
else
{
PS_switch.="$Switch" index "= '" sw "'`n"
ps_addswitches.="Add-VMNetworkAdapter -VMName $VMN -SwitchName $Switch" index "`n"
}
}
PS_dynText=$true
if (!PS_dynS)
PS_dynText= $false
ps_int_gast=Enable-VMIntegrationService -VMName $VMN -Name 'Gastdienstschnittstelle'
ps_extra=
(
$Bootorders=Get-VMFirmware -VMName $VMN
foreach($Bootorder in $Bootorders.BootOrder){
if($Bootorder.BootType -eq 'Drive'){
$FirstBootDevice=$Bootorder
}
}
Set-vmfirmware -VMName $VMN -FirstBootDevice $FirstBootDevice
)
ps_script=
(
$VMNames = '%ps_namelist%'
$Iso= '%PS_iso%'
$iso= $IsoDir + '\' + $iso
%PS_switch%
foreach($VMN in $VMNames) {
$myvhd=$VMN + '.vhdx'
New-VM $VMN -MemoryStartupBytes %PS_Ram%MB %ps_swname% -NewVHDPath $myvhd -NewVHDSizeBytes %PS_HD%GB -Generation %PS_Gen%
Set-VMMemory -VMName $VMN -DynamicMemoryEnabled %PS_dynText%
Enable-VMIntegrationService -VMName $VMN -Name 'Gastdienstschnittstelle'
)
if (PS_iso<>"")
{
ps_script .= "Add-VMDvdDrive -VMName $VMN –Path $iso`n"
ps_script .= ps_extra
}
;ps_script .= ps_addswitches . ps_extra . "}`n"
ps_script .= ps_addswitches . "}`n"
isodir=$IsoDir= '%A_scriptDir%'
if (addscript="")
ps_script := isodir . "`n" . addscript . "`n" . ps_script
else
ps_script := addscript . "`n" . ps_script
guicontrol, , powershell,%PS_script%
return
makeNewNames:
gui,submit, nohide
;msgbox, % prefix pcheck scheck
array := StrSplit(names , ",", " `t`n`r")
newnames:=""
for index, n in Array ; Recommended approach in most cases.
{
n:=trim(n)
if (index<>1)
newnames .= ","
if pcheck and scheck
newnames .= prefix n trennerS Format( "{1:02i}", index)
else if pcheck
newnames .= prefix n
else if scheck
newnames .= n trennerS Format( "{1:02i}", index)
else
newnames .= n
}
guicontrol, , NewNames,%newnames%
gosub, makePS
return
getIsoFolder:
folder :=""
FileSelectFolder, Folder, , 3
if (Folder ="")
return
Folder := RegExReplace(Folder, "\\$")
gosub getIsos
guicontrol,,PS_Iso,||%filelist%
return
getIsos:
if folder<>""
folder.="\"
FileList =
Loop, Files, %folder%*.iso
{
isoname:=A_LoopFileName
;isoname := a_index=1 ? isoName .="|" : isoName
FileList = %FileList%%isoname%|
}
;msgbox,% FileList
return
GuiEscape:
GuiClose:
ExitApp
RunWaitOne(command) {
; WshShell object: http://msdn.microsoft.com/en-us/library/aew9yb99
shell := ComObjCreate("WScript.Shell")
; Execute a single command via cmd.exe
exec := shell.Exec(ComSpec " /C " command )
; Read and return the command's output
return exec.StdOut.ReadAll()
}
; Do not edit above this line
Hatte vor einiger Zeit ein Gui-Script für so etwas geschrieben.
Es erzeugt den Powershellcode um mehrere VMs zu erzeugen.
Ich habe jetzt schon länger nicht mehr ausprobiert. Ist auch nicht der schönste Code.
Muss im Ordner mit den ISOs laufen.
Ich stelle es hier mal einfach so ein:[code]
full_command_line := DllCall("GetCommandLine", "str")
if not (A_IsAdmin or RegExMatch(full_command_line, " /restart(?!\S)"))
{
try
{
if A_IsCompiled
Run *RunAs "%A_ScriptFullPath%" /restart
else
Run *RunAs "%A_AhkPath%" /restart "%A_ScriptFullPath%"16
}
ExitApp
}
#NoEnv
#SingleInstance Force
SetWorkingDir %A_ScriptDir%
gosub, GetIsos
gosub, GetSwitches
Gui, Margin, 40, 30
Gui, Add, Tab3,x3 y3 vMyTab, Names|Powershell
Gui, Tab,1
Gui Add, Text, xp-20 ym , Erstellung eines PS-Scripts zur Erzeugung von mehreren VMs in Hyper-V. Im Order mit den Isos ablegen.
Gui, Add, GroupBox, xm-20 yp+40 w900 h300 section, Namen
Gui Add, Text, xm yp+25 w410 h27 +0x200 , Gib die gewünschten Namen der VMs (mit Komma getrennt) ein:
Gui Add, Edit, xm y+2 w860 r4 gMakeNewNames vnames, server,server
Gui Add, Edit, y+20 w100 r1 h32 vprefix gMakeNewNames
Gui Add, CheckBox, x+10 h23 vpcheck gMakeNewNames, Namens-Prefix zB. Fisi_ oder 01_..99_
Gui Add, Edit, x+20 w20 r1 h32 vTrennerS gMakeNewNames,
Gui Add, CheckBox, x+10 h23 vscheck gMakeNewNames, Nummerierung S_01 , S_02
Gui Add, Text, xm y+20 w410 h27 +0x200, neue Namen
Gui Add, Edit, xm y+2 w860 r4 vNewNames disabled ,
Gui, Add, GroupBox, xm-20 y+40 w900 h280 section, VM-Einstellungen
Gui Add, Text, xm ys+40 h23 +0x200, Auswahl der OS Iso Datei
Gui Add, DropDownList, xm y+2 w760 vPS_Iso gMakePS, ||%filelist%
Gui Add, Button, x+20 w80 h23 ggetIsoFolder, Iso-Dir
Gui Add, Text, xm y+20 w124 h32 +0x200, Switche:
Gui Add, DropDownList, xm y+2 w120 vPS_Switch1 gMakePS, unverbunden ||%switches%
Gui Add, DropDownList, x+10 w120 vPS_Switch2 gMakePS, unverbunden ||%switches%
Gui Add, DropDownList, x+10 w120 vPS_Switch3 gMakePS, unverbunden ||%switches%
Gui Add, Text, xm y+20 w61 h23 +0x200, Generation
Gui Add, DropDownList, x+2 w39 +0x200 gMakePS vPS_gen, 1|2||
Gui Add, ComboBox, xm y+20 w60 gMakePS vPS_Ram, 512|1024|2024|3024||6024
Gui Add, Text, x+5 w52 h23 +0x200 , MB Ram
Gui Add, CheckBox, x+20 h23 checked +0x200 gMakePS vPS_DynS, Dynamischer Speicher
Gui Add, Edit, x+20 w100 r1 vPS_HD gMakePS ,127
Gui Add, Text, x+5 h23 +0x200 , GB HD Grösse
Gui, Tab,2
Gui, Add, GroupBox, xm-20 y+40 w900 h500 section, Powershellbefehle
Gui Add, Text, xm yp+20 h32 +0x200 section, Powershell:
Gui Add, Edit, xm y+2 w750 h420 vpowershell
Gui Add, Button, x+20 ys+40 w80 h23 gcopy, Copy
Gui Add, Button, xp ys+80 w80 h23 gsave, Save
Gui Add, Button, xp ys+120 w80 h23 grun, Run
Gui Add, Button, xp ys+160 w80 h23 gtestVHDExist, VHD exist?
Gui Add, Button, xp ys200 w80 h23 gadd, Add some more
Gui Show, , make PS-Script for new VMs in Hyper-v
Return
testVHDExist:
t:=""
GetallVhds="& {Get-VM | select VMID | Get-VHD | ? Path -like "C:\Users\Public\*" | select Path }"
vhdFilelist:=RunWaitOne("powershell.exe -Command " GetallVhds )
Loop, Parse, newnames, `,
if InStr(vhdFilelist, A_LoopField ".vhd")
t.= A_LoopField ".vhd existiert bereits!`n"
else
t.= A_LoopField ".vhd OK`n"
msgbox, % t
return
add:
gui,submit, nohide
addscript :=powershell
guicontrol,,names
GuiControl,choose, MyTab, Names|Powershell
;msgbox, %powershell%
return
copy:
clipboard:=powershell
return
save:
FileSelectFile, savehere , S24, %A_WorkingDir%\MakeVMs.ps1, Prompt, Scriptfiles (*.ps1;*.ahk;*.txt;*.*)
fileappend, %powershell%, %savehere%
return
run:
gui,submit, nohide
;msgbox, % powershell
RunWait *runas PowerShell.exe -Command &{%powershell%} ,,hide
;RunWait *runas PowerShell.exe -NoExit -Command &{%powershell%}
;,, hide
return
getswitches:
gui,submit, nohide
t:=""
i:=0
switches:=RunWaitOne(" powershell -windowstyle hidden -command GET-VMSwitch ")
switches := StrReplace(switches, " Internal ", " (Internal) ")
switches := StrReplace(switches, " External ", " (External) ")
switches := StrReplace(switches, " Private ", " (Private) ")
Loop, parse, switches, `n, `r
{
if InStr(A_LoopField, " (Internal) ") or InStr(A_LoopField, " (External) ") or InStr(A_LoopField, " (Private) ")
{
;i++
s .= SubStr(A_LoopField, 1 , InStr(A_LoopField, ")")) "|"
;s := ++i=1 ? s .="||" : s .="|"
}
}
loop, 3
switches := StrReplace(s, " ", " ")
return
makePS:
gui,submit, nohide
ps_namelist:=StrReplace(newnames, "," , "','")
PS_switch1 :=trim(SubStr(PS_switch1, 1 , InStr(PS_switch1, "(")-1))
PS_switch2 :=trim(SubStr(PS_switch2, 1 , InStr(PS_switch2, "(")-1))
PS_switch3 :=trim(SubStr(PS_switch3, 1 , InStr(PS_switch3, "(")-1))
PS_switchStr:=""
loop,3
if !instr(PS_switch%a_index%, "unverbunden")
PS_switchStr .= PS_switch%a_index% ","
PS_switchStr:=RTrim(trim(PS_switchStr),",")
SW_array:=""
SW_array := StrSplit(PS_switchStr , ",", " `t`n`r")
PS_switch:=""
ps_addswitches:=""
for index, sw in SW_array ; Recommended approach in most cases.
{
if (index=1)
{
PS_switch:="$Switch1= '" sw "'`n"
ps_swname=-SwitchName $switch1
}
else
{
PS_switch.="$Switch" index "= '" sw "'`n"
ps_addswitches.="Add-VMNetworkAdapter -VMName $VMN -SwitchName $Switch" index "`n"
}
}
PS_dynText=$true
if (!PS_dynS)
PS_dynText= $false
ps_int_gast=Enable-VMIntegrationService -VMName $VMN -Name 'Gastdienstschnittstelle'
ps_extra=
(
$Bootorders=Get-VMFirmware -VMName $VMN
foreach($Bootorder in $Bootorders.BootOrder){
if($Bootorder.BootType -eq 'Drive'){
$FirstBootDevice=$Bootorder
}
}
Set-vmfirmware -VMName $VMN -FirstBootDevice $FirstBootDevice
)
ps_script=
(
$VMNames = '%ps_namelist%'
$Iso= '%PS_iso%'
$iso= $IsoDir + '\' + $iso
%PS_switch%
foreach($VMN in $VMNames) {
$myvhd=$VMN + '.vhdx'
New-VM $VMN -MemoryStartupBytes %PS_Ram%MB %ps_swname% -NewVHDPath $myvhd -NewVHDSizeBytes %PS_HD%GB -Generation %PS_Gen%
Set-VMMemory -VMName $VMN -DynamicMemoryEnabled %PS_dynText%
Enable-VMIntegrationService -VMName $VMN -Name 'Gastdienstschnittstelle'
)
if (PS_iso<>"")
{
ps_script .= "Add-VMDvdDrive -VMName $VMN –Path $iso`n"
ps_script .= ps_extra
}
;ps_script .= ps_addswitches . ps_extra . "}`n"
ps_script .= ps_addswitches . "}`n"
isodir=$IsoDir= '%A_scriptDir%'
if (addscript="")
ps_script := isodir . "`n" . addscript . "`n" . ps_script
else
ps_script := addscript . "`n" . ps_script
guicontrol, , powershell,%PS_script%
return
makeNewNames:
gui,submit, nohide
;msgbox, % prefix pcheck scheck
array := StrSplit(names , ",", " `t`n`r")
newnames:=""
for index, n in Array ; Recommended approach in most cases.
{
n:=trim(n)
if (index<>1)
newnames .= ","
if pcheck and scheck
newnames .= prefix n trennerS Format( "{1:02i}", index)
else if pcheck
newnames .= prefix n
else if scheck
newnames .= n trennerS Format( "{1:02i}", index)
else
newnames .= n
}
guicontrol, , NewNames,%newnames%
gosub, makePS
return
getIsoFolder:
folder :=""
FileSelectFolder, Folder, , 3
if (Folder ="")
return
Folder := RegExReplace(Folder, "\\$")
gosub getIsos
guicontrol,,PS_Iso,||%filelist%
return
getIsos:
if folder<>""
folder.="\"
FileList =
Loop, Files, %folder%*.iso
{
isoname:=A_LoopFileName
;isoname := a_index=1 ? isoName .="|" : isoName
FileList = %FileList%%isoname%|
}
;msgbox,% FileList
return
GuiEscape:
GuiClose:
ExitApp
RunWaitOne(command) {
; WshShell object: http://msdn.microsoft.com/en-us/library/aew9yb99
shell := ComObjCreate("WScript.Shell")
; Execute a single command via cmd.exe
exec := shell.Exec(ComSpec " /C " command )
; Read and return the command's output
return exec.StdOut.ReadAll()
}
; Do not edit above this line[/code]