为什么数组中的项目被跳过?

时间:2019-03-18 19:15:01

标签: powershell

我有一张桌子

table

我有以下脚本

$Result = Query "SELECT [databasename], [servertypeA], [servertypeB] from table GROUP BY [databasename], [servertypeA], [servertypeB]"

$Servers = @()
$DB = @()

foreach($row in $Result)
{   
    $i++
    $DB += $row.Item("databasename")
    $Servers += $row.Item("servertypeA")
    $Servers += $row.Item("servertypeB")

    cmd /c "PS.bat $somescript.ps1 $($Servers[-1]) $($DB[-1])"
}

这导致:

db1 serverx
db1 servery
db2 serverx
db2 servery

应该是

db1 server1
db1 serverx
db1 servery
db2 server2
db2 serverx
db2 servery

为什么跳过servertypeA,即server1 and server2中的$Server

我也尝试过

$Result = Query "SELECT distinct [databasename], [servertypeA], [servertypeB] from table"

及其产生相同的结果

3 个答案:

答案 0 :(得分:1)

简单!在循环中,您对$Servers数组进行了2次添加,但仅对外部脚本进行了一次调用,在该调用中,您仅传递了$Servers数组中的最后一项。

如果您可以原谅我所提出的严格问题,您为什么选择从cmd.exe从Powershell调用Powershell?这将是更常见的方法:

foreach($row in $Result)
{   
    $i++
    $DB = $row.Item("databasename")
    $Servers = $row.Item("servertypeA"), $row.Item("servertypeB")

    & "$somescript.ps1" @($Servers) $DB
}

通过cmd.exe消除往返的价值在于:

  • 节省浪费的过程
  • 调试能力
  • 捕获所有流的能力
  • 有用的错误消息

我假设您在其他地方定义$somescript&调用的确切语法取决于您是否已经很好地定义了参数块-拥有这样的东西总是很好的:

param
(
    [string[]]$Servers
    [string]$DB
)

编辑

既然您已经阐明了传递给$somescript的必要条件,请尝试以下操作:

foreach($row in $Result)
{   
    $DB = $row.Item("databasename")
    & "$somescript.ps1" $row.Item("servertypeA") $DB
    & "$somescript.ps1" $row.Item("servertypeB") $DB
}

答案 1 :(得分:1)

将其替换为下面的代码

$DB += $row.Item("databasename")
$Servers += $row.Item("servertypeA")
$Servers += $row.Item("servertypeB")

$DB += $row.Item("databasename")
$Servers += $row.Item("servertypeA")
$DB += $row.Item("databasename")
$Servers += $row.Item("servertypeB")

答案 2 :(得分:1)

最大的变化是查询,以获得所需的结果,但是请注意,这也使我大大简化了循环:

$Result = Query "SELECT DISTINCT [databasename], [serverTypeA] As Server from table  UNION SELECT DISTINCT [databasename], [serverTypeB] from table"

foreach($row in $Result)
{   
    $DB = $row.Item("databasename")
    $Server = $row.Item("Server")

    cmd /c "PS.bat $somescript.ps1 $Server $DB"
}