SQL Agent PowerShellコンテキストリファレンス


13

私の新しい仕事では、各サーバーに複数の名前付きインスタンスがあります。例えば

  • 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-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のインスタンスをどのように判断できますか?


4
powershellはあなたがしていることの要件ですか?
johndacostaa

真の要件は、呼び出し元インスタンスのパラメーターを使用してDOSプロセスを起動できるSQLエージェントで再利用可能な「何か」を持つことです。上記で機能しなかったものを考えると、PowerShellが最適と思われました。遅刻して申し訳ありませんが、私はスカウトキャンプに出かけました。
billinkc

回答:


9

SQL Server BOLを見ると、SQL Serverエージェントは、ジョブステップのコマンドテキストと出力ファイルの両方に置き換える「トークン」のセットを提供します(後者はGUIの「表示」ボタンが機能しないようにします)。これらのトークンは、T-SQLを除くあらゆるタイプのステップで機能するようです。

https://docs.microsoft.com/en-us/sql/ssms/agent/use-tokens-in-job-steps#sql-server-agent-tokens

そのため、SQL 2008 PowerShellの手順がある場合は、次の手順で開始できます。

$sqlInstance = "$(ESCAPE_DQUOTE(SRVR))"

代わりにMACH(machine name)とINST(just instance name)を使用する必要がありSRVR == MACHますSRVR == MACH\INST。これは、デフォルトのinstance では名前付きインスタンスであるためです。


3

悲しいことに、SQL Server内で呼び出されるPowerShellスクリプトについてはあまりやっていません。また、私は今すぐコンピューターで遊ぶことができます。

PowerShellタイプのステップを使用する代わりに、コマンドライン「powershell 'MyScript.ps1'」から行うようにCmdExecを使用してスクリプトを呼び出すと、実行元のインスタンスを持つパラメーターを渡すことができると考えています。「Powershell 'MyScript.ps1' MyInstanceName」のように。

したがって、スクリプトの開始時に、MyInstanceNameの値を受け入れるためのparam()セットアップがあります。


param(
   [Parameter(Position=0,Mandatory=$True)]
   [string]$InstanceName
)
#so if I wanted to use sqlcmd
sqlcmd -S $InstanceName -Q "SELECT @@VERSION"

PowerShellスクリプトがFoo.exeを適切に呼び出すことができるように、それがどのインスタンスであるかを知るために必要な1つのステップを述べることから始めました。ただし、後で他のステップに値を渡すことができることについて言及します。これに該当する場合は、PowerShellスクリプトを呼び出して必要な他の処理を実行する小さなSSISパッケージの作成を検討することをお勧めします。SSISを使用すると、パッケージ全体で使用できるグローバル変数を設定できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.