Как проверить доступ к сетевому порту и отобразить полезное сообщение?
Я пытался проверить, открыт ли порт или нет, используя powershell, как показано ниже.
(new-object Net.Sockets.TcpClient).Connect("10.45.23.109", 443)
Этот метод работает, но вывод не является удобным для пользователя. Это означает, что при отсутствии ошибок он имеет доступ. Есть ли способ проверить успех и отобразить сообщение типа "Порт 443 работает"?
Ответы
Ответ 1
На самом деле ответ Shay levy почти прав, но у меня есть странная проблема, о которой я упоминал в своей колонке комментариев. Поэтому я разделяю команду на две строки и отлично работает.
$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. "
}
Ответ 2
Если вы работаете в Windows 8/Windows Server 2012 или новее, вы можете использовать команду Test-NetConnection в PowerShell.
Пример:
Test-NetConnection -Port 53 -ComputerName LON-DC1
Ответ 3
Я улучшил ответ Salselvaprabu несколькими способами:
- Теперь это функция - вы можете вставить свой профиль powershell и использовать в любое время
- Он может принимать хост как имя хоста или как адрес ip
- Больше исключений, если хост или порт несовместимы - просто текст
Назовите его следующим образом:
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 for that address, let 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 Try\Catch 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
}
Ответ 4
Вы можете проверить, установлено ли значение свойства Connected равным $true и отображается дружественное сообщение:
$t = New-Object Net.Sockets.TcpClient "10.45.23.109", 443
if($t.Connected)
{
"Port 443 is operational"
}
else
{
"..."
}
Ответ 5
В последних версиях PowerShell появился новый командлет Test-NetConnection.
Этот командлет позволяет, по сути, пинговать порт, например:
Test-NetConnection -ComputerName <remote server> -Port nnnn
Я знаю, что это старый вопрос, но если вы нажмете эту страницу (как я и сделал), ища эту информацию, это дополнение может быть полезно!
Ответ 6
Я попытался улучшить предложение от мшутов.
Я добавил вариант использования вывода в качестве объекта.
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 for that address, let 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 Try\Catch 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
}
Ответ 7
Если вы используете более старые версии Powershell, где Test-NetConnection недоступен, вот однострочный для имени хоста "my.hostname" и порт "123":
$t = New-Object System.Net.Sockets.TcpClient 'my.hostname', 123; if($t.Connected) {"OK"}
Возвращает OK или сообщение об ошибке.
Ответ 8
Отличный ответ мшутов и Сальсельвапрабу. Я нуждался в чем-то чуть более надежном и проверял все IP-адреса, которые были предоставлены вместо проверки только первого.
Я также хотел реплицировать некоторые имена и функциональные возможности параметров, чем функция Test-Connection.
Эта новая функция позволяет вам установить счетчик для количества попыток и Delay между каждой попыткой. Наслаждайтесь!
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
}
Ответ 9
Если это сводится к одному, то для переменной "$ port389Open" задается значение True или false - ее можно быстро и легко скопировать для списка портов.
try{$socket = New-Object Net.Sockets.TcpClient($ipAddress,389);if($socket -eq $null){$Port389Open = $false}else{Port389Open = $true;$socket.close()}}catch{Port389Open = $false}
Если вы не хотите сходить с ума, вы можете вернуть весь 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
}
Ответ 10
При сканировании закрытого порта он перестает отвечать на запросы в течение длительного времени. Кажется, это быстрее при разрешении fqdn в ip:
[System.Net.Dns]::GetHostAddresses("www.msn.com").IPAddressToString