VMware Cloud Community
Sureshadmin
Contributor
Contributor
Jump to solution

Need powershell scripts to collect ESX storage info

Hi,

I need three scripts to collect ESX storage information as given below

1. Storage hardware info --> to collect info about SCSI controller and HBA cards.

ESX Name | SCSI controller | HBA1 | HBA2

Expected output

ESX Name | SCSI (Model,Bios version,serial Number, Raid config) | HBA1(Model, Firmware version, serial number,WWPN) | HBA2(Model, Firmware version, serial number,WWPN)

Note : Need info about all SCSI controllers and HBA's in the ESX box, so additional columns could be added as required.

2.Storage usage report ---> Storage usage report including local filesystem storage and also SAN volumes.

ESX name | Filesystem | Size | Used | Avail | Use% | Mount Point | Extents

Note : Need all sizes in GB. Extents are applicable for SAN datastores and just need the extent DiskID like vmhba1:1:1

3. San disk information -->To collect information about San Disk

Disk ID | Lun ID | Disk Size | Make/Model | Path(s) | Policy | Active HBA WWPN

Expected Output

vmhba1:1:1 | 0110 | 130G | EMCxxxx | 4 | Fixed | xxxxxxxxxxxxxxx

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

There was an error, you can't remove elements from a hash table while looping through the values.

Try this one (it works for me).

$nrMax = 10 
$taskHash = @{}

Get-Cluster <clu> | Get-VM | %{
  $spec = new-object VMware.Vim.VirtualMachineConfigSpec;
  $spec.cpuAllocation = New-Object VMware.Vim.ResourceAllocationInfo;
  $spec.cpuAllocation.Shares = New-Object VMware.Vim.SharesInfo;
  $spec.cpuAllocation.Shares.Level = "Normal";
  $spec.cpuAllocation.Limit = -1;
  $spec.cpuAllocation.Reservation = 0;
  $task = Get-View ($_.Extensiondata.ReconfigVM_Task($spec))
  $taskHash[$task.Info.Key] = $task

 
while($taskHash.Count -eq $nrMax){         $toBeRemoved = @()         foreach($task in $taskHash.Values){             $task.UpdateViewData()             if("success","error" -contains $task.Info.State){                 $toBeRemoved += $task.Info.Key             }         }         $toBeRemoved | %{              $taskHash.Remove($_)         }   } }


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

View solution in original post

0 Kudos
42 Replies
LucD
Leadership
Leadership
Jump to solution

Hi Suresh,

The first one is rather easy with the Get-VMHostHba cmdlet.

Does this list what you wanted for 1) ?

Get-VMHost | %{
	$esxImpl = $_
	$esxImpl | Get-VMHostHba | select @{N="ESX Name";E={$esxImpl.Name}},
			@{N="Device";E={$_.Device}},
			@{N="HBA Model";E={$_.Model}},
			@{N="HBA Type";E={$_.Type}},
			@{N="Driver";E={$_.Driver}},
			@{N="PCI";E={$_.Pci}}
}

____________

Blog: LucD notes

Twitter: lucd22


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

0 Kudos
Sureshadmin
Contributor
Contributor
Jump to solution

yes Luc,

This is what i want for 1st script. This script gives detailed info about SCSI and HBA adapters. But WWPN is missing for HBA. Please include that.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Here you go.

Script 1 inclusive the Port WWN (in hex) for the fiber HBAs.

Get-VMHost | %{
	$esxImpl = $_
	$esxImpl | Get-VMHostHba | select @{N="ESX Name";E={$esxImpl.Name}},
			@{N="Device";E={$_.Device}},
			@{N="HBA Model";E={$_.Model}},
			@{N="HBA Type";E={$_.Type}},
			@{N="Driver";E={$_.Driver}},
			@{N="PCI";E={$_.Pci}},
			@{N="PWWN";E={$hbaKey = $_.Key; "{0:x}" -f (($esxImpl | Get-View).Config.StorageDevice.HostBusAdapter | where {$_.GetType().Name -eq "HostFibreChannelHba" -and $_.Key -eq $hbaKey}).PortWorldWideName}}
}

