昨天在群里 有人提供了一些防火墙的策略文本,询问如何能够在PowerShell里面转换为对象。
文本样例如下所示
rule id 39
action permit
src-zone "Any"
dst-zone "Any"
src-addr "Any"
dst-addr "Any"
service "Any"
exit
rule id 46
action permit
src-zone "Any"
dst-zone "Any"
src-addr "Any"
dst-addr "Any"
service "PING"
exit
rule id 11
action permit
src-zone "untrust"
dst-zone "trust"
src-addr "nqtwgroup"
dst-addr "zj-wtqzgroup"
service "wtqz_group"
name "zj-nqtw-wtqz"
exit
因为这个文本看起来很有规律,所以第一个方案是使用 convertfrom-string这个命令,配合自己定义的模板,可以把这些字符串转换为PS对象。
$t=
@'
rule id {ID*:39}
action {action:permit}
src-zone {srz_zone:"Any"}
dst-zone {dst_zone:"Any"}
src-addr {src_addr:"Any"}
dst-addr {dst_addr:"Any"}
service {service_addr:"Any"}
{name:""}
exit
rule id {ID*:46}
action permit
src-zone "Any"
dst-zone "Any"
src-addr "Any"
dst-addr "Any"
service "PING"
exit
rule id 11
action permit
src-zone "untrust"
dst-zone "trust"
src-addr "nqtwgroup"
dst-addr "zj-wtqzgroup"
service "wtqz_group"
name "zj-nqtw-wtqz"
exit
'@
ConvertFrom-String -TemplateContent $t -InputObject $st | ft -AutoSize
简单的解释一下这个模板是怎么设计的,把整个文本copy过来,在上面开始修改,比如我所需要的模板的每一行的开始需要用*进行标明,大括号{}里面的键值对,键是自己取的名字,后面的值是文本的原先的内容;PS会自动根据规律来生成对应的对象。
具体的命令解释可以参见 https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/convertfrom-string?view=powershell-5.1
结果如下所示:
ID action srz_zone dst_zone src_addr dst_addr service_addr
-- ------ -------- -------- -------- -------- ------------
39 permit "Any" "Any" "Any" "Any" "Any"
46 permit "Any" "Any" "Any" "Any" "PING"
11 permit "untrust" "trust" "nqtwgroup" "zj-wtqzgroup" "wtqz_group"
咋一看好像需要的结果都有了,不过仔细观察 发现文本每一块策略的内容略微有些不太一样,比如说有些rule还多了个name的属性,这样的话如果不统一,一个单一的模板就对不上所以的内容了。
传统的正则+字符串拼接处理
#原始文本
$st=@"
rule id 39
action permit
src-zone "Any"
dst-zone "Any"
src-addr "Any"
dst-addr "Any"
service "Any"
exit
rule id 46
action permit
src-zone "Any"
dst-zone "Any"
src-addr "Any"
dst-addr "Any"
service "PING"
exit
rule id 11
action permit
src-zone "untrust"
dst-zone "trust"
src-addr "nqtwgroup"
dst-addr "zj-wtqzgroup"
service "wtqz_group"
name "zj-nqtw-wtqz"
exit
"@
$r=@()
#正则进行多行匹配,获取每一个rule的块
$st | Select-String '(?smi)rule id [1-9]{2}.*?exit' -AllMatches | Foreach {$_.Matches} |
Foreach {
#替代一下空格和换行符,这样更规整,方便处理
$temp=$_.value -replace 'rule id','rule-id'
$temp=$temp -replace 'exit', ''
$temp=$temp -replace '\r\n',','
$list=$temp.split(',')
$object = New-Object –TypeName PSObject
try{
foreach($item in $list){
$c=$item.trim().split()
$name=$c[0]
$value=$c[1]
$object | Add-Member -NotePropertyName $name -NotePropertyValue $value -ErrorAction SilentlyContinue
}}catch{}
$r+=$object
}
$r | select rule-id,action,src-zone,dst-zone,src-addr,dst-addr,service,name | ft
最后结果如下所示,成功获取了所以的信息
rule-id action src-zone dst-zone src-addr dst-addr service name
------- ------ -------- -------- -------- -------- ------- ----
39 permit "Any" "Any" "Any" "Any" "Any"
46 permit "Any" "Any" "Any" "Any" "PING"
11 permit "untrust" "trust" "nqtwgroup" "zj-wtqzgroup" "wtqz_group" "zj-nqtw-wtqz"
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。