私の新しい仕事では、各サーバーに複数の名前付きインスタンスがあります。例えば
- Server1 \ Dev
- Server1 \ DevIntegrated
- Server1 \ QA
OSを呼び出すSQL PowerShellスクリプトがあり、呼び出しますFoo.exe
が、コマンドラインパラメーター(接続文字列)を渡す必要があります。SQLエージェントジョブは各インスタンスに存在し、PowerShellタイプのステップで、現在のコンテキストが何であるかを知る必要があります。つまり、この実行はDevIntegratedで始まりました。
すべてのスクリプトを最初から始めたいとは思いません...
$thisInstance = "Dev"
...特に、今後数か月で環境(新しいサーバーと名前付きインスタンス)に移行するときに編集する必要があるためです。
SQLPSを起動すると、Get-Locationまたは実行の結果をスライスしてダイシングすることにより、インスタンスを特定できます。
(Invoke-Sqlcmd -Query "SELECT @@servername AS ServerName" -SuppressProviderContextWarning).ServerName
SQLエージェントがPowerShellタイプのジョブを開始すると、C:\ windows \ system32で開始さGet-Location
れ、SQLSERVERコンテキストではないため、ルートは機能しません。そのコンテキストに変更できますが、SQL Serverの「ルート」にいるので、どのインスタンスにいるべきかわかりません。Invoke-Sqlcmd
ルートを使用しても同じ理由で機能しません(技術的には、デフォルトのインスタンスではありません)
私の知る限り、ジョブログに記録できる基本的な「もの」をすべて列挙しましたが、何も表示されないようです SQLSERVER:\SQL\Server1\DevIntegrated
Get-ChildItem
Get-Host
Get-Location
Get-Process
Get-PSDrive
Get-PSProvider
Get-Service
Get-TraceSource
Get-Variable
Get-Process
私はそれと、インスタンスをヒットしてspidを一致させることによって物事を一緒にしようとするいくつかのブードゥー教を使用することができるようですが、それは地獄からの血まみれのハックのように聞こえます。私が見逃している基本的なものがあるはずです、誰かが光を当てることができますか?
調査されたPowerShellの代替
他のジョブタイプを使用して調査したところ、満足のいく解像度が得られませんでした。調査の結果、SQL Agentの下にリストされているPowerShellはSQLPSであり、Agentを右クリックしてインスタンスを起動すると、自動的に正しい場所にドロップされました。前述のように違いを知ったのは、ジョブコードに対話型コードを貼り付けたときだけです。
OSのジョブタイプは、どのインスタンスがコマンドシェルにドロップしたかを判別する方法を見つけることができなかったという点で、同じ状態になりました。もちろん、sqlcmdで値を取得できますが@@servername
、sqlcmdを開始する接続がわかっていれば、データベースを照会する必要はありません;)
TSQLは有効にすればおそらく動作する可能性xp_cmdshell
がありますが、オンになっているかどうかはわかりません。それでも、私は動的SQLに夢中になり、PowerShellが提供する表現力とパワーの多くを失います。
少し不格好ですが、最初のステップで変数を定義し、それを後続のステップに渡すことを考えましたが、この記事で複数のジョブステップの処理(BOL)
ジョブステップは自己完結型でなければなりません。つまり、ジョブは、ジョブステップ間でブール値、データ、または数値を渡すことはできません。ただし、永続テーブルまたはグローバル一時テーブルを使用して、1つのTransact-SQLジョブステップから別のステップに値を渡すことができます。ファイルを使用して、あるジョブステップから別のジョブステップに実行可能プログラムを実行するジョブステップから値を渡すことができます。
よく知られたファイル/環境変数/レジストリ設定のような一般的なトリックを使用することはできませんFoo.exe
。
TL; DR:
PowerShellタイプのSQLエージェントジョブステップで、プロセスを起動したSQL Serverのインスタンスをどのように判断できますか?