Проверить доступность udp порта windows powershell

Test-NetConnection — готовый к использованию командлет для проверки сетевого подключения появился в PowerShell 4.0 (Windows 2012 R2, Windows 8.1 и новее). Этот командлет можно использовать для проверки ответа и доступности удалённого сервера или сетевой службы на нём, портов TCP, заблокированных брандмауэрами, проверки доступности и маршрутизации ICMP. Фактически, командлет Test-NetConnection может заменить сразу несколько стандартных инструментов сетевого администрирования: ping, traceroute, сканер TCP-портов и т. д.

Test-NetConnection — готовый к использованию командлет для проверки сетевого подключения появился в PowerShell 4.0 (Windows 2012 R2, Windows 8.1 и новее). Этот командлет можно использовать для проверки ответа и доступности удалённого сервера или сетевой службы на нём, портов TCP, заблокированных брандмауэрами, проверки доступности и маршрутизации ICMP. Фактически, командлет Test-NetConnection может заменить сразу несколько стандартных инструментов сетевого администрирования: ping, traceroute, сканер TCP-портов и т. д.

Время от времени любой администратор должен проверять доступность службы на удалённом сервере, проверяя ответ удалённого TCP-порта (например, доступность электронной почты или веб-сервера). Более того, большинство администраторов используют для выполнения такой проверки порта с помощью команды telnet. Например, чтобы убедиться, что служба SMTP отвечает на почтовом сервере (по умолчанию она отвечает на TCP-порту 25), достаточно выполнить команду

telnet mail.site.com 25

Но начиная с Windows 7, клиент telnet стал функцией, которую нужно устанавливать отдельно. Давайте посмотрим, как проверить открытые/закрытые TCP-порты с помощью PowerShell.

Основное преимущество командлета Test-NetConnection заключается в том, что он уже входит в состав всех современных версий Windows, и вам не нужно устанавливать его отдельно. Командлет является частью модуля NetTCPIP (начиная с PoSh v4.0).

Подсказка: вы можете проверить текущую установленную версию PowerShell с помощью команды:

$PSVersionTable.PSVersion

Значение 7 в столбце Major означает, что на вашем компьютере установлена оболочка PowerShell 7.2.

Тестирование открытости/закрытости TCP-портов с помощью Test-NetConnection

Давайте проверим, открыт ли (доступен) TCP-порт 80 (протокол HTTP) на удалённом почтовом сервере, используя Test-NetConnection:

Test-NetConnection -ComputerName hackware-arch -Port 80

Примечание: используя командлет Test-NetConnection, вы можете проверить только подключение к порту TCP, и он не применим для проверки доступности удалённых портов UDP.

Укороченная версия той же команды выглядит так:

TNC hackware-arch -Port 80

Рассмотрим результат выполнения команды:

ComputerName     : hackware-arch
RemoteAddress    : 192.168.0.88
RemotePort       : 80
InterfaceAlias   : Ethernet
SourceAddress    : 192.168.0.101
TcpTestSucceeded : True

Как видите, командлет преобразует имя сервера в IP-адрес и проверяет доступность порта TCP. На указанном сервере TCP-порт 80 (RemotePort : 80) открыт (TcpTestSucceeded : True).

Командлет имеет специальный параметр -CommonTCPPort, который позволяет указать имя известного сетевого протокола (HTTP, RDP, SMB, WINRM).

Например, чтобы проверить доступность веб-сервера HTTP, вы можете использовать команду:

Test-NetConnection -ComputerName hackware-arch -CommonTCPPort HTTP

Или открытость порта RDP (3389):

Test-NetConnection ny-rds1 -CommonTCPPort RDP

Вы можете перечислить все параметры, которые возвращает командлет Test-NetConnection:

Test-NetConnection hackware-arch -port 80 | Format-List *

Обратите внимание на строку в выводе:

PingSucceeded            : False

Это означает следующее:

  1. Перед проверкой порта командлет пытается выполнить пинг
  2. В данном случае компьютер не ответил на пинг (такое бывает — даже включенные компьютеры не обязаны отвечать на пинг, это можно изменить в настройках файервола)
  3. Даже при неудачном пинге Test-NetConnection всё равно проверяет доступность порта

Если вам нужно только посмотреть, доступен ли порт, его можно проверить быстрее:

TNC hackware-arch -port 80 -InformationLevel Quiet

Командлет вернул True, что означает, что удалённый порт открыт.

Подсказка: в более ранних версиях PowerShell вы могли проверить доступность TCP-порта следующим образом:

(New-Object System.Net.Sockets.TcpClient).Connect('hackware-arch', 80)

В Windows 10/Windows Server 2016 вы можете использовать командлет Test-NetConnection для отслеживания маршрута к удалённому серверу с помощью параметра -TraceRoute (аналог команды tracert в Windows). Параметр -Hops позволяет ограничить максимальное количество хопов (узлов) при проверке маршрута.

Test-NetConnection suip.biz -TraceRoute

Связанная статья: Трассировка сетевого маршрута

Командлет вернул суммарную задержку сети при доступе к серверу в миллисекундах (PingReplyDetails (RTT) : 36 ms) и все IP-адреса маршрутизаторов на пути к целевому серверу.

Test-NetConnection в скриптах мониторинга PowerShell

Следующая команда позволяет вам проверить доступность определённого порта на нескольких серверах, список которых хранится в текстовом файле list_servers.txt (расположен в папке c:PS). Нам нужны серверы, на которые не отвечает указанный сервис:

Get-Content c:PSlist_servers.txt | where { -NOT (Test-Netconnection $_ -Port 25 -InformationLevel Quiet)}| Format-Table -AutoSize

Точно так же вы можете создать простой скрипт мониторинга, который проверяет доступность серверов и отображает уведомление, если один из серверов недоступен.

Например, вы можете проверить доступность базовых служб на всех контроллерах домена (список контроллеров домена можно получить с помощью командлета Get-ADDomainController). Давайте проверим следующие службы на DC (инструмент PortQry имеет аналогичное правило «Domain and trusts»):

  • RPC – TCP/135
  • LDAP – TCP/389
  • LDAP – TCP/3268
  • DNS – TCP/53
  • Kerberos – TCP/88
  • SMB – TCP/445

Скрипт проверит указанные TCP-порты на контроллерах домена, и, если один из портов недоступен, он выделит его красным цветом (вы можете запустить этот скрипт PowerShell как службу Windows).

$Ports  = "135","389","636","3268","53","88","445","3269", "80", "443"
$AllDCs = Get-ADDomainController -Filter * | Select-Object Hostname,Ipv4address,isGlobalCatalog,Site,Forest,OperatingSystem
ForEach($DC in $AllDCs)
{
	Foreach ($P in $Ports){
		$check=Test-NetConnection $DC -Port $P -WarningAction SilentlyContinue
		If ($check.tcpTestSucceeded -eq $true)
			{Write-Host $DC.name $P -ForegroundColor Green -Separator " => "}
		else
			{Write-Host $DC.name $P -Separator " => " -ForegroundColor Red}
	}
}

А это чуть модифицированная версия скрипта, в которой список серверов считывается из файла C:UsersMiAlDocumentslist_servers.txt, а также выводятся имена хостов, чтобы было понятно, чьи именно порты проверяются:

$Ports  = "135","389","636","3268","53","88","445","3269", "80", "443"
$AllHosts = Get-Content C:UsersMiAlDocumentslist_servers.txt
ForEach($Hosts in $AllHosts)
{
	$Hosts
	Foreach ($P in $Ports){
		$check=Test-NetConnection $Hosts -Port $P -WarningAction SilentlyContinue
		If ($check.tcpTestSucceeded -eq $true)
			{Write-Host $Hosts.name $P -ForegroundColor Green -Separator " => "}
		else
			{Write-Host $Hosts.name $P -Separator " => " -ForegroundColor Red}
	}
}

