PowerShell 函数返回哈希表

3

我有这个函数:

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
}

该函数接收一个长字符串(Nmap扫描报告),并构建哈希表,以便我可以按以下方式进行处理: $arr [0] [0]的输出为192.168.20.10, 然后是端口,如:$arr [0] [1]=22; $arr [0] [2]=80等。
如果我从脚本中这样调用该函数:
BuildDaHash($string)

我将得到哈希表的输出,但如果我想把输出值存储到一个变量中以便进行操作,它就为空。也就是说,如果我这样做:
$test = BuildDaHash($string)

它变成空的了,我错过了什么?我认为可能是之前构建了一个空哈希的问题,像这样:

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

但是它也是空的

*编辑 我知道Nmap有不同的格式可用,我正在使用默认的txt格式,我还有另一个函数,读取输出并返回一个只包含IP和开放/过滤端口的txt文件,这是$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

1
nmap支持不同的输出格式。您要解析哪种输出格式?对于一次性的事情,greppable格式最容易处理,但XML输出最容易无误。 - Lieven Keersmaekers
$test 可能不为空,但根据您尝试使用它的方式,它可能看起来为空。请添加如何检查 $test 是否为空(一个好的测试是例如 $test | ConvertTo-Json)。还要添加一些示例输入数据($String = ?)到您的问题中。参见:[mcve]。 - iRon
在PowerShell中,write-host "$test" 没有任何输出,同时 $test | gm 也没有任何显示。 - Shahar
在PowerShell中,您不需要在参数周围使用括号。BuildDaHash($string) --> BuildDaHash $string - Theo
1
你需要明确将 $data 参数类型定义为 [string[]],否则 $data[$i] 将会被解析为单个 [char] - Mathias R. Jessen
3个回答

2

正如评论所述,你不应该在参数周围使用括号。相反,在PowerShell中,你需要用空格分隔参数。

这里的主要问题是,你认为你发送的数据是一个字符串,但实际上它应该是一个字符串数组,因为函数期望的是这样的。

虽然我不知道你想通过生成的嵌套哈希表实现什么目的,但请尝试:

$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

1
使用开关和自定义对象来存储您的结果如何?
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
        }            
    }        
}    

测试

@'
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
            }            
        }        
    }    
}

0
我已经找到了错误。 函数BuildDaHash有一个参数,一旦它使用文件的get-content获取参数,它就可以工作,但是一旦它从字符串中获取(即使是与get-content相同的文本),它就无法工作,原因是get-content是一个字符串数组,每行都是一个对象,而字符串只是一个大的文本数据。 对于我的新手问题感到抱歉,谢谢大家的帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接