Powershell Function return HashTable

Viewed 494

I have this function:

Function BuildDaHash($data){
$arr=@{}
    $j=0
    $k=0
    For ($i=0; $i -lt $data.count; $i++){
        if ($data[$i] -match 'nmap scan report')  {
            $arr[$j]=@{}
            $arr[$j][$k] = $data[$i]
            $i++
            $k++
            Do {
               $arr[$j][$k] = $data[$i].Split(' ')[0]
               $i++
               $k++
               } While ($data[$i] -notmatch 'nmap scan report' -and $i -lt $data.count) 
           $j++
           $k=0
           $i--
        }
      }
      return $arr
}

this function takes a long string (Nmap scan report) and build Hash table so i can then address it as follows: output of $arr[0][0] is 192.168.20.10 and then followed by ports like: $arr[0][1] = 22; $arr[0][2] = 80, etc.

If i call the function from the script like so

BuildDaHash($string)

i will get the output of the hash table, but if i want to get the output to a varbiable so i can work with it, it comes empty. meaning if i do this:

$test = BuildDaHash($string)

it comes empty, what am i missing here? i thought maybe it something with building an empty hash before like so:

$tst =@{}
$tst = BuildDaHash($string)

But that also comes empty

*EDIT I know Nmap has different formats available, im working with default txt, i have another function that reads the output and return a txt only with the ip and the open/filtered ports here is an example of $string:

Nmap scan report for 11.11.111.111
21/tcp  filtered ftp
179/tcp filtered bgp
646/tcp filtered ldp
Nmap scan report for 22.22.222.12
21/tcp    filtered ftp
111/tcp   filtered rpcbind
179/tcp   filtered bgp
646/tcp   filtered ldp
3 Answers

As commented, you should not use brackets around parameters. Instead, in PowerShell you separate parameters by spaces.

The main issue here is that you think the data you're sending is a string, but in fact it should be a string array, because the function expects that.

Although I have no idea what you're trying to achieve with the resulting nested hashtable , but try:

$string = @"
Nmap scan report for 11.11.111.111
21/tcp  filtered ftp
179/tcp filtered bgp
646/tcp filtered ldp
Nmap scan report for 22.22.222.12
21/tcp    filtered ftp
111/tcp   filtered rpcbind
179/tcp   filtered bgp
646/tcp   filtered ldp
"@ -split '\r?\n'   # break the string down to a string array

$test = BuildDaHash $string

$test

How about using a switch and customobjects to hold your results?

switch -Regex ($_) {
    'Nmap' {            
        if ($current -ne $null) {$current}
        $current = [PSCustomObject]@{
            ip = ($_ -split "for ")[1]
            ports = @()
        }
    }
    '^\d+' {
        $port,$transport,$filtered,$protocol = ($_  -split '/' -split '\s+')            
        $current.ports += [PSCustomObject]@{
            port = $port
            transport = $transport
            filtered = $filtered
            protocol = $protocol
        }            
    }        
}    

Test

@'
Nmap scan report for 11.11.111.111
21/tcp  filtered ftp
179/tcp filtered bgp
646/tcp filtered ldp
Nmap scan report for 22.22.222.12
21/tcp    filtered ftp
111/tcp   filtered rpcbind
179/tcp   filtered bgp
646/tcp   filtered ldp
'@ -split "`r`n" | % {
    switch -Regex ($_) {
        'Nmap' {            
            if ($current -ne $null) {$current}
            $current = [PSCustomObject]@{
                ip = ($_ -split "for ")[1]
                ports = @()
            }
        }
        '^\d+' {
            $port,$transport,$filtered,$protocol = ($_  -split '/' -split '\s+')            
            $current.ports += [PSCustomObject]@{
                port = $port
                transport = $transport
                filtered = $filtered
                protocol = $protocol
            }            
        }        
    }    
}

I have found my error. Function BuildDaHash get a parameter, once it gets it parameter using get-content of a file it works, but once it gets from a string (even with the same txt that get-content will give) it wont work, reason is tha get-content is an array of string with each line as an object and a string is just one big text data. sorry for noobness thank you all for helping out

Related