我的所有访问点都有一个CSV(包含标题),并希望通过XML Upload将它们添加到Zabbix。
由于我不想手动为每个AP创建XML文件,我将尝试在PowerShell中执行此操作。但是 - 怎么样?
我尝试了(Get-Content .\Template.xml).Replace()
和ForEach-Object
的一些事情,但我还没有成功。
文件名是:
AP.csv
(AP列表,标题是主机名和IP):
Hostname;IP AP1;10.29.202.101 AP2;10.29.202.102 AP3;10.29.202.103 AP4;10.29.202.104 Ap5;10.29.202.105
Template.xml
:
<hosts>
<host>
<host>Hostname</host>
<name>Hostname</name>
[...]
<interfaces>
<interface>
[...]
<ip>PIIP</ip>
[...]
</interface>
<interface>
Template.xml
有2个字符串称为“主机名”,2个称为“PIIP” - 两个主机名字符串应替换为AP.csv
中的1个主机名,并且两个PIIP都应替换为相关的IP。
到目前为止,我的最后一次尝试是:
$a = Import-Csv .\Ap.csv
$APHost = ($a).Hostname
$APIP = ($a).IP
$xml = Get-Content .\Template.xml
foreach ($row in $a) {
$xml.Replace('Hostname',$APHost).Replace('PIIP',$APIP) |
Out-File ".\Aps\$row.xml"
}
但是这个以1个XML文件中的所有主机名和所有IP结束。
我希望每个主机最后都有1个XML文件,包含主机名和相关IP。
答案 0 :(得分:2)
您的主要问题是:
您在循环外的数组变量中存储了AP名称和IP($APHost
和$APIP
)
然后在循环中使用这些数组作为整体,而不是逐个引用它们的元素。
这是一个修复程序,它只使用$row.Hostname
和$row.IP
来获取适合迭代的值:
$a = Import-Csv -Delimiter ';' .\Ap.csv
$xml = Get-Content -Raw .\Template.xml
foreach ($row in $a) {
$xml.Replace('Hostname', $row.Hostname).Replace('PIIP', $row.IP) |
Out-File ".\Aps\$row.xml"
}
但是,您应该考虑使用真正的XML解析来使您的替换更加健壮:
$a = Import-Csv -Delimiter ';' .\Ap.csv
$xmlTmpl = [xml] (Get-Content -Raw .\Template.xml)
foreach ($row in $a) {
# Find the parent Xml element of the elements to update.
$parentEl = $xmlTmpl.hosts.host
# Set the hostnames, by element *name*.
$parentEl.host = $parentEl.name = $row.Hostname
# Set the IP addresses, by element *name*
foreach ($el in $parentEl.interfaces.interface.ChildNodes) {
if ($el.Name -eq 'ip') { $el.InnerText = $row.IP }
}
# XPath alternative (doesn't work in PowerShell *Core*):
# foreach ($el in $parentEl.SelectNodes('interfaces/interface/ip'))
# {
# $el.InnerText = $row.IP
# }
# Save to file
# Note: This doesn't include an XML header.
$xmlTmpl.OuterXml | Out-File ".\Aps\$row.xml"
}
请注意文档层次结构中特定位置的特定元素是如何定位的,这是一种更实用的模板实例化方法(没有误报的可能性)。
答案 1 :(得分:1)
示例:
this.$$('#drawerList')