Powershell – перебор CSV-файла

я пытаюсь использовать какой-то скрипт, который проверяет соединение NW между хостами, в основном у меня есть CSV с исходным IP-адресом и портом, который выглядит так

проблема в том, что когда я запускаю этот скрипт, он проверяет каждый IP-адрес для каждого порта, и мне нужно, чтобы он проверил порт onlu, который находится рядом с ним, то есть для 8.8.8.8 только порт 53, а для 1.1.1.1 только 443.

ниже мой код

$dest = Import-Csv "C:\temp\dest.csv"
#$dest | ft
$source = (Get-WmiObject Win32_Computersystem).name
Foreach ($d in $dest.SourceIP){
    Foreach ($P in $dest.Port){
        try{ 
            $temp = new-object Net.Sockets.TcpClient
            $temp.Connect("$d", $P)
                if ($temp.Connected -eq $true){
                    Write-Host $P -ForegroundColor Green " => port is open from" $source "to" $d
                }
            }
        catch {$theError =$_
                if ($theError.Exception -like "*A connection attempt failed*"){
                    Write-Host $P -ForegroundColor Red "=> NO TRAFFIC between" $source "and" $d
                }
                elseif ($theError.Exception -like "*No connection could be made*"){
                    Write-Host $P -ForegroundColor Red "=> port is closed from" $source "to" $d
                }
              }
     }
}

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

Прокрутите каждую строку таблицы has, используя: Foreach ($row in $dest){ } Проверка $row.SourceIP и $row.Port.

jdweng 09.07.2024 11:50

Вы случайно используете что-то под названием «Перечисление доступа к членам» — $dest.SourceIP извлекает массив, содержащий значения SourceIP из всех строк, а $dest.Port делает то же самое для свойства Port. В результате ваши вложенные циклы foreach перебирают каждый порт для каждого SourceIP, что объясняет наблюдаемое вами поведение. См. Learn.microsoft.com/en-us/powershell/module/… для получения более подробной информации об этой функции (которую вы на самом деле не хотите здесь использовать!)

mclayton 09.07.2024 11:59

Это всего лишь идея... вы можете ускориться, группируя. Что-то вроде Group-object-property Port

Walter Mitty 09.07.2024 20:36
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Get-WmiObject устарело. Использование Get-CimInstance работает примерно так же.

И почему вложенный цикл на первом месте? Вы можете получить доступ к свойствам!

$source = (Get-CimInstance -ClassName Win32_Computersystem).Name

Foreach ($Address in $dest) {
    $PortString = '{0,-5} => ' -f $Address.Port

    try { 
        if ([System.Net.Sockets.TcpClient]::new($Address.SourceIP, $Address.Port).Connected) {
            Write-Host -ForegroundColor Green $PortString 'port is open from' $source 'to' $Address.SourceIp
        }
    }
    catch [System.Net.Sockets.SocketException] {
        switch ($_.Exception.ErrorCode) {
            10060 { Write-Host -ForegroundColor Red $PortString 'NO TRAFFIC between' $source 'and' $Address.SourceIp }
            10061 { Write-Host -ForegroundColor Red $PortString 'port is closed from' $source 'to' $Address.SourceIp }
        }
    }
    catch {
        # generic error management 
    }
}

и если вы используете Powershell Core/7.x и вам нужно проверить много элементов, вы можете использовать Foreach-Object -Parallel. Видеть:

$source = (Get-CimInstance -ClassName Win32_Computersystem).Name

Import-Csv -Path $CsvPath | ForEach-Object -Parallel {

    # technically superfluous, but helps readibility.   
    $Address = $_

    # necessary to access the out-of-scope $source varible.   
    # the local name could by anything, but I kept the same name for clarity.   
    $source = $using:source

    $PortString = '{0,-5} => ' -f $Address.Port

    try { 
        if ([System.Net.Sockets.TcpClient]::new($Address.SourceIP, $Address.Port).Connected) {
            Write-Host -ForegroundColor Green $PortString 'port is open from' $source 'to' $Address.SourceIp
        }
    }
    catch [System.Net.Sockets.SocketException] {
        switch ($_.Exception.ErrorCode) {
            10060 { Write-Host -ForegroundColor Red $PortString 'NO TRAFFIC between' $source 'and' $Address.SourceIp }
            10061 { Write-Host -ForegroundColor Red $PortString 'port is closed from' $source 'to' $Address.SourceIp }
        }
    }
    catch {
        # generic error management 
    }
}

Очень хорошо. Возможно, вы захотите добавить отдельный блок catch [System.Net.Sockets.SocketException] {...} и проверить значение $_.Exception.ErrorCode (чтобы избежать сравнения с локализованным сообщением об ошибке) - ошибка «не удалось установить соединение» будет иметь код 10060, «Не удалось установить соединение» 10061

Mathias R. Jessen 09.07.2024 12:04

@MathiasR.Jessen, кстати, спасибо за редактирование моего сообщения. И да, есть несколько способов улучшить сценарий. Я сосредоточился только на основной проблеме, которую действительно поднял ОП, - двойной петле. Я отредактировал свое решение с учетом ваших предложений и нескольких других улучшений (надеюсь)

sirtao 09.07.2024 13:23

Спасибо большое, это работает. Я использовал вложенные циклы, потому что ранее я проверял исходный IP-адрес или несколько IP-адресов, непосредственно предоставленных сценарию, и несколько портов, бот, эти порты были одинаковыми для всех IP-адресов, которые нужно было проверить. В любом случае, я заметил, что это не очень эффективный способ сделать это, поэтому я хотел изменить его на файлы csv, и даже если мне придется дублировать строки с IP, чтобы проверить еще несколько портов для того же адреса, это будет все равно лучший способ сделай это. Еще раз, спасибо

gucisz 09.07.2024 13:52

Если вы используете Powershell Core/7.x и вам нужно проверить много элементов, я добавил в свое решение вариант, использующий Foreach-Object -Parallel, который позволит вам проверять несколько IP-адресов одновременно, что значительно ускоряет работу.

sirtao 09.07.2024 14:10

Другие вопросы по теме