VMware Cloud Community
Avshalom2k
Contributor
Contributor
Jump to solution

New-VM automation in the Background (as Task, or Job)

hello guy's

Need you help again...

I'm trying to automate creation of vm's. but to do it in the background, i played with the Wait-Task cmdlet and the Start-Job, but did not success to make it work,

The script change a customization spec, create new vm, set-vm with cpu/memory settings, update hot-plug/hot-add settings and power-on the vm, looks like that:

Get-OSCustomizationSpec $NewVM_OSCustomizationSpec |
Get-OSCustomizationNicMapping |
Set-OSCustomizationNicMapping -IpMode:"UseStaticIP" -IpAddress $NewVM_Ipaddress `
-SubnetMask $NewVM_SubnetMask -DefaultGateway $NewVM_Gateway `
-Dns $DNS
 
$NewVM_OSCustomizationSpec -FullName $NewVM_ServerName
New-VM -Name $NewVM_ServerName -Template $NewVM_Template `
-VMHost $NewVM_ESXHost -Datastore $NewVM_Datastore `
-OSCustomizationSpec $NewVM_OSCustomizationSpec -Location $NewVM_Folder #-RunAsync

Set-VM -VM $NewVM_ServerName -NumCpu $NewVM_CPU -MemoryMB $NewVM_RAM -Confirm:$false

$VM = Get-VM $NewVM_ServerName
$Spec = New-Object VMware.Vim.VirtualMachineConfigSpec
$Spec.memoryHotAddEnabled = $true
$Spec.cpuHotAddEnabled = $true
$Spec.NumCoresPerSocket = 1
$VM.ExtensionData.ReconfigVM_Task($spec)
Start-VM $VM

my problem is that if i start the set-vm before the new-vm task is completed, of course it's not working, i need to set up the tasks to work one by one, after wait for each task to complete before start the new task, but to it all in the background,

please help me if you can,.

Thanks a lot, i appreciate any help

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

I suspect the background job could be waiting for something.

Try disabling the Warnings to start with, add the following line at the top of your Start-Job script block.

$WarningPreference = "SilentlyContinue"

Btw, did you give up on the RunAsync ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
12 Replies
LucD
Leadership
Leadership
Jump to solution

It seems you did try the RunAsync switch (although it is commented out now).

The New-VM returns a Task object when you run it with the RunAsync switch.

With that Task object you can use the Wait-Task cmdlet, see about_runasync for more info and some examples.

Did you try it that way ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Avshalom2k
Contributor
Contributor
Jump to solution

Thanks LucD, you're the man...

Well, that's right the runasync do the job for the New-VM but the next command Set-VM, keep running and generate error because the vm is not yet ready, still in the cloning process....

I want to set all the tasks to run in the background, but in one by one order,wait for each task to complete before start the new task,

Is that possible?

Thanks for your help

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Did you try the Wait-Task cmdlet between the New-VM and the Start-VM ?

$task = New-VM .... -RunAsync

Wait-Task -Task $task

Start-VM ....


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Avshalom2k
Contributor
Contributor
Jump to solution

But what about the Set-VM cmdlet?

Where all the other tasks goes in?

1. New-VM takes 5 minutes clone

2. Only after it finish i can run the Set-VM

The thing is that i don't want to wait in the console for the new-vm to complete, i want it will be run in the background and when the New-VM finish the Set-VM will start automatically and then the rest of the script....

if i don't understand you well, can you please copy/paste the script so i will understand better.

Thanks for your effort

0 Kudos
LucD
Leadership
Leadership
Jump to solution

You can collect all the Task objects in an array.

Then when all your New-VM are submitted, you have 2 options.

Look at each entry individually and check if the task is finished, if it is, do a Start-VM for that specific VM.

The name of the VM can be found in the Result property of the Task object.

Something like this

$tasks = @()

ForEach(...){

   ...

   $tasks += New-VM ... -RunAsync

}

Wait-Task -Task $tasks

$tasks | %{

   Get-VM -Name $_.Result | Start-VM

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Avshalom2k
Contributor
Contributor
Jump to solution

Thanks LucD,

but can you please make it easier for me, i understand the concept but not practically,

Can you put 2 cmdlets like the New-VM and Set-VM in the example so i can more easilly understand?

0 Kudos
Avshalom2k
Contributor
Contributor
Jump to solution

??

0 Kudos
LucD
Leadership
Leadership
Jump to solution

I would do the Set-VM just before the Start-VM

$tasks = @()

ForEach(...){

   ...

   $tasks += New-VM ... -RunAsync

}

Wait-Task -Task $tasks

$tasks | %{

   $vm = Get-VM -Name $_.Result

   Set-VM -VM $vm

   Start-VM -VM $vm

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Avshalom2k
Contributor
Contributor
Jump to solution

Thanks LucD,

I appreciate your help and patience,

but i'm woking on it all the day and no success, it's really #%@#@#$@#$

please if you or anybody else, can help me just like for a dummy,

i don't need to create multiple vm's, just one vm, and then change a setting on it.. ram/cpu etc...

i want to do all in the background so the console is free, because i do it from a GUI form and don't want to stuck the application...

i tried with Start-Job, but i can only do the first part - create the VM but the settings later just don't work- here what i tried...

$jobVM=Start-Job -Name "New-VM" -ScriptBlock {

Add-PSSnapin Vmware*

Connect-VIServer vcenter | Out-Null

$Global:Task=New-VM -Name Test99VM

-Template XP32 `

-VMHost ESX8 -Datastore VNX `

-Location DisabledServers -RunAsync

While ($Global:Task.State -eq "Running") {Sleep 1}

Set-VM -VM Test99VM -NumCpu 2 -MemoryMB 8072 -Confirm:$false

}

IT'S NOT WORKING !!!

the job stay in 'running' mode, and the second part Set-VM not working...

Also with Wait-Task $task (inside the Start-Job)it's not working

if you know different way, whatever you like, if it works it's good for me....

1. Create VM

2. Change VM settings

3. Start VM

All to run in the background, one after one,

Please Please, Wait for your help....

0 Kudos
LucD
Leadership
Leadership
Jump to solution

I suspect the background job could be waiting for something.

Try disabling the Warnings to start with, add the following line at the top of your Start-Job script block.

$WarningPreference = "SilentlyContinue"

Btw, did you give up on the RunAsync ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Avshalom2k
Contributor
Contributor
Jump to solution

LucD,

Thanks man

The $WarningPreference = "SilentlyContinue" did the trick, you are the man as i said!!!

i didn't give up the -RunAsync but it's not working for me, maybe somthing with this line is wrong:

While ($Global:Task.State -eq "Running") {Sleep 1}


thanks man, appreciate your help

all the best

0 Kudos
LucD
Leadership
Leadership
Jump to solution

That where-clause looks ok, but I would need to see the complete script to check.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos