Powershell范围:添加到第二个数组时,循环内的变量数组不会填充

时间:2014-08-17 00:16:56

标签: arrays variables powershell scope

在下面的Powershell示例中,如何在第5行中填充$server?我尝试将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
}
  1. 我尝试将$ server变量的范围分配给global或script。
  2. 我已经研究过其他类似的问题,但我找不到这种情况
  3. 我尝试过不同的滚边,报价,背虱等组合。
  4. 一如既往,提前谢谢。

    编辑好的,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}
    }
    

2 个答案:

答案 0 :(得分:4)

我不是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,而最终将收集整个电话会议的结果。

答案 1 :(得分:2)

...代替

$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循环中。然后你可以使用$ _