VMware Cloud Community
tdubb123
Expert
Expert

need a jobs script to modify large # vms

any examples on how to modifying advance settings on vms using powercli jobs? instead of using foreach loop?

0 Kudos
7 Replies
LucD
Leadership
Leadership

What exactly do you need?


The script would need the Start-Job cmdlet, and in the background job you would use the Set-AdvancedSetting cmdlet.

There is a template for using Start-Job with PowerCLI scripts in my Running a background job post.


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

0 Kudos
tdubb123
Expert
Expert

I have the script that does new-advancedsetting

foreach ($vm in $vms) {

get-vm $vm | new-advancedsettings

}

I need to do it faster than just a foreach loop one at a time is too long

0 Kudos
sjesse
Leadership
Leadership

Thats what the start-job part does, starts a background job that does the modification, so your modifying multiple a time instead of just one at a time without using it.

0 Kudos
LucD
Leadership
Leadership

When you do a background job per VM, you will not see an enormous speed improvement.
Remember that setting up and starting a background job also requires time and resources.

You could consider starting for example 1 background job per 5 or 10 VMs.


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

0 Kudos
LucD
Leadership
Leadership

Have a look at the following example.

It takes 12 VMs and submits background jobs, where each background job handles 5 VMs.

$code = {

   param(

     [string]$Server,

     [string]$SessionId,

     [string]$Name,

     [PSOBject]$Value,

     [string[]]$VMNames

   )

   Set-PowerCLIConfiguration -DisplayDeprecationWarnings $false -Confirm:$false | Out-Null

   Connect-VIServer -Server $Server -Session $SessionId | Out-Null

   Get-VM -Name $VMNames | New-AdvancedSetting -Name $Name -Value $Value -Confirm:$false

}


$vms = 'VM1','VM2','VM3','VM4','VM5','VM6','VM7','VM8','VM9','VM10','VM11','VM12'


$advancedSettingName = 'softPowerOff'

$advancedSettingValue = 'FALSE'

$vmPerJob = 5

$nrJobs = $vms.Count % $vmPerJob


$jobs = @()


0..$nrJobs |

ForEach-Object -Process {

   $sJOb = @{

     ScriptBlock = $code

     ArgumentList = $global:DefaultVIServer.Name, $global:DefaultVIServer.SessionId,

       $advancedSettingName,

       $advancedSettingValue,

       $vms[($_ * $vmPerJob)..[math]::Min((($_ + 1) * $vmPerJob) - 1,($vms.Count - 1))]

     }

   $jobs += Start-Job @sJob

}


Receive-Job -Job $jobs -Wait


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

0 Kudos
tdubb123
Expert
Expert

Thanks

for the $code block. Do i have to put my script there or can i specify a ps1 file?

is there a limit on how many to run

0 Kudos
LucD
Leadership
Leadership

Yes, the $code variable should contain a codeblock with your script.

Just make sure the also pass the name of the VCSA and the SessionId.

If you want to store that in a .ps1 file, you could read the that .ps1 file into the $code variable.

$code = [scriptblock]::Create((Get-Content -Path .\yourscript.ps1 | Out-String))

The available resources on the station where you run this, determine how many you should be able to run in parallel.


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

0 Kudos