2014-09-04 82 views
0

我正在转换目前为每个代理机构解析大型csv文件的代码。以下是一条线的样子:Powershell。试图循环使用导入-csv

Import-Csv $HostList | Where-Object {$_."IP Address" -Match "^192.168.532.*" -or $_Domain -eq  "MYDOMAIN"` 
-and (get-date $_.discovery_timestamp) -gt $PreviousDays} | select-object Hostname","Domain","IP Address","discovery_timestamp","some_version" | ` 
Export-Csv -NoTypeInformation -Path $out_data"\OBS_"$Days"_days.txt" 
write-host "OBS_DONE" 

我有大约30个这些。 我想解析一次csv文件,可能使用foreach和import.csv。 我想我可以做这样的事情:

$HostFile = Import-csv .\HostList.csv 
foreach ($line in $HostFile) 
{ 
Where-Object {$_."IP Address" -Match "^172.31.52.*"} 
write-host $line 
#| Export-Csv -NoTypeInformation -Path H:\Case_Scripts\test.csv 

我已经试过上述的许多排列,并且它永远不会是匹配的“位置对象”像它的功能例如上面的脚本。

任何指导和学习机会表示赞赏。

回答

1

Where-Object应该有传递给它的对象的集合。在你的第二个脚本块中,这不会发生,所以在过滤器中$ _变量将是空的。

有几种方法可以解决这个问题 - 首先想到的是用'if'语句替换Where-Object。例如

if ($line."IP Address" -Match "^172.31.52.*") { write-output $line } 
+0

Tyork,谢谢你的回复。你们很棒。 – Bruce 2014-09-05 13:39:09

+0

谢谢你的回复。确实这个例子有效。接下来,要了解为什么我的工作原理如正在运行的示例中所示,但不是在我的重写中。 – Bruce 2014-09-05 14:23:11

2

我的好人,你需要引入到Switch cmdlet。这会立即为您的所有公司排序。

$CompanyA = @() 
$CompanyB = @() 
$CompanyD = @() 
$Unknown = @()  
Switch(Import-CSV .\HostList.csv){ 
    {(($_."IP Address" -match "^192.168.532.*") -or ($_Domain -eq "CompanyA.com")) -and ((get-date $_.discovery_timestamp) -gt $PreviousDays)} {$CompanyA += $_; Continue} 
    {(($_."IP Address" -match "^192.26.19.*") -or ($_Domain -eq "CompanyB.net")) -and ((get-date $_.discovery_timestamp) -gt $PreviousDays)} {$CompanyB += $_; Continue} 
    {(($_."IP Address" -match "^94.8.222.*") -or ($_Domain -eq "CompanyC.org")) -and ((get-date $_.discovery_timestamp) -gt $PreviousDays)} {$CompanyC += $_; Continue} 
    default {$Unknown += $_} 
} 
$CompanyA | Export-Csv $out_data"\CompanyA"$Days"_days.txt" -NoType 
$CompanyB | Export-Csv $out_data"\CompanyB"$Days"_days.txt" -NoType 
$CompanyC | Export-Csv $out_data"\CompanyC"$Days"_days.txt" -NoType 
If($Unknown.count -gt 0){Write-Host $Unknown.count + " Entries Did Not Match Any Company" -Fore Red 
$Unknown} 

这将导入CSV,并为每个条目尝试将它与三条线中的每条线的条件相匹配。如果它匹配第一个ScriptBlock中的条件,它将在第二个ScriptBlock中执行动作(将该条目添加到我首先创建的三个数组中的一个)。然后,按照您在脚本中所做的操作,将每个数组输出到CSV格式的自己的文本文件中。 ;Continue只是让它停止尝试匹配,一旦它找到一个有效的匹配,并且继续到下一个记录。如果它们不能匹配其中的任何一个,它将默认将它添加到Unknown数组中,并在最后检查是否有任何警告主机并列出不匹配的条目。

编辑:交换机的-regex说法...好,所以这样做的目的是,如果你想要一个简单的正则表达式匹配,如:

Switch -regex ($ArrayOfData){ 
    ".*@.+?\..{2,5}" {"It's an email address"} 
    "\d{3}(?:\)|\.|-)\d{3}(?:\.|-)\d{4}" {"It's a phone number"} 
    "\d{3}-\d{2}-\d{4}" {"Probably a social security number"} 
} 

这是什么不允许的-and ,或 - 或语句。如果你使用scriptblock进行匹配(就像我在前面的例子中那样),你可以使用-match运算符,该运算符默认执行正则表达式匹配,所以你仍然可以使用regex而不必使用Switch的-regex参数。

+0

圣烟! ..和一个疯狂的技术人员!我正在阅读关于这个神奇的东西。谢谢。 – Bruce 2014-09-05 13:36:59

+0

阅读获取帮助,我看到:PS> switch -Regex(“fourteen”) { 1 {“It is one。”;休息} 2 {“这是两个。”; Break} – Bruce 2014-09-05 14:11:25

+0

阅读获取帮助,我看到:PS> switch -Regex( “fourteen”) { 1 {“It is one。”;休息} 2 {“这是两个。”;打破} 我想使用正则表达式,但没有得到如何插入它。 我想用: $ CompanyA = @() {(($ _。“IP Address”-match“^ 172 \ .2 [1,2] \。\ d {1,3} \。\ d {1,3}“) 我需要在某处添加-RegEx,我已经尝试过不同的地方,但是PS笑了我的尝试。 – Bruce 2014-09-05 14:22:04