I'm trying to build a little script with PowerShell, but I'm stuck.
I need to give out the structure of a folder as a tree with its NTFS permissions.
C:\TEST ├───Test1 - Access │ ├───Test1.1 - Access │ └───Test1.2 - Access │ └───Test1.2.1 - Access ├───Test2 - Access │ ├───Test2.1 - Access │ └───Test2.2 - Access ├───Test3 - Access └───Test4 - Access ├───Test4.1 - Access ├───Test4.2 - Access └───Test4.3 - Access
Something like this.
I tried with Get-ChidlItem C:\Test -Recurse
and Get-Acl
, but I couldn't figure out how to display the results as a tree.
Below is a script that I wrote recently to output a directory structure as a tree with file sizes to the console.
You can easily modify the Write-Host
lines to remove the file sizes and add in your ACL information (I'm not really sure aesthetically how this will work).
The big limitation of using Write-Host
is that you can't work with the data further down the script, you can't output the data to a file - Start-Transcript
loses the formatting.
Jacob Colvin's comments descript a much better approach, something I would be interested to see in practice.
The only other approach I could think of, would be to create an object which combines the Get-ACL
and Get-ChildItem
data, and then when outputting the data, counting the \
's in the directory structure to generate the indentation.
function Show-Tree
{
param
(
$directory
)
if ((Get-PSCallStack)[1].Command -eq 'Show-Tree') {
Write-host "├──" -NoNewline
if(Test-Path $directory/*)
{
Write-host "┬" -NoNewline
}
else
{
Write-host "─" -NoNewline
}
Write-Host "$($directory | Split-Path -Leaf)/"
}
else
{
Write-Host "$directory"
$Script:StartingIndent = ($directory).Split("\").Count+1
}
Get-ChildItem -path $directory -File | % {
$i = 0
$indent = ($_.FullName).Split("\").Count-$script:StartingIndent
while($i -lt $indent)
{
[console]::Write("│ ")
$i++
}
if(($_.length / 1MB) -ge 1)
{
Write-Host "├───[$([int]($_.length / 1MB)) MB] $($_.name)"
}
elseif(($_.length / 1KB -ge 1))
{
Write-Host "├───[$([int]($_.length / 1KB)) KB] $($_.name)"
}
else
{
Write-Host "├───[$($_.length) B] $($_.name)"
}
}
Get-ChildItem -Path $directory -Directory | % {
$i = 0
$indent = ($_.FullName).Split("\").Count-$script:StartingIndent
while($i -lt $indent)
{
Write-host "│ " -NoNewline
$i++
}
Show-Tree -directory $_.FullName
}
}
Show-Tree -directory C:\Testing
Output
C:\Testing
├───[7 KB] $RY3NETI.prop
├───[9 KB] Book1.xlsx
├───[308 B] csvOut.csv
├───[308 B] csvOut2.csv
├───[297 B] csvout3.csv
├───[6 MB] Shakespear.txt
├───[570 KB] ShakeSpeareUniqueWords.txt
├───[1 KB] Transcript.txt
├──┬Test1/
│ ├───[183 B] filename.rtf
│ ├───[7 KB] img3.png
│ ├───[18 KB] img4.png
│ ├───[43 KB] img5.png
│ ├───[19 KB] img7.png
│ ├───[26 KB] test.doc
├──┬Test2/
│ ├───[83 MB] filetest.rar
│ ├───[7 KB] img10.png
│ ├───[18 KB] img9.png
│ ├──┬Test2 Subfolder/
│ │ ├───[33 KB] img1.png
│ │ ├───[17 KB] img2.png
│ │ ├───[14 KB] img8.png