VMware Cloud Community
EdZ
Contributor
Contributor
Jump to solution

Problems with variables on PowerCLI script

Hello,

I'm hoping someone in the community can tell me where I went wrong in the script below. I have some other PowerCLI scripts which work in a similar way to this one, and those work, but this one has a problem. The script is intended to collect information on a number of ESX objects into an array of arrays, $reportfinal, which can then be written out to a CSV file which will have column names for the objects and each row will report the values for RDM related objects for each VM. The problem is that instead of appending the results into the $reportfinal array, the results are overwritten, and even worse, values repeat themselves (e.g. the size of different disks is reported as the same value).

$report = @()

$reportfinal = @()

$VMs = Get-VMHost | Get-VM | Get-View

$rowcoll = "" | select VM, VMController, SCSIBusShare, SCSIBusNumber, SCSIUnitNo, DeviceLabel, SCSISummary, DeviceFilename, DeviceCapKB, DeviceDiskMode,DeviceDiskUUID

ForEach ($VM in $VMs) {

#Clear report array for each VM

$report=@()

Foreach ($SCSI_Controller in ($VM.Config.Hardware.Device | where {$_.DeviceInfo.Label -like "SCSI*" } )) {

$rowcoll.VM = $VM.Name

$rowcoll.VMController = $SCSI_Controller.DeviceInfo.Label

Foreach ($Disk_Key in $SCSI_Controller.Device) {

Foreach ($Disk_Device in ($VM.Config.Hardware.Device | where {$_.key -eq $Disk_Key } )) {

$rowcoll.SCSIBusShare = $SCSI_Controller.SharedBus

$rowcoll.SCSIBusNumber = $SCSI_Controller.BusNumber

$rowcoll.SCSIUnitNo = $Disk_Device.UnitNumber

$rowcoll.DeviceLabel = $Disk_Device.DeviceInfo.Label

$rowcoll.SCSISummary = $SCSI_Controller.DeviceInfo.Summary

$rowcoll.DeviceFilename = $Disk_Device.Backing.Filename

$rowcoll.DeviceCapKB = $Disk_Device.CapacityInKB

$rowcoll.DeviceDiskMode = $Disk_Device.Backing.DiskMode

$rowcoll.DeviceDiskUUID = $Disk_Device.Backing.UUID

}

}

}

#Append the next collection of row data to the report

$report += $rowcoll

#Append the next collection of report data to the final report

$reportfinal += $report

}

$reportfinal | Export-Csv -path D:\temp\SAP_Report_Disks_RDM_Mappings.csv -NoTypeInformation

Note: Some parts of the script were derived from another posting on this forum regarding a script to list RDM information for a list of VM's.

Cheers,

Ed

Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

My mistake, I deleted the wrong $report line.

Try this one

$reportfinal = @()

$VMs = Get-View -ViewType VirtualMachine


foreach ($VM in $VMs) {

	#Clear report array for each VM

	foreach ($SCSI_Controller in ($VM.Config.Hardware.Device | where {$_.DeviceInfo.Label -like "SCSI*" } )) {

		foreach ($Disk_Key in $SCSI_Controller.Device) {
			foreach ($Disk_Device in ($VM.Config.Hardware.Device | where {$_.key -eq $Disk_Key } )) {
				$rowcoll = "" | select VM, VMController, SCSIBusShare, SCSIBusNumber, SCSIUnitNo, DeviceLabel, SCSISummary, DeviceFilename, DeviceCapKB, DeviceDiskMode,DeviceDiskUUID
		        $rowcoll.VM = $VM.Name
		        $rowcoll.VMController = $SCSI_Controller.DeviceInfo.Label
				$rowcoll.SCSIBusShare = $SCSI_Controller.SharedBus
				$rowcoll.SCSIBusNumber = $SCSI_Controller.BusNumber
				$rowcoll.SCSIUnitNo = $Disk_Device.UnitNumber
				$rowcoll.DeviceLabel = $Disk_Device.DeviceInfo.Label
				$rowcoll.SCSISummary = $SCSI_Controller.DeviceInfo.Summary
				$rowcoll.DeviceFilename = $Disk_Device.Backing.Filename
				$rowcoll.DeviceCapKB = $Disk_Device.CapacityInKB
				$rowcoll.DeviceDiskMode = $Disk_Device.Backing.DiskMode
				$rowcoll.DeviceDiskUUID = $Disk_Device.Backing.UUID
				$reportfinal += $rowcoll
			}
		}
	}

}

