首页 > 解决方案 > 使用从函数返回的数据将列添加到 CSV

问题描述

我一直在编写一个脚本,该脚本从包含防火墙日志的 syslog 服务器获取输出,以更易读的格式将该输出重新组织为新的 CSV 文件,然后查找源 IP 地址以确定哪些城市流量起源于。我不确定如何从我的函数中获取结果,该函数会查找 IP 地址的详细信息以将其他列添加到新的 CSV 文件中。

这是来自源文件的单个记录的示例。注意:我已经编辑了 IP 地址以屏蔽它们。

2018-07-01 14:48:47,Local7.Info,192.168.1.00,device="SFW" date=2018-07-01 time=14:48:39 timezone="PDT" device_name="XG" device_id= 00000000000000 log_id=010101600001 log_type="Firewall" log_component="Firewall Rule" log_subtype="Allowed" status="Allow" priority=信息持续时间=11 fw_rule_id=3 policy_type=3 user_name="" user_gp="" iap=0 ips_policy_id= 0 appfilter_policy_id=0 application="安全套接层协议" application_risk=1 application_technology="网络协议" application_category="Infrastructure" in_interface="Port2" out_interface="Port1" src_mac=00: 0:00: 0:00: 0 src_ip =75.148.000.000 src_country_code=美国 dst_ip=23.24.000.000 dst_country_code=美国协议="TCP" src_port=55000 dst_port=443 sent_pkts=7 recv_pkts=6 sent_bytes=1369 recv_bytes=918 tran_src_ip=192.168.000.000 tran_src_port=0 tran_dst_ip=192.168.000.000 tran_dst_port=0 srczonetype="WANLOs" " dstzone="LOCAL" dir_disp="" connevent="Stop" connid="1782869248" vconnid="" hb_health="无心跳" message="" appresolvedby="签名"vconnid=""hb_health="无心跳" message=""appresolvedby="签名"vconnid=""hb_health="无心跳" message=""appresolvedby="签名"

在此处其他用户的帮助下,我已经能够编写一个脚本来创建一个新的 CSV 文件 ( $output_file ),该文件具有更易于阅读的格式,并在src_ip列上查找信息。我不确定如何从该函数(Get-IPGeolocation)中获取结果并将附加列添加到我的$output_file中。

#Parameters for environment
$regex = '\b(\w+)=([^ ]+)'
$input_path = "C:\powershell_work\ParsingSophos\data.csv"
$output_file = "C:\powershell_work\GeolocatingIPs\combine-output.csv"


#Function used to lookup IP-Address information.
function Get-IPGeolocation
{
    Param
    (
        [string]$IPAddress
    )

    $request = Invoke-RestMethod -Method Get -Uri "http://geoip.nekudo.com/api/$IPAddress"

    [PSCustomObject]@{
        IP        = $request.IP
        City      = $request.City
        Country   = $request.Country.Name
        Code      = $request.Country.Code
        Location  = $request.Location.Latitude
        Longitude = $request.Location.Longitude
        TimeZone  = $request.Location.Time_zone
    }
}

# Parsing the input_path file, and exporting to a more workable format
Select-String -LiteralPath $input_path -AllMatches -Pattern $regex | ForEach-Object {
    $obj = New-Object pscustomobject
    foreach ($match in $_.Matches) {
      Add-Member -InputObject $obj -NotePropertyName $match.Groups[1].Value -NotePropertyValue $match.Groups[2].Value
    }
    $obj
} | Select-Object *_ip, srczone, src_country_code, dstzone, dst_country_code | 
     Export-Csv -NoTypeInformation $output_file


# Gathering list of Source IPs to be used in the lookup
$src_ips = Import-CSV $output_file | select -ExpandProperty src_ip


# Loop that runs each IP through the function to find IP address information
ForEach($ip in $src_ips) {
Get-IPGeolocation -IPAddress $ip
}

使用$input_path CSV 文件中的多条数据记录运行该脚本会返回如下结果。 输出示例

标签: functionpowershellcsvformatting

解决方案


本质上,您是在问如何合并两个自定义对象

一个简单的示例(PSv4+ 语法,假设属性名称集不重叠):

# Create two sample custom objects to merge.
$co1 = [pscustomobject] @{ one = 1; two = 2; three = 3 }
$co2 = [pscustomobject] @{ four = 4; five = 5; six = 6 }

# Add $co2's properties to $co1
$co2.psobject.properties.foreach({
  Add-Member -InputObject $co1 -NotePropertyName $_.Name -NotePropertyValue $_.Value
})

# Output $co1, which now contains its own properties plus the ones from $co2.
$co1

以上产生:

one   : 1
two   : 2
three : 3
four  : 4
five  : 5
six   : 6

应用于您的场景:

Import-Csv $output_file | ForEach-Object {
  $obj = $_
  (Get-IPGeolocation -IPAddress $obj.src_ip).psobject.properties.foreach({
    Add-Member -InputObject $obj -NotePropertyName $_.Name -NotePropertyValue $_.Value
  })
  $obj
} | Export-Csv -NoTypeInformation .\merged.csv

推荐阅读