Коллеги, приветствую. В этой небольшой статье-заметке я бы хотел представить несколько командлетов Powershell для работы с TCP и ICMP.
Зачем это нужно?
Время от времени возникает ситуация при которой необходимо проверить доступность различных узлов, как серверов, так и пользовательских ПК. Обычно для решения таких задач, может устанавливаться дополнительное ПО. Однако, есть и другие, более простые решения, не требующее инсталляции компонентов на компьютер. В этой статье мы рассмотрим проверку портов TCP и проверку через ICMP. Для работы потребуется только Powershell и умение его запускать. 🙂 Ниже будут представлены три вариации командлетов для проверки.
Как этим пользоваться
Если у Вас пока не было опыта работы с Powershell, ничего страшного. Для того, чтобы воспользоваться инструментами, которые мы рассматриваем в этой статье, понадобится выполнить несколько несложных действий.
- Запустить Windows Powershell ISE и включить область сценариев (CTRL+R).
- Скопировать код из этой статьи и вставить в область сценариев.
- Выполнить код нажатием клавиши F5.
После выполнения этих действий, командлеты станут доступны для использования в консоли снизу, под областью сценариев.
Проверка доступности TCP порта
Первый вариант содержит командлет, позволяющий проверить доступность одного порта для разных хостов.
function Test-Port { [CmdletBinding()] param ( [string[]]$Hostname='localhost', [int]$Port='80', [int]$Timeout='1000' ) foreach ($h in $Hostname) { $tab = "`t" $requestCallback = $state = $null $client = New-Object System.Net.Sockets.TcpClient $beginConnect = $client.BeginConnect($h, $Port, $requestCallback, $state) Start-Sleep -milli $Timeout if ($client.Connected) { Write-Host $h':'$Port -ForegroundColor Green } else { Write-Host $h':'$Port -ForegroundColor Red } $client.Close() } }
Попробуем запустить командлет и проверить его выполнение. Для примера укажем несколько хостов и проверим доступность 80 TCP-порта.
Теперь попробуем сделать тоже самое, но для 53 TCP-порта.
Сканер открытых TCP портов
Второй вариант немного отличается тем, что здесь можно указывать несколько портов для проверки. Также у него снижено время ожидания ответа TCP, для того, чтобы нам не пришлось долго ждать результатов проверки большого количества портов и хостов.
function Check-Ports { [CmdletBinding()] param ( [string[]]$Hostname='localhost', [int[]]$Port=1..1000, [int]$Timeout='300' ) foreach ($h in $Hostname) { foreach ($p in $Port) { $requestCallback = $state = $null $client = New-Object System.Net.Sockets.TcpClient $beginConnect = $client.BeginConnect($h, $p, $requestCallback, $state) Start-Sleep -milli $Timeout if ($client.Connected) { Write-Host $h':'$p -ForegroundColor Green } $client.Close() } } }
Давайте попробуем выполнить проверку портов для узла google.ru. По умолчанию командлет проверяет порты от 1 до 1000.
Если нам необходим другой диапазон портов, мы можем определить его при помощи переменной и подставить в параметр -Ports.
Во время выполнения командлета может показаться, что он завис. 🙂 Мы можем убедиться в обратном запустив TCPView или утилиту resmon.
Также мы можем указать несколько хостов через запятую.
В ходе работы с командлетом, может возникнуть ситуация, при которой время ожидания ответа будет настолько малым, что удаленный хост просто не успеет ответить, либо настолько большим, что нам придется долго ждать результаты проверки. Для того, чтобы мы могли сами указывать это время, мы можем воспользоваться параметром -Timeout, который указывается в миллисекундах.
Для наглядной демонстрации попробуем замерить время выполнения командлета (по умолчанию значение Timeout = 300).
Теперь запустим командлет с параметром -Timeout 200.
Сканируем хосты по ICMP
Третий командлет может пригодиться в случае, когда необходимо проверить доступность хостов не через TCP, а при помощи ICMP. Один из таких случаев — у нас есть устройство, которому был назначен статический IP-адрес и мы не знаем точно, какой именно адрес был определен, только подсеть.
#Allow run powershell scripts for current user Set-ExecutionPolicy RemoteSigned -Scope CurrentUser #Get subnet calculator powershell function [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $URL = "https://gallery.technet.microsoft.com/scriptcenter/PowerShell-Subnet-db45ec74/file/141596/2/Get-IPs.ps1" $Path = "$env:HOMEPATH\Get-IPs.ps1" (New-Object System.Net.WebClient).DownloadFile($URL, $Path) . $Path function Ping-Hosts { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [array]$Subnet ) #Define subnet and ping hosts $Subnet = Get-IPs -Subnets $Subnet Write-Host "OK. Ping hosts in subnets starting. Be patient." foreach ($h in $Subnet) { $result = Test-Connection -Count 1 -ComputerName $h -ErrorAction SilentlyContinue if ($result) { Write-Host $h 'is Online' -ForegroundColor Green } } }
Запустим командлет и определим сеть для поиска. Например, попробуем поискать устройства во внутренней сети моего провайдера связи. В качестве параметра командлета укажем сеть для ICMP сканирования в формате IP-адрес/маска.
Мы можем указать несколько сетей сразу. Для этого мы просто перечисляем их в параметре через запятую.
Итоги
Итак, мы посмотрели в действии на несколько командлетов позволяющие протестировать доступность хостов. Какой командлет выбрать и для какого сценария — дело конкретного случая. Коллеги, если у Вас есть замечания или дополнения, приглашаю обсудить это в комментариях.