Код скрипта сохранён в файл port_checker.ps1, пример запуска:

C:UsersMiAlDocumentsport_checker.ps1

Простой сканер IP-сетей/портов с помощью PowerShell

Вы также можете реализовать простой сетевой сканер портов и IP-подсетей для сканирования удалённых серверов или подсетей на предмет открытых/закрытых TCP-портов.

Просканируем диапазон IP-адресов в поисках открытого порта 80:

foreach ($ip in 100..150) {Test-NetConnection -Port 80 -InformationLevel "Detailed" 192.168.1.$ip}

А этот пример просканирует диапазон TCP-портов от 1 до 1024 на указанном удалённом сервере:

foreach ($port in 1..1024) {If ((Test-NetConnection 192.168.0.88 -Port $port -WarningAction SilentlyContinue).tcpTestSucceeded -eq $true){ "TCP port $port is open!"}}

Скорость проверки, конечно, оставляет желать лучшего.

Test-NetConnection в Linux

На момент написания, в Linux командлет Test-NetConnection отсутствует

Но старый способ проверки открытых портов работает:

(New-Object System.Net.Sockets.TcpClient).Connect('suip.biz', 80)

Связанные статьи:

  • Как в PowerShell просмотреть открытые порты. Как узнать, какая программа прослушивает порт (100%)
  • Как в PowerShell просмотреть открытые порты UDP (72%)
  • Использование PortQry для проверки открытых портов TCP/UDP (сканер портов) (64%)
  • Как в PowerShell установить IP, маску сети, шлюз по умолчанию и DNS для сетевого интерфейса (58%)
  • Как в PowerShell настроить сетевой интерфейс на использование динамичного IP адреса (DHCP) (58%)
  • Как настроить Windows Server 2022 с помощью PowerShell (RANDOM — 8%)

В PowerShell 4.0 (Windows 2012 R2, Windows 8.1 и выше) появился встроенный командлет для проверки сетевых соединений — Test-NetConnection. С помощью данного командлета вы можете проверить доступность удаленного сервера или сетевой службы на нем, блокировку TCP портов файерволами, проверить доступность по ICMP и маршрутизацию. По сути, командлет
Test-NetConnection
позволяет заменить сразу несколько привычных сетевых утилит: ping, traceroute, сканер TCP портов и т.д.

Содержание:

  • TCP Port Ping: Использование Test-NetConnection для проверки открытых портов и доступности серверов
  • Test-NetConnection в скриптах мониторинга
  • Сканер сети на PowerShell

Любому администратору периодически приходится проверять доступность службы на удаленном сервере путем проверки ответа от удаленного TCP порта (например, доступность почтового или веб сервера). Причем, все привыкли, что такую проверку быстрее всего выполнить с помощью команды telnet. Например, для проверки доступности SMTP службы на почтовом сервере (по умолчанию он отвечает на 25 TCP порту) достаточно выполнить команду
telnet msk-msg01.winitpro.ru 25
. Но начиная с Windows 7 клиент telnet выделен в отдельный компонент, который нужно устанавливать отдельно. Посмотрим, как выполнить аналогичное действие в PowerShell.

Основное преимущество командлета Test-NetConnection – он уже входит в состав всех современных версий Windows и вам не нужно устанавливать его отдельно. Командлет входит в состав модуля NetTCPIP (начиная с PoSh v4.0).

TCP Port Ping: Использование Test-NetConnection для проверки открытых портов и доступности серверов

Проверим, открыт ли порт TCP 25 (SMTP протокол) на почтовом сервере с помощью Test-NetConnection:

Test-NetConnection -ComputerName msk-msg01 -Port 25

Примечание. С помощью командлета Test-NetConnection можно проверить только TCP соединение, для проверки доступности UDP портов он не применим.

В сокращенном виде аналогичная команда выглядит так:

TNC msk-mail1 -Port 25

Test-NetConnection - прверка ответа от TCP порта

Разберем результат команды:

ComputerName           : msk-msg01
RemoteAddress          : 10.10.1.7
RemotePort             : 25
InterfaceAlias         : CORP
SourceAddress          : 10.10.1.70
PingSucceeded          : True
PingReplyDetails (RTT) : 0 ms
TcpTestSucceeded       : True

Как вы видите, командлет выполняет разрешение имени сервера в IP адрес, выполняется проверка ответа ICMP (аналог ping) и доступность TCP порта. Указанный сервер доступен по ICMP (
PingSucceeded = True
) и 25 TCP порт также отвечает (
RemotePort=25, TcpTestSucceeded= True
).

Примечание. В некоторых случаях может оказаться, что PingSucceeded=False, а TcpTestSucceeded= True. Скорее всего означает, что на удаленном сервере запрещен ICMP Ping.

У командлета есть специальный параметр –CommonTCPPort, позволяющий указать наименование известного сетевого протокола (HTTP, RDP, SMB, WINRM).

Например, чтобы проверить доступность веб-сервера, можно использовать команду:

Test-NetConnection -ComputerName winitpro.ru -CommonTCPPort HTTP

Или доступность RDP порта (3389):

Test-NetConnection msk-rds1 –CommonTCPPort RDP

Можно вывести все параметры, которые возвращает командлет Test-NetConnection:

Test-NetConnection msk-man01 -port 445|Format-List *

Test-NetConnection все свойства

Если нужна только информация по доступности TCP порта, в более лаконичном виде проверка может быть выполнена так:

TNC msk-mail1 -Port 25 -InformationLevel Quiet

Командлет вернул True, значит удаленный порт доступен.

TNC InformationLevel Quiet

Совет. В предыдущих версиях PowerShell проверить доступность удаленного TCP порта можно так:

(New-Object System.Net.Sockets.TcpClient).Connect(‘msk-msg01’, 25)

New-Object System.Net.Sockets.TcpClient

В Windows 10/ Windows Server 2016 вы можете использовать командлет Test-NetConnection для трассировки маршрута до удаленного сервера при помощи параметра TraceRoute (аналог tracert). С помощью параметра Hops можно ограничить максимальное количество хопов при проверке.

Test-NetConnection msk-man01 –TraceRoute

Командлет вернул сетевую задержку при доступе к серверу в милисекундах (
PingReplyDetails (RTT) : 41 ms
) и все IP адреса маршрутизаторов на пути до целевого сервера.

Test-NetConnection TraceRoute

Test-NetConnection в скриптах мониторинга

Следующая команда позволить проверить доступность определенного порта на множестве серверов, список которых хранится в текстовом файле servers.txt. Нас интересуют сервера, где искомая служба не отвечает:

Get-Content c:Distrservers.txt |  where { -NOT (Test-Netconnection $_ -Port 25  -InformationLevel Quiet)}| Format-Table –AutoSize

Аналогичным образом вы можете создать простейшую систему мониторинга, которая проверяет доступность серверов и выводит уведомление, если один из серверов недоступен.

Например, вы можете проверить доступность основных служб на всех контроллеров домена (список DC можно получить командлетом Get-ADDomainController). Проверим следующие службы на DC (в утилите PortQry есть аналогичное правило Domain and trusts):

  • RPC – TCP/135
  • LDAP – TCP/389
  • LDAP – TCP/3268
  • DNS – TCP/53
  • Kerberos – TCP/88
  • SMB – TCP/445

