VMware Cloud Community
andypocock
Contributor
Contributor
Jump to solution

help with loop construct to run a script against multiple VCs required

I have a script that I use for capacity management which I want to run once against multiple VCs and I cannot get the script to loop and append one output csv file for multiple VCs

Example of how I am, failing, to do it:

$Clusters = Get-Cluster |Sort Name

$VCs = "vcserver1.domain.com", "vcserver2.domain.com"

### Capacity report array to hold output

$Capreport = @()

foreach($VC in $VCs){

Connect-VIServer $VC

Foreach

($Cluster in $Clusters){

### Error trap with continue

trap

{

write-host "Error but I will continue" -fore red

continue

}

$ESXhosts = $cluster | get-vmhost

$firstESXhosts = $ESXhosts[0]

$HardwareSpec = $firstESXhosts | Get-View

$ServerVendor = $HardwareSpec.Hardware.SystemInfo.Vendor

$serverModel = $HardwareSpec.Hardware.SystemInfo.Model

$ServerNumCores = $HardwareSpec.Hardware.CpuInfo.NumCpuCores

$CLTotalNumCores = $ServerNumCores * $ESXhosts.count

etc, etc...

the script then outputs to a CSV file:

$column = "" | Select Cluster, HostModel, etc, etc...

$column.Cluster = $Cluster.Name

$column.HostModel = $ServerModel # $ServerVendor " "

etc, etc...

$Capreport += $column

I can get this to work fine if i connect to one VC server at a time, but would like to get this connecting to a VC and creating the report, then connecting to another VC and appending to this report.

Thanks in advance.

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Your script has to use 2 nested foreach loops, one accross all the VCs and the innner one accross all the clusters for a specific VC.

The report array $CapReport is initialised outside the loops and you add an element for each cluster in the inner loop.

Something like this

$VCs = "BP1XGBAP027.bp1.ad.bp.com", "BP1XGBAP029.bp1.ad.bp.com" 
#
## Capacity report array to hold output
$Capreport = @()

foreach
($VC in $VCs){
   
Connect-VIServer $VC   
    $Clusters
= Get-Cluster |Sort Name
   
foreach    ($Cluster in $Clusters){
       
trap        {
           
write-host "Error but I will continue" -fore red
           
continue
        }

       
$ESXhosts = $cluster | get-vmhost
        $firstESXhosts = $ESXhosts[0]
       
$HardwareSpec = $firstESXhosts | Get-View
       
$ServerVendor = $HardwareSpec.Hardware.SystemInfo.Vendor
       
$serverModel = $HardwareSpec.Hardware.SystemInfo.Model
       
$ServerNumCores = $HardwareSpec.Hardware.CpuInfo.NumCpuCores
       
$CLTotalNumCores = $ServerNumCores * $ESXhosts.count
       
# ....
        $column = "" | Select Cluster, HostModel, etc, etc...
       
$column.Cluster = $Cluster.Name
        $column.HostModel = $ServerModel # $ServerVendor " "         etc, etc...
        # ....


        $Capreport += $column
   }

   Disconnect-VIServer -Confirm:$false    

}


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

View solution in original post

0 Kudos
4 Replies
LucD
Leadership
Leadership
Jump to solution

Your script has to use 2 nested foreach loops, one accross all the VCs and the innner one accross all the clusters for a specific VC.

The report array $CapReport is initialised outside the loops and you add an element for each cluster in the inner loop.

Something like this

$VCs = "BP1XGBAP027.bp1.ad.bp.com", "BP1XGBAP029.bp1.ad.bp.com" 
#
## Capacity report array to hold output
$Capreport = @()

foreach
($VC in $VCs){
   
Connect-VIServer $VC   
    $Clusters
= Get-Cluster |Sort Name
   
foreach    ($Cluster in $Clusters){
       
trap        {
           
write-host "Error but I will continue" -fore red
           
continue
        }

       
$ESXhosts = $cluster | get-vmhost
        $firstESXhosts = $ESXhosts[0]
       
$HardwareSpec = $firstESXhosts | Get-View
       
$ServerVendor = $HardwareSpec.Hardware.SystemInfo.Vendor
       
$serverModel = $HardwareSpec.Hardware.SystemInfo.Model
       
$ServerNumCores = $HardwareSpec.Hardware.CpuInfo.NumCpuCores
       
$CLTotalNumCores = $ServerNumCores * $ESXhosts.count
       
# ....
        $column = "" | Select Cluster, HostModel, etc, etc...
       
$column.Cluster = $Cluster.Name
        $column.HostModel = $ServerModel # $ServerVendor " "         etc, etc...
        # ....


        $Capreport += $column
   }

   Disconnect-VIServer -Confirm:$false    

}


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

0 Kudos
avlieshout
VMware Employee
VMware Employee
Jump to solution

you can connect to multiple vCenter servers and run your command against both.

For this you need to have your server mode set to "Multiple"

Check with:

Get-PowerCLIConfiguration

Set with:

Set-PowerCLIConfiguration -DefaultVIServerMode "Multiple"

You can connect to both VIserver is one command:

Connect-VIserver $VCs

Now after connecting just run the script as if you were running against one server and information from both servers will be retrieved.

Arnim van Lieshout

Now available for pre-order: VMware vSphere PowerCLI Reference: Automating vSphere Administration

Arnim van Lieshout Blogging: http://www.van-lieshout.com Twitter: http://www.twitter.com/avlieshout If you find this information useful, please award points for "correct" or "helpful".
0 Kudos
andypocock
Contributor
Contributor
Jump to solution

Thanks Luc, I had moved the nested loop around but had never included the disconnect-visever cmdlet - which seems stupid seeing how logical the requirement for it is.

Appreciated - thank you

0 Kudos
andypocock
Contributor
Contributor
Jump to solution

Thanks Arnim, this is new to me too and I will give it a try as it seems a configurably simple way to get the same result as the correct loop nesting and disconnect-viserver cmdlet Luc answered with.

Thansk Andy

0 Kudos