VMware Cloud Community
madpro
Enthusiast
Enthusiast

Running commands on multiple machines from a csv

Hi there

I have a list of VMs in a .csv file which I want to update Tools on.

I think I have the basis of the script correct, but what I need help with is I want to do just one machine at a time.

So, all machines are off so I will power them on, update tools, then power them off, one by one.

Anybody help?

Thanks

Reply
0 Kudos
6 Replies
aerodevil
Hot Shot
Hot Shot

By default most of your PowerCLI scripts will run synchronously.  If you'd like to post your script then we can take a look to make sure you are getting your intended behavior.

My guess is you're doing something along these lines:

$vms = Import-CSV "C:\Path\VMsFile.csv"

$vms | %{

$vm = Get-VM -Name $_.<VMcolumnheader>

Start-VM $vm
Update-Tools -VM $vm -NoReboot
Shutdown-VMGuest -VM $vm

}

This sound about right?

Josh Atwell @Josh_Atwell http://www.vtesseract.com http://github.com/joshatwell/
madpro
Enthusiast
Enthusiast

Hi Josh

Thanks for the quick reply!

That is roughly what I am doing, the VM situation makes this slightly different on my side

What I need to do is make VM persistent, then power up, update tools with a reboot, shutdown then make non-persistent

So, what i'm doing is importing the csv

$vms= Import-Csv "C:\UpdateTools\VMs.csv"

Then for each part

foreach

($obj in $vms){

Get-VM $obj.vm | Get-HardDisk | Set-HardDisk –Persistence IndependentPersistent

}

Now what I want is for each VM to go through the full process individually, one at a time

Is this possible?

Reply
0 Kudos
madpro
Enthusiast
Enthusiast

I've just thought, by doing this part

%{
$vm = Get-VM -Name $_.<VMcolumnheader>

does this mean it goes through each of the next steps on each VM in the list one at a time?

Reply
0 Kudos
aerodevil
Hot Shot
Hot Shot

That is correct.  using foreach will go through each vm listed one at a time.

what you did is pretty much the same.  % = foreach

the only difference that i've ever seen is that you use % in the pipeline whereas "foreach(){}" would be used on a separate line.

Keep in mind that when doing Import-CSV it will look at the first line as a header (unless you specify differently with -Header) so you'll want to make sure you reference it properly.

CSV File

VM, Owner, CPU

test01, Yogi, 4

test02, BooBoo, 2

Your Code

foreach

($obj in $vms){

Get-VM $obj.VM | Get-HardDisk | Set-HardDisk –Persistence IndependentPersistent

}

$obj.VM would be "test01" on the first pass then "test02" and so on...

Just make sure that $obj.XXX matches the header that you want and you should be good to go!

Josh Atwell @Josh_Atwell http://www.vtesseract.com http://github.com/joshatwell/
madpro
Enthusiast
Enthusiast

Thanks Josh

This has been very helpful!

One last question

Do I need to put any pauses in anywhere? For instance each VM will vary in the time it takes to start up, so should I put a wait-task in between the start-vm and update-tools, or does powercli wait till the machine is powered up until updating tools?

Reply
0 Kudos
mattboren
Expert
Expert

Hello, madpro-

Yes, you would need to wait for the VM to be up (and for VMware Tools to be running in it).  Otherwise, you would get an error like "Cannot complete operation because VMware Tools is not running in this virtual machine."

The timing issue is always a bit tricky.  One way to try to handle it would be to to add some hard-coded pauses, but that is not very scientific.  The way to do it would be to use the Wait-Tools cmdlet.  So, the snippet of code would be something like:

...
$vm = Get-VM -Name $_.<VMcolumnheader>
Start-VM $vm
## wait for VMware Tools to be running
Wait-Tools $vm -TimeoutSeconds 300
Update-Tools -VM $vm -NoReboot
...

You can adjust the timeout to a value of your liking, of course.  Enjoy.

Reply
0 Kudos