Главная

Thursday, 14 April 2022

NET и Powershell.

Всем привет.

PowerShell может быть мощным инструментом устранения неполадок в сети благодаря своему использования классов  .NET Framework. Для расширения кругозора по связке PowerShell с .NET следует ознакомиться с некоторыми полезными классами .NET, которые можно использовать для, например, решения проблем с сетью и написания других PowerShell-сценариев. В сети есть многo примеров на Powershell потому как создать сканер портов для проверки открытых портов в вашей сети, отправки и получения данных между портами, создавать форматированные пакеты для отправки Direct-запросов (LDAP) к контроллеру домена и обработки ответных пакетов для эмуляции вывода из интерфейса командной строки утилиты portqry.exe.  Используя такие методы и сценарии, вы иметь возможность устранять неполадки приложений в вашей сети, проверяя доступны ли необходимые порты в системе или они заблокированы, либо программным обеспечением на сервере, либо чем-то еще, например аппаратным брандмауэром или список управления доступом (ACL) на коммутаторе.

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

Но прежде чем продолжить следует уяснить для себя некоторую сетевую терминологию .NET:

1. Port идентифицирует различные приложения, службы или процессы, работающие на одной системе и позволяет им совместно использовать одно физическое соединение в сети. Можно считать его как вход к конкретному экземпляру приложения на хосте. Если порт открыт, вы можете общаться с приложением на другой стороне, но вы не можете установить соединение если порт закрыт или заблокирован (фильтруется фаерволлом).

2. EndPoint - это логическое окончание сетевого соединения между клиентом и сервером, который позволяет использование сетевые потоки для связи друг с другом. Конечная точка также предоставляет утилиту чтобы увидеть, активно ли соединение и доступны ли потоки для чтения или для записи, а также для настройки размера буферов для этих потоков.

3. Socket - это экземпляр конечной точки двусторонней связи между двумя приложениями в одной сети путем сопряжения IP-адреса с портом.

Пример с отправкой данных - не самая сложная часть, но базово важная. Чтобы отправить что-либо между портами, данные должны быть преобразованы в байты, это необходимо для самого процесса передачи данных. 

Для этого следует выполнить такие шаги:

  • Создайте объект TCPClient ($Socket).
  • Создайте сетевой поток ($Writer), который будет использоваться для передачи данных.
  • Возьмите входные данные ($message) для передачи и преобразуйте их в байты.
  • Передайте байты на удаленный порт, используя сетевой поток ($Writer.WriteLine).

Пишем функцию Send-TCPMessage которая и выполнит эти шаги.

Function Send-TCPMessage {

Param (

    [Parameter(Mandatory=$true, Position=0)]

    [ValidateNotNullOrEmpty()]

    [string]$EndPoint,

    [Parameter(Mandatory=$true, Position=1)]

    [int] $Port,

    [Parameter(Mandatory=$true, Position=2)]

    [string] $Message

)

Process {

    # Setup connection

    $IP = [System.Net.Dns]::GetHostAddresses($EndPoint)

    $Address = [System.Net.IPAddress]::Parse($IP)

    $Socket = New-Object System.Net.Sockets.TCPClient($Address,$Port)

    # Setup stream writer

    $Stream = $Socket.GetStream()

    $Writer = New-Object System.IO.StreamWriter($Stream)

    # Write message to stream

    $Message | % {

        $Writer.WriteLine($_)

        $Writer.Flush()

    }

    # Close connection and stream

    $Stream.Close()

    $Socket.Close()

    }

}


Далее пошлем строку на порт 29800 локального хоста (не забываем про фаерволл!):

Send-TCPMessage -Port 29800 -Endpoint 127.0.0.1 -message "My first TCP message!"


Послать то мы послали, но надо же наши данные и принять. Создаем функцию Receive-TCPMessage, которая будет нашим слушателем.

Шаги будут следующими:

  • Создайте объект TCPClient ($listener).
  • Создайте сетевой поток ($stream), который будет использоваться для приема данных.
  • Возьмите входные данные для передачи и преобразуйте их в строку ($data).
  • Публикем полученные данные ($msg).

Function Receive-TCPMessage {

Param (

    [Parameter(Mandatory=$true, Position=0)]

    [ValidateNotNullOrEmpty()]

    [int] $Port

)

Process {

    Try {

    # Set up endpoint and start listening

        $endpoint = new-object System.Net.IPEndPoint([ipaddress]::any,$port)

        $listener = new-object System.Net.Sockets.TcpListener $EndPoint

        $listener.start()

    # Wait for an incoming connection

        $data = $listener.AcceptTcpClient()

    # Stream setup

        $stream = $data.GetStream()

        $bytes = New-Object System.Byte[] 1024

    # Read data from stream and write it to host

        while (($i = $stream.Read($bytes,0,$bytes.Length)) -ne 0){

            $EncodedText = New-Object System.Text.ASCIIEncoding

            $data = $EncodedText.GetString($bytes,0, $i)

            Write-Output $data

            }

    # Close TCP connection and stop listening

        $stream.close()

        $listener.stop()

}

    Catch {

        "Receive Message failed with: `n" + $Error[0]

          }

        }

}

Теперь слушаем по порту 29800:

$msg = Receive-TCPMessage -Port 29800

$msg

Вот и все для начала. Использование .NET в Powershell в сравнении с привычными  командлетами Test-NetConnection  позволяет настроить больше параметров, например, процесса сканирования портов или даже обычного пинга. Но для этого надо будет добавить чуточку своего кода.

Успехов.


No comments:

Post a Comment

А что вы думаете по этому поводу?