Writing to array – and then outputting the array as csv – for large files.

by Apr 12, 2015


I need some advice for my script. It gets a directory list and for each directory it checks teh ACL to try and find a match for an item in $groups array.  Any matches are written/exported.


  1. For my function getDirectories I am using += to add to the array $Directs.  This is fine for testing but I have read that using += for large arrays is a big no no.  I am looking at about 230,000 directories.
  2. My output at the end of script line46, is (Write-Host $dir","$identity","$filerights","$inheritance). This shows be I am getting the correct out. But how do I write each of these lines to an array and later export the whole thing to a csv?  I don't really understand the create new $obj threads I have been reading online.
  3. Finally, I'm pretty sure that reading each directory to get the path first, and then go back and read each directory to get the ACL is not a good idea and I should be getting what I want on the first pass.  As I am learning had to make each separate to check they worked and now I don't know how to join them up. Is the function even necessary?

Any advice is appreciated. Thanks.




$stopwatch = [system.diagnostics.stopwatch]::StartNew()

$groups = @("users", "Simon", "Administrat", "citadel")

# Change the starting directory below.
$Start = "\CITADELUsersSimonDocuments"

function getDirectories($Start){
$Directs =@()
$d = Get-ChildItem -Path $Start -Recurse -Directory -force | select fullname, name, parent

foreach ($dd in $d){
$path = ($dd.fullname).ToString()
$name = ($dd.Name).toString()
$parent = ($dd.Parent).ToString()

#how to add $name and $parent aswell?
$Directs += $path
return $Directs

$directories = getDirectories($Start)
#Write-Host ==============================================================
#Write-Host ==============================================================

# Loop through each of the directories.
foreach($dir in $directories){

$ACL = Get-Acl $dir | select -ExpandProperty Access

foreach($entry in $ACL){

# Convert to string and strip out anything before and including the "". Removes "BUILTIN", "NT AUTHORITY" etc
$identity = (($entry.IdentityReference).tostring() -replace '^[^\]*\', '')

$inheritance = $entry.IsInherited

# Convert to string and strip out the Synchronize. ex."FileSystemRights : ReadAndExecute, Synchronize"
$filerights = (($entry.FileSystemRights).ToString() -replace ', Synchronize', '')

# Try and match the Identity to an item in $groups
if ($groups -match $identity){

#if there is a match record it.
#output to array.

Write-Host $dir","$identity","$filerights","$inheritance

# $name , $parent , $path , $identity , $filerights , $inheritance


Write-host "Stopwatch :" $stopwatch.Elapsed