2017-07-20 25 views
1

我一直在編寫一個腳本(由Vidrine編寫,來自http://jfrmilner.rdpress.com/),該腳本編錄了文件服務器的NTFS權限。目前它查看整個服務器共享並僅從文件夾收集權限並忽略文件。它將數據存儲在一個對象中,並將其寫入一個數組列表中,稍後將其轉儲到CSV中。作爲參考,文件服務器相當大,其中大約有7.4TB的數據。最初,我調用了一個數組並使用+ =運算符寫入數據,但.net處理的數組在中等大小的子目錄上運行,這是一個非常耗內存的全天事件。將RAM添加到ArrayList後從RAM中刪除自定義Powershell對象?

我遇到的問題是,腳本完全是內存飢餓,我不能說這是否僅僅是因爲腳本是如何寫入的,或者如果在將它們寫入數組列表後將其保留在對象上。例如,當我針對特定的子目錄而不是整個服務器運行腳本時,該腳本將使用大約1.4GB的RAM,並生成148MB(100,000行×3列)的CSV。我正在運行這臺機器有16GB的內存,它仍然設法在整個目錄下運行。

我已經玩弄了[void]在寫入$ arrResults之後試圖從內存中消除$ objResults,但我似乎無法理解void void的工作原理。我也嘗試使用[System.GC] :: Collect()函數,但它只是減緩循環和內存的積累,但沒有幫助(這似乎也是一種討厭的做法)

我試過在Powershell V5(也是V1,V2和V4)ISE中運行它,並直接從命令行運行。

是$ objResults被添加到$ arrResults後是否留在內存中並且可以修復?或者是數組列表實際上達到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. 無需中間數組:簡單地輸出的值和延長管道導出-CSV。

  2. 添加成員非常緩慢,特別是通過管道多次調用時。
    在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