1

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

目前我被困在所有东西都结合在一起的最后一部分。我可以添加服务器,但不能添加数据库。

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

我遇到的问题:我设法将服务器动态添加到数组中,当我运行查询时,我得到了正确的响应。在这种情况下,我使用了主数据库并将其设为静态(-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]
    })
4

1 回答 1

1

似乎以下解决方案有效。归功于:Foreach 循环中的多个变量 [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}
于 2015-11-22T21:44:40.363 回答