0

假设我有 2 台服务器服务器 1 和服务器 2。

在每台服务器中都有 x 个数据库,每个数据库都连接到一个全局数据库。

server1 有database1、datatabse2、database3。

server2有database4、database5

我们将有 2 个文件,一个包含服务器的文件,另一个包含“数据库”

那么循环将是:

Import-Module SqlServer 

foreach ($server in $servers_file)
{
    $Analysis_Server = New-Object Microsoft.AnalysisServices.Server  
    $Analysis_Server.connect("$server") 

    foreach ($database in $databases_file)
    {
        $database = $Analysis_Server.Databases.FindByName($database)

        ####### Setting connection property for $database #######

        $database.DataSources[0].ConnectionString = "UserId=…;Password=…."
    }

} 

这里的问题是这个循环不考虑数据库属于服务器的位置。

例如,如果我的数据库文件为:

数据库1

数据库2

数据库3

数据库4

数据库5

我怎样才能让这个循环知道当 database1-3 从 server1 完成时它必须退出内循环,现在你必须转到外循环以连接到 database4 和 5 的 server2。

ConnectionInfo 类:https ://docs.microsoft.com/it-it/dotnet/api/microsoft.analysisservices.connectioninfo?view=sqlserver-2016

4

2 回答 2

1

我建议您制作一个哈希表,在其中将数据库值分配给每个服务器。

$h=@{'server1'=( 'database1','database2','database3');'server2'=( 'database4','database5')}

然后你的循环变成:

foreach($key in $h.keys){ 
   $Analysis_Server = New-Object Microsoft.AnalysisServices.Server  
   $Analysis_Server.connect("$key") 
   foreach($value in $h[$key])
    {
      write-output "$key - has db $value"
      $database = $Analysis_Server.Databases.FindByName($database)

      ####### Setting connection property for $database #######

      $database.DataSources[0].ConnectionString = "UserId=…;Password=…."

    }
}
于 2018-10-24T23:34:07.507 回答
1

看到您对希望使用 csv 文件填充哈希表的最后评论,您可以这样做:

假设您的 CSV 看起来像这样

"Server","Database"
"server1","database1"
"server2","database4"
"server1","database2"
"server1","database3"
"server2","database5"

然后您可以使用它来读取它Import-Csv并像这样从中创建一个哈希

$h = @{}
Import-Csv '<PATH_TO_THE_CSV_FILE>' | Group-Object Server | ForEach-Object {
    $db = @()
    foreach ($item in $_.Group) {
        $db += $item.Database 
    }
    $h += @{$($_.Name) = $db}
}

根据您的 PowerShell 版本(我认为您至少需要 5.1),您可以通过执行以下操作来简化以前的版本:

$h = @{}
Import-Csv 'D:\Code\PowerShell\StackOverflow\Databases.csv' | Group-Object Server | ForEach-Object {
    $h += @{$($_.Name) = $_.Group.Database}
}

接下来,您可以使用 thom schumacher 描述的循环:

foreach($server in $h.Keys){ 
   $Analysis_Server = New-Object Microsoft.AnalysisServices.Server  
   $Analysis_Server.connect("$server") 
   foreach($db in $h[$server]) {
      write-output "$server - has db $db"
      $database = $Analysis_Server.Databases.FindByName($db)

      ####### Setting connection property for $database #######

      $database.DataSources[0].ConnectionString = "UserId=…;Password=…."

    }
}

编辑

从您的评论中,我收集到您的 csv 文件如下所示:

"Server","Database"
"server1", "database1, database2, database3"
"server2","database4, database5"

在这种情况下,您可以将其读入 Hashtable,如下所示:

$h = @{}
Import-Csv '<PATH_TO_THE_CSV_FILE>' | ForEach-Object {
    $h += @{$($_.Server) = ($_.Database -split '\s*,\s*') }
}

如果您的 CSV 文件没有上面这样的标题,请使用cmdlet-Header上的开关Import-Csv为列指定一个我们可以使用的名称,如下所示:

    Import-Csv '<PATH_TO_THE_CSV_FILE>' -Header 'Server','Database'
于 2018-10-25T08:36:19.080 回答