Link to home
Start Free TrialLog in
Avatar of amyassein
amyassein

asked on

How to stretch the "User" Column in this report ?

Hi all,

I just dowloaded this PowerShell script from the internet 1 hour ago. This script is to dump the folder/file ACL into a friendly HTML format. My problem is that the "user" column in the report is very narrow, which means the long user ID names or long group ID names crossing and interfering with other columns in the right, so the final report is completely uselss and un-understandable.

I need someone experienced in PS to help me to stretch the "user" column into the left a little bit until i can read long user ID names.

Please find below the code.

Appreciate your quick response.
#######################################
# TITLE: listACL.ps1                  #
# AUTHOR: Santiago Fernandez Mu¿oz    #
#                                     #
# DESC: This script generate a HTML   #
# report show all ACLs asociated with #
# a Folder tree structure starting in #
# root specified by the user          #
#######################################
        
param ([string] $computer = 'localhost',
                [string] $path = $(if ($help -eq $false) {Throw "A path is needed."}),
                [int] $level = 0,
                [string] $scope = 'administrator', 
                [switch] $help = $false,
                [switch] $debug = $false
        )
        
#region Initializations and previous checkings
#region Initialization
$allowedLevels = 10
$Stamp = get-date -uformat "%Y%m%d"
$report = "$PWD\$computer.html"
$comparison = ""
$UNCPath = "\\" + $computer + "\" + $path + "\"
#endregion
 
#region Previous chekings
#require -version 2.0
if ($level -gt $allowedLevels -or $level -lt 0) {Throw "Level out of range."}
if ($computer -eq 'localhost' -or $computer -ieq $env:COMPUTERNAME) { $UNCPath = $path }
switch ($scope) {
        micro {
                $comparison = '($acl -notlike "*administrator*" -and $acl -notlike "*BUILTIN*" -and $acl -notlike "*NT AUTHORITY*")'
        }
        user {
                $comparison = '($acl -notlike "*administrator*" -and $acl -notlike "*BUILTIN*" -and $acl -notlike "*IT*" -and $acl -notlike "*NT AUTHORITY*" -and $acl -notlike "*All*")'
        }
}
#endregion
#endregion
 
#region Function definitions
function drawDirectory([ref] $directory) {
        $dirHTML = '
        <div class="'
                if ($directory.value.level -eq 0) { $dirHTML += 'he0_expanded' } else { $dirHTML += 'he' + $directory.value.level } 
                $dirHTML += '"><span class="sectionTitle" tabindex="0">Folder ' + $directory.value.Folder.FullName + '</span></div>
                <div class="container"><div class="he' + ($directory.value.level + 1) + '"><span class="sectionTitle" tabindex="0">Access Control List</span></div>
                        <div class="container">
                                <div class="heACL">
                                        <table class="info3" cellpadding="0" cellspacing="0">
                                                <thead>
                                                        <th scope="col"><b>Owner</b></th>
                                                        <th scope="col"><b>Privileges</b></th>
                                                </thead>
                                                <tbody>'
                foreach ($itemACL in $directory.value.ACL) {
                        $acls = $null
                        if ($itemACL.AccessToString -ne $null) {
                                $acls = $itemACL.AccessToString.split("`n")
                        }
                        $dirHTML += '<tr><td>' + $itemACL.Owner + '</td>
                        <td>
                        <table>
                                <thead>
                                        <th>User</th>
                                        <th>Control</th>
                                        <th>Privilege</th>
                                </thead>
                                <tbody>'
                        foreach ($acl in $acls) {
                                $temp = [regex]::split($acl, "(?<!(,|NT))\s{1,}")
                                if ($debug) {
                                        write-host "ACL(" $temp.gettype().name ")[" $temp.length "]: " $temp
                                }
                                if ($temp.count -eq 1) {
                                        continue
                                }
                                if ($scope -ne 'administrator') {
                                        if ( Invoke-Expression $comparison ) {
                                                $dirHTML += "<tr><td>" + $temp[0] + "</td><td>" + $temp[1] + "</td><td>" + $temp[2] + "</td></tr>"
                                        }
                                } else {
                                        $dirHTML += "<tr><td>" + $temp[0] + "</td><td>" + $temp[1] + "</td><td>" + $temp[2] + "</td></tr>"
                                }
                        }
                        $dirHTML += '</tbody>
                                                </table>
                                                </td>
                                                </tr>'
                }
$dirHTML += '
                                                </tbody>
                                        </table>
                                </div>
                        </div>
                </div>'
        return $dirHTML
}
 
#endregion
 
#region Printing help message
if ($help) {
        Write-Host @"
/··················································\
· Script gather access control lists per directory ·
\··················································/
 
USAGE: ./listACL -computer <machine or IP> 
                -path <path>
                -level <0-10>
                -help:[$false]
        
PARAMETERS:
        computer [OPTIONAL]     - Computer name or IP addres where folder is hosted (Default: localhost)
        path [REQUIRED]         - Folder's path to query.
        level [OPTIONAL]        - Level of folders to go down in the query. Allowd values are between 0 and $allowedLevels.
                                  0 show that there's no limit in the going down (Default: 0)
        scope [OPTIONAL]        - Sets the amount of information showd in the report. Allowd values are: 
                                 · user, show important information to the user.
                                 · micro, show user scope information plus important information for the IT Department.
                                 · administrator, show all information.
        help [OPTIONAL]         - This help.
"@
        exit 0
        
}
#endregion
 
if (Test-Path $report)
 {
  Remove-item $report
 }
 
