Создание массива моих пользовательских объектов Powershell - PullRequest
3 голосов
/ 02 августа 2020

У меня есть файл данных, содержащий TXT. Я создаю функцию для итерации по этому файлу данных и строю пользовательские объекты соответственно. и в конце, я хочу, чтобы функция возвращала массив этих настраиваемых объектов. вот пример одного объекта и того, как он должен выглядеть:

$NmapOBJ1 = New-Object PSObject
$NmapOBJ1 | Add-Member -type NoteProperty -name "IP" -Value "192.168.10.10"
$ports = @(22,80,435)
$NmapOBJ1 | Add-Member -type NoteProperty -name "Ports" -Value $ports

Каждый объект имеет IP и порты. Теперь я создаю al oop, и мне нужна переменная типа $ k = 0, которая получит $ k ++ каждый раз, когда цикл повторяется. поэтому один раз будет создан $ NmapOBJ1, а затем $ NmapOBJ2, $ NmapOBJ3 .. но я не могу использовать:

$k=0
$NmapOBJ$k = New-Object PSObject

Потому что я получаю сообщение об ошибке: Неожиданный токен '$ k' в выражении или инструкции. Заранее благодарим

*** РЕДАКТИРОВАТЬ *** Пример txt-файла может быть:

Nmap scan report for 11.1.1.11
21/tcp  filtered ftp
49/tcp  filtered tacacs
67/tcp  open     tcpwrapped
111/tcp filtered rpcbind
121/tcp filtered rpcbind
123/tcp filtered ntp
179/tcp filtered bgp
646/tcp filtered ldp
Nmap scan report for 2.2.22.2
21/tcp    filtered ftp
67/tcp    open     tcpwrapped
111/tcp   filtered rpcbind
123/tcp   filtered ntp
179/tcp   filtered bgp
646/tcp   filtered ldp
33012/tcp filtered unknown

Тогда мне нужен object1.ip = 11.1.1.11; object1.ports = @ (21,49,67,111,121,123,179,646)

и так далее ..

Ответы [ 2 ]

3 голосов
/ 02 августа 2020

Как вы обнаружили, $NMapObj$k не работает - синтаксис ссылок на переменные PowerShell не поддерживает переменные переменные (например, PHP)

Я бы предложите использовать список для сбора объектов:

$listOfObjects = New-Object 'System.Collections.Generic.List[psobject]'

$obj = New-Object psobject
$obj |Add-Member ...
$listOfObjects.Add($obj)

Затем в конце вашей функции:

return $listOfObjects

PowerShell затем перечислит список, и цель назначения получит массив объекты в списке

Еще одно решение PowerShell-idiomati c состоит в том, чтобы просто выдавать каждый настраиваемый объект, как вы go!

Для показанного вами входного образца вы можете написать простой синтаксический анализатор с switch, как это:

function Parse-NMapReport
{
    param(
        [string]$Path
    )

    $IP = ""

    switch -File $path -Regex {
        'Nmap scan report for (?<ip>[\d\.]+)' {
            if($IP){
                # Defining the object without assigning it to anything
                # This will make the object "bubble up" back to the caller
                [PSCustomObject]@{
                    IP = $IP
                    Ports = $Ports
                }
            }
            $IP = $Matches['ip']
            $Ports = @()
        }
        '^(?<port>\d+)/tcp' {
            $Ports += ($Matches['port'] -as [int])
        }
    }

    if($IP){
        [PSCustomObject]@{
            IP = $IP
            Ports = $Ports
        }
    }
}

Теперь вы можете сделать:

PS C:\> $results = Parse-NMapReport -Path ".\Path\to\nmap.txt"

И $results будет массивом созданных настраиваемых объектов:

PS C:\> $results
IP        Ports
--        -----
11.1.1.11 {21, 49, 67, 111…}
2.2.22.2  {21, 67, 111, 123…}
2 голосов
/ 02 августа 2020

Вместо того, чтобы пытаться создавать новые переменные, лучше получить массив объектов PSObject из этого файла.

Должно получиться что-то вроде этого:

# read the text file as single string and split it into n textblocks. Remove empty blocks
$result = (Get-Content -Path 'D:\Test\NmapScanReport.txt' -Raw) -split 'Nmap.+for\s*' | 
            Where-Object { $_ -match '\S'} | 
            ForEach-Object {
                # split each textblock into separate lines
                $lines = $_ -split '\r?\n'
                # and output an object with properties IP and Ports (the latter is an array)
                [PsCustomObject]@{
                    IP    = $lines[0].Trim()
                    Ports = for ($i = 1; $i -lt $lines.Count; $i++) { ($lines[$i] -split '/')[0] }
                }
            }

# output on screen
$result

# write to csv file
$result | Export-Csv -Path 'D:\Test\IpAndPorts.csv' -NoTypeInformation

Вывод на экран :

IP        Ports                
--        -----                
11.1.1.11 {21, 49, 67, 111...} 
2.2.22.2  {21, 67, 111, 123...}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...