web-dev-qa-db-ja.com

NTFSファイルプロパティを収集してSQL Serverテーブルに挿入する方法

ファイルシステムの使用状況に関するレポートを提供する必要があります。

ファイルサーバーの使用状況に関する統計を個々のファイルレベルまで収集しているので、誰がどのファイル/フォルダーを使用しているか、どのくらいのストレージを使用しているか、ファイル数は、いつ作成され、最後に使用されたかを確認できます。

これを行うには、2つのPowerShellスクリプトがあります。

1つ目は、ファイルシステムを読み取り、必要な属性をキャプチャしてファイルに保存します。

dir -rec G:\ | Select LastWriteTime, Directory, Name, Extension, Length, @{Name="Owner";Expression={get-acl $_.FullName| select Owner}} | export-csv FileInfo.csv

2番目のスクリプトはcsvファイルを読み取り、データをテーブルに挿入します。

データがSQLに入ると、テキストを解析してさまざまな列に分割し、さまざまなレポートを生成してさまざまな方法でデータを分析できます。私のアプローチは機能しますが、面倒です。

NTFS情報を収集してSQL Serverに保存するより良い方法はありますか?代替案は何ですか? SSIS?

編集:これをすべて組み合わせて単一のプロセスで一緒に操作できますか?

6

SSISは、CSVファイルを処理してSQL Serverにロードするために十分に装備されています。

Flat File Sourceを使用すると、非常にシンプルなパッケージを作成できます。 enter image description here

ダイアログと設定はプロセスのようなおなじみの「ウィザード」のようなウィンドウであり、そのほとんどは自動化されています...注意する必要があるのは、長さとデータ型についてファイルを正しく推測したことです。接続マネージャーの設定を調整するか、後でSSISタスクを使用してデータ型を変更できます。整数の10,000行と言って文字を取得し始めた場合、フラットファイルソースはその列に整数データ型を簡単に割り当て、文字を検出すると失敗することに注意してください。したがって、適切に構造化されていない可能性がある大きなファイルでは、これらの設定にもっと注意を払う必要があります。 Suggest Types...ボタンを使用すると、検査される行の数を増やすことができますが、これでも依然として間違ったデータ型を推奨できることがわかりました。

enter image description here

SSISは巨大なツールであり、データのクリーンアップタスクを実行したり、単一のCSVからデータを異なるテーブルに分割したりすることもできます。異なるテーブルがある場合は、MulticastConditional Splitなどのタスクを使用します。また、Data ConversionおよびDerived Columnは、パッケージ内を移動するときに必要なデータを効率的に生成するのに役立つ場合もあります。

ただし、SSISを使用して、データのクリーンアップ、分割、変更、およびSQL Serverへの読み込み以外のことは行いません。 SQL Serverは、集計、並べ替えなどを生成するために高度に最適化されていますが、SSISはそのようなタスクにはあまり適していません。 Aggregateのようなタスクは ブロッキング変換 です。これは、SSISパッケージを停止させ、大量のメモリを消費する可能性があることを本質的に意味します。

例として、以下のSSISデータフローは次のタスクを実行します。

  1. CSVファイルを読み取ります
  2. オリジナルのトリミングされたバージョンである派生列を作成します
  3. 参照を実行して、レコードが宛先にすでに存在するかどうかを確認します
  4. レコードが見つからなかった場合は、宛先に挿入されます

enter image description here

5
Dave

外部呼び出し、CSVファイル、SSISなどを回避する別のオプションは、SQLCLRを使用することです。 DirectoryInfo.EnumerateFiles メソッド(新しい、リストが入力される前にリストを列挙できる)または DirectoryInfo.GetFiles メソッド(古い、リストを作成しています)。 EnumerateFilesメソッドは.NET 4.0で新しく追加されたため、SQL Server 2012以降を使用している場合にのみ使用できます。

これらのメソッドは、ほとんどのプロパティを直接取得する FileInfo オブジェクトのコレクションを返します。所有者を取得するには、PowerShellスクリプトで行っているのと同様に、もう少し作業を行う必要があります。 FileInfo.GetAccessControl メソッドを使用し、次に GetOwner メソッドを呼び出します。 GetOwnertypeのパラメーターを受け取り、MSDNドキュメントには例はありませんが、このS.O.回答、 C#でファイルの所有者/作成者を検索 、それは次のようになります:

FileProperties _Obj = new FileProperties();
DirectoryInfo _Directory = new DirectoryInfo(@"G:\", SearchOption.AllDirectories);

foreach (FileInfo _File in _Directory.EnumerateFiles())
{
  _Obj.Size = _File.Length;
  _Obj.Owner = _File.GetAccessControl().GetOwner(typeof(System.Security.Principal.NTAccount)).ToString();
  _Obj.other properties = _File.other properties
  yield return _Obj;
}

上記のコードは、ストリーミングTVFの行を返すために使用されるFilePropertiesという名前の構造体またはクラスがあることを前提としています。

このメソッドを使用すると、返される値を厳密に型指定できます(そうする必要があります)。したがって、次のようにテーブルにデータを入力できます。

INSERT INTO dbo.FileProperties (Name, Length, Path, Owner, ...)
  SELECT Name, Length, Path, Owner, ...
  FROM   dbo.GetFileProperties();

また、GetFilePropertiesを更新して、開始ディレクトリの入力パラメータを受け入れることもできます:-)。

4
Solomon Rutzky