____________

Blog: LucD notes

Twitter: lucd22


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

LucD
Leadership
Leadership
Jump to solution

Script 2.

Note that for a multi-extent VMFS volume it will only show the first extent.

For VMFS volumes this is the CanonicalName and for NFS volumes this is the remote host and the remote path.

$dsTab = @{}
Get-VMHost | %{
	$esxImpl = $_
	$ds = $esxImpl | Get-Datastore | %{$dsTab[http://$_.Name|http://$_.Name] = $_}
	$esxImpl | Get-VMHostStorage | %{
		$_.FileSystemVolumeInfo | %{
			$sizeGB = $_.Capacity/1GB
			$usedGB = ($_.Capacity/1MB - ($dsTab[http://$_.Name|http://$_.Name]).FreeSpaceMB)/1KB
			$usedPerc = $usedGB / $sizeGB
			$availGB = ($dsTab[http://$_.Name|http://$_.Name]).FreeSpaceMB/1KB
			$ds = Get-View $dsTab[http://$_.Name|http://$_.Name].Id
			$_ | select @{N="ESX Name";E={$esxImpl.Name}},
				@{N="FS Name";E={$_.Name}},
				@{N="Type";E={$_.Type}},
				@{N="SizeGB";E={"{0:N1}" -f $sizeGB}},
				@{N="UsedGB";E={"{0:N1}" -f $usedGB}},
				@{N="AvailableGB";E={"{0:N1}" -f $availGB}},
				@{N="Used%";E={"{0:P1}" -f $usedPerc}},
				@{N="Mount point";E={$_.Path}},
				@{N="Extents";E={if($_.Type -eq "VMFS"){$ds.Info.Vmfs.Extent[0].DiskName}
								elseif($_.Type -eq "NFS"){$ds.Info.Nas.RemoteHost + ":" + $ds.Info.Nas.RemotePath}}}
		}
	}
}

Since there are some square brackets I attached the script.

____________

Blog: LucD notes

Twitter: lucd22


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

Sureshadmin
Contributor
Contributor
Jump to solution

Luc,

1. First script is fine now with WWN

2. Second script is also fine. But i also need the esx filesystem usage like /, /boot etc.. Can you please include that also. Also, Is there a way to show all extents for multi extent volumes?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

How do you want to display these multiple extents ?

Each on a separate line ?

The LUN's that are listed in the 2nd script are not the LUNs used for the local file system(s) of the COS.

It's not too straightforward to get these without using sometink like plink.exe.

____________

Blog: LucD notes

Twitter: lucd22


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

0 Kudos
LucD
Leadership
Leadership
Jump to solution

For the 3th script, what do you mean with the "LUN Id" ?

With which field in the vSphere client does this correspond ?

____________

Blog: LucD notes

Twitter: lucd22


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

0 Kudos
Sureshadmin
Contributor
Contributor
Jump to solution

hi Luc,

1. I want the multiple extent to be displayed in a single field separated by comma's like vmhba1:1:0, vmhba1:1:1

2. If plink.exe can be used to retrieve ESX file system usage, please use it.

3. Lun ID is just the last digit in vmhbax:y:z, where z is the LUN ID. Sorry, in expected output in my question i messed up a bit.

0 Kudos
Sureshadmin
Contributor
Contributor
Jump to solution

In 3rd script please leave the LUN ID field. Its not required. If we can get other fields it's ok for me.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Sorry, seems I forgot about the 3th script.

Try the attached script.

____________

Blog: LucD notes

Twitter: lucd22


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

0 Kudos
Sureshadmin
Contributor
Contributor
Jump to solution

hi Luc,

I have a bit of confusion on how to run this script.

This script starts with the line $esxname = . should i specify the esx server name here?

or, can i use connect-viserver and avoid the above given line?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Yes, you will have to pass 1 ESX server.

And you connect to the vCenter.

If you want run this over all your ESX servers the script needs to be slightly modified and the output will need to contain the name of the ESX server.

The attached script runs through all the ESX servers.

If you want to limit the ESX servers you can use the -SearchRoot parameter (see the commented out lines).

____________

Blog: LucD notes

Twitter: lucd22


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

0 Kudos
Sureshadmin
Contributor
Contributor
Jump to solution

Luc,

Since i use Ecoshell, please give the modified version so that i can run on all ESX server on a virtual center. Usually, first i will connect to the virtual center using Ecoshell and then run the script.

-


Also, i have one more request for a new script, please read the below requirement and please let me know whether it's possible.

1. I have a csv file with a list of ESX servers

2. I need a script which would prompt to input the command, and it should run the command in all esx servers one by one from the input csv file and should export the result in csv format.

For Example,

If i give a command vmware-cmd -l it should run this command in all the esx server in the csv file one by one and output the result to a result csv file.

I guess this can be done using plink.exe. if you can help me in getting this script also it would be so useful for me.

0 Kudos
Sureshadmin
Contributor
Contributor
Jump to solution

Sorry, you have attached the modified version already. Just noticed it.

0 Kudos
RvdNieuwendijk
Leadership
Leadership
Jump to solution

I have tried to create a general solution to your question about a script to run a command on a list of ESX servers. So I created a function Invoke-VMhostCommand that runs a command on one ESX server. Thanks to LucD, because most of this function's code is made by him.

Function Invoke-VMhostCommand {
  # This function assumes that plink.exe is in your path
  Param($VMHost,$User,$Password,$Command)

  $plink = "plink.exe"
  $plinkoptions = " -v -batch -pw $Password"
  $remoteCommand = '"' + $Command + '"'
  $PlinkCommand = $plink + " " + $plinkoptions + " " + $User + "@" + $VMHost + " " + $remoteCommand
  $msg = Invoke-Expression -command $PlinkCommand
  $msg
}

With this Invoke-VMhostCommand function you can do the rest of your question in quite simple PowerShell. I assume you have a csv file ESXservers.csv that has the following layout:

Name
ESX1
ESX2

Now the answer to your question is the following script:

$Command = Read-Host "Please enter a command"
Import-CSV -Path ESXservers.csv | `
  ForEach-Object {
    Invoke-VMHostCommand -VMHost $_.Name -User username -Password password -Command $command
  } | `
  Select-Object @{n="Item";e={$_}} | `
    Export-CSV -NoTypeInformation -Path VMhost-cmd.csv

Robert

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
0 Kudos
Sureshadmin
Contributor
Contributor
Jump to solution

hi Robert,

This script works very well. Just need one important addition,

When i run a command using this script on multiple ESX servers, the ouput file does not show the esx server name. So from output file, can't identify the output belongs to which ESX server? Can u please modify the script so that the ESX server name gets printed first and then the ouput.

0 Kudos
Sureshadmin
Contributor
Contributor
Jump to solution

Luc,

I ran this script with having one esx server connected. This script runs but does not give a output and also does not give any error. Do i need to put a write-output statement in order to view the output?

0 Kudos
RvdNieuwendijk
Leadership
Leadership
Jump to solution

I modified the script so that the ESX server name gets printed first and then the ouput:

$Command = Read-Host "Please enter a command"
Import-CSV -Path ESXservers.csv | `
  ForEach-Object {
    $VMHost = $_.Name
    Invoke-VMHostCommand -VMHost $VMHost -User username -Password password -Command $command
  } | `
  Select-Object @{n="VMhost";e={$VMHost}},@{n="Item";e={$_}} | `
    Export-CSV -NoTypeInformation -Path VMHost-cmd.csv

Robert

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
Sureshadmin
Contributor
Contributor
Jump to solution

Thank you, Robert.

0 Kudos