Robocopy、複数行の処理 SSIS タスクの実行、またはバッチ ファイルの結果を SSIS に出力
-
06-07-2019 - |
質問
SSIS パッケージ内のある場所から別の場所にファイルをロボコピーする必要があります。フォルダーは別のドメイン上にあるため、robocopy.exe コマンドを実行する前に別のアカウントになりすます必要があります。「net use」コマンドを実行して必要なユーザーアカウントを偽装し、その直後に robocopy コマンドを実行できることがわかりました。これをプロセス実行コマンドで直接実行する方法が見つからないため、プロセス実行タスクを使用して、これら 2 つのコマンドを別個の行として含むバッチ ファイルを実行します。このアプローチの欠点は、「プロセスの実行」コマンドの結果を読み取ることができないことです。したがって、次の 3 つの疑問が生じます。
- 単一のプロセス実行タスクで複数行のコマンドを実行する方法はありますか?
- 1行で別のアカウントになりすましてrobocopy.exeを実行する方法はありますか?
- バッチ ファイルの結果を SSIS の変数または SSIS データベース ログに書き戻す方法はありますか?
上記 3 つの質問のいずれかに肯定的な答えがあれば、robocopy コマンドの結果に基づいてジョブの成功または失敗のルールを追加する方法を見つけられる可能性があります。
解決
拡張ストアド プロシージャ「xp_cmdshell」の使用を有効にしている場合、これは簡単に実現できます (「サーフェス エリアの構成」については、Books Online を参照してください)。
次のサンプルでは、すべての ROBOCOPY オプションを含む .CMD ファイルを構築し、出力をテーブル変数 (代わりに永続テーブルにすることもできます) に取得する xp_cmdshell を使用してこのコマンド ファイルを単純に実行します。
次のステートメントを使用して、T-SQL ステートメント実行タスクを SSIS パッケージに追加するだけです。
/** START **/
DECLARE @cmdfile nvarchar(255) = N'C:\myFolder\myCommandFile.cmd'
DECLARE @logtable table (
[RowId] integer IDENTITY(1,1) NOT NULL
,[Message] nvarchar(1024) NULL
)
INSERT INTO @logtable ([Message])
EXEC xp_cmdshell @cmdfile
SELECT *
FROM @logtable
WHERE
[Message] IS NOT NULL
/** END **/
ROBOCOPY コマンドに設定したログ オプションに応じて、進行状況、ヘッダー、レポートなどを表示できます。これらのオプションについては、ROBOCOPY のドキュメントを参照してください。ROBOCOPY コマンドからコンソール出力を取得する場合は、/TEE スイッチを使用してみてください。
他のヒント
これを行う方法の1つは、 RUNAS
(別のユーザーアカウントを偽装する)を使用してバッチコマンドを実行する(複数の行項目を実行できる)ことです
バッチファイルの出力をログファイルにキャプチャし、スクリプトを使用してその内容をSSISに読み込むことができます。
SSISログに書き込む方法がわからないので、他の開発者がそれについて何と言っているのか興味があります。
バッチ ファイルの実行からデータベースにデータを取得するための 2 つの迂回方法を見つけました。1 つの方法は、実際のバッチ ファイルにログを追加することです。私はまだ試していませんが、概念的には可能だと思われます。私が試してうまくいったもう 1 つのオプションは、バッチ ファイルの実行を SQL Server エージェントのジョブ ステップとして配置し、フラット ファイル ログを追加することです。これを行った後、特定のメッセージのファイルをスクレイピングする小さなパッケージを作成しました。私はまだより良い解決策を好みますが、今のところこれで十分に機能します。
単一の実行で複数行のコマンドを実行する方法はありますか タスクを処理しますか?
はい、「Cmd.exe」を使用します;実行可能ファイルとして
次の式を使用して string
変数を作成します(サンプル):
*"/C \"start robocopy c:\\temp\\v10.2a c:\\temp\\v1 *.WRI /Z /S && start robocopy c:\\temp\\v10.2a c:\\temp\\v1 *.dll /Z /S\""*
そして、コンポーネント式を介してargumentsパラメータにマップします。その後、//
でこれらの2つ(またはそれ以上)のロボコピーを実行できます。