Good Afternoon everyone!!!
I am attempting to devise a script that I can use to point to clusters of ESX hosts and generate the last 10 lines of any particular log files on these systems using Get-log. First, I would like to point out that the following code works for one individual host:
$esx = Get-VMHost -VMhost "hostname"
$esxlog = Get-Log -Key "vmkernel" -VMHost $esx
$esxlog.Entries <----
This will show expected results, which is the last 10 lines of the log on that host.
Now, when I try to expand upon this concept and try to create a loop based on this using the code below:
$esx = Get-Cluster "clustername" | Get-VMHost
foreach ($_ in $esx) {$esxlog = Get-Log -Key "vmkernel" -VMHost $_
$esxlog.Entries} <----
I only get the following error: A parameter cannot be found that matches parameter name 'System.Object[]'.
What am I doing wrong with my script?
The variable $_ is a pre-defined variable so you shouldn't use it as your loop variable.
You could do it like this
$esx = Get-Cluster <clustername> | Get-VMHost $esx | %{ $esxlog = Get-Log -Key "vmkernel" -VMHost $_ $nrEntries = $esxlog.Entries.Count Write-Host $_.Name -foregroundcolor green $esxlog.Entries[http://($nrEntries-11)..($nrEntries-1)|http://($nrEntries-11)..($nrEntries-1)] }
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
The variable $_ is a pre-defined variable so you shouldn't use it as your loop variable.
You could do it like this
$esx = Get-Cluster <clustername> | Get-VMHost $esx | %{ $esxlog = Get-Log -Key "vmkernel" -VMHost $_ $nrEntries = $esxlog.Entries.Count Write-Host $_.Name -foregroundcolor green $esxlog.Entries[http://($nrEntries-11)..($nrEntries-1)|http://($nrEntries-11)..($nrEntries-1)] }
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD, your suggestion worked flawlessly.........I appreciate your input.....if you dont mind, I'd love it if you could break your script down for me just a bit so that I can understand the logic behind how you decided to proceed.
Sure, no problem.
In variable $esx I get all the ESX servers that are in the cluster .
Provided you have more than 1 ESX server in the cluster, $esx will be an array of objects.
Them I pipe the contents of the array to the Foreach-Object cmdlet.
I used "%" but that is an alias for the Foreach-Object cmdlet.
By doing it this way I don't have to use a test to check if $esx is a single object (an atom) or an array of objects.
The pipe takes care of that.
In the codeblock of the Foreach-Object the current object, which represents an ESX server object, is passed in the variable $_.
From there it is rather straightforward:
get the content of the vmkernel log into variable $esxlog
in that variable, which is again an object, there is a property "Entries" which contains an array of strings, with 1 line of the log per element
as with each array you can find the number of elements in the array with the Count property
I write the name of the server (in green) to the console
I display the last 10 lines of the log
Feel free to ask further questions if something is not yet clear.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD,
Great info! I appreciate your time!
Two things stick out in my mind:
#1: How do I find a comprehensive definition of the various object types and their properties and methods? I understand the get-member cmdlet, but what if one ddnt know what even exists?
#2: The part where u are specifying exactly what range of lines of the log file to display, what is the significance of the '-11......-1'? What is the relationship with this range identifier and the retrieval of the 'count' property?
#1: if you mean the objects that come with the VITK I'm afraid that you will have to use the Get-Member cmdlet.
Hal's soon to be released book will contain a wealth of information on the VITK objects.
As a side remark, the objects as used by the VITK are not the objects that the VI API uses !
#2: The number of elements (lines from the log) in the Entries property is not always the same.
To get the number of elements I store the Count property in variable $nrEntries.
To get the last 10 lines from the log and taking into account that an array index starts at 0 (zero), I start at the 10th line before the end.
And a..b is a PowerShell feature that allows you to address a series of elements in an array.
Example:
- Get-VIEvent returned 88 lines
- $nrEntries will contain the value 88
- I ask for the array elements 88-11 till 88-1 ==> 77 till 87 ==> the last 10 lines
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Just to assist in future Googling, "a..b" is called the range operator.
[PowerShell MVP|https://mvp.support.microsoft.com/profile=5547F213-A069-45F8-B5D1-17E5BD3F362F], VI Toolkit forum moderator
Author of the upcoming book: Managing VMware Infrastructure with PowerShell
Co-Host, PowerScripting Podcast (http://powerscripting.net)
Need general, non-VMware-related PowerShell Help? Try the forums at PowerShellCommunity.org
Great Great info, LucD and Halr9000!!!
I have learned a great deal from this discussion, as focused as it was.......Hal, I cant wait for your book man!