#To normalize I check if last character in the path is the folder separator character
if ($path.Substring($path.Length - 1,1) -eq "\") { $path = $path.Substring(0,$path.Length - 1) }
 
#region Header, style and javascript functions needed by the html report
@"
<html dir="ltr" xmlns:v="urn:schemas-microsoft-com:vml" gpmc_reportInitialized="false">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-16" />
<title>Access Control List for $path in $computer</title>
<!-- Styles -->
<style type="text/css">
                body{ background-color:#FFFFFF; border:1px solid #666666; color:#000000; font-size:68%; font-family:MS Shell Dlg; margin:0px 0px 10px 0px; }
 
               table{ font-size:100%; table-layout:fixed; width:100%; }
 
               td,th{ overflow:visible; text-align:left; vertical-align:top; white-space:normal; }
 
               .title{ background:#FFFFFF; border:none; color:#333333; display:block; height:24px; margin:0px 0px -1px 0px; padding-top:4px; position:relative; table-layout:fixed; width:100%; z-index:5; }
 
               .he0_expanded{ background-color:#FEF7D6; border:1px solid #BBBBBB; color:#3333CC; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:0px; margin-right:0px; padding-left:8px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he1_expanded{ background-color:#A0BACB; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:10px; margin-right:0px; padding-left:8px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he1{ background-color:#A0BACB; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:10px; margin-right:0px; padding-left:8px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he2{ background-color:#C0D2DE; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:20px; margin-right:0px; padding-left:8px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he3{ background-color:#D9E3EA; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:30px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he4{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:40px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he4h{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:45px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he4i{ background-color:#F9F9F9; border:1px solid #BBBBBB; color:#000000; display:block; font-family:MS Shell Dlg; font-size:100%; margin-bottom:-1px; margin-left:45px; margin-right:0px; padding-bottom:5px; padding-left:21px; padding-top:4px; position:relative; width:100%; }
 
               .he5{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:50px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he5h{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; padding-left:11px; padding-right:5em; padding-top:4px; margin-bottom:-1px; margin-left:55px; margin-right:0px; position:relative; width:100%; }
 
               .he5i{ background-color:#F9F9F9; border:1px solid #BBBBBB; color:#000000; display:block; font-family:MS Shell Dlg; font-size:100%; margin-bottom:-1px; margin-left:55px; margin-right:0px; padding-left:21px; padding-bottom:5px; padding-top: 4px; position:relative; width:100%; }
 
               .he6{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:55px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
                                .he7{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:60px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                                
                                .he8{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:65px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                                
                                .he9{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:70px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                                
                                .he10{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:75px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                                
                                .he11{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:80px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                                
                                .heACL { background-color:#ECFFD7; border:1px solid #BBBBBB; color:#000000; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:90px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                                
                                DIV .expando{ color:#000000; text-decoration:none; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:normal; position:absolute; right:10px; text-decoration:underline; z-index: 0; }
 
               .he0 .expando{ font-size:100%; }
 
               .info, .info3, .info4, .disalign{ line-height:1.6em; padding:0px 0px 0px 0px; margin:0px 0px 0px 0px; }
 
               .disalign TD{ padding-bottom:5px; padding-right:10px; }
 
               .info TD{ padding-right:10px; width:50%; }
 
               .info3 TD{ padding-right:10px; width:33%; }
 
               .info4 TD, .info4 TH{ padding-right:10px; width:25%; }
                                
                                .info5 TD, .info5 TH{ padding-right:0px; width:20%; }
 
               .info TH, .info3 TH, .info4 TH, .disalign TH{ border-bottom:1px solid #CCCCCC; padding-right:10px; }
 
               .subtable, .subtable3{ border:1px solid #CCCCCC; margin-left:0px; background:#FFFFFF; margin-bottom:10px; }
 
               .subtable TD, .subtable3 TD{ padding-left:10px; padding-right:5px; padding-top:3px; padding-bottom:3px; line-height:1.1em; width:10%; }
 
               .subtable TH, .subtable3 TH{ border-bottom:1px solid #CCCCCC; font-weight:normal; padding-left:10px; line-height:1.6em;  }
 
               .subtable .footnote{ border-top:1px solid #CCCCCC; }
 
               .subtable3 .footnote, .subtable .footnote{ border-top:1px solid #CCCCCC; }
 
               .subtable_frame{ background:#D9E3EA; border:1px solid #CCCCCC; margin-bottom:10px; margin-left:15px; }
 
               .subtable_frame TD{ line-height:1.1em; padding-bottom:3px; padding-left:10px; padding-right:15px; padding-top:3px; }
 
               .subtable_frame TH{ border-bottom:1px solid #CCCCCC; font-weight:normal; padding-left:10px; line-height:1.6em; }
 
               .subtableInnerHead{ border-bottom:1px solid #CCCCCC; border-top:1px solid #CCCCCC; }
 
               .explainlink{ color:#000000; text-decoration:none; cursor:pointer; }
 
               .explainlink:hover{ color:#0000FF; text-decoration:underline; }
 
               .spacer{ background:transparent; border:1px solid #BBBBBB; color:#FFFFFF; display:block; font-family:MS Shell Dlg; font-size:100%; height:10px; margin-bottom:-1px; margin-left:43px; margin-right:0px; padding-top: 4px; position:relative; }
 
               .filler{ background:transparent; border:none; color:#FFFFFF; display:block; font:100% MS Shell Dlg; line-height:8px; margin-bottom:-1px; margin-left:43px; margin-right:0px; padding-top:4px; position:relative; }
 
               .container{ display:block; position:relative; }
 
               .rsopheader{ background-color:#A0BACB; border-bottom:1px solid black; color:#333333; font-family:MS Shell Dlg; font-size:130%; font-weight:bold; padding-bottom:5px; text-align:center; }
 
               .rsopname{ color:#333333; font-family:MS Shell Dlg; font-size:130%; font-weight:bold; padding-left:11px; }
 
               .gponame{ color:#333333; font-family:MS Shell Dlg; font-size:130%; font-weight:bold; padding-left:11px; }
 
               .gpotype{ color:#333333; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; padding-left:11px; }
 
               #uri    { color:#333333; font-family:MS Shell Dlg; font-size:100%; padding-left:11px; }
 
               #dtstamp{ color:#333333; font-family:MS Shell Dlg; font-size:100%; padding-left:11px; text-align:left; width:30%; }
 
               #objshowhide { color:#000000; cursor:pointer; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; margin-right:0px; padding-right:10px; text-align:right; text-decoration:underline; z-index:2; }
 
               #gposummary { display:block; }
 
               #gpoinformation { display:block; }
 
</style>
</head>
<body>
<table class="title" cellpadding="0" cellspacing="0">
<tr><td colspan="2" class="gponame">Access Control List for $path on machine $computer</td></tr>
<tr>
   <td id="dtstamp">Data obtained on: $(Get-Date)</td>
   <td><div id="objshowhide" tabindex="0"></div></td>
</tr>
</table>
<div class="filler"></div>
"@ | Set-Content $report
#endregion
 
#region Information gathering
$colFiles = Get-ChildItem -path $UNCPath -Filter *. -Recurse -force -Verbose | Sort-Object FullName
$colACLs = @()
#We start going through the path pointed out by the user
foreach($file in $colFiles)
{
#To control the current level in the tree we are in it's needed to count the number of separator characters
#contained in the path. However in order to make the count correctly it's needed to delete the path 
#provided by the user (the parent). Once the parent has been deleted, the rest of the full name will be 
#string used to do the level count.
#It's needed to use a REGEX object to get ALL separator character matches.
$matches = (([regex]"\\").matches($file.FullName.substring($path.length, $file.FullName.length - $path.length))).count
if ($level -ne 0 -and ($matches - 1) -gt $level) {
        continue
}
if ($debug) {
        Write-Host $file.FullName "->" $file.Mode 
}
if ($file.Mode -notlike "d*") {
        continue
}
$myobj = "" | Select-Object Folder,ACL,level
$myobj.Folder = $file
$myobj.ACL = Get-Acl $file.FullName
$myobj.level = $matches - 1
$colACLs += $myobj
}
#endregion
 
#region Setting up the report
        '<div class="gposummary">' | Add-Content $report
        
        for ($i = 0; $i -lt $colACLs.count; $i++) {
                drawDirectory ([ref] $colACLs[$i]) | Add-Content $report
        }
        '</div></body></html>' | Add-Content $report
        
#endregion

Open in new window

Avatar of Chris Dent
Chris Dent
Flag of United Kingdom of Great Britain and Northern Ireland image


You might be better with someone experienced in CSS and HTML ;)

It's all in the HTML style statement. Tracing it.

Chris

This is a bit of a dirty way to do it... is it enough?

I've changed line 67 to this:

<th width="50%">User</th>

And lines 82 and 85 to:

$dirHTML += "<tr><td width='50%'>" + $temp[0] + "</td><td>" + $temp[1] + "</td><td>" + $temp[2] + "</td></tr>"

I think I'd be too tempted to start from scratch with the script otherwise. I would have thought there'd be something we could do to display this from XML, but there we go.

Chris
#######################################
# TITLE: listACL.ps1                  #
# AUTHOR: Santiago Fernandez Mu¿oz    #
#                                     #
# DESC: This script generate a HTML   #
# report show all ACLs asociated with #
# a Folder tree structure starting in #
# root specified by the user          #
#######################################
        
param ([string] $computer = 'localhost',
                [string] $path = $(if ($help -eq $false) {Throw "A path is needed."}),
                [int] $level = 0,
                [string] $scope = 'administrator', 
                [switch] $help = $false,
                [switch] $debug = $false
        )
        
#region Initializations and previous checkings
#region Initialization
$allowedLevels = 10
$Stamp = get-date -uformat "%Y%m%d"
$report = "$PWD\$computer.html"
$comparison = ""
$UNCPath = "\\" + $computer + "\" + $path + "\"
#endregion
 
#region Previous chekings
#require -version 2.0
if ($level -gt $allowedLevels -or $level -lt 0) {Throw "Level out of range."}
if ($computer -eq 'localhost' -or $computer -ieq $env:COMPUTERNAME) { $UNCPath = $path }
switch ($scope) {
        micro {
                $comparison = '($acl -notlike "*administrator*" -and $acl -notlike "*BUILTIN*" -and $acl -notlike "*NT AUTHORITY*")'
        }
        user {
                $comparison = '($acl -notlike "*administrator*" -and $acl -notlike "*BUILTIN*" -and $acl -notlike "*IT*" -and $acl -notlike "*NT AUTHORITY*" -and $acl -notlike "*All*")'
        }
}
#endregion
#endregion
 
#region Function definitions
function drawDirectory([ref] $directory) {
        $dirHTML = '
        <div class="'
                if ($directory.value.level -eq 0) { $dirHTML += 'he0_expanded' } else { $dirHTML += 'he' + $directory.value.level } 
                $dirHTML += '"><span class="sectionTitle" tabindex="0">Folder ' + $directory.value.Folder.FullName + '</span></div>
                <div class="container"><div class="he' + ($directory.value.level + 1) + '"><span class="sectionTitle" tabindex="0">Access Control List</span></div>
                        <div class="container">
                                <div class="heACL">
                                        <table class="info3" cellpadding="0" cellspacing="0">
                                                <thead>
                                                        <th scope="col"><b>Owner</b></th>
                                                        <th scope="col"><b>Privileges</b></th>
                                                </thead>
                                                <tbody>'
                foreach ($itemACL in $directory.value.ACL) {
                        $acls = $null
                        if ($itemACL.AccessToString -ne $null) {
                                $acls = $itemACL.AccessToString.split("`n")
                        }
                        $dirHTML += '<tr><td>' + $itemACL.Owner + '</td>
                        <td>
                        <table>
                                <thead>
                                        <th width="50%">User</th>
                                        <th>Control</th>
                                        <th>Privilege</th>
                                </thead>
                                <tbody>'
                        foreach ($acl in $acls) {
                                $temp = [regex]::split($acl, "(?<!(,|NT))\s{1,}")
                                if ($debug) {
                                        write-host "ACL(" $temp.gettype().name ")[" $temp.length "]: " $temp
                                }
                                if ($temp.count -eq 1) {
                                        continue
                                }
                                if ($scope -ne 'administrator') {
                                        if ( Invoke-Expression $comparison ) {
                                                $dirHTML += "<tr><td width='50%'>" + $temp[0] + "</td><td>" + $temp[1] + "</td><td>" + $temp[2] + "</td></tr>"
                                        }
                                } else {
                                        $dirHTML += "<tr><td width='50%'>" + $temp[0] + "</td><td>" + $temp[1] + "</td><td>" + $temp[2] + "</td></tr>"
                                }
                        }
                        $dirHTML += '</tbody>
                                                </table>
                                                </td>
                                                </tr>'
                }
$dirHTML += '
                                                </tbody>
                                        </table>
                                </div>
                        </div>
                </div>'
        return $dirHTML
}
 
#endregion
 
#region Printing help message
if ($help) {
        Write-Host @"
/··················································\
· Script gather access control lists per directory ·
\··················································/
 
USAGE: ./listACL -computer <machine or IP> 
                -path <path>
                -level <0-10>
                -help:[$false]
        
PARAMETERS:
        computer [OPTIONAL]     - Computer name or IP addres where folder is hosted (Default: localhost)
        path [REQUIRED]         - Folder's path to query.
        level [OPTIONAL]        - Level of folders to go down in the query. Allowd values are between 0 and $allowedLevels.
                                  0 show that there's no limit in the going down (Default: 0)
        scope [OPTIONAL]        - Sets the amount of information showd in the report. Allowd values are: 
                                 · user, show important information to the user.
                                 · micro, show user scope information plus important information for the IT Department.
                                 · administrator, show all information.
        help [OPTIONAL]         - This help.
"@
        exit 0
        
}
#endregion
 
if (Test-Path $report)
 {
  Remove-item $report
 }
 
#To normalize I check if last character in the path is the folder separator character
if ($path.Substring($path.Length - 1,1) -eq "\") { $path = $path.Substring(0,$path.Length - 1) }
 
#region Header, style and javascript functions needed by the html report
@"
<html dir="ltr" xmlns:v="urn:schemas-microsoft-com:vml" gpmc_reportInitialized="false">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-16" />
<title>Access Control List for $path in $computer</title>
<!-- Styles -->
<style type="text/css">
                body{ background-color:#FFFFFF; border:1px solid #666666; color:#000000; font-size:68%; font-family:MS Shell Dlg; margin:0px 0px 10px 0px; }
 
               table{ font-size:100%; table-layout:fixed; width:100%; }
 
               td,th{ overflow:visible; text-align:left; vertical-align:top; white-space:normal; }
 
               .title{ background:#FFFFFF; border:none; color:#333333; display:block; height:24px; margin:0px 0px -1px 0px; padding-top:4px; position:relative; table-layout:fixed; width:100%; z-index:5; }
 
               .he0_expanded{ background-color:#FEF7D6; border:1px solid #BBBBBB; color:#3333CC; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:0px; margin-right:0px; padding-left:8px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he1_expanded{ background-color:#A0BACB; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:10px; margin-right:0px; padding-left:8px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he1{ background-color:#A0BACB; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:10px; margin-right:0px; padding-left:8px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he2{ background-color:#C0D2DE; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:20px; margin-right:0px; padding-left:8px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he3{ background-color:#D9E3EA; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:30px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he4{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:40px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he4h{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:45px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he4i{ background-color:#F9F9F9; border:1px solid #BBBBBB; color:#000000; display:block; font-family:MS Shell Dlg; font-size:100%; margin-bottom:-1px; margin-left:45px; margin-right:0px; padding-bottom:5px; padding-left:21px; padding-top:4px; position:relative; width:100%; }
 
               .he5{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:50px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he5h{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; padding-left:11px; padding-right:5em; padding-top:4px; margin-bottom:-1px; margin-left:55px; margin-right:0px; position:relative; width:100%; }
 
               .he5i{ background-color:#F9F9F9; border:1px solid #BBBBBB; color:#000000; display:block; font-family:MS Shell Dlg; font-size:100%; margin-bottom:-1px; margin-left:55px; margin-right:0px; padding-left:21px; padding-bottom:5px; padding-top: 4px; position:relative; width:100%; }
 
               .he6{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:55px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
                                .he7{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:60px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                                
                                .he8{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:65px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                                
                                .he9{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:70px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                                
                                .he10{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:75px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                                
                                .he11{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:80px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                                
                                .heACL { background-color:#ECFFD7; border:1px solid #BBBBBB; color:#000000; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:90px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                                
                                DIV .expando{ color:#000000; text-decoration:none; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:normal; position:absolute; right:10px; text-decoration:underline; z-index: 0; }
 
               .he0 .expando{ font-size:100%; }
 
               .info, .info3, .info4, .disalign{ line-height:1.6em; padding:0px 0px 0px 0px; margin:0px 0px 0px 0px; }
 
               .disalign TD{ padding-bottom:5px; padding-right:10px; }
 
               .info TD{ padding-right:10px; width:50%; }
 
               .info3 TD{ padding-right:10px; width:33%; }
 
               .info4 TD, .info4 TH{ padding-right:10px; width:25%; }
                                
                                .info5 TD, .info5 TH{ padding-right:0px; width:20%; }
 
               .info TH, .info3 TH, .info4 TH, .disalign TH{ border-bottom:1px solid #CCCCCC; padding-right:10px; }
 
               .subtable, .subtable3{ border:1px solid #CCCCCC; margin-left:0px; background:#FFFFFF; margin-bottom:10px; }
 
               .subtable TD, .subtable3 TD{ padding-left:10px; padding-right:5px; padding-top:3px; padding-bottom:3px; line-height:1.1em; width:10%; }
 
               .subtable TH, .subtable3 TH{ border-bottom:1px solid #CCCCCC; font-weight:normal; padding-left:10px; line-height:1.6em;  }
 
               .subtable .footnote{ border-top:1px solid #CCCCCC; }
 
               .subtable3 .footnote, .subtable .footnote{ border-top:1px solid #CCCCCC; }
 
               .subtable_frame{ background:#D9E3EA; border:1px solid #CCCCCC; margin-bottom:10px; margin-left:15px; }
 
               .subtable_frame TD{ line-height:1.1em; padding-bottom:3px; padding-left:10px; padding-right:15px; padding-top:3px; }
 
               .subtable_frame TH{ border-bottom:1px solid #CCCCCC; font-weight:normal; padding-left:10px; line-height:1.6em; }
 
               .subtableInnerHead{ border-bottom:1px solid #CCCCCC; border-top:1px solid #CCCCCC; }
 
               .explainlink{ color:#000000; text-decoration:none; cursor:pointer; }
 
               .explainlink:hover{ color:#0000FF; text-decoration:underline; }
 
               .spacer{ background:transparent; border:1px solid #BBBBBB; color:#FFFFFF; display:block; font-family:MS Shell Dlg; font-size:100%; height:10px; margin-bottom:-1px; margin-left:43px; margin-right:0px; padding-top: 4px; position:relative; }
 
               .filler{ background:transparent; border:none; color:#FFFFFF; display:block; font:100% MS Shell Dlg; line-height:8px; margin-bottom:-1px; margin-left:43px; margin-right:0px; padding-top:4px; position:relative; }
 
               .container{ display:block; position:relative; }
 
               .rsopheader{ background-color:#A0BACB; border-bottom:1px solid black; color:#333333; font-family:MS Shell Dlg; font-size:130%; font-weight:bold; padding-bottom:5px; text-align:center; }
 
               .rsopname{ color:#333333; font-family:MS Shell Dlg; font-size:130%; font-weight:bold; padding-left:11px; }
 
               .gponame{ color:#333333; font-family:MS Shell Dlg; font-size:130%; font-weight:bold; padding-left:11px; }
 
               .gpotype{ color:#333333; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; padding-left:11px; }
 
               #uri    { color:#333333; font-family:MS Shell Dlg; font-size:100%; padding-left:11px; }
 
               #dtstamp{ color:#333333; font-family:MS Shell Dlg; font-size:100%; padding-left:11px; text-align:left; width:30%; }
 
               #objshowhide { color:#000000; cursor:pointer; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; margin-right:0px; padding-right:10px; text-align:right; text-decoration:underline; z-index:2; }
 
               #gposummary { display:block; }
 
               #gpoinformation { display:block; }
 
</style>
</head>
<body>
<table class="title" cellpadding="0" cellspacing="0">
<tr><td colspan="2" class="gponame">Access Control List for $path on machine $computer</td></tr>
<tr>
   <td id="dtstamp">Data obtained on: $(Get-Date)</td>
   <td><div id="objshowhide" tabindex="0"></div></td>
</tr>
</table>
<div class="filler"></div>
"@ | Set-Content $report
#endregion
 
#region Information gathering
$colFiles = Get-ChildItem -path $UNCPath -Filter *. -Recurse -force -Verbose | Sort-Object FullName
$colACLs = @()
#We start going through the path pointed out by the user
foreach($file in $colFiles)
{
#To control the current level in the tree we are in it's needed to count the number of separator characters
#contained in the path. However in order to make the count correctly it's needed to delete the path 
#provided by the user (the parent). Once the parent has been deleted, the rest of the full name will be 
#string used to do the level count.
#It's needed to use a REGEX object to get ALL separator character matches.
$matches = (([regex]"\\").matches($file.FullName.substring($path.length, $file.FullName.length - $path.length))).count
if ($level -ne 0 -and ($matches - 1) -gt $level) {
        continue
}
if ($debug) {
        Write-Host $file.FullName "->" $file.Mode 
}
if ($file.Mode -notlike "d*") {
        continue
}
$myobj = "" | Select-Object Folder,ACL,level
$myobj.Folder = $file
$myobj.ACL = Get-Acl $file.FullName
$myobj.level = $matches - 1
$colACLs += $myobj
}
#endregion
 
#region Setting up the report
        '<div class="gposummary">' | Add-Content $report
        
        for ($i = 0; $i -lt $colACLs.count; $i++) {
                drawDirectory ([ref] $colACLs[$i]) | Add-Content $report
        }
        '</div></body></html>' | Add-Content $report
        
#endregion

Open in new window

Avatar of amyassein
amyassein

ASKER

Chris,

You know what !  ... You are totally right, i should say HTML not PS, sorry.

Ok .. let me try your modified one.

Thx
Chris,

It worked but it needs a little bit more stretching ... i tried to increase the width % more than 50 but the other columns shrinked ... lol

Please help to strecth it 2 bits more ..... You know ! the problem is with user groups not users as user group names are long in my company ... Or let me tell you another thing .... can we just get rid of the domain name in the left as it takes space :( ? (i.e. domain.com\sales - long term)

Thx

Yeah, they will. By default those columns are equally spaced, the bit I added just overrides the normal behaviour, spreading out Users at the expense of the other two.

It would be better if we could change the Permissions / Owners column width...

I'll see if I can do that and drop the domain name, that latter at least shouldn't be a problem if I can just resist massive rewrites ;)

Chris
Wow Chris,

If you can just change the Permissions / Owners Column width and also drop the domain, by this way, we will have awesome space :)

Appreciate your effort man.

Wait your response in this


Thx a lot
Chris,

I got also another issue in this script  ...... i receive this error a lot:

"Get-ChildItem : the specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters."

Of course i know the meaning of the error but doesn it mean that long folder or file name will not be listed in the report? ...  Anyways, even though this error happens, the report is finished successfully but i doubt that these long folders are not listed.

Help needed pls :(

Thx

Yeah, those won't list at all. All PowerShell does is use .NET classes to do things, if the underlying .NET class can't cope with the name the neither can PowerShell.

I did try to trap errors from long names at one point, but without writing an entirely new version of Get-ChildItem is was all a bit pointless. As such, I don't have much of a suggestion for dealing with those at the moment :-\

Chris

Okay... adjusted the column width.

Owner is 30%, Privileges 70%.

I'll add the domain name removal in a moment so you can choose :)

Chris
#######################################
# TITLE: listACL.ps1                  #
# AUTHOR: Santiago Fernandez Mu¿oz    #
#                                     #
# DESC: This script generate a HTML   #
# report show all ACLs asociated with #
# a Folder tree structure starting in #
# root specified by the user          #
#######################################
        
param ([string] $computer = 'localhost',
  [string] $path = $(if ($help -eq $false) {Throw "A path is needed."}),
  [int] $level = 0,
  [string] $scope = 'administrator', 
  [switch] $help = $false,
  [switch] $debug = $false
)
        
#region Initializations and previous checkings
#region Initialization

$allowedLevels = 10
$Stamp = get-date -uformat "%Y%m%d"
$report = "$PWD\$computer.html"
$comparison = ""
$UNCPath = "\\" + $computer + "\" + $path + "\"
#endregion

#region Previous chekings
#require -version 2.0

if ($level -gt $allowedLevels -or $level -lt 0) {Throw "Level out of range."}

if ($computer -eq 'localhost' -or $computer -ieq $env:COMPUTERNAME) { $UNCPath = $path }

switch ($scope) {
  micro
  { 
    $comparison = '($acl -notlike "*administrator*" -and $acl -notlike "*BUILTIN*" -and $acl -notlike "*NT AUTHORITY*")'
  }
  user 
  { 
    $comparison = '($acl -notlike "*administrator*" -and $acl -notlike "*BUILTIN*" -and $acl -notlike "*IT*" -and $acl -notlike "*NT AUTHORITY*" -and $acl -notlike "*All*")'
  }
}
#endregion
#endregion
 
#region Function definitions

Function drawDirectory([ref] $directory) {
  $dirHTML = '<div class="'

  if ($directory.value.level -eq 0) {
    $dirHTML += 'he0_expanded'
  } else { 
    $dirHTML += 'he' + $directory.value.level 
  } 

  $dirHTML += '"><span class="sectionTitle" tabindex="0">Folder ' + $directory.value.Folder.FullName + '</span></div>
    <div class="container">
      <div class="he' + ($directory.value.level + 1) + '"><span class="sectionTitle" tabindex="0">Access Control List</span></div>
      <div class="container">
        <div class="heACL">
          <table class="info3" cellpadding="0" cellspacing="0">
            <thead>
              <th width="30%" scope="col"><b>Owner</b></th>
              <th width="70%" scope="col"><b>Privileges</b></th>
            </thead>
            <tbody>'

  ForEach ($itemACL in $directory.value.ACL) {

    $acls = $null
    if ($itemACL.AccessToString -ne $null) {
      $acls = $itemACL.AccessToString.split("`n")
    }

    $dirHTML += '<tr><td width="30%">' + $itemACL.Owner + '</td>
      <td width="70%">
        <table>
          <thead>
            <th width="50%">User</th>
            <th>Control</th>
            <th>Privilege</th>
          </thead>
          <tbody>'

    ForEach ($acl in $acls) {
      $temp = [regex]::split($acl, "(?<!(,|NT))\s{1,}")

      if ($debug) { write-host "ACL(" $temp.gettype().name ")[" $temp.length "]: " $temp }

      if ($temp.count -eq 1) { continue }

      if ($scope -ne 'administrator') {
        if ( Invoke-Expression $comparison ) {
          $dirHTML += "<tr><td width='50%'>" + $temp[0] + "</td><td>" + $temp[1] + "</td><td>" + $temp[2] + "</td></tr>"
        }
      } else {
        $dirHTML += "<tr><td width='50%'>" + $temp[0] + "</td><td>" + $temp[1] + "</td><td>" + $temp[2] + "</td></tr>"
      }
    }

    $dirHTML += '</tbody>
        </table>
      </td>
    </tr>'
  }

  $dirHTML += '</tbody>
  </table>
  </div>
  </div>
  </div>'

  Return $dirHTML
}
 
#endregion

#region Printing help message

if ($help) {
        Write-Host @"
/··················································\
· Script gather access control lists per directory ·
\··················································/
 
USAGE: ./listACL -computer <machine or IP> 
                -path <path>
                -level <0-10>
                -help:[$false]
        
PARAMETERS:
        computer [OPTIONAL]     - Computer name or IP addres where folder is hosted (Default: localhost)
        path [REQUIRED]         - Folder's path to query.
        level [OPTIONAL]        - Level of folders to go down in the query. Allowd values are between 0 and $allowedLevels.
                                  0 show that there's no limit in the going down (Default: 0)
        scope [OPTIONAL]        - Sets the amount of information showd in the report. Allowd values are: 
                                 · user, show important information to the user.
                                 · micro, show user scope information plus important information for the IT Department.
                                 · administrator, show all information.
        help [OPTIONAL]         - This help.
"@
        exit 0
        
}
#endregion
 
if (Test-Path $report)
 {
  Remove-item $report
 }
 

#To normalize I check if last character in the path is the folder separator character
if ($path.Substring($path.Length - 1,1) -eq "\") { $path = $path.Substring(0,$path.Length - 1) }
 
#region Header, style and javascript functions needed by the html report
@"
<html dir="ltr" xmlns:v="urn:schemas-microsoft-com:vml" gpmc_reportInitialized="false">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-16" />
<title>Access Control List for $path in $computer</title>
<!-- Styles -->
<style type="text/css">
                body{ background-color:#FFFFFF; border:1px solid #666666; color:#000000; font-size:68%; font-family:MS Shell Dlg; margin:0px 0px 10px 0px; }
 
               table{ font-size:100%; table-layout:fixed; width:100%; }
 
               td,th{ overflow:visible; text-align:left; vertical-align:top; white-space:normal; }
 
               .title{ background:#FFFFFF; border:none; color:#333333; display:block; height:24px; margin:0px 0px -1px 0px; padding-top:4px; position:relative; table-layout:fixed; width:100%; z-index:5; }
 
               .he0_expanded{ background-color:#FEF7D6; border:1px solid #BBBBBB; color:#3333CC; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:0px; margin-right:0px; padding-left:8px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he1_expanded{ background-color:#A0BACB; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:10px; margin-right:0px; padding-left:8px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he1{ background-color:#A0BACB; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:10px; margin-right:0px; padding-left:8px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he2{ background-color:#C0D2DE; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:20px; margin-right:0px; padding-left:8px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he3{ background-color:#D9E3EA; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:30px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he4{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:40px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he4h{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:45px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he4i{ background-color:#F9F9F9; border:1px solid #BBBBBB; color:#000000; display:block; font-family:MS Shell Dlg; font-size:100%; margin-bottom:-1px; margin-left:45px; margin-right:0px; padding-bottom:5px; padding-left:21px; padding-top:4px; position:relative; width:100%; }
 
               .he5{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:50px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he5h{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; padding-left:11px; padding-right:5em; padding-top:4px; margin-bottom:-1px; margin-left:55px; margin-right:0px; position:relative; width:100%; }
 
               .he5i{ background-color:#F9F9F9; border:1px solid #BBBBBB; color:#000000; display:block; font-family:MS Shell Dlg; font-size:100%; margin-bottom:-1px; margin-left:55px; margin-right:0px; padding-left:21px; padding-bottom:5px; padding-top: 4px; position:relative; width:100%; }
 
               .he6{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:55px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he7{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:60px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                               
               .he8{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:65px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                                
               .he9{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:70px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                                
               .he10{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:75px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                                
               .he11{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:80px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                                
               .heACL { background-color:#ECFFD7; border:1px solid #BBBBBB; color:#000000; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:90px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                                
               DIV .expando{ color:#000000; text-decoration:none; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:normal; position:absolute; right:10px; text-decoration:underline; z-index: 0; }
 
               .he0 .expando{ font-size:100%; }
 
               .info, .info3, .info4, .disalign{ line-height:1.6em; padding:0px 0px 0px 0px; margin:0px 0px 0px 0px; }
 
               .disalign TD{ padding-bottom:5px; padding-right:10px; }
 
               .info TD{ padding-right:10px; width:50%; }
 
               .info3 TD{ padding-right:10px; width:33%; }
 
               .info4 TD, .info4 TH{ padding-right:10px; width:25%; }
                                
               .info5 TD, .info5 TH{ padding-right:0px; width:20%; }
 
               .info TH, .info3 TH, .info4 TH, .disalign TH{ border-bottom:1px solid #CCCCCC; padding-right:10px; }
 
               .subtable, .subtable3{ border:1px solid #CCCCCC; margin-left:0px; background:#FFFFFF; margin-bottom:10px; }
 
               .subtable TD, .subtable3 TD{ padding-left:10px; padding-right:5px; padding-top:3px; padding-bottom:3px; line-height:1.1em; width:10%; }
 
               .subtable TH, .subtable3 TH{ border-bottom:1px solid #CCCCCC; font-weight:normal; padding-left:10px; line-height:1.6em;  }
 
               .subtable .footnote{ border-top:1px solid #CCCCCC; }
 
               .subtable3 .footnote, .subtable .footnote{ border-top:1px solid #CCCCCC; }
 
               .subtable_frame{ background:#D9E3EA; border:1px solid #CCCCCC; margin-bottom:10px; margin-left:15px; }
 
               .subtable_frame TD{ line-height:1.1em; padding-bottom:3px; padding-left:10px; padding-right:15px; padding-top:3px; }
 
               .subtable_frame TH{ border-bottom:1px solid #CCCCCC; font-weight:normal; padding-left:10px; line-height:1.6em; }
 
               .subtableInnerHead{ border-bottom:1px solid #CCCCCC; border-top:1px solid #CCCCCC; }
 
               .explainlink{ color:#000000; text-decoration:none; cursor:pointer; }
 
               .explainlink:hover{ color:#0000FF; text-decoration:underline; }
 
               .spacer{ background:transparent; border:1px solid #BBBBBB; color:#FFFFFF; display:block; font-family:MS Shell Dlg; font-size:100%; height:10px; margin-bottom:-1px; margin-left:43px; margin-right:0px; padding-top: 4px; position:relative; }
 
               .filler{ background:transparent; border:none; color:#FFFFFF; display:block; font:100% MS Shell Dlg; line-height:8px; margin-bottom:-1px; margin-left:43px; margin-right:0px; padding-top:4px; position:relative; }
 
               .container{ display:block; position:relative; }
 
               .rsopheader{ background-color:#A0BACB; border-bottom:1px solid black; color:#333333; font-family:MS Shell Dlg; font-size:130%; font-weight:bold; padding-bottom:5px; text-align:center; }
 
               .rsopname{ color:#333333; font-family:MS Shell Dlg; font-size:130%; font-weight:bold; padding-left:11px; }
 
               .gponame{ color:#333333; font-family:MS Shell Dlg; font-size:130%; font-weight:bold; padding-left:11px; }
 
               .gpotype{ color:#333333; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; padding-left:11px; }
 
               #uri    { color:#333333; font-family:MS Shell Dlg; font-size:100%; padding-left:11px; }
 
               #dtstamp{ color:#333333; font-family:MS Shell Dlg; font-size:100%; padding-left:11px; text-align:left; width:30%; }
 
               #objshowhide { color:#000000; cursor:pointer; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; margin-right:0px; padding-right:10px; text-align:right; text-decoration:underline; z-index:2; }
 
               #gposummary { display:block; }
 
               #gpoinformation { display:block; }
 
</style>
</head>
<body>
<table class="title" cellpadding="0" cellspacing="0">
<tr><td colspan="2" class="gponame">Access Control List for $path on machine $computer</td></tr>
<tr>
   <td id="dtstamp">Data obtained on: $(Get-Date)</td>
   <td><div id="objshowhide" tabindex="0"></div></td>
</tr>
</table>
<div class="filler"></div>
"@ | Set-Content $report
#endregion
 
#region Information gathering
$colFiles = Get-ChildItem -path $UNCPath -Filter *. -Recurse -force -Verbose | Sort-Object FullName
$colACLs = @()
#We start going through the path pointed out by the user
foreach($file in $colFiles)
{
#To control the current level in the tree we are in it's needed to count the number of separator characters
#contained in the path. However in order to make the count correctly it's needed to delete the path 
#provided by the user (the parent). Once the parent has been deleted, the rest of the full name will be 
#string used to do the level count.
#It's needed to use a REGEX object to get ALL separator character matches.
$matches = (([regex]"\\").matches($file.FullName.substring($path.length, $file.FullName.length - $path.length))).count
if ($level -ne 0 -and ($matches - 1) -gt $level) {
        continue
}
if ($debug) {
        Write-Host $file.FullName "->" $file.Mode 
}
if ($file.Mode -notlike "d*") {
        continue
}
$myobj = "" | Select-Object Folder,ACL,level
$myobj.Folder = $file
$myobj.ACL = Get-Acl $file.FullName
$myobj.level = $matches - 1
$colACLs += $myobj
}
#endregion
 
#region Setting up the report
        '<div class="gposummary">' | Add-Content $report
        
        for ($i = 0; $i -lt $colACLs.count; $i++) {
                drawDirectory ([ref] $colACLs[$i]) | Add-Content $report
        }
        '</div></body></html>' | Add-Content $report
        
#endregion

Open in new window

No problem ... My friend

I am waiting your response regarding the column stretching issue.. :-)

Thx

And minus the local domain name.

We can be flexible on this, what is drops is defined by a regular expression match and a replace.

At the moment I use this:

$($Env:UserDomain)\\

Which will be the current domain name followed by a \. However, if you just want to replace all instances of any kind of domain name you might change that to:

.*\\

I kind of suspect you know rather more about RegEx than I so I'll refrain from giving more examples :)

That occurs twice... I can't see why, but it does and I'm trying to resist rewriting ;) Lines 99 and 105 below.

Chris
#######################################
# TITLE: listACL.ps1                  #
# AUTHOR: Santiago Fernandez Mu¿oz    #
#                                     #
# DESC: This script generate a HTML   #
# report show all ACLs asociated with #
# a Folder tree structure starting in #
# root specified by the user          #
#######################################
        
param ([string] $computer = 'localhost',
  [string] $path = $(if ($help -eq $false) {Throw "A path is needed."}),
  [int] $level = 0,
  [string] $scope = 'administrator', 
  [switch] $help = $false,
  [switch] $debug = $false
)
        
#region Initializations and previous checkings
#region Initialization

$allowedLevels = 10
$Stamp = get-date -uformat "%Y%m%d"
$report = "$PWD\$computer.html"
$comparison = ""
$UNCPath = "\\" + $computer + "\" + $path + "\"
#endregion

#region Previous chekings
#require -version 2.0

if ($level -gt $allowedLevels -or $level -lt 0) {Throw "Level out of range."}

if ($computer -eq 'localhost' -or $computer -ieq $env:COMPUTERNAME) { $UNCPath = $path }

switch ($scope) {
  micro
  { 
    $comparison = '($acl -notlike "*administrator*" -and $acl -notlike "*BUILTIN*" -and $acl -notlike "*NT AUTHORITY*")'
  }
  user 
  { 
    $comparison = '($acl -notlike "*administrator*" -and $acl -notlike "*BUILTIN*" -and $acl -notlike "*IT*" -and $acl -notlike "*NT AUTHORITY*" -and $acl -notlike "*All*")'
  }
}
#endregion
#endregion
 
#region Function definitions

Function drawDirectory([ref] $directory) {
  $dirHTML = '<div class="'

  if ($directory.value.level -eq 0) {
    $dirHTML += 'he0_expanded'
  } else { 
    $dirHTML += 'he' + $directory.value.level 
  } 

  $dirHTML += '"><span class="sectionTitle" tabindex="0">Folder ' + $directory.value.Folder.FullName + '</span></div>
    <div class="container">
      <div class="he' + ($directory.value.level + 1) + '"><span class="sectionTitle" tabindex="0">Access Control List</span></div>
      <div class="container">
        <div class="heACL">
          <table class="info3" cellpadding="0" cellspacing="0">
            <thead>
              <th width="30%" scope="col"><b>Owner</b></th>
              <th width="70%" scope="col"><b>Privileges</b></th>
            </thead>
            <tbody>'

  ForEach ($itemACL in $directory.value.ACL) {

    $acls = $null
    if ($itemACL.AccessToString -ne $null) {
      $acls = $itemACL.AccessToString.split("`n")
    }

    $dirHTML += '<tr><td width="30%">' + $itemACL.Owner + '</td>
      <td width="70%">
        <table>
          <thead>
            <th width="50%">User</th>
            <th>Control</th>
            <th>Privilege</th>
          </thead>
          <tbody>'

    ForEach ($acl in $acls) {
      $temp = [regex]::split($acl, "(?<!(,|NT))\s{1,}")

      if ($debug) { write-host "ACL(" $temp.gettype().name ")[" $temp.length "]: " $temp }

      if ($temp.count -eq 1) { continue }

      if ($scope -ne 'administrator') {
        if ( Invoke-Expression $comparison ) {
          # Drop the domain name
          $temp[0] = $temp[0] -Replace "$($Env:UserDomain)\\"

          $dirHTML += "<tr><td width='50%'>" + $temp[0] + "</td><td>" + $temp[1] + "</td><td>" + $temp[2] + "</td></tr>"
        }
      } else {
        # Drop the domain name
        $temp[0] = $temp[0] -Replace "$($Env:UserDomain)\\"

        $dirHTML += "<tr><td width='50%'>" + $temp[0] + "</td><td>" + $temp[1] + "</td><td>" + $temp[2] + "</td></tr>"
      }
    }

    $dirHTML += '</tbody>
        </table>
      </td>
    </tr>'
  }

  $dirHTML += '</tbody>
  </table>
  </div>
  </div>
  </div>'

  Return $dirHTML
}
 
#endregion

#region Printing help message

if ($help) {
        Write-Host @"
/··················································\
· Script gather access control lists per directory ·
\··················································/
 
USAGE: ./listACL -computer <machine or IP> 
                -path <path>
                -level <0-10>
                -help:[$false]
        
PARAMETERS:
        computer [OPTIONAL]     - Computer name or IP addres where folder is hosted (Default: localhost)
        path [REQUIRED]         - Folder's path to query.
        level [OPTIONAL]        - Level of folders to go down in the query. Allowd values are between 0 and $allowedLevels.
                                  0 show that there's no limit in the going down (Default: 0)
        scope [OPTIONAL]        - Sets the amount of information showd in the report. Allowd values are: 
                                 · user, show important information to the user.
                                 · micro, show user scope information plus important information for the IT Department.
                                 · administrator, show all information.
        help [OPTIONAL]         - This help.
"@
        exit 0
        
}
#endregion
 
if (Test-Path $report)
 {
  Remove-item $report
 }
 

#To normalize I check if last character in the path is the folder separator character
if ($path.Substring($path.Length - 1,1) -eq "\") { $path = $path.Substring(0,$path.Length - 1) }
 
#region Header, style and javascript functions needed by the html report
@"
<html dir="ltr" xmlns:v="urn:schemas-microsoft-com:vml" gpmc_reportInitialized="false">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-16" />
<title>Access Control List for $path in $computer</title>
<!-- Styles -->
<style type="text/css">
                body{ background-color:#FFFFFF; border:1px solid #666666; color:#000000; font-size:68%; font-family:MS Shell Dlg; margin:0px 0px 10px 0px; }
 
               table{ font-size:100%; table-layout:fixed; width:100%; }
 
               td,th{ overflow:visible; text-align:left; vertical-align:top; white-space:normal; }
 
               .title{ background:#FFFFFF; border:none; color:#333333; display:block; height:24px; margin:0px 0px -1px 0px; padding-top:4px; position:relative; table-layout:fixed; width:100%; z-index:5; }
 
               .he0_expanded{ background-color:#FEF7D6; border:1px solid #BBBBBB; color:#3333CC; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:0px; margin-right:0px; padding-left:8px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he1_expanded{ background-color:#A0BACB; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:10px; margin-right:0px; padding-left:8px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he1{ background-color:#A0BACB; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:10px; margin-right:0px; padding-left:8px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he2{ background-color:#C0D2DE; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:20px; margin-right:0px; padding-left:8px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he3{ background-color:#D9E3EA; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:30px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he4{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:40px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he4h{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:45px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he4i{ background-color:#F9F9F9; border:1px solid #BBBBBB; color:#000000; display:block; font-family:MS Shell Dlg; font-size:100%; margin-bottom:-1px; margin-left:45px; margin-right:0px; padding-bottom:5px; padding-left:21px; padding-top:4px; position:relative; width:100%; }
 
               .he5{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:50px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he5h{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; padding-left:11px; padding-right:5em; padding-top:4px; margin-bottom:-1px; margin-left:55px; margin-right:0px; position:relative; width:100%; }
 
               .he5i{ background-color:#F9F9F9; border:1px solid #BBBBBB; color:#000000; display:block; font-family:MS Shell Dlg; font-size:100%; margin-bottom:-1px; margin-left:55px; margin-right:0px; padding-left:21px; padding-bottom:5px; padding-top: 4px; position:relative; width:100%; }
 
               .he6{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:55px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
 
               .he7{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:60px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                               
               .he8{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:65px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                                
               .he9{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:70px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                                
               .he10{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:75px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                                
               .he11{ background-color:#E8E8E8; border:1px solid #BBBBBB; color:#000000; cursor:pointer; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:80px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                                
               .heACL { background-color:#ECFFD7; border:1px solid #BBBBBB; color:#000000; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; height:2.25em; margin-bottom:-1px; margin-left:90px; margin-right:0px; padding-left:11px; padding-right:5em; padding-top:4px; position:relative; width:100%; }
                                
               DIV .expando{ color:#000000; text-decoration:none; display:block; font-family:MS Shell Dlg; font-size:100%; font-weight:normal; position:absolute; right:10px; text-decoration:underline; z-index: 0; }
 
               .he0 .expando{ font-size:100%; }
 
               .info, .info3, .info4, .disalign{ line-height:1.6em; padding:0px 0px 0px 0px; margin:0px 0px 0px 0px; }
 
               .disalign TD{ padding-bottom:5px; padding-right:10px; }
 
               .info TD{ padding-right:10px; width:50%; }
 
               .info3 TD{ padding-right:10px; width:33%; }
 
               .info4 TD, .info4 TH{ padding-right:10px; width:25%; }
                                
               .info5 TD, .info5 TH{ padding-right:0px; width:20%; }
 
               .info TH, .info3 TH, .info4 TH, .disalign TH{ border-bottom:1px solid #CCCCCC; padding-right:10px; }
 
               .subtable, .subtable3{ border:1px solid #CCCCCC; margin-left:0px; background:#FFFFFF; margin-bottom:10px; }
 
               .subtable TD, .subtable3 TD{ padding-left:10px; padding-right:5px; padding-top:3px; padding-bottom:3px; line-height:1.1em; width:10%; }
 
               .subtable TH, .subtable3 TH{ border-bottom:1px solid #CCCCCC; font-weight:normal; padding-left:10px; line-height:1.6em;  }
 
               .subtable .footnote{ border-top:1px solid #CCCCCC; }
 
               .subtable3 .footnote, .subtable .footnote{ border-top:1px solid #CCCCCC; }
 
               .subtable_frame{ background:#D9E3EA; border:1px solid #CCCCCC; margin-bottom:10px; margin-left:15px; }
 
               .subtable_frame TD{ line-height:1.1em; padding-bottom:3px; padding-left:10px; padding-right:15px; padding-top:3px; }
 
               .subtable_frame TH{ border-bottom:1px solid #CCCCCC; font-weight:normal; padding-left:10px; line-height:1.6em; }
 
               .subtableInnerHead{ border-bottom:1px solid #CCCCCC; border-top:1px solid #CCCCCC; }
 
               .explainlink{ color:#000000; text-decoration:none; cursor:pointer; }
 
               .explainlink:hover{ color:#0000FF; text-decoration:underline; }
 
               .spacer{ background:transparent; border:1px solid #BBBBBB; color:#FFFFFF; display:block; font-family:MS Shell Dlg; font-size:100%; height:10px; margin-bottom:-1px; margin-left:43px; margin-right:0px; padding-top: 4px; position:relative; }
 
               .filler{ background:transparent; border:none; color:#FFFFFF; display:block; font:100% MS Shell Dlg; line-height:8px; margin-bottom:-1px; margin-left:43px; margin-right:0px; padding-top:4px; position:relative; }
 
               .container{ display:block; position:relative; }
 
               .rsopheader{ background-color:#A0BACB; border-bottom:1px solid black; color:#333333; font-family:MS Shell Dlg; font-size:130%; font-weight:bold; padding-bottom:5px; text-align:center; }
 
               .rsopname{ color:#333333; font-family:MS Shell Dlg; font-size:130%; font-weight:bold; padding-left:11px; }
 
               .gponame{ color:#333333; font-family:MS Shell Dlg; font-size:130%; font-weight:bold; padding-left:11px; }
 
               .gpotype{ color:#333333; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; padding-left:11px; }
 
               #uri    { color:#333333; font-family:MS Shell Dlg; font-size:100%; padding-left:11px; }
 
               #dtstamp{ color:#333333; font-family:MS Shell Dlg; font-size:100%; padding-left:11px; text-align:left; width:30%; }
 
               #objshowhide { color:#000000; cursor:pointer; font-family:MS Shell Dlg; font-size:100%; font-weight:bold; margin-right:0px; padding-right:10px; text-align:right; text-decoration:underline; z-index:2; }
 
               #gposummary { display:block; }
 
               #gpoinformation { display:block; }
 
</style>
</head>
<body>
<table class="title" cellpadding="0" cellspacing="0">
<tr><td colspan="2" class="gponame">Access Control List for $path on machine $computer</td></tr>
<tr>
   <td id="dtstamp">Data obtained on: $(Get-Date)</td>
   <td><div id="objshowhide" tabindex="0"></div></td>
</tr>
</table>
<div class="filler"></div>
"@ | Set-Content $report
#endregion
 
#region Information gathering
$colFiles = Get-ChildItem -path $UNCPath -Filter *. -Recurse -force -Verbose | Sort-Object FullName
$colACLs = @()
#We start going through the path pointed out by the user
foreach($file in $colFiles)
{
#To control the current level in the tree we are in it's needed to count the number of separator characters
#contained in the path. However in order to make the count correctly it's needed to delete the path 
#provided by the user (the parent). Once the parent has been deleted, the rest of the full name will be 
#string used to do the level count.
#It's needed to use a REGEX object to get ALL separator character matches.
$matches = (([regex]"\\").matches($file.FullName.substring($path.length, $file.FullName.length - $path.length))).count
if ($level -ne 0 -and ($matches - 1) -gt $level) {
        continue
}
if ($debug) {
        Write-Host $file.FullName "->" $file.Mode 
}
if ($file.Mode -notlike "d*") {
        continue
}
$myobj = "" | Select-Object Folder,ACL,level
$myobj.Folder = $file
$myobj.ACL = Get-Acl $file.FullName
$myobj.level = $matches - 1
$colACLs += $myobj
}
#endregion
 
#region Setting up the report
        '<div class="gposummary">' | Add-Content $report
        
        for ($i = 0; $i -lt $colACLs.count; $i++) {
                drawDirectory ([ref] $colACLs[$i]) | Add-Content $report
        }
        '</div></body></html>' | Add-Content $report
        
#endregion

Open in new window


Just in case... because all sizes in this are relative (everything is a percentage), resizing the window will have a pretty major impact on the output. The changes I've put in will become more apparent as it's stretched out.

Chris
Chris,

Thank you so much , it works great now ....

However, even though, we did our best by stretching the User column and dropping the domain name. the long group name still intereferring with the Privilege column ..... For example, i have many groups looks like this "BSD - QA", "ENGG - Admin" .... what happens is when you generate the report, the "ENGG" words is in the User Column and the "Admin" word in the privilege column. The groups with one words are fine such as "Sales", "Marketing". But the problem with the groups with hyphen names.

Do you have any idea why this is happening? ... Do we need to add something to the code in order to gather the hyphen group names correctly under the User column ?

Thx and appreciate your efforts.

I think the problem is with the spaces in the group names not the hyphen because i have other hypen group names such as PE-ENGG , it works great.

Just a thought.

It's how he choose to split it. See this:

$acl = "ENG - Admin"
[regex]::split($acl, "(?<!(,|NT))\s{1,}")

It's going to take a bit of looking into, need to step through the code and figure out the design choices.

Chris

Oh, and you're completely correct about it being caused by  the space.

Chris
Chris,

Take your time please ... but note that i need to apply this to all the "Spaces" group names not only "ENG - Admin". For example, tell the code to look for any group names with spaces and split them if needed.

Thx

I'm not entirely sure why it needs to split anything at all at the moment, the tiny snippet above was just to show where / why the problem is occurring :)

Chris
No problem Chris .....

I will try to convince the management to rename all the space group names which is not a practical solution. But if you can get around this, i will be glad.

Thx

I can, I just need to rewrite it a bit so I can control the output properly.

Chris
No problem take your time ...

This report should be sent to the Dpt. Manager next week so no rush.

And thx for all the kind efforts and prompt actions.


Okay... so this is a little bit of a rewrite.

Can you let me know if it still meets your requirements? It's not quite as colourful. I can potentially bring some of the variety back if you need it though.

I quite like this bit, it produces validated strict HTML and CSS, and it'll work properly in Firefox rather than only in IE. But there we go, I'm a geek ;)

Chris
# This script is a re-design of listACL.ps1
#
# Original Author: Santiago Fernandex Mu¿oz
# Modified By: Chris Dent
# Date: 20/01/2010
#
# Description:
#
# This script generate a HTML report which shows all ACLs associated with
# a Folder tree

# Script Parameters

Param(
  [Switch]$Help,
  [String]$Path = $( If (!$Help) { Throw("Path is mandatory") }),
  [String]$SaveAs = "$PWD\ACLReport.html",
  [Int]$Level = 2,
  [Switch]$Open
)

#
# Script Help
#

If ($Help) {
  "NAME"
  "    $($MyInvocation.MyCommand)"
  ""
  "SYNOPSIS"
  "    Generates an HTML Report of the permissions assigned to folders a file system."
  ""
  "SYNTAX"
  "    ./$($MyInvocation.MyCommand) -Help"
  ""
  "    ./$($MyInvocation.MyCommand) [-Path] <string> [-SaveAs <string>] [-Level <Int32>] [-Open]"
  ""
  "PARAMETERS"
  "     -Help"
  "         Displays this help page."
  ""
  "     -Level <int32>"
  "         If specified recursion will stop at this depth beneath the starting point. The default value is 2."
  ""
  "     -Open"
  "         Opens the report using Internet Explorer."
  ""
  "     -Path <string>"
  "         Specifies the path to begin the reporting."
  ""
  "     -SaveAs <string>"
  "         Save the report using the specified path or filename. The default file name is ACLReport.html"
  ""
  Break
}

#
# Functions associated with this script
#

Function Get-ChildItemToLevel {
  Param(
    [String]$Path = $(Throw("Path is mandatory")),
    [Int]$ToDepth = 2,
    [Int]$CurrentDepth = 0,
    [Switch]$DebugMode
  )

  $CurrentDepth++

  If ($Debug) { $DebugPreference = "Continue" }

  Get-ChildItem $Path | %{
    $_ | Select-Object *, @{n='Depth';e={ $CurrentDepth }}

    If ($_.PsIsContainer) {
      If ($CurrentDepth -le $ToDepth) {
        Get-ChildItemToLevel -Path $_.FullName -ToDepth $ToDepth -CurrentDepth $CurrentDepth
      } Else {
        Write-Debug "Skipping GCI for Folder: $($_.FullName) (Why: Current depth $CurrentDepth vs limit depth $ToDepth)"
      }
    }
  }
}

#
# Functions to generate HTML from objects
#

Function Replace-ColGroup {
  # Remove the default colgroup statements and drop the blank lines

  Param( [String]$HtmlBody, [String]$ColGroup )

  $HtmlBody = $HtmlBody -Replace "<col(group)?/?>" | ?{ $_ -ne [String]::Empty }
  $HtmlBody = $HtmlBody -Replace "</colgroup>", "`n$ColGroup"

  Return $HtmlBody
}

Function Convert-AclToHtml {
  # Generate the Owner and Privileges table

  Param( [Security.AccessControl.FileSystemSecurity]$Acl )

  $AclTable = $Acl | Select-Object Owner, @{n='Privileges';e={ "PLACEHOLDER" }} | `
    ConvertTo-Html -Fragment

  # Defines the layout of the Owner / Privilege Table (2 columns)

  $ColGroup = "  <colgroup>
    <col width='30%'></col>
    <col width='70%'></col>
  </colgroup>"

  $AclTable = Replace-ColGroup $AclTable $ColGroup

  # Generate and insert the Access rights table

  $AclTable = $AclTable -Replace "PLACEHOLDER", $(Convert-AccessToHtml $Acl.Access) 

  Return $AclTable
}

Function Convert-AccessToHtml {
  # Generate the Access Table

  Param( [Security.AccessControl.AuthorizationRuleCollection]$Access )

  $AccessTable = $Access | Select-Object @{n='User';e={ $_.IdentityReference }}, `
      @{n='Control';e={ $_.AccessControlType }}, `
      @{n='Privilege';e={ $_.FileSystemRights }} | `
    ConvertTo-Html -Fragment

  # Defines the layout of the User / Control / Privilege Table (3 columns)

  $ColGroup = "  <colgroup>
    <col width='50%'></col>
    <col width='20%'></col>
    <col width='30%'></col>
  </colgroup>"

  $AccessTable = Replace-ColGroup $AccessTable $ColGroup

  Return $AccessTable
}

Function GenerateHead {
  $HeadHtml = "
    <title>ACL Report</title>
    <style type='text/css'>
      body  { font-family: sans-serif; font-size: 8pt; }

      table { width: 100%; border-collapse: collapse; }
      th    { vertical-align: top; text-align: left; padding: 0px 5px 0px 5px; border-bottom: 1px solid #CCCCCC; }
      td    { vertical-align: top; text-align: left; padding: 0px 5px 0px 5px; }

      div.path    {
        font-size: 10pt;
        font-weight: bold;
        border: 1px solid;
        margin-left: 10px;
        padding-left: 5px;
        background-color:#A0BACB;
      }

      div.expand  {
        font-size: 8pt;
        float: right;
        vertical-align: middle;
      }

      div.access  { 
        font-size: 8pt;
        border-width: 0px 1px 0px 1px; 
        border-style: solid;
        margin-left: 50px;
        padding-left: 5px;
        background-color: #ECFFD7;
      }

      #Container
      {
        margin-left: auto;
        margin-right: auto;
        margin-top: 30px;
        width: 900px;
        text-align: left;
        border: none;
      }
    </style>
    <script type='text/javascript'><!--
      function ShowOrHideBlock(strID) {
        var Element = document.getElementById(strID);
        if ( Element.style.display != 'none' ) { Element.style.display = 'none'; }
        else { Element.style.display = ''; }
      }
    --></script>"

  Return $HeadHtml
}

Function GenerateReport {
  Param( $Folders )

  # Used to id tag div elements for expand / collapse

  $ACLID = 0;
  $FolderID = 0;
  $DivCounter = 0;

  $HTML = New-Object Text.StringBuilder

  For ($CurrentEntry = 0; $CurrentEntry -lt $Folders.Count; $CurrentEntry++)
  {
    $Folder = $Folders[$CurrentEntry]

    # Note the current depth of the folder structure
    $CurrentDepth = $Folder.Depth

    # See if the next folder will be nested within this one
    $NextDepth = 0
    If ($CurrentEntry -lt $Folders.Count) { $NextDepth = $Folders[$CurrentEntry + 1].Depth }

    If ($CurrentEntry -eq ($Folders.Count - 1)) {

      # If this is the last entry prevent it collapsing with the first

      [Void]$HTML.AppendLine("</div>")
      [Void]$HTML.AppendLine("<div id='Folder$FolderID'>")
    } ElseIf ($CurrentDepth -gt $PreviousDepth) {

      # If we're entering a new level write a new div and tag it with a Folder ID

      [Void]$HTML.AppendLine("<div id='Folder$FolderID'>")
      $FolderID++; $DivCounter++
    }

    # Write the Path as a title for this div and override the margin value

    [Void]$HTML.AppendLine("<div class='path' style='margin-left: $($CurrentDepth * 10)px'>Folder $($Folder.FullName)")

    # Allow individual ACL blocks to expand / collapse

    [Void]$HTML.AppendLine("<div class='expand'>ACL: <a href='javascript:ShowOrHideBlock(`"ACL$ACLID`")'>[Show / Hide]</a></div>")

    # If the next folder is nested within this one

    If ($NextDepth -gt $CurrentDepth) {
      [Void]$HTML.AppendLine("<div class='expand'>Sub-Folders: <a href='javascript:ShowOrHideBlock(`"Folder$FolderID`")'>[Show / Hide]</a></div>")
    }

    # Close the path block

    [Void]$HTML.AppendLine("</div>")

    # Get and convert the ACL to HTML

    [Void]$HTML.AppendLine("<div id='ACL$ACLID' class='access'>$(Convert-AclToHtml $(Get-ACL $Folder.FullName))</div>")

    # If the current depth is greater than the next, close off the folder block

    If ($CurrentDepth -gt $NextDepth) {

      # If we are leaving a nested set, close the div

      [Void]$HTML.AppendLine("</div>")
      $DivCounter--
    }

    $ACLID++
    $PreviousDepth = $CurrentDepth
  }

  # If anything else is still open

  For ($i = $DivCounter; $i -gt 0; $i--)
  {
    [Void]$HTML.AppendLine("</div>")
  }

  Return $HTML.ToString()
}

#
# Main code for script
#

# Retrieve all folders beneath specified path to the specified depth

$Folders = Get-ChildItemToLevel -Path $Path -ToDepth $Level | ?{ $_.PsIsContainer }

#
# HTML Generation
#

$BaseHtml = ConvertTo-Html -Head $(GenerateHead)

$Container = "<div id='Container'>
  PLACEHOLDER
</div>"

$BaseHtml = $BaseHtml -Replace "<table>" | ?{ $_ -ne [String]::Empty }
$BaseHtml = $BaseHtml -Replace "</table>", $Container
$BaseHtml = $BaseHtml -Replace "PLACEHOLDER", $(GenerateReport $Folders)

$BaseHtml > $SaveAs

If ($Open) { [Void]([Diagnostics.Process]::Start("$($Env:ProgramFiles)\Internet Explorer\IExplore.exe","$SaveAs")) }

Open in new window

Hey man,

Did you do a some kind of magic to the script or something ? ;) ....... The script now is doing exactly what i want ... Don't bother about the looks and feel of the report as this report is fantastic ... Also, you added the show/hide functionality which makes the report looks more smart.  Also, i noticed when i run the script the error message regarding too long folder names no longer appears, does it mean that you did something to the script to list these long folder names as well ? ... is it possible to inject my company logo and the IT department name into the header of the report ? :)

Thanks Chris.

Cheers.
ASKER CERTIFIED SOLUTION
Avatar of Chris Dent
Chris Dent
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Chris,

I don't have anything else to say but Bravo and claps. :)

I really appreciate all the valuable efforts that you've done so far and i will close this topic for good with 500 Points on the GO.

Excellent !

Thanks

You're welcome :)

Chris
Chris,

One last thing .. lol  i know that i am annoying you but there is a little issue about this logo.gif. I need to permanently inject the logo in the report. In other words, the logo.gif should be always with the report in the same directory in order to see the logo in the report. But if the logo.gif is not the in the same directory so a red X is shown.

Help please :(

You can feed -Logo a full path, e.g. "\\server\share\somelogo.gif" or "c:\wherever\logo.gif". Or a URL like "http://somesite/logo.gif".

I can't embed the image into the HTML file itself I'm afraid so it'll always have to travel or at least be accessible by whoever runs the report.

Is that any good?

Chris
Yeahhh , it is very good idea :) Wow

Thanks Man ... :)