运行 查询不同服务器上的多个数据库

run query against multiple databases on different server

我正在编写一个 PowerShell 脚本来 运行 针对多个服务器和数据库的查询,其想法是将服务器和数据库动态添加到数组并执行它们。

目前我卡在了所有内容合并的最后部分。我可以添加服务器,但不能添加数据库。

我想要实现的目标:使用 MFP GUI 的 PowerShell 脚本 运行 针对多个 MSSQL 服务器的查询,这些服务器都包含相同的数据库(具有不同的数据)但数据库具有不同的名称,例如 Sql_Data-Node1, SqlData-Node2, 等等

我遇到的问题:我设法将服务器动态添加到数组中,当我 运行 查询时,我得到了正确的响应。在这种情况下,我使用了 master 数据库并将其设为静态 (-database 'master')。当我尝试对数据库执行相同操作(将它们添加到数组中)时,出现错误:

Invoke-Sqlcmd : Cannot validate argument on parameter 'Database'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At C:\Users\master\Documents\MULTSCRIPT\MultiQueryV0.6.ps1:368 char:109
+ ... ame -Password $PassWord -ServerInstance $_[0] -Database $_[1] -Query  ...
+                                                             ~~~~~
+ CategoryInfo          : InvalidData: (:) [Invoke-Sqlcmd], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand

我的代码:

#Create EMPTY ARRAY for Databases
$script:DBSet = New-Object System.Collections.ArrayList 

    #==========================================================================

    $window.Master.add_Checked({
        $script:Master = 'master' #Add IP to Variable
        $script:DBSet.Add("$script:Master") #Add Variable to Array
        [System.Object]$sender = $args[0]
        [System.Windows.RoutedEventArgs]$e = $args[1]
    })

    $window.Master.add_Unchecked({
        $script:Master = $null
        $script:DBSet.Remove("$script:Master")
        [System.Object]$sender = $args[0]
        [System.Windows.RoutedEventArgs]$e = $args[1]
    })

    #==========================================================================

    $window.DataNodes.add_Checked({
        $script:DB01 = 'Database01'                                                  
        $script:DBSet.Add("$script:DB01")
        [System.Object]$sender = $args[0]
        [System.Windows.RoutedEventArgs]$e = $args[1]
    })

    $window.DataNodes.add_Unchecked({
        $script:DB01 = $null
        $script:DBSet.Remove("$script:DB01")
        [System.Object]$sender = $args[0]
        [System.Windows.RoutedEventArgs]$e = $args[1]
    })

    #Create EMPTY ARRAY For Servers
    $script:ServerAddress = New-Object System.Collections.ArrayList

    #Add action to Checkbox====================================================

    $window.DB00.add_Checked({
        $script:SRV00 = '190.168.1.8' #Add IP to Variable
        $script:ServerAddress.Add("$script:SRV00") #Add Variable to Array
        [System.Object]$sender = $args[0]
        [System.Windows.RoutedEventArgs]$e = $args[1]
    })

    $window.DB00.add_Unchecked({
        $script:SRV00 = $null
        $script:ServerAddress.Remove("$script:SRV00") #Remove Variable to Array 
        [System.Object]$sender = $args[0]
        [System.Windows.RoutedEventArgs]$e = $args[1]
    })

    #==========================================================================

    $window.DB01.add_Checked({
        $script:SRV01 = '192.168.1.9'
        $script:ServerAddress.Add("$script:SRV01")
        [System.Object]$sender = $args[0]
        [System.Windows.RoutedEventArgs]$e = $args[1]
    })

    $window.DB01.add_Unchecked({
        $script:SRV01 = $null
        $script:ServerAddress.Remove("$script:SRV01")
        [System.Object]$sender = $args[0]
        [System.Windows.RoutedEventArgs]$e = $args[1]
    })

    #Collect Credentials#======================================================

    $credential = Get-Credential 
    $UserName = $credential.UserName.Replace('\','')
    $PassWord = $credential.GetNetworkCredential().password


    #Collect From Input Fields#================================================

    $window.Button.add_Click({
        $SQLQuery = $window.Query.Text.ToString()
        $Server = $script:ServerAddress
        $DatabaseSet = $script:DBSet
        $instances = @( @($Server, $DatabaseSet) )
        $instances | ForEach{
            Invoke-Sqlcmd -AbortOnError `
                -Username $UserName`
                -Password $PassWord`
                -ServerInstance $_[0]`
                -Database $_[1]`
                -Query $SQLQuery`
                -QueryTimeout 30 |
                Out-GridView -Title $_[0]
        }
        [System.Object]$sender = $args[0]
        [System.Windows.RoutedEventArgs]$e = $args[1]
    })

看来以下解决方案有效。 归功于:Mutiple Variables in Foreach Loop [Powershell]

$window.Button.add_Click(
{   $DataBase = $window.DataBase.Text.ToString()
    $SQLQuery = $window.Query.Text.ToString()
    $Server = $ServerAddress.getenumerator()
    $Database = $DBSet.getenumerator()
    while($Server.MoveNext() -and $Database.MoveNext()){
    Invoke-Sqlcmd -AbortOnError -Username $UserName -Password $PassWord -ServerInstance $Server.Current -Database $Database.Current -Query $SQLQuery -QueryTimeout 30 | Out-GridView -Title $Server.Current}