1

I have a problem where I need to clone one virtual machine into several machines for production. The machines have names that is assigned by variables and a rdp port is also assigned by a variable. Both variables is increased by 1 at the end of the script. The problem I have is that I can't figure out how to loop the create machine and increase variable value code until the %M% value is at a defined number.

Here is my current code:

SET VBoxManage="C:\Program Files\Oracle\VirtualBox\VBoxManage.exe"
SET M=1
SET P=25553

if %%M < 4 (

%VBoxManage% clonevm Win2012 --mode all --name M%M% --register
%VBoxManage% modifyvm M%M% --vrde on --vrdeauthtype null --vrdemulticon on --vrdeport %P%
SET /A M=%M%+1
SET /A P=%P%+1

ECHO Done
ECHO %M%
ECHO %P%
)

ECHO All cloning finished.

pause

I have tried with FOR, IF and WHILE but I can't figure out how to get it to work.

How FOR did look like:

SET VBoxManage="C:\Program Files\Oracle\VirtualBox\VBoxManage.exe"
SET M=1
SET P=25553

FOR /L (if %%M IN (1,1,5)
(
%VBoxManage% clonevm Win2012 --mode all --name M%M% --register
%VBoxManage% modifyvm M%M% --vrde on --vrdeauthtype null --vrdemulticon on --vrdeport %P%
SET /A M=%M%+1
SET /A P=%P%+1

ECHO Done
ECHO %M%
ECHO %P%
)

ECHO All cloning finished.

pause
HopelessN00b
  • 53,795
  • 33
  • 135
  • 209
Dempa
  • 143
  • 1
  • 2
  • 9
  • I see no loop here, only a conditional `if %%M < 4`, which isn't valid syntax regardless. `WHILE` isn't valid at all. What did your `FOR` block look like? You can edit your question to update it. – jscott Feb 23 '15 at 11:01
  • I added how the FOR block looked like. Also, I am a bit lost in the batch scripting world. – Dempa Feb 23 '15 at 11:11

2 Answers2

3

I think you just need to review the FOR /? help a bit. You've mixed a couple different things together which won't work. The cmd interpreter is limited compared to other scripting environments you may be familiar with.

I think all you're asking is "How do I use FOR in a batch file to count from 1 to 5 in increments of 1?" And that's simple enough:

FOR /L %%M IN (1, 1, 5) DO (
    ECHO %%M
)

The second part of your question is about incrementing another variable within the FOR loop. For that, you'll want to lookup SETLOCAL EnableDelayedExpansion. Here's an example using your provided script.

@ECHO OFF
SETLOCAL EnableDelayedExpansion
SET VBoxManage="C:\Program Files\Oracle\VirtualBox\VBoxManage.exe"
SET P=25553

FOR /L %%M IN (1, 1, 5) DO (
    %VBoxManage% clonevm Win2012 --mode all --name M%%M --register
    %VBoxManage% modifyvm M%%M --vrde on --vrdeauthtype null --vrdemulticon on --vrdeport !P!
    SET /A P=P + 1

    ECHO Done
    ECHO %%M
    ECHO !P!
)

ECHO All cloning finished.
PAUSE
jscott
  • 24,484
  • 8
  • 79
  • 100
  • Ok, it looks like it is working now but I just wonder if the `SETLOCAL EnableDelayedExpansion` is needed to get this to work since it's only numerical values. – Dempa Feb 23 '15 at 14:59
  • @Dempa I believe `EnableDelayedExpansion` is needed when using `SET` within `FOR`. You're of course welcome to post your own solution, or edit mine to correct me. http://www.robvanderwoude.com/variableexpansion.php – jscott Feb 24 '15 at 11:08
  • I've did try to skip using `SETLOCAL EnableDelayedExpansion` but it didn't work. I also did some further testing to get an better understanding of batch and the `FOR`. From what I can see is the `SETLOCAL EnableDelayedExpansion` needed if a value is going to be both changed and used. Thanks for the help! – Dempa Feb 24 '15 at 17:54
2

To flee of EnableDelayedExpansion you could try next approach with a procedure call:

@ECHO OFF >NUL
setlocal
SET "VBoxManage=C:\Program Files\Oracle\VirtualBox\VBoxManage.exe"
SET /A "P=25553"

FOR /L %%M IN (1,1,5) Do call :treat %%M

ECHO All cloning finished.
pause

endlocal
goto :eof

:treat
rem next two operational commands are ECHO-ed for debugging purposes
echo "%VBoxManage%" clonevm Win2012 --mode all --name M%~1 --register
echo "%VBoxManage%" modifyvm M%~1 --vrde on --vrdeauthtype null --vrdemulticon on --vrdeport %P%

ECHO Done M=%~1 P=%P%
SET /A "P+=1"
goto :eof

Next source (FOR) and SET

JosefZ
  • 1,564
  • 1
  • 10
  • 18