Ask a questionAsk a question
 

AnswerGet-Acl without inheritance

  • Friday, January 23, 2009 4:34 PMJonas_Bson Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hello,

    When i type the following line in PS "Get-ChildItem I:\ -recurse -exclude *.* | Get-Acl" It lists all the directories and their security rights. I need to be able to only list the folders which have the security set on them and not inherited by parent folder.

    Is this possible?

     

    What I'm aiming for is a script to list all parent-rights in our file-structure. Perhaps this is possible to do some other way?

     

    Best Regards,

    Joans Bson

Answers

  • Friday, January 23, 2009 7:20 PMMarco ShawMVP, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    I think you can get this by looking at the SDDL value for a folder.  There may be easier ways, but I think this will work for you:
    1$no_inh=get-acl .|foreach{$_.sddl} 
    2gci . -rec|where{$_.psiscontainer}|foreach{if(($_|get-acl|foreach{$_.sddl}) -eq $no_inh){$_.fullname}} 

    On line 1, I move to a directory where I know inheritance has been removed.  I save the SDDL string to a variable.

    On line 2, I get the ACLs and SDDL for every directory, then compare the SDDL against my variable, if the SDDLs match, I have a directory without inheritance, and I print out the full directory name.

    [EDIT: I reread your post.  I think I've missed the point.  Please provide feedback.]

All Replies

  • Friday, January 23, 2009 7:20 PMMarco ShawMVP, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    I think you can get this by looking at the SDDL value for a folder.  There may be easier ways, but I think this will work for you:
    1$no_inh=get-acl .|foreach{$_.sddl} 
    2gci . -rec|where{$_.psiscontainer}|foreach{if(($_|get-acl|foreach{$_.sddl}) -eq $no_inh){$_.fullname}} 

    On line 1, I move to a directory where I know inheritance has been removed.  I save the SDDL string to a variable.

    On line 2, I get the ACLs and SDDL for every directory, then compare the SDDL against my variable, if the SDDLs match, I have a directory without inheritance, and I print out the full directory name.

    [EDIT: I reread your post.  I think I've missed the point.  Please provide feedback.]

  • Sunday, February 01, 2009 6:38 PMdmdamen Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Proposed AnswerHas Code
    The line of code below will show you all file names that have explicit security set.

    get-childitem -recurse | where-object {$_.mode -match "d"} | %{$file=$_;get-acl $($_.FullName)} | %{$_.GetAccessRules($True,$False,[Security.Principal.SecurityIdentifier]) | %{write-host "$($file.FullName) has explicit security set"}}
    • Proposed As Answer bydmdamen Sunday, February 01, 2009 6:39 PM
    •  
  • Friday, June 19, 2009 6:14 PMScott Meilicke Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I know this thread is quite old, but here is how I did this. Keep in mind I am quite new to powershell, so I like to spell things out. I would be interested in techniques to speed this up. if ($args.length -ne 2) { "This script takes exactly two arguments, in this order: file for output, a path to analyze" } else { $path = $args[1] $outPutFile = $args[0] $startDate = Get-Date #Build information for the header of the output file. `r`n is a carrage return/line feed. $header = "Start: " + $startDate + "`r`n" + "Output file: " + $outPutFile + "`r`n" + "Path analyzed: " + $path + "`r`n" out-file -encoding ASCII -filePath $outPutFile -append -InputObject $header # Get all directories, not files, get their ACLs, and stuff them into a variable ($dirs). $dirs = Get-ChildItem $path -Recurse -Force | ? { $_.GetType() -like 'System.IO.DirectoryInfo'} | get-ACL Foreach ($dir in $dirs) { Foreach ($Access in $dir.Access) { $Inherited = [string]$Access.IsInherited if ($Inherited -eq "False") { $pathPieces = $dir.Path.split(":") $output = $PathPieces[2] + ":" + $pathPieces[3] + ", " + $Access.IdentityReference + ", " + $Access.FileSystemRights out-file -encoding ASCII -filePath $outPutFile -append -InputObject $output } } } $endDate = Get-Date $elapsedTime = $endDate - $startDate $footer = "`r`nRun completed at: " + $endDate + "`r`n" + "Elapsed Time:`r`n" + $elapsedTime + "`r`n" out-file -encoding ASCII -filePath $outPutFile -append -InputObject $footer } -Scott

    EDIT - shoot, sorry for the crappy word wrapping.
  • Thursday, October 15, 2009 2:34 PMcbreaker Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi Scott,

    I can't seem to get your example to work.    I'm really no powershell programmer and I think I have the wrapping all wrong.  Since powershell uses CRLF's to seperate commands (against say Bash) when it's all on one big line it won't run.

    Any help?
  • Thursday, October 15, 2009 2:35 PMcbreaker Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Replying to myself to enable e-mail notification..
  • Thursday, October 15, 2009 2:51 PMMarco ShawMVP, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I'll fix up the code in the next 24 hours and post it as a script, and that should help...
  • Friday, October 16, 2009 10:07 AMMarco ShawMVP, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    I think this is fixed up properly.  I haven't tested it yet:

    if ($args.length -ne 2) { 
      "This script takes exactly two arguments, in this order: file for output, a path to analyze" 
    } 
    else { 
      $path = $args[1] 
      $outPutFile = $args[0] 
      $startDate = Get-Date 
      #Build information for the header of the output file. `r`n is a carrage return/line feed. 
      $header = "Start: " + $startDate + "`r`n" + "Output file: " + $outPutFile + "`r`n" + "Path analyzed: " + $path + "`r`n" 
      out-file -encoding ASCII -filePath $outPutFile -append -InputObject $header 
      # Get all directories, not files, get their ACLs, and stuff them into a variable ($dirs). 
      $dirs = Get-ChildItem $path -Recurse -Force | ? { $_.GetType() -like 'System.IO.DirectoryInfo'} | get-ACL 
      Foreach ($dir in $dirs) { 
        Foreach ($Access in $dir.Access) { 
          $Inherited = [string]$Access.IsInherited 
          if ($Inherited -eq "False") { 
            $pathPieces = $dir.Path.split(":") 
            $output = $PathPieces[2] + ":" + $pathPieces[3] + ", " + $Access.IdentityReference + ", " + $Access.FileSystemRights 
            out-file -encoding ASCII -filePath $outPutFile -append -InputObject $output 
          } 
        } 
      } 
      $endDate = Get-Date 
      $elapsedTime = $endDate - $startDate 
      $footer = "`r`nRun completed at: " + $endDate + "`r`n" + "Elapsed Time:`r`n" + $elapsedTime + "`r`n" 
      out-file -encoding ASCII -filePath $outPutFile -append -InputObject $footer 
    }