2017-07-20 1 views
1

私はファイルサーバーのNTFSアクセス許可をカタログ化したスクリプト(Vidrineによって書かれた、http://jfrmilner.rdpress.com/からのソース)を手にしていました。現時点では、サーバー共有全体を調べ、フォルダからのみアクセス許可を収集し、ファイルは無視します。データをオブジェクトに格納し、後でCSVにダンプされる配列リストに書き込みます。参考までに、ファイルサーバーはかなり大きく、その中に約7.4TBのデータがあります。最初は配列を呼び出して+ =演算子を使って書きましたが、.netは中規模のサブディレクトリで実行された配列を処理します。カスタムPowershellオブジェクトをArrayListに追加した後にRAMから削除しますか?

私が遭遇した問題は、スクリプトが完全にメモリが空いているということです。これは単純にスクリプトの記述方法であるのか、オブジェクトをarraylistに書き込んだ後でオブジェクトに保持されているのか分かりません。たとえば、サーバー全体ではなく特定のサブディレクトリに対してスクリプトを実行すると、スクリプトはおよそ1.4GBのRAMを使用し、148MB(100,000行×3列)のCSVを生成します。私がこれを実行しているマシンには16GBのRAMがあり、それはディレクトリ全体に対して実行している間もキャップしています。

私は$ arrResultsに書き込まれた後に$ objResultsをメモリから削除しようとしましたが、空のキャストがどのように動作するのかわかりません。私も[System.GC] :: Collect()関数を使用しようとしましたが、ループとメモリの蓄積が遅くなりましたが、助けにはなりません(これも嫌われています)。

私はPowershell V5(V1、V2、V4)ISEでコマンドラインから直接実行しようとしました。

$ objResultsは$ arrResultsに追加されてメモリに残っていますが、これは修正可能ですか?または、arraylistが実際に最大15GBのサイズになっていますか? 私はPowershell FYIにとってかなり新しいです。

Import-module ActiveDirectory 
$targetServer = 'S:\shared data\' #Enter hostname 
$targetDirectory = '' #Enter directory name 
$target  = Join-Path -ChildPath $targetDirectory -Path $targetServer 
$arrResults  = New-ObjectSystem.Collections.Generic.List[System.Object] 
$exportPath = 'C:\temp\NTFS-OUTPUT.csv' #Enter name of the CSV output file 

#Query target directory for all 'folders' (excludes files via Where statement) 
Get-ChildItem -Recurse -Path $target | Where { $_.PSIsContainer} | 

forEach { 

$objPath = $_.FullName 
$coLACL = Get-Acl -Path $objPath 
forEach ($objACL in $colACL) { 
    forEach ($accessRight in $objACL.Access) {   
     $objResults = New-Object –TypeName PSObject 
     $objResults | Add-Member –MemberType NoteProperty –Name DirectoryPath  –Value $objPath 
     $objResults | Add-Member –MemberType NoteProperty –Name Identity   –Value $accessRight.IdentityReference 
     $objResults | Add-Member –MemberType NoteProperty –Name SystemRights  –Value $accessRight.FileSystemRights 
     #$objResults | Add-Member –MemberType NoteProperty –Name SystemRightsType –Value $accessRight.AccessControlType 
     #$objResults | Add-Member -MemberType NoteProperty -Name IsInherited  -Value $accessRight.IsInherited 
     #$objResults | Add-Member -MemberType NoteProperty -Name InheritanceFlags -Value $accessRight.InheritanceFlags 
     #$objResults | Add-Member –MemberType NoteProperty –Name RulesProtected  –Value $objACL.AreAccessRulesProtected 
     $arrResults.Add($objResults) 

     } 
    } 
} 
$arrResults | Export-CSV -NoTypeInformation -Path $exportPath 

答えて

3
  1. 中間アレイの必要はありません:単に出力値とExport-CSVへのパイプラインを拡張します。

  2. Add-Memberは、特にパイプライン経由で何度も呼び出された場合、非常に遅いです。
    PowerShell 3.0以降では、リテラルハッシュテーブルにアクセラレータ[PSCustomObject]を使用できます。

Get-ChildItem -Recurse -Path $target -Directory | ForEach { 
    foreach ($objACL in (Get-Acl -Path $_.FullName)) { 
     foreach ($accessRight in $objACL.Access) {   
      [PSCustomObject]@{ 
       DirectoryPath = $_.FullName 
       Identity  = $accessRight.IdentityReference 
       SystemRights = $accessRight.FileSystemRights 
      } 
     } 
    } 
} | Export-CSV -NoTypeInformation -Path $exportPath 
関連する問題