Powershell invoke-sqlcmd:值不能为null。参数名称:ServerInstance

时间:2015-10-02 19:28:21

标签: powershell sqlps

我在使用下面列出的方法调用本地数据库时遇到问题。

错误消息

  

invoke-sqlcmd:值不能为null。   参数名称:ServerInstance   在C:\ filelocation \ HealthCheckCombined.ps1:86 char:3    1. invoke-sqlcmd -query $ agentquery -serverinstance $ servername ...    2. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~       + CategoryInfo:InvalidArgument:(:) [Invoke-Sqlcmd],ArgumentNullException       + FullyQualifiedErrorId:CannotGetServerInstance,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand

环境(S)

  • Server 2016 Candidate 3
  • Server 2012
  • SQL Server 2014
  • SQL Server 2012
  • PowerShell 3.0,4.0& 5.0

目标

我正在尝试通过PowerShell对servers.txt(配置文件)中列出的任何SQL实例运行查询。

两个组件 -

  1. 外部配置文件(servers.txt)
  2. 包含函数的PowerShell脚本,循环从servers.txt创建数组并执行函数。
  3. 所以 servers.txt 的内容看起来像=

    server=test2k16\powershell
    server=test2k16\healthcheck
    

    以下是导入文本文件并创建函数=

    的部分
    #===============================================================================
    #Configurable variables
    #===============================================================================
    $configfile = 'C:\filelocation\servers.txt'
    Import-Module "sqlps"
    #===============================================================================
    
    #===============================================================================
    #SQL Agent Jobs
    #===============================================================================
    function SQLAgent{
    $agentquery= @"
        declare @count int
        select @count = count(1) from msdb.dbo.sysjobs as sj
        join msdb.dbo.sysjobhistory as sjh on sj.job_id = sjh.job_id
        where sj.enabled != 0
        and sjh.sql_message_id > 0
        and sjh.run_date > CONVERT(char(8), (select dateadd (day,(-30), getdate())), 112)
        and sjh.Step_id <= 1
    
        if (@count >= 1)
            begin
                select distinct sj.name as SQLJobName
                from msdb.dbo.sysjobs as sj
                join msdb.dbo.sysjobhistory as sjh on sj.job_id = sjh.job_id
                where sj.enabled != 0
                and sjh.sql_message_id > 0
                and sjh.run_date > CONVERT(char(8), (select dateadd (day,(-30), getdate())), 112)
                and sjh.Step_id <= 1
            order by name
        end
    
            else
            begin
                Select 'No Job Failed in Last Month' as SQLJobName
            end
    "@
    
            invoke-sqlcmd -query $agentquery -serverinstance $servername -username "user" -password "password" | Format-Table -AutoSize -Wrap
    }
    #===============================================================================
    

    现在我通过格式化导入的变量并在运行function =

    时循环遍历它来实现神奇
    #===============================================================================
    #Run Health Check for each server
    #===============================================================================
    $import = $(foreach ($line in get-content $configfile) {$line.tolower().split(" ")}) | sort | get-unique
    ForEach ($_ in $import){
        $servername = $import.trimstart("server=")
    }
    ForEach ($_ in $servername){
        SQLAgent
    }
    #===============================================================================
    

    到目前为止的结果

    • 在函数中提取代码并导入文本文件非常合适。没错。
    • 如果我将脚本更改为仅在循环中显示这些变量,则循环中的$ servername变量显示正确的值(test2k16 \ powershell&amp; test2k16 \ healthcheck)

    我显然错过了一些东西......我一直在堆栈和谷歌搜索一天,一无所获。希望这是我对PowerShell的忽视或不了解的小事。

    提前感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

您正在为$ServerName参数引用-ServerInstance。它需要一个字符串,并且您将使用一个字符串数组来呈现它。此外,您最近两次错误地使用ForEach循环。它应该是变量名,而不是$_的自动变量。例如:

ForEach($Server in $ServerName){
    SQLAgent
}

然后更改您的函数中的-ServerInstance以引用$Server。更好的是,为您的函数设置参数,并在循环中为其提供所需的信息。

Function SQLAgent($Server){
    <Code goes here!>
    invoke-sqlcmd -query $agentquery -serverinstance $server -username "user" -password "password" | Format-Table -AutoSize -Wrap
}
$ServerList = Get-Content $configfile | ForEach{$_.Split('=')[1]}
ForEach($Item in $ServerList){
    SQLAgent -Server $Item
}