arrayspowershellperformanceout-of-memorypublic-folders

Array causing 'system.outofmemoryexception'


I am running the below script and it is causing exception of type 'system.outofmemoryexception' was thrown

I believe that it is due to the @Results array growing past the 2gb allocated to windows shell. Is there possibly a way to iterate through the results, or am I stuck with allocating more memory (which could ultimately be a lot...)?

$Path = "path to output" 

### Get all PF
$publicFolders = Get-PublicFolder "Public Folder Name" -Recurse -resultsize unlimited | Select-Object *


### Array to contain results
$results = @()

###Begin looping through each PF and grab each user/group with AccessRights to that folder
$final = ForEach($pf in $publicFolders){    
    $perms     = Get-PublicFolderClientPermission -Identity $pf.Identity | Where-Object {$_.User -notmatch "Default|Anonymous|S-X-X-XX"} 
    
    Foreach($perm in $perms){
        $temp = [PSCustomObject]@{
                    MailFolderName = $pf.Identity 
                    UserWithPerms  = $perm.User
                    AccessRights   = $perm | Select-Object -ExpandProperty AccessRights

                }
                $results += $temp
    }
                   
}

$final | Export-Csv $path -NoTypeInformation
                  

Am I barking up the wrong tree?

Thanks in advance.


Solution

  • Use the ForEach-Object cmdlet instead of a foreach(){} loop statement for the outer loop - this way you can start piping the output to Export-Csv immediately instead of buffering it in an array:

    $publicFolders |ForEach-Object {
        $pf    = $_
        $perms = Get-PublicFolderClientPermission -Identity $pf.Identity | Where-Object {$_.User -notmatch "Default|Anonymous|S-X-X-XX"} 
        
        Foreach($perm in $perms){
            [PSCustomObject]@{
                MailFolderName = $pf.Identity 
                UserWithPerms  = $perm.User
                AccessRights   = $perm | Select-Object -ExpandProperty AccessRights
            }
        }                   
    } | Export-Csv $path -NoTypeInformation
    

    Alternatively, flush the partial set of results to file after enumerating the permissions for each folder:

    ForEach($pf in $publicFolders){    
        $perms     = Get-PublicFolderClientPermission -Identity $pf.Identity | Where-Object {$_.User -notmatch "Default|Anonymous|S-X-X-XX"} 
        
        $results = Foreach($perm in $perms){
            [PSCustomObject]@{
                MailFolderName = $pf.Identity 
                UserWithPerms  = $perm.User
                AccessRights   = $perm | Select-Object -ExpandProperty AccessRights
            }
        }
    
        # flush the buffer before moving to the next set of permissions
        $results |Export-Csv $path -NoTypeInformation -Append
    }