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
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
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
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.
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
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
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?
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
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
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.
In 3rd script please leave the LUN ID field. Its not required. If we can get other fields it's ok for me.
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
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?
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
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.
Sorry, you have attached the modified version already. Just noticed it.
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
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.
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?
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
Thank you, Robert.