$Ports  = "135","389","636","3268","53","88","445","3269", "80", "443"
$AllDCs = Get-ADDomainController -Filter * | Select-Object Hostname,Ipv4address,isGlobalCatalog,Site,Forest,OperatingSystem
ForEach($DC in $AllDCs)
{
Foreach ($P in $Ports){
$check=Test-NetConnection $DC -Port $P -WarningAction SilentlyContinue
If ($check.tcpTestSucceeded -eq $true)
{Write-Host $DC.name $P -ForegroundColor Green -Separator " => "}
else
{Write-Host $DC.name $P -Separator " => " -ForegroundColor Red}
}

Скрипт проверит указанные TCP порты на контроллерах домена, и, если один из портов недоступен, выделит его красным цветом (с небольшими доработками можно запустить данный PowerShell скрипт как службу Windows).

powershell: test-netconnection проверить порты на конроллерах домена

Сканер сети на PowerShell

Также вы можете реализовать простой сканер портов и IP подсетей для сканирования удаленных серверов или подсетей на открытые/закрытые TCP порты.

Просканируем диапазон IP адресов на открытый порт 3389:

foreach ($ip in 5..30) {Test-NetConnection -Port 3389 -InformationLevel "Detailed" 10.10.10.$ip}

Просканируем диапазон TCP портов от 1 до 1024 на указанном сервере:

foreach ($port in 1..1024) {If (($a=Test-NetConnection srvfs01 -Port $port -WarningAction SilentlyContinue).tcpTestSucceeded -eq $true){ "TCP port $port is open!"}}

powershell сканирование открытых сетевых портов

It was brought to my attention earlier in the week that my Test-Port script had a fairly big bug involving checking the UDP port to determine whether it was open or not. Initially, the function would always come back with a True statement giving a false positive that the port was open, when in fact it was not. In the case of the bug report, the system in question was actually turned off, making it even more of a false positive. The reason behind this is that sending out a message or request via UDP does not guarantee that a response will be given back, unlike TCP where you will know pretty quickly if the port is open or closed. More information here, here and here.

So with that, I set off to find a good way of querying for an open UDP port.  I immediately went to the MSDN page for the System.Net.Sockets.UDPClient to see what methods were available to me. I also took note of the example that was given for making a UDP connection and receiving a message from that port. Since this was written in C#, I knew I could easily translate this into PowerShell (and in fact I left a community contribution on the page).

There are some gotchas  here that I will share with you that I came across while working on this. I can tell you that one of these caused me some pain as it made the executed code hang forever.

The first thing we need to do is create the UDPClient object. Using a constructor, I am opening the local UDP port on my laptop using port 11000:

$udpobject = new-Object system.Net.Sockets.Udpclient(11000)

Now that I have my object created, I can now proceed to set up my message string that will be sent along with actually sending out the data. The trick here with sending out a message via the UDPclient is that it must be in bytes. So while I supply a string message to send, it must be converted into a byte format.  This is done by using the System.Text.ASCIIEncoding class.  For this message, I will just send a date string to the remote server.

$a = new-object system.text.asciiencoding
$byte = $a.GetBytes("$(Get-Date)")

Capture

Ok, now lets create the “connection” to the remote server using the Connect() method. This method requires us to supply a hostname and port to connect on. I say “connection” because even if the port isn’t open, it will still act like a connection was made. You will only receive an error if the host does not exist, or is not on the network.

$udpobject.Connect("dc1",11000)

Now lets send the message to the remote host. Again, just like making the connection, we will not receive any sort of response if the send was successful or not. By doing this, we are forcing some sort of response by the port, either it will receive the data, or we will receive an error stating the port was closed.

[void]$udpobject.Send($byte,$byte.length)

After sending the data, we now need to setup the receiving portion of the code. The Receive() method requires the System.Net.IPEndpoint class to be supplied. That can be created using the following code by declaring that we are looking for data sent to us from any source.

#IPEndPoint object will allow us to read datagrams sent from any source.
$remoteendpoint = New-Object system.net.ipendpoint([system.net.ipaddress]::Any,0)

The 0 stands for any port and [System.Net.IPAddress]::Any means from any host.

Now that I have created an endpoint, lets now set the udp object to wait until a response is given back from the host which we sent the data to. We will also read the response back from the remote host.

 #Blocks until a message returns on this socket from a remote host.
$receivebytes = $udpobject.Receive([ref]$remoteendpoint)

#Convert returned data into string format
[string]$returndata = $a.GetString($receivebytes)

#Uses the IPEndPoint object to show that the host responded.
Write-Host "This is the message you received: $($returndata.ToString())"
Write-Host "This message was sent from: $($remoteendpoint.address.ToString()) on their port number: $($remoteendpoint.Port.ToString())"

Let’s assume that the port is closed on the remote host. Running the first line of the code will produce an error such as the one below.

Capture

Luckily, this error can be caught using Try/Catch so you can easily write to a log or anything else if this happens. Ok, so we know how to tell if a UDP port is closed on a remote machine, but what is going to happen if that port is open?  Let’s find out.  I am going to open a UDP port on my server, DC1 and then we will run the same code to see what happens.

First, lets open up that port on DC1:

Capture

Perfect, now lets re-run the same code and see what happens:

Capture

Cool, no errors and now we are just waiting for a response back from the remote server.

10 minutes later… (crickets chirping)

Capture

Hmmm… nothing at all being returned. You might think that the code is hung or something else is going on.  And you are right about something else going on.  Remember what I said earlier about how UDP works? It will not return anything to use even if you send data to that port. So in effort, this wait will basically go on forever.

Here is a gotcha that I was telling you about.  One way to resolve this is by setting a timeout on the receiving of data. To do this, you need to look at the properties of the $udpobject object we created:

PS C:Usersboe> $udpobject | Format-List *

Client              : System.Net.Sockets.Socket
Available           : 0
Ttl                 : 64
DontFragment        : False
MulticastLoopback   : True
EnableBroadcast     : False
ExclusiveAddressUse : False

Take note of the client property which consists of the System.Net.Sockets.Socket class. Within this class is where we need to make a slight adjustment to the receiving timeout. Now we will expand out the Client property to find out where we need to make that change.

PS C:Usersboe> $udpobject.client

Available           : 0
LocalEndPoint       : 0.0.0.0:11000
RemoteEndPoint      :
Handle              : 1364
Blocking            : True
UseOnlyOverlappedIO : False
Connected           : False
AddressFamily       : InterNetwork
SocketType          : Dgram
ProtocolType        : Udp
IsBound             : True
ExclusiveAddressUse : False
ReceiveBufferSize   : 8192
SendBufferSize      : 8192
ReceiveTimeout      : 0
SendTimeout         : 0
LingerState         :
NoDelay             :
Ttl                 : 64
DontFragment        : False
MulticastLoopback   : True
EnableBroadcast     : False

And there it is, the ReceiveTimeout property. Currently, it is set to 0, meaning that this will never timeout.  Keep in mind that the value you supply will be in milliseconds. I will go ahead and set this to 10000 milliseconds and now we will re-run the code again to see what happens.

Capture

Now, after 10 seconds, we get the error stating:

Exception calling “Receive” with “1” argument(s): “A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond”

Setting the timeout now allows the code to error out when the port is open so it does not wait forever for a response back. Plus, this can be caught with a Try/Catch statement so we can parse the error and show that the port is open on the system. One more gotcha is that if the server is powered down, but still in DNS, then the error will still occur instead of automatically reporting an error. So keep that in mind. In fact, performing a ping test (or Test-Connection)  prior to making the port check would be recommended.

Sending and Receiving a Message

Ok, now for something fun.  I am going to go onto DC1 and send a response to my laptop on the same port. So instead of a timeout, you will see the message and the ip and port that the message responded back on.

Lets start it off by opening port 11000 on DC1 and connecting to my laptop.

$udp = new-object System.Net.Sockets.Udpclient(11000)
$udp.Connect("boe-laptop",11000)

Capture

Now we create our UDP object here and wait for our message to be sent from DC1. For this I will not specify a timeout as I need to run some code on DC1. Most of the code will not run until it has received a message from DC1.

$udpobject = new-Object system.Net.Sockets.Udpclient(11000)
$remoteendpoint = New-Object system.net.ipendpoint([system.net.ipaddress]::Any,0)
$receivebytes = $udpobject.Receive([ref]$remoteendpoint)
[string]$returndata = $a.GetString($receivebytes)
Write-Host -fore green "This is the message you received: $($returndata.ToString())"
Write-Host -fore green "This message was sent from: $($remoteendpoint.address.ToString()) on their port number: $($remoteendpoint.Port.ToString())"

Capture

Now the command is waiting for a message from DC1. Lets go back to DC1 and create a message from a string and convert it into bytes. Once converted to bytes, we can then send the message to the waiting laptop.

$a = New-Object system.text.asciiencoding
$byte = $a.GetBytes("This message sent from DC1 to boe-laptop")
$udp.Send($byte,$byte.length)

If you have both windows available to view. You will notice that as soon as you perform the Send() method, the waiting PowerShell console will immediately process the message and display the results.

Capture

Pretty cool, isn’t it? You could go back and forth between these to systems and send messages if you wanted to.

That wraps it up for my post on working with UDP ports in PowerShell. As you can see, it is pretty easy to find out if a UDP port is actually open as long as you have a timeout specified in the UDPClient.Client properties. Once you do that, just some simple parsing of the error can determine if the port was open or closed.

Code

I am going to reference my Test-Port function I wrote a while back that is now updated with the UDP code bug fix.

Script Repository

PoshCode

function Test-Port{  
<#    
.SYNOPSIS    
    Tests port on computer.  
    
.DESCRIPTION  
    Tests port on computer. 
     
.PARAMETER computer  
    Name of server to test the port connection on.
      
.PARAMETER port  
    Port to test 
       
.PARAMETER tcp  
    Use tcp port 
      
.PARAMETER udp  
    Use udp port  
     
.PARAMETER UDPTimeOut 
    Sets a timeout for UDP port query. (In milliseconds, Default is 1000)  
      
.PARAMETER TCPTimeOut 
    Sets a timeout for TCP port query. (In milliseconds, Default is 1000)
                 
.NOTES    
    Name: Test-Port.ps1  
    Author: Boe Prox  
    DateCreated: 18Aug2010   
    List of Ports: http://www.iana.org/assignments/port-numbers  
      
    To Do:  
        Add capability to run background jobs for each host to shorten the time to scan.         
.LINK    
    https://boeprox.wordpress.org 
     
.EXAMPLE    
    Test-Port -computer 'server' -port 80  
    Checks port 80 on server 'server' to see if it is listening  
    
.EXAMPLE    
    'server' | Test-Port -port 80  
    Checks port 80 on server 'server' to see if it is listening 
      
.EXAMPLE    
    Test-Port -computer @("server1","server2") -port 80  
    Checks port 80 on server1 and server2 to see if it is listening  
    
.EXAMPLE
    Test-Port -comp dc1 -port 17 -udp -UDPtimeout 10000
    
    Server   : dc1
    Port     : 17
    TypePort : UDP
    Open     : True
    Notes    : "My spelling is Wobbly.  It's good spelling but it Wobbles, and the letters
            get in the wrong places." A. A. Milne (1882-1958)
    
    Description
    -----------
    Queries port 17 (qotd) on the UDP port and returns whether port is open or not
       
.EXAMPLE    
    @("server1","server2") | Test-Port -port 80  
    Checks port 80 on server1 and server2 to see if it is listening  
      
.EXAMPLE    
    (Get-Content hosts.txt) | Test-Port -port 80  
    Checks port 80 on servers in host file to see if it is listening 
     
.EXAMPLE    
    Test-Port -computer (Get-Content hosts.txt) -port 80  
    Checks port 80 on servers in host file to see if it is listening 
        
.EXAMPLE    
    Test-Port -computer (Get-Content hosts.txt) -port @(1..59)  
    Checks a range of ports from 1-59 on all servers in the hosts.txt file      
            
#>   
[cmdletbinding(  
    DefaultParameterSetName = '',  
    ConfirmImpact = 'low'  
)]  
    Param(  
        [Parameter(  
            Mandatory = $True,  
            Position = 0,  
            ParameterSetName = '',  
            ValueFromPipeline = $True)]  
            [array]$computer,  
        [Parameter(  
            Position = 1,  
            Mandatory = $True,  
            ParameterSetName = '')]  
            [array]$port,  
        [Parameter(  
            Mandatory = $False,  
            ParameterSetName = '')]  
            [int]$TCPtimeout=1000,  
        [Parameter(  
            Mandatory = $False,  
            ParameterSetName = '')]  
            [int]$UDPtimeout=1000,             
        [Parameter(  
            Mandatory = $False,  
            ParameterSetName = '')]  
            [switch]$TCP,  
        [Parameter(  
            Mandatory = $False,  
            ParameterSetName = '')]  
            [switch]$UDP                                    
        )  
    Begin {  
        If (!$tcp -AND !$udp) {$tcp = $True}  
        #Typically you never do this, but in this case I felt it was for the benefit of the function  
        #as any errors will be noted in the output of the report          
        $ErrorActionPreference = "SilentlyContinue"  
        $report = @()  
    }  
    Process {     
        ForEach ($c in $computer) {  
            ForEach ($p in $port) {  
                If ($tcp) {    
                    #Create temporary holder   
                    $temp = "" | Select Server, Port, TypePort, Open, Notes  
                    #Create object for connecting to port on computer  
                    $tcpobject = new-Object system.Net.Sockets.TcpClient  
                    #Connect to remote machine's port                
                    $connect = $tcpobject.BeginConnect($c,$p,$null,$null)  
                    #Configure a timeout before quitting  
                    $wait = $connect.AsyncWaitHandle.WaitOne($TCPtimeout,$false)  
                    #If timeout  
                    If(!$wait) {  
                        #Close connection  
                        $tcpobject.Close()  
                        Write-Verbose "Connection Timeout"  
                        #Build report  
                        $temp.Server = $c  
                        $temp.Port = $p  
                        $temp.TypePort = "TCP"  
                        $temp.Open = "False"  
                        $temp.Notes = "Connection to Port Timed Out"  
                    } Else {  
                        $error.Clear()  
                        $tcpobject.EndConnect($connect) | out-Null  
                        #If error  
                        If($error[0]){  
                            #Begin making error more readable in report  
                            [string]$string = ($error[0].exception).message  
                            $message = (($string.split(":")[1]).replace('"',"")).TrimStart()  
                            $failed = $true  
                        }  
                        #Close connection      
                        $tcpobject.Close()  
                        #If unable to query port to due failure  
                        If($failed){  
                            #Build report  
                            $temp.Server = $c  
                            $temp.Port = $p  
                            $temp.TypePort = "TCP"  
                            $temp.Open = "False"  
                            $temp.Notes = "$message"  
                        } Else{  
                            #Build report  
                            $temp.Server = $c  
                            $temp.Port = $p  
                            $temp.TypePort = "TCP"  
                            $temp.Open = "True"    
                            $temp.Notes = ""  
                        }  
                    }     
                    #Reset failed value  
                    $failed = $Null      
                    #Merge temp array with report              
                    $report += $temp  
                }      
                If ($udp) {  
                    #Create temporary holder   
                    $temp = "" | Select Server, Port, TypePort, Open, Notes                                     
                    #Create object for connecting to port on computer  
                    $udpobject = new-Object system.Net.Sockets.Udpclient
                    #Set a timeout on receiving message 
                    $udpobject.client.ReceiveTimeout = $UDPTimeout 
                    #Connect to remote machine's port                
                    Write-Verbose "Making UDP connection to remote server" 
                    $udpobject.Connect("$c",$p) 
                    #Sends a message to the host to which you have connected. 
                    Write-Verbose "Sending message to remote host" 
                    $a = new-object system.text.asciiencoding 
                    $byte = $a.GetBytes("$(Get-Date)") 
                    [void]$udpobject.Send($byte,$byte.length) 
                    #IPEndPoint object will allow us to read datagrams sent from any source.  
                    Write-Verbose "Creating remote endpoint" 
                    $remoteendpoint = New-Object system.net.ipendpoint([system.net.ipaddress]::Any,0) 
                    Try { 
                        #Blocks until a message returns on this socket from a remote host. 
                        Write-Verbose "Waiting for message return" 
                        $receivebytes = $udpobject.Receive([ref]$remoteendpoint) 
                        [string]$returndata = $a.GetString($receivebytes)
                        If ($returndata) {
                           Write-Verbose "Connection Successful"  
                            #Build report  
                            $temp.Server = $c  
                            $temp.Port = $p  
                            $temp.TypePort = "UDP"  
                            $temp.Open = "True"  
                            $temp.Notes = $returndata   
                            $udpobject.close()   
                        }                       
                    } Catch { 
                        If ($Error[0].ToString() -match "bRespond after a period of timeb") { 
                            #Close connection  
                            $udpobject.Close()  
                            #Make sure that the host is online and not a false positive that it is open 
                            If (Test-Connection -comp $c -count 1 -quiet) { 
                                Write-Verbose "Connection Open"  
                                #Build report  
                                $temp.Server = $c  
                                $temp.Port = $p  
                                $temp.TypePort = "UDP"  
                                $temp.Open = "True"  
                                $temp.Notes = "" 
                            } Else { 
                                <# 
                                It is possible that the host is not online or that the host is online,  
                                but ICMP is blocked by a firewall and this port is actually open. 
                                #> 
                                Write-Verbose "Host maybe unavailable"  
                                #Build report  
                                $temp.Server = $c  
                                $temp.Port = $p  
                                $temp.TypePort = "UDP"  
                                $temp.Open = "False"  
                                $temp.Notes = "Unable to verify if port is open or if host is unavailable."                                 
                            }                         
                        } ElseIf ($Error[0].ToString() -match "forcibly closed by the remote host" ) { 
                            #Close connection  
                            $udpobject.Close()  
                            Write-Verbose "Connection Timeout"  
                            #Build report  
                            $temp.Server = $c  
                            $temp.Port = $p  
                            $temp.TypePort = "UDP"  
                            $temp.Open = "False"  
                            $temp.Notes = "Connection to Port Timed Out"                         
                        } Else {                      
                            $udpobject.close() 
                        } 
                    }     
                    #Merge temp array with report              
                    $report += $temp  
                }                                  
            }  
        }                  
    }  
    End {  
        #Generate Report  
        $report 
    }
}

Introducing another addition to our portfolio of minimalistic tools for pentesting. This time we are going to be looking on a minimalistic TCP and UDP port scanner.

Written in pure PowerShell, this small yet powerful port scanner is useful in specific attack simulations where we cannot use any traditional or typical port scanners.

  • Introduction
  • Why writing port scanner from scratch?
  • TCP and UDP port scanner in PowerShell
  • List of features
  • Typical usage scenario
    • Port scan of a single host
    • Port scan of a network range
    • List of hosts in a file
  • Getting the results
  • Requirements and limitations
  • Conclusion
  • See also

Introduction

There are many network port scanners out there. Some of the most popular ones include Nmap, Masscan, Angry IP Scanner, ZMap any there are plenty of others.

They are all great, well tested and functional, but they are also big, complex and most importantly flagged by every decent Antivirus or EDR solution. And that can be a deal breaker in some penetration testing scenarios.

In some situations we simply need something small and minimalistic, something that we could write from scratch quickly, if we needed to.

Why writing port scanner from scratch?

Writing tools from scratch may be necessary, for instance, when we are performing pentest from a heavily restricted environment where we cannot use any typical pentesting tools.

This would be vital while testing of an isolated VDI / Citrix environment where we cannot upload anything or when we are performing a simulation of a disgruntled employee from a workstation with all the security controls in place.

In all these cases we would need to build our own tools in order for us to be able to perform basic operations such as port scanning.

Without port scanning abilities, we would hardly be able to make any progress, discover systems on the network, or perform any lateral movement for that matter.

Port scanner is simply a must and if we cannot use one, we have to make one.

For such occasions, I have developed the following quick and easy, but powerful and reliable port scanner.

To keep the size small, I have divided the scanner into two separate independent modules:

  • TCP port scanner: port-scan-tcp.ps1
  • UDP port scanner: port-scan-udp.ps1

So it’s really two port scanners, not one. Both scanners can be found in the following GitHub repository:

  • https://github.com/InfosecMatter/Minimalistic-offensive-security-tools

List of features

Both port scanners have the following features:

  • Detection of open, closed and filtered ports (both TCP and UDP)
  • Ability to scan a single host, network range or a list of hosts in a file
  • Adjustable timeout values for effective and reliable port scanning
  • Non-malicious – undetected by any Antivirus or EDR solution

From the design point of view:

  • Small and minimalistic – can be typed out by hand (on the keyboard)
  • Written in pure PowerShell – no additional modules needed
  • Practical and smart design:
    • Support resuming, if interrupted
    • Skip already scanned hosts / ports

Let’s have a look on how to use these scanners.

Typical usage scenario

Since the port scanners are written in PowerShell, we have to be able to run PowerShell commands on the system that we are using. On a restricted workstation this may a be a problem, so..

(1) First step is typically to circumvent the restrictions and spawn a shell. Once we can comfortably run PowerShell commands, we can progress to the next step.

(2) Now we can write up the port scanners somewhere on the file system. For instance, we could place them on our Desktop, but due to various restrictions we may have to place them somewhere else where we can write, e.g.:

  • C:UsersPublic
  • C:WindowsTasks
  • C:WindowsTracing
  • C:WindowsSystem32SpoolDriversColor
  • etc.

And that’s all!

Now we can start doing some port scanning. Here’s a quick intro into how to use them.

TCP port scanner:

Import-Module .port-scan-tcp.ps1

# Usage:
port-scan-tcp <host(s)> <port(s)>

UDP port scanner:

Import-Module .port-scan-udp.ps1

# Usage:
port-scan-udp <host(s)> <port(s)>

Let’s see some examples on how to use them in practice.

Port scan of a single host

Here’s the simplest example – check if a remote host has port tcp/445 open:

port-scan-tcp 192.168.204.183 445

Port scanning a single host and port

Here’s an example of port scanning a single host for selected tcp ports:

port-scan-tcp 192.168.204.183 (21,22,23,25,80,443,445,3389)

Port scanning a single host for selected ports

Port scan of a network range

Here’s an example of port scanning a network range 192.168.204.0/24 for port tcp/445 (port sweeping):

0..255 | foreach { port-scan-tcp 192.168.204.$_ 445 }

Port scanning (sweeping) a network range for a single port

Here’s an example of port scanning a network range 192.168.204.0/24 for selected tcp ports:

0..255 | foreach { port-scan-tcp 192.168.204.$_ (22,80,445) }

Port scanning a network range for selected ports

List of hosts in a file

We can also provide list of targets as an input file.

For instance, in corporate networks with Active Directory (AD) deployment, we could extract list of computers from AD using PowerShell cmdlets like this:

$a = [adsisearcher]”(objectCategory=computer)”
$a.PropertiesToLoad.add(“dnshostname”) | out-null
$a.PageSize = 1
$a.FindAll() | % { echo $_.properties.dnshostname } > computers.txt

Now we could identify all alive Windows systems by port sweeping on port tcp/445:

port-scan-tcp (gc .computers.txt) 445

Port scanning of computers found in active directory using input file

Getting the results

Both scanners keep track of everything using a state file (scanresults.txt) which is created in the current working directory. This allows us to check on the results anytime, even during ongoing scans.

For instance, here’s how we can get a list systems with port tcp/445 open:

Get-Content .scanresults.txt | Select-String "tcp,445,Open"

Port scan results - hosts with port tcp/445 open

If we wanted to list only the first column, we could easily do that with PowerShell like this:

(Get-Content .scanresults.txt | Select-String "tcp,445,Open") -replace ",.*",""

Extracting list of hosts with open port tcp/445

Now we could feed this list into our SMB login bruteforcer, for instance, and attempt to compromise some of these Windows machines. Or we could employ some other automation, anything we would like.

Requirements and limitations

Compatibility. The TCP scanner comes in two versions with the difference of using the TcpClient.ConnectAsync() method. This method, available in .NET 4.5, gives the scanner ability to discern between ‘Closed’ and ‘Filtered’ ports. The compat version of the scanner (for older systems) cannot discern this and just reports both such cases as ‘Closed’.

Speed. Both port scanners (TCP and UDP) are only a single threaded loops without any parallelization. Thus, the scanning speed is limited. But, in the worst case the speed should be around 1 port scan per second, depending on the timeout values which you can also simply just change.

Speed degradation. Something to also keep in mind is that the scanners may get a bit slow after some time if there are too many results already. To mitigate this issue, we can rotate the results file or use a different one by modifying the modules and reloading:

Import-Module .port-scan-tcp.ps1 -force
Import-Module .port-scan-udp.ps1 -force

Conclusion

Although these port scanners are not perfect, in some situations they are exactly what gets the job done with a nice feature list and compact form.

Hope you will find them useful too sometimes!

If you like these tools and you would like more like it, please subscribe to my mailing list and follow me on Twitter, Facebook or Github to get notified about new additions!

See also

  • Active Directory Brute Force Attack Tool in PowerShell (ADLogin.ps1)
  • Windows Local Admin Brute Force Attack Tool (LocalBrute.ps1)
  • SMB Brute Force Attack Tool in PowerShell (SMBLogin.ps1)

I was trying to check whether the port is opened or not using powershell like follows.

(new-object Net.Sockets.TcpClient).Connect("10.45.23.109", 443)

This method works , but the output is not user-friendly. It means if there are no errors then it has access. Is there any way to check for success and display some message like » Port 443 is operational»?

essential's user avatar

essential

6181 gold badge6 silver badges19 bronze badges

asked Mar 5, 2012 at 11:44

Samselvaprabu's user avatar

SamselvaprabuSamselvaprabu

16.2k30 gold badges136 silver badges228 bronze badges

1

If you’re running Windows 8/Windows Server 2012 or newer, you can use the Test-NetConnection command in PowerShell.

Ex:

Test-NetConnection -Port 53 -ComputerName LON-DC1

EvilDr's user avatar

EvilDr

8,45812 gold badges70 silver badges128 bronze badges

answered Sep 18, 2014 at 23:33

SimonOzturk's user avatar

4

I improved Salselvaprabu’s answer in several ways:

  1. It is now a function — you can put in your powershell profile and use anytime you need
  2. It can accept host as hostname or as ip address
  3. No more exceptions if host or port unavaible — just text

Call it like this:

Test-Port example.com 999
Test-Port 192.168.0.1 80

function Test-Port($hostname, $port)
{
    # This works no matter in which form we get $host - hostname or ip address
    try {
        $ip = [System.Net.Dns]::GetHostAddresses($hostname) | 
            select-object IPAddressToString -expandproperty  IPAddressToString
        if($ip.GetType().Name -eq "Object[]")
        {
            #If we have several ip's for that address, let's take first one
            $ip = $ip[0]
        }
    } catch {
        Write-Host "Possibly $hostname is wrong hostname or IP"
        return
    }
    $t = New-Object Net.Sockets.TcpClient
    # We use TryCatch to remove exception info from console if we can't connect
    try
    {
        $t.Connect($ip,$port)
    } catch {}

    if($t.Connected)
    {
        $t.Close()
        $msg = "Port $port is operational"
    }
    else
    {
        $msg = "Port $port on $ip is closed, "
        $msg += "You may need to contact your IT team to open it. "                                 
    }
    Write-Host $msg
}

answered Mar 21, 2014 at 8:02

mshutov's user avatar

mshutovmshutov

7771 gold badge5 silver badges13 bronze badges

Actually Shay levy’s answer is almost correct but i got an weird issue as i mentioned in his comment column. So i split the command into two lines and it works fine.

$Ipaddress= Read-Host "Enter the IP address:"
$Port= Read-host "Enter the port number to access:"

$t = New-Object Net.Sockets.TcpClient
$t.Connect($Ipaddress,$Port)
    if($t.Connected)
    {
        "Port $Port is operational"
    }
    else
    {
        "Port $Port is closed, You may need to contact your IT team to open it. "
    }

answered Mar 8, 2012 at 7:06

Samselvaprabu's user avatar

SamselvaprabuSamselvaprabu

16.2k30 gold badges136 silver badges228 bronze badges

You can check if the Connected property is set to $true and display a friendly message:

    $t = New-Object Net.Sockets.TcpClient "10.45.23.109", 443 

    if($t.Connected)
    {
        "Port 443 is operational"
    }
    else
    {
        "..."
    }

answered Mar 5, 2012 at 12:54

Shay Levy's user avatar

Shay LevyShay Levy

119k30 gold badges180 silver badges202 bronze badges

2

With the latest versions of PowerShell, there is a new cmdlet, Test-NetConnection.

This cmdlet lets you, in effect, ping a port, like this:

Test-NetConnection -ComputerName <remote server> -Port nnnn

I know this is an old question, but if you hit this page (as I did) looking for this information, this addition may be helpful!

answered Jul 18, 2017 at 19:41

Thomas Lee's user avatar

Thomas LeeThomas Lee

1,1386 silver badges13 bronze badges

I tried to improve the suggestion from mshutov.
I added the option to use the output as an object.

 function Test-Port($hostname, $port)
    {
    # This works no matter in which form we get $host - hostname or ip address
    try {
        $ip = [System.Net.Dns]::GetHostAddresses($hostname) | 
            select-object IPAddressToString -expandproperty  IPAddressToString
        if($ip.GetType().Name -eq "Object[]")
        {
            #If we have several ip's for that address, let's take first one
            $ip = $ip[0]
        }
    } catch {
        Write-Host "Possibly $hostname is wrong hostname or IP"
        return
    }
    $t = New-Object Net.Sockets.TcpClient
    # We use TryCatch to remove exception info from console if we can't connect
    try
    {
        $t.Connect($ip,$port)
    } catch {}

    if($t.Connected)
    {
        $t.Close()
        $object = [pscustomobject] @{
                        Hostname = $hostname
                        IP = $IP
                        TCPPort = $port
                        GetResponse = $True }
        Write-Output $object
    }
    else
    {
        $object = [pscustomobject] @{
                        Computername = $IP
                        TCPPort = $port
                        GetResponse = $False }
        Write-Output $object

    }
    Write-Host $msg
}

Brettski's user avatar

Brettski

18.9k15 gold badges74 silver badges93 bronze badges

answered Aug 4, 2014 at 9:56

Hilbert's user avatar

If you are using older versions of Powershell where Test-NetConnection isn’t available, here is a one-liner for hostname «my.hostname» and port «123»:

$t = New-Object System.Net.Sockets.TcpClient 'my.hostname', 123; if($t.Connected) {"OK"}

Returns OK, or an error message.

answered Oct 19, 2017 at 21:54

David I.'s user avatar

David I.David I.

4,7193 gold badges25 silver badges34 bronze badges

Great answer by mshutov & Salselvaprabu. I needed something a little bit more robust, and that checked all IPAddresses that was provided instead of checking only the first one.

I also wanted to replicate some of the parameter names and functionality than the Test-Connection function.

This new function allows you to set a Count for the number of retries, and the Delay between each try. Enjoy!

function Test-Port {

    [CmdletBinding()]
    Param (
        [string] $ComputerName,
        [int] $Port,
        [int] $Delay = 1,
        [int] $Count = 3
    )

    function Test-TcpClient ($IPAddress, $Port) {

        $TcpClient = New-Object Net.Sockets.TcpClient
        Try { $TcpClient.Connect($IPAddress, $Port) } Catch {}

        If ($TcpClient.Connected) { $TcpClient.Close(); Return $True }
        Return $False

    }

    function Invoke-Test ($ComputerName, $Port) {

        Try   { [array]$IPAddress = [System.Net.Dns]::GetHostAddresses($ComputerName) | Select-Object -Expand IPAddressToString } 
        Catch { Return $False }

        [array]$Results = $IPAddress | % { Test-TcpClient -IPAddress $_ -Port $Port }
        If ($Results -contains $True) { Return $True } Else { Return $False }

    }

    for ($i = 1; ((Invoke-Test -ComputerName $ComputerName -Port $Port) -ne $True); $i++)
    {
        if ($i -ge $Count) {
            Write-Warning "Timed out while waiting for port $Port to be open on $ComputerName!"
            Return $false
        }

        Write-Warning "Port $Port not open, retrying..."
        Sleep $Delay
    }

    Return $true

}

answered Oct 25, 2017 at 13:10

Marc Kellerman's user avatar

boiled this down to a one liner sets the variable «$port389Open» to True or false — its fast and easy to replicate for a list of ports

try{$socket = New-Object Net.Sockets.TcpClient($ipAddress,389);if($socket -eq $null){$Port389Open = $false}else{Port389Open = $true;$socket.close()}}catch{Port389Open = $false}

If you want ot go really crazy you can return the an entire array-

Function StdPorts($ip){
    $rst = "" |  select IP,Port547Open,Port135Open,Port3389Open,Port389Open,Port53Open
    $rst.IP = $Ip
    try{$socket = New-Object Net.Sockets.TcpClient($ip,389);if($socket -eq $null){$rst.Port389Open = $false}else{$rst.Port389Open = $true;$socket.close();$ipscore++}}catch{$rst.Port389Open = $false}
    try{$socket = New-Object Net.Sockets.TcpClient($ip,53);if($socket -eq $null){$rst.Port53Open = $false}else{$rst.Port53Open = $true;$socket.close();$ipscore++}}catch{$rst.Port53Open = $false}
    try{$socket = New-Object Net.Sockets.TcpClient($ip,3389);if($socket -eq $null){$rst.Port3389Open = $false}else{$rst.Port3389Open = $true;$socket.close();$ipscore++}}catch{$rst.Port3389Open = $false}
    try{$socket = New-Object Net.Sockets.TcpClient($ip,547);if($socket -eq $null){$rst.Port547Open = $false}else{$rst.Port547Open = $true;$socket.close();$ipscore++}}catch{$rst.Port547Open = $false}
    try{$socket = New-Object Net.Sockets.TcpClient($ip,135);if($socket -eq $null){$rst.Port135Open = $false}else{$rst.Port135Open = $true;$socket.close();$SkipWMI = $False;$ipscore++}}catch{$rst.Port135Open = $false}
    Return $rst
}

answered Apr 1, 2018 at 21:49

jdelpheki's user avatar

When scanning closed port it becomes unresponsive for long time. It seems to be quicker when resolving fqdn to ip like:

[System.Net.Dns]::GetHostAddresses("www.msn.com").IPAddressToString

Bhargav Rao's user avatar

Bhargav Rao

48.7k28 gold badges124 silver badges139 bronze badges

answered Apr 17, 2015 at 18:05

uzjsme's user avatar

Skip to content

Powershell — Перечислите открытые порты UDP

Powershell — Перечислите открытые порты UDP

Хотите узнать, как перечислить открытые порты UDP с помощью Powershell? В этом учебнике мы покажем вам, как использовать Powershell для создания списка портов UDP в состоянии прослушивания на компьютере под управлением Windows.

• Windows 2012 R2
• Windows 2016
• Windows 2019
• Windows 10

Список оборудования

В следующем разделе представлен список оборудования, используемого для создания этого учебника.

Как Amazon Associate, я зарабатываю от квалификационных покупок.

Похожий учебник — PowerShell

На этой странице мы предлагаем быстрый доступ к списку учебников, связанных с PowerShell.

Учебник Powershell — Перечислите открытые порты UDP

Как Администратор, запустите новый запрос командной строки POWERSHELL.

Windows 10 - powershell elevated

Перечислите текущие соединения UDP.

Перечислите открытые порты UDP.

В нашем примере мы перечислили только порты UDP в состоянии прослушивания.

Дополнительно сортировать выход на основе номера порта UDP.

В нашем примере мы перечислили открытые порты UDP в состоянии прослушивания.

В нашем примере мы организовали выход команды на основе номера порта UDP.

Поздравляю! Вы можете перечислить открытые порты UDP с помощью Powershell.

Учебник Powershell — Перечислите соединения UDP с помощью скрипта

Как Администратор, запустите новый запрос командной строки POWERSHELL.

Windows 10 - powershell elevated

Перечислите все соединения по определенному IP-адресу.

Перечислите все соединения в порту UDP.

Перечислите название процесса и идентификатор локального порта UDP.

Поздравляю! Вы можете перечислить информацию о портах UDP с помощью скрипта Powershell.

VirtualCoin CISSP, PMP, CCNP, MCSE, LPIC22021-02-28T19:34:22-03:00

Related Posts

Page load link

Join Our Newsletter 

Stay updated with the latest tutorials

close-link

This website uses cookies and third party services.

Ok

Let’s dive into how to build a PowerShell test port tool that allows you to test open ports by port number and label.

To build a robust script that’s not going to fall over and die on half your servers it’s important to first make sure the prerequisites that exist in order for you to get your end result are met.

What are these prereqs? Prerequisites are services like FTP, HTTP, DCOM, WMI, WSMAN, etc. The connection you’re trying to make to a server typically depend on services like these.

There is a hierarchy of several layers of checks you can perform on your servers before attempting to make a connection depending on how anal you want to get.

For starters you’ve got the entire OSI stack to traverse on the network side. That’s not including services on the host system that you’re executing the script from and everything else on the remote host system.

One of the first tests you need to perform when querying a remote server is to check to ensure the appropriate network ports are open and accessible. Depending on the services running on the remote server depends on the ports you need to query.

I always used to either not even attempting to test port connections or fumbling around with finding that latest Test-Port script I had scavenged somewhere. Once I found it to figure out what ports I actually needed to a test ahead of time. Today was the final straw.

I needed to query a set of domain controllers before running some CIM queries against them. I went about my normal fumbling around and decided enough was enough and sat down and built my own, fully featured port testing script.

With help from this Technet script I managed to create pretty good pair of PowerShell functions that will not only allow you to test for open TCP and UDP ports but to test port groups by server role. No more Googling every time for what ports what service uses!

Granted, especially for Active Directory, the ports can vary by server OS, various services on a domain controller, etc. Feel free to tweak them as needed for your environment.

Here’s a screen host of a usage example:

Testing ports with PowerShell
Testing ports with PowerShell

As you can see, you can specify as many servers as you want and it will output a nice list of objects broken down by the service port group and the port for each computer. So far it’s come in very handy! I hope you get some use out of it like I have!

function Test-ServerRolePortGroup {
	<#
	.SYNOPSIS
		This function tests for open TCP/UDP ports by server role.
	.DESCRIPTION
		This function tests for all the approprite TCP/UDP ports by server role so you don't have
		to memorize or look up all of the ports that need to be tested for every time
		you want to verify remote connectivity on a specific server role.
	.NOTES
		Link port references:
		http://technet.microsoft.com/en-us/library/dd772723(v=ws.10).aspx
		http://en.wikipedia.org/wiki/Server_Message_Block
		http://technet.microsoft.com/en-us/library/cc940063.aspx
	.PARAMETER Computername
		One or more remote, comma-separated computer names
	.PARAMETER ServerRole
		The services on the computer that you'd like to find open ports for. This can be
		common services like WinRm, Smb, Dns, Active Directory and NetBIOS
	.EXAMPLE
		PS> Test-ServerRolePortGroup -Computername 'LABDC','LABDC2' -ServerRole NetBIOS,WinRm,Dns
		
		This example tests the network ports necessary for NetBIOS, WinRm and Dns
		to operate on the servers LABDC and LABDC2.
	#>
	
	[CmdletBinding()]
	[OutputType([System.Management.Automation.PSCustomObject])]
	param (
		[Parameter(Mandatory)]
		[ValidateScript({ Test-Connection -ComputerName $_ -Count 1 -Quiet})]
		[string[]]$Computername,
		[Parameter(Mandatory)]
		[ValidateSet('WinRm','Smb','Dns','ActiveDirectoryGeneral','ActiveDirectoryGlobalCatalog','NetBios')]
		[string[]]$ServerRole
	)
	begin {
		$PortGroups = @{
			'WinRm' = @{ 'TCP' = 5985}
			'Smb' = @{ 'TCP' = 445; 'UDP' = 445 }
			'Dns' = @{ 'TCP' = 53; 'UDP' = 53 }
			'ActiveDirectoryGeneral' = @{ 'TCP' = 25, 88, 389, 464, 636, 5722, 9389; 'UDP' = 88,123,389,464 }
			'ActiveDirectoryGlobalCatalog' = @{ 'TCP' = 3268, 3269 }
			'NetBios' = @{ 'TCP' = 135, 137, 138, 139; 'UDP' = 137,138,139 }
		}
	}
	process {
		foreach ($Computer in $Computername) {
			Write-Verbose "Beginning port tests on computer '$Computer'"
			try {
				$TestPortGroups = $PortGroups.GetEnumerator() | where { $ServerRole -contains $_.Key }
				Write-Verbose "Found '$($TestPortGroups.Count)' port group(s) to test"
				foreach ($PortGroup in $TestPortGroups) {
					$PortGroupName = $PortGroup.Key
					$PortGroupValues = $PortGroup.Value
					foreach ($Value in $PortGroupValues.GetEnumerator()) {
						$Protocol = $Value.Key
						$Ports = $Value.Value
						$TestResult = Test-Port -ComputerName $Computer -Protocol $Protocol -Port $Ports
						$TestResult | Add-Member -MemberType 'NoteProperty' -Name 'PortSet' -Value $PortGroupName
						$TestResult
					}
				}
			} catch {
				Write-Verbose "$($MyInvocation.MyCommand.Name) - Computer: $Computer - Error: $($_.Exception.Message) - Line Number: $($_.InvocationInfo.ScriptLineNumber)"
				$false
			}
		}
	}
}

function Test-Port {
	<#
	.SYNOPSIS
		This function tests for open TCP/UDP ports.
	.DESCRIPTION
		This function tests any TCP/UDP port to see if it's open or closed.
	.NOTES
		Known Issue: If this function is called within 10-20 consecutively on the same port
			and computer, the UDP port check will output $false when it can be
			$true.  I haven't figured out why it does this.
	.PARAMETER Computername
		One or more remote, comma-separated computer names
	.PARAMETER Port
		One or more comma-separated port numbers you'd like to test.
	.PARAMETER Protocol
		The protocol (UDP or TCP) that you'll be testing
	.PARAMETER TcpTimeout
		The number of milliseconds that the function will wait until declaring
		the TCP port closed.
	.PARAMETER
		The number of millieconds that the function will wait until declaring
		the UDP port closed.
	.EXAMPLE
		PS> Test-Port -Computername 'LABDC','LABDC2' -Protocol TCP 80,443
		
		This example tests the TCP network ports 80 and 443 on both the LABDC
		and LABDC2 servers.
	#>
	[CmdletBinding(DefaultParameterSetName='TCP')]
	[OutputType([System.Management.Automation.PSCustomObject])]
	param (
		[Parameter(Mandatory)]
		[string[]]$ComputerName,
		[Parameter(Mandatory)]
		[int[]]$Port,
		[Parameter(Mandatory)]
		[ValidateSet('TCP', 'UDP')]
		[string]$Protocol,
		[Parameter(ParameterSetName='TCP')]
		[int]$TcpTimeout = 1000,
		[Parameter(ParameterSetName = 'UDP')]
		[int]$UdpTimeout = 1000
	)
	process {
		foreach ($Computer in $ComputerName) {
			foreach ($Portx in $Port) {
				$Output = @{ 'Computername' = $Computer; 'Port' = $Portx; 'Protocol' = $Protocol; 'Result' = '' }
				Write-Verbose "$($MyInvocation.MyCommand.Name) - Beginning port test on '$Computer' on port '$Protocol<code>:$Portx'"
				if ($Protocol -eq 'TCP') {
					$TcpClient = New-Object System.Net.Sockets.TcpClient
					$Connect = $TcpClient.BeginConnect($Computer, $Portx, $null, $null)
					$Wait = $Connect.AsyncWaitHandle.WaitOne($TcpTimeout, $false)
					if (!$Wait) {
						$TcpClient.Close()
						Write-Verbose "$($MyInvocation.MyCommand.Name) - '$Computer' failed port test on port '$Protocol</code>:$Portx'"
						$Output.Result = $false
					} else {
						$TcpClient.EndConnect($Connect)
						$TcpClient.Close()
						Write-Verbose "$($MyInvocation.MyCommand.Name) - '$Computer' passed port test on port '$Protocol<code>:$Portx'"
						$Output.Result = $true
					}
					$TcpClient.Close()
					$TcpClient.Dispose()
				} elseif ($Protocol -eq 'UDP') {
					$UdpClient = New-Object System.Net.Sockets.UdpClient
					$UdpClient.Client.ReceiveTimeout = $UdpTimeout
					$UdpClient.Connect($Computer, $Portx)
					Write-Verbose "$($MyInvocation.MyCommand.Name) - Sending UDP message to computer '$Computer' on port '$Portx'"
					$a = new-object system.text.asciiencoding
					$byte = $a.GetBytes("$(Get-Date)")
					[void]$UdpClient.Send($byte, $byte.length)
					#IPEndPoint object will allow us to read datagrams sent from any source.
					Write-Verbose "$($MyInvocation.MyCommand.Name) - Creating remote endpoint"
					$remoteendpoint = New-Object system.net.ipendpoint([system.net.ipaddress]::Any, 0)
					try {
						#Blocks until a message returns on this socket from a remote host.
						Write-Verbose "$($MyInvocation.MyCommand.Name) - Waiting for message return"
						$receivebytes = $UdpClient.Receive([ref]$remoteendpoint)
						[string]$returndata = $a.GetString($receivebytes)
						If ($returndata) {
							Write-Verbose "$($MyInvocation.MyCommand.Name) - '$Computer' passed port test on port '$Protocol</code>:$Portx'"
							$Output.Result = $true
						}
					} catch {
						Write-Verbose "$($MyInvocation.MyCommand.Name) - '$Computer' failed port test on port '$Protocol`:$Portx' with error '$($_.Exception.Message)'"
						$Output.Result = $false
					}
					$UdpClient.Close()
					$UdpClient.Dispose()
				}
				[pscustomobject]$Output
			}
		}
	}
}

Понравилась статья? Поделить с друзьями:
  • Проброс маршрута в другую сеть windows
  • Проверить все драйвера windows 10 онлайн
  • Проверить все диски на наличие ошибок windows 10
  • Проверить возможность установки windows 11 на ноутбук
  • Проверить винт на битые сектора на windows 7