我在4.1423
有一个包含以下信息的XML文件:
$DSConfigPath
我的目标是对<dataSources>
<add id="DataSource1" type="Fixed" distance="1">
<parameters>
<name />
<address>10.1.1.10</address>
<otherIdentifiers>DataSource1</otherIdentifiers>
<activeStatus>true</activeStatus>
<ip>10.1.1.10</ip>
<port>952</port>
</parameters>
</add>
<add id="DataSource2" type="Fixed" distance="2">
<parameters>
<name />
<address>10.1.1.11</address>
<otherIdentifiers>DataSource2</otherIdentifiers>
<activeStatus>true</activeStatus>
<ip>10.1.1.11</ip>
<port>952</port>
</parameters>
</add>
<add id="DataSource3" type="Fixed" distance="3">
<parameters>
<name />
<address>10.1.1.12</address>
<otherIdentifiers>DataSource1</otherIdentifiers>
<activeStatus>false</activeStatus>
<ip>10.1.1.12</ip>
<port>952</port>
</parameters>
</add>
</dataSources>
为'true'的任何IP /端口进行端口连接测试。
我有以下功能,当我输入特定的<activeStatus>
和$hostname
时,我已验证会给我正确的结果:
$port
所以现在我添加以下变量:
function Test-Port($hostname, $port) {
# This works no matter in which form we get $host - hostname or ip address
try {
$ip = [System.Net.Dns]::GetHostAddresses($hostname) |
Select-Object IPAddressToString -ExpandProperty IPAddressToString
if ($ip.GetType().Name -eq "Object[]") {
#If we have several ip's for that address, let's take first one
$ip = $ip[0]
}
} catch {
Write-Host "Possibly $hostname is wrong hostname or IP"
return
}
$t = New-Object Net.Sockets.TcpClient
# We use Try\Catch to remove exception info from console if we can't connect
try {
$t.Connect($ip,$port)
} catch {}
if ($t.Connected) {
$t.Close()
$msg = "Port $port is operational"
} else {
$msg = "Port $port on $ip is closed, "
$msg += "You may need to contact your IT team to open it. "
}
Write-Host $msg
}
然后运行:
[xml]$DSConfig = gc "$DSConfigPath"
$DS = $dsconfig.datasources.add.parameters
$DSName = $DS.otherIdentifiers
$DSIP = $DS.ip
$DSPort = $DS.port
$DSActive = $DS | Where-Object {$_.activeStatus -eq 'True'}
$hostname = $DSIP # yes I realize this is redundant
$port = $DSPORT # and yes, I realize this is redundant as well
我得到了结果:
Possibly 10.1.1.10 10.1.1.11is wrong hostname or IP
有任何建议如何让它测试到10.1.1.10:952的连接,给出结果,然后测试连接到10.1.1.11:952然后给出结果?
答案 0 :(得分:2)
使用mouseup
从xml文档中获取onmouseup
个节点:
SelectNodes()
答案 1 :(得分:0)
使用Select-Xml
的替代方法。这实际上与Mathias的答案相同,但使用cmdlet而不是方法。除非您想要利用cmdlet中内置的一些其他选项(该方法不可用)(在这里不是很有用,但在更复杂的用途中肯定有用),但不是特别有用。
# Read XML document
[xml]$DSConfig = gc "$DSConfigPath"
# Select <parameters> nodes
$ParametersNode = Select-Xml -Xml $DSConfig -XPath '//parameters'|% {
Test-Port $_.Node.ip $_.Node.port
}
答案 2 :(得分:0)
声明
$DS = $dsconfig.datasources.add.parameters
列出变量<parameter>
中所有$DS
个节点的列表。如果您检查$DS.Count
,您会看到它的示例数据值为3,如果您回显变量,则会看到如下内容:
PS C:\> Write-Output $DS name : address : 10.1.1.10 otherIdentifiers : DataSource1 activeStatus : true ip : 10.1.1.10 port : 952 name : address : 10.1.1.11 otherIdentifiers : DataSource2 activeStatus : true ip : 10.1.1.11 port : 952 name : address : 10.1.1.12 otherIdentifiers : DataSource1 activeStatus : false ip : 10.1.1.12 port : 952
接下来的陈述
$DSIP = $DS.ip
$DSPort = $DS.port
将变量$DSIP
和$DSPort
分别填入所有IP地址和所有端口的列表。
PS C:\> Write-Output $DSIP 10.1.1.10 10.1.1.11 10.1.1.12
在PowerShell v3和更新版本上,即。在PowerShell v3之前,语句会引发错误,因为较旧的版本不支持member enumeration,即当数组对象本身不支持时,访问数组的元素上的属性和方法。拥有该属性或方法。
当您将此IP地址列表传递给Test-Port
时,语句
$ip = [System.Net.Dns]::GetHostAddresses($hostname)
以MethodInvocationException
失败,因为GetHostAddresses()
需要单个字符串,而不是字符串数组。
另外,你的循环
foreach ($DSActive in $DSConfig) {Test-Port $hostname $port}
将在一次迭代后终止,因为$DSConfig
只有一个元素:根节点(<dataSources>
)。
要让代码为每个IP地址和端口调用Test-Path
,请将上述循环更改为:
foreach ($DSActive in $DSConfig.datasources.add.parameters) {
Test-Port $DSActive.ip $DSActive.port
}