以下に概説する方法を使用してローカル データベースを呼び出す際に問題が発生します。
エラーメッセージ
invoke-sqlcmd : 値を null にすることはできません。パラメータ名: ServerInstance At 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
環境
- サーバー 2016 候補 3
- サーバー 2012
- SQL Server 2014
- SQL Server 2012
- PowerShell 3.0、4.0、および 5.0
ゴール
server.txt (構成ファイル) にリストされている SQL インスタンスに対して、PowerShell 経由でクエリを実行しようとしています。
2 つのコンポーネント-
- 外部構成ファイル (servers.txt)
- 関数を含む PowerShell スクリプト。ループして、servers.txt から配列を作成し、関数を実行します。
したがって、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 & test2k16\healthcheck) が表示されます。
明らかに何かが欠けています...スタックとGoogleを1日検索しましたが、何も見つかりませんでした。うまくいけば、PowerShell について見落としているか、まだ理解していない小さなことです。
助けてくれてありがとう!