locked
Multithreading with Recursive RRS feed

  • Question

  • Hi Folks,

    I am new to multithreading and this is my first multithreading script.

    I am trying to get ACLs in a DFS using the script below:

    param(
    $FolderPath
    )
    $ScriptBlock=
    {
    Param($FolderPath)
    $Folder=Get-Item $FolderPath
    $Permissions = @()
    $Folder.GetAccessControl().Access|Where-Object{$_.IdentityReference.Value -like '*Domain*'}|%{
    $Properties = [ordered]@{'FolderName'=$Folder.FullName;'AD
    Group or
    User'=$_.IdentityReference;'Permissions'=$_.FileSystemRights;'Inherited'=$_.IsInherited}
                $Permissions += New-Object -TypeName PSObject -Property $Properties
    }
    return $Permissions
    }

    Function Get-FolderPermissions
    {
    param($path)
    $childitems=gci $path  | where {$_.psiscontainer -eq $true}
    if($childitems.Count -le 0)
     {
      Start-Job -ScriptBlock $ScriptBlock -ArgumentList $path
     }
     else
      {
      $childitems|%{Get-FolderPermissions $_.FullName}
      } 
    }

    Get-FolderPermissions -path $FolderPath
    Get-Job|Wait-Job
    $result=Get-Job | Receive-Job
    Remove-Job *
    $result

    I do not get any output from receive job. 

    Has anyone tried something like this before? 


    Thanks and Regards, Siva Kumar Balaguru


    Wednesday, October 24, 2018 1:15 PM

All replies

  • Please post code correctly using the code posting tool provided.  Edit your original post.


    \_(ツ)_/

    Wednesday, October 24, 2018 1:41 PM
  • See the added comment.

    Function Get-FolderPermissions{
        param($path)
        
        $childitems = Get-ChildItem $path -Directory
        if($childitems.Count -le 0){
            # this code will never be executed
            Start-Job -ScriptBlock $ScriptBlock -ArgumentList $path
        }else{
            $childitems|%{Get-FolderPermissions $_.FullName}
        } 
    }
    
    The function is not recursive.  It is hard to say what it is trying to do.


    \_(ツ)_/

    Wednesday, October 24, 2018 1:50 PM
  • To get folder permissions recursively here is the basic template.  Add select bits to get the folder path.

    Get-ChildItem $path -Directory -Recurse | Get-Acl | select -expand access


    \_(ツ)_/

    Wednesday, October 24, 2018 1:53 PM
  • Nevermind...

    Got it fixed ...

    param(
    $FolderPath
    )
    $ScriptBlock=
    {
    Param($FolderPath)
    $Folder=Get-Item $FolderPath
    $Permissions = @()
     $Acl = Get-Acl -Path $Folder.FullName -ErrorAction SilentlyContinue
    $Acl.Access|%{
    $Properties = [ordered]@{'FolderName'=$Folder.FullName;'AccessTo'=$_.IdentityReference;'Permissions'=$_.FileSystemRights;'Inherited'=$_.IsInherited}
                $Permissions += New-Object -TypeName PSObject -Property $Properties
    }
    return $Permissions
    }
    
    Function Get-FolderPermissions
    {
    param($path)
    $childitems=gci $path -ErrorAction SilentlyContinue  | where {$_.psiscontainer -eq $true}
    $childitems|%{Get-FolderPermissions $_.FullName}
    Start-Job -ScriptBlock $ScriptBlock -ArgumentList $path|out-null 
    }
    #"started at {0}" -f (Get-Date)
    Get-FolderPermissions -path $FolderPath
    
    $result=Get-Job|Wait-Job|Receive-Job
    Remove-Job *
    #"Finished at {0}" -f (Get-Date)
    $result
    
    
    
    


    Thanks and Regards, Siva Kumar Balaguru

    Wednesday, October 24, 2018 2:54 PM
  • That code makes no sense.  It will not do what you ask. 

    What is the purpose of this?  Getting permissions recursively takes only a couple of lines.


    \_(ツ)_/

    Wednesday, October 24, 2018 7:46 PM
  • gci -recurse will not go multithread.

    This script creates a thread for each folder and retrieves the result.

    I am using this script to gt the ACLs from the File Server where gci -recurse was never ending.. This script has returned results bit faster.

    Hope it makes sense now. :)


    Thanks and Regards, Siva Kumar Balaguru

    Thursday, October 25, 2018 8:05 AM
  • Why would you do that?  Jobs are very inefficient for small tasks.

    Yes "Recuse" will do exactly what you want.

    Get-ChildItem $path -Directory -Recurse | 
         ForEach-Object{
               Start-Job -ScriptBlock $scriptblock  -ArgumentList $_ 
         }

    This will create one job per folder.

    You can return the Access and add the folder in the external select statement.


    \_(ツ)_/


    • Edited by jrv Thursday, October 25, 2018 8:13 AM
    Thursday, October 25, 2018 8:12 AM
  • This is all you need to do.  No need for many fancy functions or any thing else you may have seen in some blog.  Just use PowerShell and it will be easy.

    $sb = {
        $folder = $args[0]
        $folder | 
            Get-Acl | 
            select -expand Access |
            select @{n='Folder';e={$folder}},*
    }
    $jobs = Get-ChildItem $path -Directory -Recurse | 
         ForEach-Object{
               Start-Job -ScriptBlock $s -ArgumentList $_
         }
    $jobs | Wait-Job | Receive-Job


    \_(ツ)_/


    • Edited by jrv Thursday, October 25, 2018 8:25 AM
    Thursday, October 25, 2018 8:24 AM