Difference between revisions of "ESX Script Extracts and Examples"

Jump to navigation Jump to search
Syntax highlighting broken
m (→‎ESX BIOS, NIC and HBA Driver Versions: Added link to vBlog SSH example)
(Syntax highlighting broken)
 
(3 intermediate revisions by the same user not shown)
Line 1: Line 1:
== Daily ESX Up/Down Check ==
Simple script that runs every morning just before I start work to provide a basic sanity check email to glance through over the first tea of the day.
<syntaxhighlight lang='powershell'>
#############################################################################################
#
#  ESX Checker
#
#############################################################################################
#
# By Simon Strutt
#
# Version 1 - Aug 10
# - Initial creation
#
# Version 2 - Oct 10
# - Fixed VIServer handling (was never good but stuffed by upgrade to PowerCLI 4.1)
# - Improved email in case of vCentre connection failure
#
# Version 2.1 - Nov 10
# - Minor text changes
#
# Version 2.2 - Nov 10
# - Added InvalidLogon catch to vCentre logon to prevent a/c lockout
#
# Version 3 - Dec 10
# - Truncated displayed ESX hostname (stripped domain)
# - Added "since <datetime>" info to ESX's that aren't in a good state
# - Bugfix: Incorrect email config used when VC list config file load failed
#
# Version 3.1 Jan 11
# - Workaround: Powershell/MS DateTime object returns incorrect (US) date format
#
# Version 3.2 Jan 11
# - Bugfix: Extraneous " hrs" on end of v3.1 fixed datetimes
#
#############################################################################################
$DateFormat = "%R hrs, %a %d %b %Y"
$EmailBody = "Results of ESX status check as of " + (get-date -uFormat "$DateFormat.`n`n")
$EmailRecipients = "person1@domain.com,person2@domain.com"
$EmailSender = "VI-Mgmt@domain.com"
$UserFile = "User.fil"
$PassFile = "Pass.fil"
$smtp = New-Object Net.Mail.SmtpClient -arg "smtp-server.domain.com"
$VCAlertToSend = 0
$ESXAlertToSend = 0
$start = Get-Date
try {
    $ToCheck = Import-CSV "ESX-Check.csv"
} catch {
    $EmailBody = "ERROR: Failed to load config file, no checks have been done.`n"
    $EmailBody += $_
    $smtp.Send($EmailSender, $EmailRecipients, "ESX-Check: Check failed", $EmailBody)
    Exit
}
$pass = Get-Content $PassFile -errorAction Stop | ConvertTo-SecureString
$user = Get-Content $UserFile -errorAction Stop
$cred = New-Object System.Management.Automation.PsCredential($user, $pass)
foreach ($vc in $ToCheck) {
    Write-Host "Checking ESXs on" $vc.vc
    $VChasBadESX = 0
    try {
        $VCconn = Connect-VIServer -Server $vc.vc -Credential $cred -NotDefault -errorAction "Stop"
    } catch [VMware.VimAutomation.ViCore.Types.V1.ErrorHandling.InvalidLogin] {
        $EmailBody += ($vc.vc).ToUpper() + "`t" + "Unable to connect to vCentre, invalid logon error !!`n`n"
        $EmailBody += "Abandoning further script processing in order to prevent potential account lockout.`n"
        $VCAlertToSend = 1
        Break
    } catch {
        $EmailBody += ($vc.vc).ToUpper() + "`t" + "Unable to connect to vCentre, ESX's not checked !!`n"
        $VCAlertToSend = 1
        Continue
    }
    $ESXs = Get-VMHost -Server $vc.vc | Where {$_.State -ne "Connected"} | Sort -property Name
    if ($ESXs) {
        foreach ($ESX in $ESXs) {
            # Attempt to work out when ESX went into its bad state
            Switch ($ESX.State) {
                NotResponding {
                    $events = Get-VIEvent -Entity $ESX -Types Error | Where {$_.fullFormattedMessage -like "*is not responding*"}
                }
                Maintenance {
                    $events = Get-VIEvent -Entity $ESX -MaxSamples 1000 | Where {$_.fullFormattedMessage -like "*has entered maintenance mode*"}
                }
                Disconnected {
                    $events = Get-VIEvent -Entity $ESX -MaxSamples 1000 | Where {$_.fullFormattedMessage -like "*Disconnected from*"}
                }
                Default {
                    $events = 0
                }
            }
            If ($events) {
                $SinceString = " since " + (Get-Date $events[0].CreatedTime -uFormat $DateFormat)
            } else {
                $SinceString = ""
            }
                   
            $EmailBody += $vc.vc + "`t" + ($ESX.Name.Split(".")[0]).ToUpper() + "`t" + $ESX.State + $SinceString + "`n"
            $ESXAlertToSend = 1
            $VChasBadESX = 1
        }
    }
    if (!$VChasBadESX) {
        $EmailBody += $vc.vc + "`t" + "All good`n"
    }
    Disconnect-VIServer -Server $VCconn -Confirm:$false
}
$end = Get-Date
$EmailBody += "`n`n`nCheck started      : " + (Get-Date $start -uFormat $DateFormat) + "`n"
$EmailBody += "Check finished    : " + (Get-Date $end -uFormat $DateFormat) + "`n"
$EmailBody += "Generated by script: " + ($MyInvocation.MyCommand.Name) + "`n"
$EmailBody += "Sent from machine  : $env:computername"
$EmailBody
Write-Host "Sending email..."
if ($VCAlertToSend) {
    $smtp.Send($EmailSender, $EmailRecipients, "ESX-Check: Unable to connect to some/all vCentres", $EmailBody)
} elseif ($ESXAlertToSend) {
    $smtp.Send($EmailSender, $EmailRecipients, "ESX-Check: Some ESX's are NOT CONNECTED", $EmailBody)
} else {
    $smtp.Send($EmailSender, $EmailRecipients, "ESX-Check: All connected OK", $EmailBody)
}
if (-not $?) {
    Write-Host "SMTP send failed!!"
    Start-Sleep(30000)
}
</syntaxhighlight>
{{PowerShell_Credentials_Files}}
== ESX NIC Info ==
== ESX NIC Info ==
Provides a list of all vmnic speeds for ESX's managed by the vCentre you're connected to.
Provides a list of all vmnic speeds for ESX's managed by the vCentre you're connected to.
Line 17: Line 159:
}
}
</source>
</source>
== Discovered Networks Hint ==
This function provides the discovered network hints for the network interface its passed.  Bear in mind that its just a hint, for an ESX to be aware of a particular vLAN it needs to see traffic.  If there's no traffic (eg a newly set-up ESX with no VMs) it will show nothing.
Adapted from the following article on the VMware site blog http://blogs.vmware.com/vipowershell/2010/02/how-to-find-out-what-vlans-your-esx-hosts-can-really-see.html
<source lang="powershell">
function Get-ObservedIPRange {
param(
[Parameter(Mandatory=$true,ValueFromPipeline=$true,HelpMessage="Physical NIC from Get-VMHostNetworkAdapter")]
[VMware.VimAutomation.Client20.Host.NIC.PhysicalNicImpl]
$Nic
)
process {
$hostView = Get-VMHost -Id $Nic.VMHostId | Get-View -Property ConfigManager
$ns = Get-View $hostView.ConfigManager.NetworkSystem
$hints = $ns.QueryNetworkHint($Nic.Name)
foreach ($hint in $hints) {
foreach ($subnet in $hint.subnet) {
$observed = New-Object -TypeName PSObject
$observed | Add-Member -MemberType NoteProperty -Name Device -Value $Nic.Name
$observed | Add-Member -MemberType NoteProperty -Name VlanId -Value $subnet.VlanId
$observed | Add-Member -MemberType NoteProperty -Name IPSubnet -Value $subnet.IPSubnet
$observed | Add-Member -MemberType NoteProperty -Name BitRatePerSec -Value $nic.BitRatePerSec
Write-Output $observed
}
}
}
}
# Example use:
$result = Get-VMHost MyESX* | Get-VMHostNetworkAdapter | Where {$_.Name -Match ".*vmnic*"} | Get-ObservedIPRange | Sort-Object -Property Device, VlanId
$result | Export-Csv -path ESX-vLANs-Observed.csv
</source>
== Add VLANs/PortGroups to Standard Switch ==
Simple script to add new port groups to an ESX.  Create a CSV file in the format as show in the example below.  Then update the <code>$esx</code> and <code>$vSwitch</code> variables as appropriate in the script and run in a PowerCLI session connected to the vCenter.
<source lang="powershell">
$PG_List = "ESX-Add-PortGroups.csv"        # CSV to list new port groups in
$esx = "esx-name*"                        # ESX to add port groups to
$vSwitch = "vSwitch0"                      # vSwitch (standard not dvSwitch) on ESX to add port groups to
$Switch = Get-VirtualSwitch -Name $vSwitch -VMHost (Get-VMHost $esx)
try {
    $PGs = Import-CSV $PG_List
} catch {
  Write-Host("ERROR: Failed to load list of PortGroup's")
  Exit
}
foreach ($pg in $PGs) {
    Write-Host ("Adding VLAN " + $pg.VLAN + " " + $pg.Name)
    New-VirtualPortGroup -VirtualSwitch $Switch -Name $pg.Name -VLanId $pg.VLAN
}
</source>
{| class="vwikitable"
|+ Example contents of CSV file
! VLAN !! Name
|-
|  101 || Testing
|-
|  102 || Development
|-
|  103 || ABC Production
|}
== ESX CDP Info ==
Adapted from posted by LucD on VMware forum http://communities.vmware.com/message/977487
<source lang="powershell">
Get-VMHost | Sort -Property Name | %{Get-View $_.ID} | %{$esxname = $_.Name; Get-View $_.ConfigManager.NetworkSystem} | %{
  foreach($physnic in $_.NetworkInfo.Pnic){
    $pnicInfo = $_.QueryNetworkHint($physnic.Device)
    foreach($hint in $pnicInfo){
      Write-Host $esxname $physnic.Device $hint.connectedSwitchPort.DevId $hint.connectedSwitchPort.PortId
    }
  }
}
</source>