$reportfinal | Export-Csv -path C:\SAP_Report_Disks_RDM_Mappings.csv -NoTypeInformation


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

View solution in original post

Reply
0 Kudos
4 Replies
LucD
Leadership
Leadership
Jump to solution

The basic problem is that you create the variable $rowcoll outside the loop.

The array $reportfinal will contain the correct number of rows but they will point to the same $rowcoll variable which will contain the values for the last VM in your loop.

Some other remarks, not really problems but they can be optimised

1) In the line where you get all the VMs there is no need to do a Get-VmHost first

2) since you need the VirtualMachine object you could go immediately for the Get-View -ViewType VirtualMachine cmdlet

3) there is no need to have a $report per VM that you than add to the final $reportfinal

The adapted script


$report = @()
$reportfinal = @()

$VMs = Get-View -ViewType VirtualMachine


foreach ($VM in $VMs) {

	#Clear report array for each VM

	foreach ($SCSI_Controller in ($VM.Config.Hardware.Device | where {$_.DeviceInfo.Label -like "SCSI*" } )) {

		foreach ($Disk_Key in $SCSI_Controller.Device) {
			foreach ($Disk_Device in ($VM.Config.Hardware.Device | where {$_.key -eq $Disk_Key } )) {
				$rowcoll = "" | select VM, VMController, SCSIBusShare, SCSIBusNumber, SCSIUnitNo, DeviceLabel, SCSISummary, DeviceFilename, DeviceCapKB, DeviceDiskMode,DeviceDiskUUID
		                $rowcoll.VM = $VM.Name
		                $rowcoll.VMController = $SCSI_Controller.DeviceInfo.Label
				$rowcoll.SCSIBusShare = $SCSI_Controller.SharedBus
				$rowcoll.SCSIBusNumber = $SCSI_Controller.BusNumber
				$rowcoll.SCSIUnitNo = $Disk_Device.UnitNumber
				$rowcoll.DeviceLabel = $Disk_Device.DeviceInfo.Label
				$rowcoll.SCSISummary = $SCSI_Controller.DeviceInfo.Summary
				$rowcoll.DeviceFilename = $Disk_Device.Backing.Filename
				$rowcoll.DeviceCapKB = $Disk_Device.CapacityInKB
				$rowcoll.DeviceDiskMode = $Disk_Device.Backing.DiskMode
				$rowcoll.DeviceDiskUUID = $Disk_Device.Backing.UUID

			}
		}
	}

#Append the next collection of report data to the final report
	$reportfinal += $rowcoll

}

$reportfinal | Export-Csv -path C:\SAP_Report_Disks_RDM_Mappings.csv -NoTypeInformation

PS: the name of your CSV file doesn't really reflect what is in there. The script doesn't really filter out RDM disks.


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

EdZ
Contributor
Contributor
Jump to solution

Thanks Luc - Those are all very helpful observations. I will apply them to my next revision of the script. In the meantime, however, I tried the modified script and it does not produce the results that I was hoping for, probably because of a poor initial design. The idea that I had (and have used in other scripts) is to collect an array of variables on each VM. Ideally the output would be something like this table below. I'm trying to information on multiple disks captured for each VM, with the VM name repeating ($rowcoll.VM) and the other properties such as SCSIUnitNo going into an array, then appending the arrays together to form several rows of arrays so they can be exported to a CSV. I've done it before, but if you can advise me on the design in this script I would be most grateful.

