Я переписываю Пинг (в PS)
вывод
DateTime IP Status hasChanged ICMP ICMP-Ttl Tcp-53
-------- -- ------ ---------- ---- -------- ------
2018-11-29 12:13:44 8.8.8.8 50% True TimedOut 35
2018-11-29 12:13:46 8.8.8.8 100% True 20 116 20
2018-11-29 12:13:48 8.8.8.8 100% False 18 116 18
код
function Ping {
<#
.SYNOPSIS
Implementation PS du ping + tcp-Ping
.DESCRIPTION
retourne les temps de reponce ICMP (port 0) et TCP (port 1-65535)
.PARAMETER DestNode
HostName ou IP a tester,
pour le HostName une resolution DNS est faite a chaque boucle
.PARAMETER ports
Liste des ports TCP-IP a tester, le port 0 pour l'ICMP
.PARAMETER timeout
TimeOut des test individuel
.PARAMETER loop
nombre de boucle a effectuer, par defaut Infini
.PARAMETER Intervale
intervale entre chaque series de test
.PARAMETER ComputerName
permet de faire ce Ping en total remote,
si ComputerName est fournis, joignable et different de localhost alors c'est lui qui executera ce code et retourne le resultat
Requiere "Enable-PSRemoting -force"
.EXAMPLE
Ping sur ICMP + TCP:53,80,666 timeout 80ms (par test)
Ping 8.8.8.8 -ports 0,53,80,666 -timeout 80 | ft
.EXAMPLE
3 ping en remote depuis le serveur vdiv05 sur ICMP,3389,6516 le tous dans une jolie fenetre
ping 10.48.50.27 0,3389,6516 -ComputerName vdiv05 -count 3 | Out-GridView
.NOTES
Alban LOPEZ 2018
alban.lopez @t gmail.com
#>
Param(
[string]$DestNode = 'vps.opt2',
[ValidateRange(0, 65535)]
[int[]]$ports = @(0, 22, 135),
[ValidateRange(0, 2000)]
[int]$timeout = 200,
[alias("count")][int32]$loop = [int32]::MaxValue, # 68 annees !
[ValidateSet(250, 500, 1000, 2000, 4000, 10000)]
[int]$Intervale = 2000,
$size = 1Kb,
$ComputerName = $null
)
begin {
if ($computerName -and $computerName -notmatch "^(\.|localhost|127.0.0.1)$|^$($env:computername)" -and (Test-TcpPort -DestNodes $computerName -ConfirmIfDown)) {
$pingScriptBlock = Include-ToScriptblock -functions 'write-logStep', 'write-color', 'Write-Host', 'ping', 'Test-TcpPort', 'Include-ToScriptblock'
} else {
$ComputerName = $null
$ObjPing = [pscustomobject]@{
DateTime = $null
IP = $null
Status = $null
hasChanged = $null
}
$ObjPings = $test = @()
if (!$ports) {$ports = @(0)}
$Ports | ForEach-Object {
if ($_) {
# TCP
$ObjPing | Add-Member -MemberType NoteProperty -Name "Tcp-$_" -Value $null
$test += "Tcp-$_"
}
else {
# ICMP
$ping = new-object System.Net.NetworkInformation.Ping
$ObjPing | Add-Member -MemberType NoteProperty -Name ICMP -Value $null
$ObjPing | Add-Member -MemberType NoteProperty -Name 'ICMP-Ttl' -Value $null
# $ObjPing | Add-Member -MemberType NoteProperty -Name 'ICMP-Size' -Value $size
$buffer = [byte[]](1..$size | ForEach-Object {get-random -Minimum 20 -Maximum 255})
$test += "ICMP ($size Octs)"
}
}
# Write-LogStep -prefixe 'L.%Line% Ping' "Ping [$DestNode] ", ($test -join(' + ')) ok
}
}
process {
if(!$ComputerName){
While ($loop--) {
$ms = (Measure-Command {
try {
$ObjPing.DateTime = (get-date)
$ObjPing.status = $ObjPing.haschanged = $null
$ObjPing.IP = [string][System.Net.Dns]::GetHostAddresses($DestNode).IPAddressToString
#Write-LogStep -prefixe 'L.%Line% Ping' "Ping $DestNode", $ObjPing.IP wait
foreach ($port in $ports) {
if ($port) {
# TCP
$ObjPing."Tcp-$port" = $iar = $null
try {
$tcpclient = new-Object system.Net.Sockets.TcpClient # Create TCP Client
$iar = $tcpclient.BeginConnect($ObjPing.IP, $port, $null, $null) # Tell TCP Client to connect to machine on Port
$timeMs = (Measure-Command {
$wait = $iar.AsyncWaitHandle.WaitOne($timeout, $false) # Set the wait time
}).TotalMilliseconds
}
catch {
# Write-verbose $_
}
# Write-LogStep -prefixe 'L.%Line% Ping' "Tcp-$port", $x.status, $timeMs ok
# Check to see if the connection is done
if (!$wait) {
# Close the connection and report timeout
$ObjPing."Tcp-$port" = 'TimeOut'
$tcpclient.Close()
}
else {
try {
$ObjPing."Tcp-$port" = [int]$timeMs
$ObjPing.status ++
# Write-LogStep -prefixe 'L.%Line% Ping' 'TCP ', "$($ObjPing."Tcp-$port") ms" ok
$tcpclient.EndConnect($iar) | out-Null
$tcpclient.Close()
}
catch {
# $ObjPing."Tcp-$port" = 'Unknow Host'
}
}
if ($tcpclient) {
$tcpclient.Dispose()
$tcpclient.Close()
}
}
else {
# ICMP
$ObjPing.ICMP = $ObjPing."ICMP-Ttl" = $null # $ObjPing."ICMP-Size"
try {
$x = $ping.send($ObjPing.IP, $timeOut, $Buffer)
if ($x.status -like 'Success') {
$ObjPing."ICMP" = [int]$x.RoundtripTime
$ObjPing."ICMP-Ttl" = $x.Options.Ttl
# $ObjPing."ICMP-Size" = $x.Buffer.Length
$ObjPing.status ++
# Write-LogStep -prefixe 'L.%Line% Ping' 'ICMP ', "$($x.RoundtripTime) ms", $x.Options.Ttl, $x.Buffer.Length ok
}
else {
# Write-LogStep -prefixe 'L.%Line% Ping' 'ICMP ', "$($x.RoundtripTime) ms", $x.Options.Ttl, $x.Buffer.Length Warn
$ObjPing."ICMP" = $x.status
$ObjPing."ICMP-Ttl" = $ObjPing."ICMP-Size" = '-'
}
}
catch {
# $ObjPing.ICMP = 'Unknow Host'
}
}
}
}
catch {
# Write-LogStep -prefixe 'L.%Line% Ping' '', 'Inpossible de determiner le noeud de destination !' error
$ObjPing.Status = 0
}
$ObjPing.status = "$([int]([Math]::Round($ObjPing.status / $ports.count,2) * 100))%"
$ObjPing.hasChanged = !($ObjPing.Status -eq $last -and $ObjPing.IP -eq $IP )
$last = $ObjPing.Status
$IP = $ObjPing.IP
ipconfig /flushdns
}).TotalMilliseconds
$ObjPings += $ObjPing
$ObjPing
if ($loop -and $Intervale - $ms -gt 0) {
start-sleep -m ($Intervale - $ms)
}
}
}
}
end {
if ($computerName) {
$pingScriptBlock = $pingScriptBlock | Include-ToScriptblock -StringBlocks "Ping -DestNode $DestNode -ports $($ports -join(',')) -timeout $timeout -loop $loop -Intervale $Intervale"
Invoke-Command -ComputerName $ComputerName -ScriptBlock $pingScriptBlock | Select-Object -Property * -ExcludeProperty RunspaceID
}
}
}
для удаленного использования с -computerName args add function:
function Include-ToScriptblock {
<#
.SYNOPSIS
integre des fonctions dans un script-block
.DESCRIPTION
Ajoute au debut d'un scriptBlock (au niveau du marquage IncludeArea)
.PARAMETER functions
liste des fonctions a ajouter
.PARAMETER ScriptBlock
ScriptBlock a ettendre
.EXAMPLE
ettend un scriptBlock avec la finction test-TcpPort
Include-ToScriptblock -ScriptBlock {
param($x = 2)
# Inclide Area #
run $x
} -functions test-TcpPort
.NOTES
Alban LOPEZ 2018
alban.lopez @t gmail.com
#>
param (
[Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
[ScriptBlock]$ScriptBlock = [scriptBlock]{
# Inclide Area #
},
[string[]]$Functions,
[string[]]$StringBlocks,
[string]$marker = '# Inclide Area #'
)
begin {
$FuncTionSting = @()
}
process {
$ScriptBlockStr = $ScriptBlock.ToString()
if ($ScriptBlockStr -notmatch $marker) {
throw "Ou inclure ce code dans le ScriptBlock ? : utiliser le marquage `"$marker`""
}
foreach ($function in ($functions | ?{$_})) {
try {
$function = Get-Item function:$function -ea stop
$FuncTionSting += "`r`n# Imported from $($function.Source), V$($function.Version)`r`n $($function.CommandType) $($function.name){$($function.Definition)}`r`n`r`n"
}
catch {
if ($function -notlike 'Write-Host') {
# Write-LogStep -prefixe 'L.%Line% %Caller%' $function, $_ Error
}
}
}
foreach ($StringBlock in ($StringBlocks | ?{$_})) {
try {
$FuncTionSting += "`r`n$StringBlock`r`n`r`n"
}
catch {
# Write-LogStep -prefixe 'L.%Line% %Caller%' '', $_ Error
}
}
}
end {
[ScriptBlock]::Create($ScriptBlockStr.Replace($marker, "$FuncTionSting`r`n`r`n$marker"))
}
}