在下面的Powershell示例中,如何让$server
填充在第#5行中?我正在尝试将Get-EventLog
查询的结果保存到每个$server
循环迭代的数组中。
例:
$serversArray = @("one", "two", "three")
ForEach ($server in $serversArray) {
echo $server "Variable array iteration populates here correctly"
$eventArray = @()
$eventArray += Get-EventLog -computerName $server #But not here, where I need it
$eventArray #Yet it populates from calling the second array correctly
}
- 我尝试将$server变量的范围分配给全局或脚本。
- 我研究过其他类似的问题,但我找不到这种情况
- 我尝试了管道、引号、反勾号等的不同组合。
与往常一样,提前感谢。
编辑好的,ISE正在缓存一些变量(或奇怪的变量(,因为上面的示例在我重新启动ISE后开始工作。无论如何,问题出在$servers
数组输入上,完整脚本中的输入来自 MySQL 查询。如果我用服务器名称静态分配数组(如上例所示(,则脚本可以工作。如果我使用 MySQL 查询的输入,Get-EventLog
会失败并显示 The network path was not found
.因此,即使服务器值看起来正确(并且某些内容可能正在扩展(,也可能是文本编码问题等。很抱歉浪费时间,但讨论它有助于缩小范围。以下是实际脚本的相关部分:
#Open SQL Connection
[System.Reflection.Assembly]::LoadWithPartialName("MySql.Data")
$connectionString = "server=dbserver;uid=odbc;pwd=password;database=uptime;"
$connection = New-Object MySql.Data.MySqlClient.MySqlConnection
$connection.ConnectionString = $connectionString
$connection.Open()
#Get server names from db
$sqlGetServers = "select server_nm from servers limit 3;"
$command = New-Object MySql.Data.MySqlClient.MySqlCommand($sqlGetServers, $connection)
$dataAdapter = New-Object MySql.Data.MySqlClient.MySqlDataAdapter($command)
$dataSet = New-Object System.Data.DataSet
$recordCount = $dataAdapter.Fill($dataSet, "sample_data")
$server_names = @()
$server_names += $dataSet.Tables["sample_data"]
#$server_names = @("server-1","server-2") <-- this works
#loop through array of server names
foreach($server in $server_names) {
$eventData = @()
$eventData += Get-EventLog -computerName $server -LogName System -Newest 10
foreach($event in $eventdata) {Do-Stuff}
}
我不能 100% 确定您遇到的问题是什么。我假设问题是您的$eventArray
最终只会得到最后一个结果。
如果这是正确的,那么原因是因为您在第 4 行的每次迭代中将其重新初始化为空:$eventArray = @()
试试这个:
$serversArray = @("one", "two", "three")
$eventArray = @()
ForEach ($server in $serversArray) {
echo $server "Variable array iteration populates here correctly"
$eventArray += Get-EventLog -computerName $server #But not here, where I need it
$eventArray #Yet it populates from calling the second array correctly
}
或者,或者,像这样ForEach-Object
:
$serversArray = @("one", "two", "three")
$eventArray = $serversArray | ForEach-Object {
echo $_ "Variable array iteration populates here correctly"
Get-EventLog -computerName $_ #But not here, where I need it
#Yet it populates from calling the second array correctly
}
方法1的说明:
在循环开始之前将$eventArray
声明为空数组,然后在循环的每次迭代中向其添加项,而不是在每次迭代时对其进行初始化。
按照你的方式,$eventArray
每次都会重置为空数组,最后它只会包含最后一个结果。
方法2的说明:
ForEach-Object
是一个管道 cmdlet,并返回其代码块的结果(对于通过管道传输到其中的每个对象运行一次(。
在这种情况下,我们使用$_
来表示单个对象。我们没有将Get-EventLog
的结果分配给$eventArray
,而是简单地调用它,允许从块返回返回值。
我们将整个ForEach-Object
调用分配到$eventArray
中,最终将收集整个调用的结果。
相反....
$serversArray = @("one", "two", "three")
$eventArray = @()
$serversArray | ForEach-Object {
echo $_ "Variable array iteration populates here correctly"
$eventArray += Get-EventLog -computerName $_ #But not here, where I need it
$eventArray #Yet it populates from calling the second array correctly
}
通过管道将数组传送到 for-each 循环中。然后可以使用 $_