VM

VMController

SCSIBusShare

SCSIBusNumber

SCSIUnitNo

DeviceLabel

SCSISummary

DeviceFilename

DeviceCapKB

DeviceDiskMode

DeviceDiskUUID

Server1

SCSI Controller 0

noSharing

0

1

Hard Disk 2

LSI Logic

Server1/Server1.vmdk

104857600

persistent

6000C290-54a0-8a91-c0f1-fbf5490f5de8

Server1

SCSI Controller 0

noSharing

0

2

Hard Disk 3

BusLogic

Server1/Server1_2.vmdk

62926737

persistent

6000C298-1e61-0fce-f4fd-4bca3886d908

Server1

SCSI Controller 2

noSharing

2

9

Hard Disk 4

LSI Logic

Server1/Server1_3.vmdk

71385600

independent_persistent

6000C290-54a0-8a91-c0f1-fbf5490f5439

Server2

SCSI Controller 0

noSharing

0

1

Hard Disk 2

LSI Logic

Server2/Server2.vmdk

134857600

persistent

6000C290-54a0-8a91-c0f1-fbf5490f53f7

Server2

SCSI Controller 0

noSharing

0

2

Hard Disk 3

BusLogic

Server2/Server2_2.vmdk

67926737

persistent

6000C298-1e61-0fce-f4fd-4bca3886d783

Server2

SCSI Controller 2

noSharing

2

5

Hard Disk 4

LSI Logic

Server2/Server2_3.vmdk

81385600

independent_persistent

6000C290-54a0-8a91-c0f1-fbf5490f5c47

Note: This is the first part of a script that I am writing that is intended to capture RDM information and then allow RDM's to be recreated per VM if needed from the recordset.

Regards,

Ed

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

My mistake, I deleted the wrong $report line.

Try this one

$reportfinal = @()

$VMs = Get-View -ViewType VirtualMachine


foreach ($VM in $VMs) {

	#Clear report array for each VM

	foreach ($SCSI_Controller in ($VM.Config.Hardware.Device | where {$_.DeviceInfo.Label -like "SCSI*" } )) {

		foreach ($Disk_Key in $SCSI_Controller.Device) {
			foreach ($Disk_Device in ($VM.Config.Hardware.Device | where {$_.key -eq $Disk_Key } )) {
				$rowcoll = "" | select VM, VMController, SCSIBusShare, SCSIBusNumber, SCSIUnitNo, DeviceLabel, SCSISummary, DeviceFilename, DeviceCapKB, DeviceDiskMode,DeviceDiskUUID
		        $rowcoll.VM = $VM.Name
		        $rowcoll.VMController = $SCSI_Controller.DeviceInfo.Label
				$rowcoll.SCSIBusShare = $SCSI_Controller.SharedBus
				$rowcoll.SCSIBusNumber = $SCSI_Controller.BusNumber
				$rowcoll.SCSIUnitNo = $Disk_Device.UnitNumber
				$rowcoll.DeviceLabel = $Disk_Device.DeviceInfo.Label
				$rowcoll.SCSISummary = $SCSI_Controller.DeviceInfo.Summary
				$rowcoll.DeviceFilename = $Disk_Device.Backing.Filename
				$rowcoll.DeviceCapKB = $Disk_Device.CapacityInKB
				$rowcoll.DeviceDiskMode = $Disk_Device.Backing.DiskMode
				$rowcoll.DeviceDiskUUID = $Disk_Device.Backing.UUID
				$reportfinal += $rowcoll
			}
		}
	}

}

$reportfinal | Export-Csv -path C:\SAP_Report_Disks_RDM_Mappings.csv -NoTypeInformation


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

Reply
0 Kudos
EdZ
Contributor
Contributor
Jump to solution

That's it Luc - you fixed it - works like a charm!

Thanks!

Ed

Reply
0 Kudos