param ( [string]$vCenter = "", [string]$VMHost = "", [string]$Test1Vmk = "", [string]$Test1Host = "", [int]$Test1Frame = 0, [string]$Test2Vmk = "", [string]$Test2Host = "", [int]$Test2Frame = 0, [int]$Count = 0, [switch]$SaveCred = $false, [switch]$Help = $false ) <# Write-Host "vCenter - $vCenter" Write-Host "VMHost - $VMHost" Write-Host "Test1VMK - $Test1Vmk" Write-Host "Test1Host - $Test1Host" Write-Host "Test1Frame - $Test1Frame" Write-Host "Test2VMK - $Test2Vmk" Write-Host "Test2Host - $Test2Host" Write-Host "Test2Frame - $Test2Frame" Write-Host "Count - $Count" Write-Host "SaveCred - $SaveCred"#> # Variables $fileVersion = "1.3.2" $fileDate = "2023-04-16" # Display Script Banner Write-Host "--------------------------------------------------" -ForegroundColor White Write-Host "Host Mulitple Concurrent VMK Ping Script" -ForegroundColor Green Write-Host "Version $($FileVersion) ($($FileDate))" -ForegroundColor Green Write-Host "Written by Charlie Silverman" -ForegroundColor Green Write-Host "--------------------------------------------------" -ForegroundColor White if ($Help) { Write-Host Write-Host "Purpose: Perform multiple ping tests simultaneously from an ESXi host." Write-Host "Command Syntax:" Write-Host " HostMultiPingTest.ps1 (-vcenter [vcenter host name]) (-VMHost ""[host]"") (-Test1Host ""[ipaddress]"")" -foregroundcolor green Write-Host " (-Test1VMK ""[vmkPort]"") (-Test1Frame [framesize]) (-Test2Host ""[ipaddress]"") (-Test2VMK ""[vmkPort]"")" -foregroundcolor green Write-Host " (-Test2Frame [framesize]) (-count [count]) (-savecred) (-help)`n" -foregroundcolor green Write-Host "Command Line Options:" Write-Host Write-Host -NoNewLine " -vCenter " -foregroundcolor Green Write-Host "- The FQDN or IP address of a vCenter server." Write-Host -NoNewLine " -VMHost " -foregroundcolor Green Write-Host "- The name of the host as shown in vCenter." Write-Host -NoNewLine " -Test1Host " -foregroundcolor Green Write-Host "- The IP address of the system to ping for test 1." Write-Host -NoNewLine " -Test1Vmk " -foregroundcolor Green Write-Host "- The VMkernel port on the host to ping for test 1." Write-Host -NoNewLine " -Test1Frame " -foregroundcolor Green Write-Host "- The TCP frame size to use for test 1. Default: 1500." Write-Host -NoNewLine " -Test2Host " -foregroundcolor Green Write-Host "- The IP address of the system to ping for test 2." Write-Host -NoNewLine " -Test2Vmk " -foregroundcolor Green Write-Host "- The VMkernel port on the host to ping for test 2." Write-Host -NoNewLine " -Test2Frame " -foregroundcolor Green Write-Host "- The TCP frame size to use for test 2. Default: 1500." Write-Host -NoNewLine " -count " -foregroundcolor Green Write-Host "- The number of ping tests to run. Default: unlimited." Write-Host -NoNewLine " -savecred " -foregroundcolor Green Write-Host "- Configure and store vCenter server credentials. This will only store the credentials under" Write-Host " the current logged in user." Write-Host -NoNewLine " -help " -foregroundcolor Green Write-Host "- Display command help." Write-Host Write-Host "If no any of the information is not provided, you will be prompted. If a credential has been previously stored, it will be used again" Write-Host "unless the -savecred option is specified." Write-Host exit } $quiet = Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false if ($vCenter -eq "") { $vCenter = Read-Host "Enter name of vCenter Server" } if ($SaveCred) { $credential = Get-Credential -Message "Enter credentials for vCenter server $vCenter x" $credential | Export-Clixml -path $env:USERPROFILE\kispingtest-$vcenter.cred Write-Host "Saving credentials." } if (Test-Path -path $env:USERPROFILE\kispingtest-$vcenter.cred -PathType Leaf) { $credentials = Import-Clixml -path $env:USERPROFILE\kispingtest-$vcenter.cred Write-Host "Using stored credentials" } else { $credentials = Get-Credential -Message "Enter credentials for vCenter server $vCenter" if (!$credentials) { Write-Host "ERROR: No credentials were entered" -foregroundcolor yellow } } try { Write-Host -NoNewLine "Connecting to vCenter $vcenter..." $vcconn = Connect-VIServer $vcenter -Credential $credentials -ErrorAction SilentlyContinue Write-Host " Success" -ForegroundColor green } catch { Write-Host " Failure" -ForegroundColor Yellow -BackgroundColor Red exit } if ($VMHost -eq "") { $VMHostlist = Get-VMHost | Sort-Object While (($VMHost -eq "") -or (-not $VMHost)) { Write-Host "`nHost Selection:`n" for ($x = 0; $x -lt $VMHostlist.length; $x++) { Write-Host "$(([string]($x+1)).PadLeft(3,' '))" -NoNewLine -ForegroundColor Green Write-Host ": " -NoNewLine -ForegroundColor Gray Write-Host "$($VMHostlist[$x].name)" -ForegroundColor Yellow } $VMHostnum = Read-Host "`nSelect Host Number" $VMHostnum = [int]$VMHostnum - 1 $VMHost = $VMHostlist[$VMHostnum] } $myhost = get-vmhost $VMHost } else { $myhost = get-vmhost $VMHost } $vmks = $myhost | Get-VMHostNetworkAdapter | Where-Object {$_.Name -like "vmk*"} | Sort-Object Name While (($Test1Vmk -eq "") -or (-not $Test1Vmk)) { Write-Host "`nVMKernel Port 1 Selection:`n" for ($x = 0; $x -lt $vmks.length; $x++) { $myvmk1 = $vmks[$x]; $mask = [ipaddress]$myvmk1.SubnetMask $binary = [convert]::ToString($mask.Address, 2) $mask_length = ($binary -replace 0,$null).Length Write-Host "$(([string]($x+1)).PadLeft(3,' '))" -NoNewLine -ForegroundColor Green Write-Host ": " -NoNewLine -ForegroundColor Gray Write-Host "$($myvmk1.Name) ($($myvmk1.IP)/$($mask_length))" -ForegroundColor Yellow } $vmknum = Read-Host "`nSelect VMKernel Port Number for Test 1" $Test1Vmk = $vmks[$vmknum - 1].Name $myvmk1 = $vmks[$vmknum - 1] } if ((-not(Test-Path variable:myvmk1) -or ($myvmk1 -ne $null))) { $myvmk1 = $myhost | Get-VMHostNetworkAdapter | Where-Object {$_.Name -like "$Test1Vmk"} $mask = [ipaddress]$myvmk1.SubnetMask $binary = [convert]::ToString($mask.Address, 2) $mask_length = ($binary -replace 0,$null).Length Write-Host "Using $($myvmk1.Name) - $($myvmk.PortGroupName) ($($myvmk1.IP)/$($mask_length)) for Test 1" } $vmk1testvalid = $false while (-not $vmk1testvalid) { if ($Test1Host -ne "") { $thisip = [ipaddress]$Test1Host $subnet = [ipaddress]$myvmk1.IP $netmask = [ipaddress]$myvmk1.SubnetMask $ipbits = [int[]]$($myvmk1.IP).split('.') $maskbits = [int[]]$($myvmk1.SubnetMask).split('.') $networkidbits = 0..3 | ForEach-Object { $ipbits[$_] -band $maskbits[$_] } $networkid = [ipaddress]($networkidbits -join '.') If ($networkid.Address -eq ($thisip.Address -band $netmask.Address)) { $vmk1testvalid = $true } else { Write-Host "Error: IP Address is outside the allowed subnet." -ForegroundColor Red $Test1Host = Read-Host "Enter IP Address to ping for Test 1" } } else { $Test1Host = Read-Host "Enter IP Address to ping for Test 1" } } While ( (-not ($Test1Frame -is [int]) -or ($Test1Frame -lt 1500) ) ) { if ($Test1Frame -eq 0) { $Test1Frame = Read-Host "`nFrame size for Test 1 (1500)" if (!($Test1Frame -is [int]) -or ($Test1Frame -lt 1500)) { $Test1Frame = 1500 } } } While (($Test2Vmk -eq "") -or (-not $Test2Vmk)) { Write-Host "`nVMKernel Port 2 Selection:`n" for ($x = 0; $x -lt $vmks.length; $x++) { $myvmk2 = $vmks[$x] if ($myvmk2.Name.substring(0,3) -ne "vmk") { continue } $mask = [ipaddress]$myvmk2.SubnetMask $binary = [convert]::ToString($mask.Address, 2) $mask_length = ($binary -replace 0,$null).Length Write-Host "$(([string]($x+1)).PadLeft(3,' '))" -NoNewLine -ForegroundColor Green Write-Host ": " -NoNewLine -ForegroundColor Gray Write-Host "$($myvmk2.Name) - $($myvmk.PortGroupName) ($($myvmk2.IP)/$($mask_length))" -ForegroundColor Yellow } $vmknum = Read-Host "`nSelect VMKernel Port Number for Test 2" $Test2Vmk = $vmks[$vmknum - 1].Name $myvmk2 = $vmks[$vmknum - 1] } if ((-not(Test-Path variable:myvmk2) -or ($myvmk2 -ne $null))) { $myvmk2 = $myhost | Get-VMHostNetworkAdapter | Where-Object {$_.Name -like "$Test2Vmk"} $mask = [ipaddress]$myvmk2.SubnetMask $binary = [convert]::ToString($mask.Address, 2) $mask_length = ($binary -replace 0,$null).Length Write-Host "Using $($myvmk2.Name) ($($myvmk2.IP)/$($mask_length)) for Test 2" } $vmk2testvalid = $false while (-not $vmk2testvalid) { if (($Test2Host -ne "") -and $Test2Host) { $thisip = [ipaddress]$Test2Host $subnet = [ipaddress]$myvmk2.IP $netmask = [ipaddress]$myvmk2.SubnetMask $ipbits = [int[]]$($myvmk2.IP).split('.') $maskbits = [int[]]$($myvmk2.SubnetMask).split('.') $networkidbits = 0..3 | ForEach-Object { $ipbits[$_] -band $maskbits[$_] } $networkid = [ipaddress]($networkidbits -join '.') If ($networkid.Address -eq ($thisip.Address -band $netmask.Address)) { $vmk2testvalid = $true } else { Write-Host "Error: IP Address is outside the allowed subnet." -ForegroundColor Red $Test2Host = Read-Host "Enter IP Address to ping for Test 2" } } else { $Test2Host = Read-Host "Enter IP Address to ping for Test 2" } } While ( (-not ($Test2Frame -is [int]) -or ($Test2Frame -lt 1500) ) ) { if ($Test2Frame -eq 0) { $Test2Frame = Read-Host "`nFrame size for Test 2 (1500)" if (!($Test2Frame -is [int]) -or ($Test2Frame -lt 1500)) { $Test2Frame = 1500 } } } Write-host "`nBegin Testing:" $esxcli = get-esxcli -vmhost (get-vmhost $myhost) -v2 $params1 = (get-esxcli -v2 -vmhost (get-vmhost $myhost)).network.diag.ping.CreateArgs() $params2 = (get-esxcli -v2 -vmhost (get-vmhost $myhost)).network.diag.ping.CreateArgs() $params1.host = $Test1Host $params1.interface = $Test1Vmk $params1.size = $Test1Frame $params1.count = 1 $params2.host = $Test2Host $params2.interface = $Test2Vmk $params2.size = $Test2Frame $params2.count = 1 $counter = 0 $test1passcount = 0 $test2passcount = 0 try { while (($counter -lt $Count) -or ($Count -eq 0)) { $counter += 1 $result1 = ($esxcli.network.diag.ping.Invoke($params1)).summary $result2 = ($esxcli.network.diag.ping.Invoke($params2)).summary $part1 = $Test1Vmk + "->" + $result1.HostAddr + "(" + $Test1Frame + ") " if ($result1.Received -eq 1) { $test1 = "Good" ++$test1passcount } else { $test1 = "Bad" } $part2 = $Test2Vmk + "->" + $result2.HostAddr + "(" + $Test2Frame + ") " if ($result2.Received -eq 1) { $test2 = "Good" ++$test2passcount } else { $test2 = "Bad" } Write-Host "$(([string]$counter).PadLeft(4,' ')): $($VMHost): $part1" -NoNewLine If ($test1 -eq "Good") { Write-Host "$test1" -NoNewLine -ForegroundColor Green } else { Write-Host "$test1" -NoNewLine -ForegroundColor Red } Write-Host " $part2" -NoNewLine If ($test2 -eq "Good") { Write-Host "$test2" -ForegroundColor Green } else { Write-Host "$test2" -ForegroundColor Red } Start-Sleep -seconds 1 } } finally { if ($counter -ne $Count) { Write-Host "`n--- Script processing cancelled." -ForegroundColor Red } Write-Host "`n------------------------------------------------" Write-Host "Results:" Write-Host "From: " -NoNewLine Write-Host $VMHost -ForegroundColor Yellow Write-Host "Count: " -NoNewLine Write-Host $counter -ForegroundColor Yellow Write-Host "`nTest 1:" Write-Host "VMKernel port: " -NoNewLine Write-Host $Test1Vmk -ForegroundColor Yellow Write-Host "Destination: " -NoNewLine Write-Host $Test1Host -ForegroundColor Yellow Write-Host "Frame Size: " -NoNewLine Write-Host $Test1Frame -ForegroundColor Yellow Write-Host "Success: " -NoNewLine Write-Host $test1passcount -ForegroundColor Green -NoNewLine Write-Host " - Failure: " -NoNewLine Write-Host ($counter - $test1passcount) -ForegroundColor Red Write-Host "`nTest 2:" Write-Host "VMKernel port: " -NoNewLine Write-Host $Test2Vmk -ForegroundColor Yellow Write-Host "Destination: " -NoNewLine Write-Host $Test2Host -ForegroundColor Yellow Write-Host "Frame Size: " -NoNewLine Write-Host $Test2Frame -ForegroundColor Yellow Write-Host "Success: " -NoNewLine Write-Host $test2passcount -ForegroundColor Green -NoNewLine Write-Host " - Failure: " -NoNewLine Write-Host ($counter - $test2passcount) -ForegroundColor Red }