== ESX Log Tail ==
== ESX Log Tail ==
Line 81: Line 309:
     $ESXlog.Entries
     $ESXlog.Entries
     $LineNo = $ESXLog.LastLineNum
     $LineNo = $ESXLog.LastLineNum
}
</source>
== Discovered Networks Hint ==
This function provides the discovered network hints for the network interface its passed.  Bear in mind that its just a hint, for an ESX to be aware of a particular vLAN it needs to see traffic.  If there's no traffic (eg a newly set-up ESX with no VMs) it will show nothing.
Adapted from the following article on the VMware site blog http://blogs.vmware.com/vipowershell/2010/02/how-to-find-out-what-vlans-your-esx-hosts-can-really-see.html
<source lang="powershell">
function Get-ObservedIPRange {
param(
[Parameter(Mandatory=$true,ValueFromPipeline=$true,HelpMessage="Physical NIC from Get-VMHostNetworkAdapter")]
[VMware.VimAutomation.Client20.Host.NIC.PhysicalNicImpl]
$Nic
)
process {
$hostView = Get-VMHost -Id $Nic.VMHostId | Get-View -Property ConfigManager
$ns = Get-View $hostView.ConfigManager.NetworkSystem
$hints = $ns.QueryNetworkHint($Nic.Name)
foreach ($hint in $hints) {
foreach ($subnet in $hint.subnet) {
$observed = New-Object -TypeName PSObject
$observed | Add-Member -MemberType NoteProperty -Name Device -Value $Nic.Name
$observed | Add-Member -MemberType NoteProperty -Name VlanId -Value $subnet.VlanId
$observed | Add-Member -MemberType NoteProperty -Name IPSubnet -Value $subnet.IPSubnet
$observed | Add-Member -MemberType NoteProperty -Name BitRatePerSec -Value $nic.BitRatePerSec
Write-Output $observed
}
}
}
}
# Example use:
$result = Get-VMHost MyESX* | Get-VMHostNetworkAdapter | Where {$_.Name -Match ".*vmnic*"} | Get-ObservedIPRange | Sort-Object -Property Device, VlanId
$result | Export-Csv -path ESX-vLANs-Observed.csv
</source>
== ESX CDP Info ==
Adapted from posted by LucD on VMware forum http://communities.vmware.com/message/977487
<source lang="powershell">
Get-VMHost | Sort -Property Name | %{Get-View $_.ID} | %{$esxname = $_.Name; Get-View $_.ConfigManager.NetworkSystem} | %{
  foreach($physnic in $_.NetworkInfo.Pnic){
    $pnicInfo = $_.QueryNetworkHint($physnic.Device)
    foreach($hint in $pnicInfo){
      Write-Host $esxname $physnic.Device $hint.connectedSwitchPort.DevId $hint.connectedSwitchPort.PortId
    }
  }
}
}
</source>
</source>
Line 278: Line 454:
Stop-Transcript
Stop-Transcript
          
          
</source>
{{PowerShell_Credentials_Files}}
== Daily ESX Up/Down Check ==
Simple script that runs every morning just before I start work to provide a basic sanity check email to glance through over the first tea of the day.
<source lang="Powershell">
#############################################################################################
#
#  ESX Checker
#
#############################################################################################
#
# By Simon Strutt
#
# Version 1 - Aug 10
# - Initial creation
#
# Version 2 - Oct 10
# - Fixed VIServer handling (was never good but stuffed by upgrade to PowerCLI 4.1)
# - Improved email in case of vCentre connection failure
#
# Version 2.1 - Nov 10
# - Minor text changes
#
# Version 2.2 - Nov 10
# - Added InvalidLogon catch to vCentre logon to prevent a/c lockout
#
# Version 3 - Dec 10
# - Truncated displayed ESX hostname (stripped domain)
# - Added "since <datetime>" info to ESX's that aren't in a good state
# - Bugfix: Incorrect email config used when VC list config file load failed
#
# Version 3.1 Jan 11
# - Workaround: Powershell/MS DateTime object returns incorrect (US) date format
#
# Version 3.2 Jan 11
# - Bugfix: Extraneous " hrs" on end of v3.1 fixed datetimes
#
#############################################################################################
$DateFormat = "%R hrs, %a %d %b %Y"
$EmailBody = "Results of ESX status check as of " + (get-date -uFormat "$DateFormat.`n`n")
$EmailRecipients = "person1@domain.com,person2@domain.com"
$EmailSender = "VI-Mgmt@domain.com"
$UserFile = "User.fil"
$PassFile = "Pass.fil"
$smtp = New-Object Net.Mail.SmtpClient -arg "smtp-server.domain.com"
$VCAlertToSend = 0
$ESXAlertToSend = 0
$start = Get-Date
try {
    $ToCheck = Import-CSV "ESX-Check.csv"
} catch {
    $EmailBody = "ERROR: Failed to load config file, no checks have been done.`n"
    $EmailBody += $_
    $smtp.Send($EmailSender, $EmailRecipients, "ESX-Check: Check failed", $EmailBody)
    Exit
}
$pass = Get-Content $PassFile -errorAction Stop | ConvertTo-SecureString
$user = Get-Content $UserFile -errorAction Stop
$cred = New-Object System.Management.Automation.PsCredential($user, $pass)
foreach ($vc in $ToCheck) {
    Write-Host "Checking ESXs on" $vc.vc
    $VChasBadESX = 0
    try {
        $VCconn = Connect-VIServer -Server $vc.vc -Credential $cred -NotDefault -errorAction "Stop"
    } catch [VMware.VimAutomation.ViCore.Types.V1.ErrorHandling.InvalidLogin] {
        $EmailBody += ($vc.vc).ToUpper() + "`t" + "Unable to connect to vCentre, invalid logon error !!`n`n"
        $EmailBody += "Abandoning further script processing in order to prevent potential account lockout.`n"
        $VCAlertToSend = 1
        Break
    } catch {
        $EmailBody += ($vc.vc).ToUpper() + "`t" + "Unable to connect to vCentre, ESX's not checked !!`n"
        $VCAlertToSend = 1
        Continue
    }
    $ESXs = Get-VMHost -Server $vc.vc | Where {$_.State -ne "Connected"} | Sort -property Name
    if ($ESXs) {
        foreach ($ESX in $ESXs) {
            # Attempt to work out when ESX went into its bad state
            Switch ($ESX.State) {
                NotResponding {
                    $events = Get-VIEvent -Entity $ESX -Types Error | Where {$_.fullFormattedMessage -like "*is not responding*"}
                }
                Maintenance {
                    $events = Get-VIEvent -Entity $ESX -MaxSamples 1000 | Where {$_.fullFormattedMessage -like "*has entered maintenance mode*"}
                }
                Disconnected {
                    $events = Get-VIEvent -Entity $ESX -MaxSamples 1000 | Where {$_.fullFormattedMessage -like "*Disconnected from*"}
                }
                Default {
                    $events = 0
                }
            }
            If ($events) {
                $SinceString = " since " + (Get-Date $events[0].CreatedTime -uFormat $DateFormat)
            } else {
                $SinceString = ""
            }
                   
            $EmailBody += $vc.vc + "`t" + ($ESX.Name.Split(".")[0]).ToUpper() + "`t" + $ESX.State + $SinceString + "`n"
            $ESXAlertToSend = 1
            $VChasBadESX = 1
        }
    }
    if (!$VChasBadESX) {
        $EmailBody += $vc.vc + "`t" + "All good`n"
    }
    Disconnect-VIServer -Server $VCconn -Confirm:$false
}
$end = Get-Date
$EmailBody += "`n`n`nCheck started      : " + (Get-Date $start -uFormat $DateFormat) + "`n"
$EmailBody += "Check finished    : " + (Get-Date $end -uFormat $DateFormat) + "`n"
$EmailBody += "Generated by script: " + ($MyInvocation.MyCommand.Name) + "`n"
$EmailBody += "Sent from machine  : $env:computername"
$EmailBody
Write-Host "Sending email..."
if ($VCAlertToSend) {
    $smtp.Send($EmailSender, $EmailRecipients, "ESX-Check: Unable to connect to some/all vCentres", $EmailBody)
} elseif ($ESXAlertToSend) {
    $smtp.Send($EmailSender, $EmailRecipients, "ESX-Check: Some ESX's are NOT CONNECTED", $EmailBody)
} else {
    $smtp.Send($EmailSender, $EmailRecipients, "ESX-Check: All connected OK", $EmailBody)
}
if (-not $?) {
    Write-Host "SMTP send failed!!"
    Start-Sleep(30000)
}
</source>
</source>


Navigation menu