We use cookies to improve your experience.
By your continued use of this site you accept such use.
For more details please see our privacy policy and cookies policy.

Script Repository

User permissions for shares, shared files and folders on server

February 24, 2021 Views: 3778

The script generates and emails a report on permissions granted to a user to access shares and all shared folders and files on a specific server. Using the script, you can, for example, create a custom command to generate such a report on demand. To add the script to your custom command, use the Run a program or PowerShell script action.

Parameters:

  • $computerName - Specifies the fully qualified domain name (FQDN) of the server.
  • $allowPermissionMarker - Specifies an HTML marker for Allow permissions. You need to specify how an HTML table cell for Allow permissions will look like using HTML code.
  • $denyPermissionMarker - Specifies an HTML marker for Deny permissions. You need to specify how an HTML table cell for Deny permissions will look like using HTML code.
  • $to - Specifies a semicolon-spearated list of recipients of the report. You can use value references for a recipient. For example, if you specify %adm-InitiatorEmail%, reports will be sent to the email address of the user who executes the custom command.
  • $subject - Specifies the email message subject.
  • $reportHeader - Specifies an HTML-formatted header of the report.
  • $reportFooter - Specifies an HTML-formatted footer of the report.
    You can use value references in the subject, header and footer. For example, if you specify %name%, the report will include the full name of the user on which the script is executed.
Edit Remove
PowerShell
$computerName = "server.domain.com" # TODO: modify me
$allowPermissionMarker = "<td bgcolor='Green'></td>" # TODO: modify me
$denyPermissionMarker = "<td bgcolor='Red'></td>" # TODO: modify me

# E-Mail settings
$to = "recipient@domain.com;%adm-InitiatorEmail%" # TODO: modify me
$subject = "%name%'s permissions for shares on computer '$computerName'" # TODO: modify me
$reportHeader = "<b>%name%'s permissions for shares on computer '$computerName'</b><br/><br/>"
$reportFooter = "<hr /><p><i>Please do not reply to this e-mail, it has been sent to you for notification purposes only.</i></p>" # TODO: modify me

function GetColumnNumber($column)
{
    if ($columns.ContainsKey($column))
    {
        return $columns[$column]
    }
    
    $columnNumber = $columns.Count
    $columns.Add($column, $columnNumber)
    return $columnNumber
}

# Test connection
if (!(Test-Connection $computerName -Quiet))
{
    $Context.LogMessage("Unable to connect to computer '$computerName'", "Warning")
    return
}

# Get user SID
$trustee = New-Object "System.Collections.Generic.HashSet[System.String]"
$sidByte = $Context.TargetObject.Get("objectSid")
$userSid = New-Object "Softerra.Adaxes.Adsi.Sid" @($sidByte, 0)
[void]$trustee.Add($userSid)

# Get SIDs of groups user belongs to
try
{
    $groupGuidsBytes = $Context.TargetObject.GetEx("adm-MemberOfGuid")
}
catch
{
    $groupGuidsBytes = $NULL
}

if ($groupGuidsBytes)
{
    # Build filter to find all groups
    $filter = New-Object "System.Text.StringBuilder"
    [void]$filter.Append("(|")
    foreach ($guidBytes in $groupGuidsBytes)
    {
        [void]$filter.Append([Softerra.Adaxes.Ldap.FilterBuilder]::Create("objectGuid", $guidBytes))
    }
    [void]$filter.Append(")")
    
    $searcher = $Context.BindToObject("Adaxes://rootDSE")
    $searcher.SearchFilter = $filter.ToString()
    $searcher.SearchScope = "ADS_SCOPE_SUBTREE"
    $searcher.PageSize = 500
    $searcher.ReferralChasing = "ADS_CHASE_REFERRALS_NEVER"
    $searcher.SetPropertiesToLoad(@("objectSid"))
    $searcher.VirtualRoot = $True
    
    try
    {
        $searchResultIterator = $searcher.ExecuteSearch()
        $searchResults = $searchResultIterator.FetchAll()
        
        # Get group SID
        foreach ($searchResult in $searchResults)
        {
            $sidBytes = $searchResult.Properties["objectSid"].Value
            if ($sidBytes -eq $NULL)
            {
                continue
            }
            $sid = New-Object "Softerra.Adaxes.Adsi.Sid" @($sidBytes, 0)
            [void]$trustee.Add($sid)
        }
    }
    finally
    {
        # Release resources used by the search
        $searchResultIterator.Dispose()
    }
}

# Get all shares on the server
$shares = Get-WmiObject -Class Win32_Share -Computer $computerName | WHere {$_.Type -eq 0}
$columns = @{}
$objectsInfo = @{}
foreach ($share in $shares)
{
    $sharePath = "\\$computerName\" + $share.Name
    if (!(Test-Path $sharePath))
    {
        $Context.LogMessage("Cannot verify user permissions for share '$sharePath' probably because of insufficient access rights", "Information")
        continue
    }
    
    # Get permissions for the share
    $aclObjects = @()
    try
    {
        $shareAclObject = Get-Acl $sharePath -ErrorAction Stop
        $aclObjects += $shareAclObject
    }
    catch
    {
        $Context.LogMessage("Unable to get permissions for share '$sharePath'. Error: " + $_.Exception.Message, "Warning")
    }
    
    # Get permissions for child objects
    $childObjects = Get-ChildItem -Path $sharePath -Recurse -ErrorAction SilentlyContinue
    if ($childObjects -ne $NULL)
    {
        foreach ($object in $childObjects)
        {
            try
            {
                $acl = $object | Get-Acl -ErrorAction Stop
            }
            catch
            {
                $objectPath = $object.FullName
                $Context.LogMessage("Unable to get permissions for file or folder '$objectPath'. Error: " + $_.Exception.Message, "Warning")
                
            }
            $aclObjects += $acl
        }
    }
    
    # Get user permissions
    foreach ($aclObject in $aclObjects)
    {
        # Get object path
        $objectPath = Convert-Path $aclObject.PSPath
        
        # Get access rules
        $rules = $aclObject.GetAccessRules($true, $true, [System.Security.Principal.SecurityIdentifier])
        foreach ($rule in $rules)
        {
            if (!($trustee.Contains($rule.IdentityReference.Value)))
            {
                continue
            }
            
            # Add object info
            if (!($objectsInfo.ContainsKey($objectPath)))
            {
                $objectsInfo.Add($objectPath, @{})
            }
            $permissions = $objectsInfo[$objectPath]
            
            # Get File system rights
            $fileSystemRights = $rule.FileSystemRights -split ","
            foreach ($value in $fileSystemRights)
            {
                # Get column number in report
                $columnNumber = GetColumnNumber $value
                
                # Get access control mask
                if ($rule.AccessControlType -eq [System.Security.AccessControl.AccessControlType]::Allow)
                {
                    $type = $allowPermissionMarker
                }
                else
                {
                    $type = $denyPermissionMarker
                }
                
                # Update object info
                if ($permissions.ContainsKey($columnNumber) -and $permissions[$columnNumber] -eq $type)
                {
                    continue
                }
                elseif ($permissions.ContainsKey($columnNumber) -and ($type -eq $denyPermissionMarker))
                {
                    $permissions[$columnNumber] = $type
                }
                elseif (!($permissions.ContainsKey($columnNumber)))
                {
                    $permissions.Add($columnNumber, $type)
                }
            }
        }
    }
}
if ($columns.Count -eq 0)
{
    return
}

# Build report
$htmlTable = "<table border='1' width=100%%><tr><th>Object path</th>"
$columns.GetEnumerator() | Sort-Object Value | %%{$htmlTable += "<th>$($_.Name)</th>"}
$htmlTable += "</tr>"
$objectsInfoSorted = $objectsInfo.GetEnumerator() | Sort-Object Key

foreach ($objectInfo in $objectsInfoSorted)
{
    # Add user permissions to the report
    $objectPath = $objectInfo.Name
    $permissions = $objectInfo.Value
    $recordParts = @("<td></td>") * $columns.Count
    foreach ($columnNumber in $permissions.Keys)
    {
        $type = $permissions[$columnNumber]
        $recordParts[$columnNumber] = $type
    }
    $htmlTable += "<tr><td>$objectPath</td>" + ($recordParts -join "") + "</tr>"
}
$htmlTable += "</table>"

# Send Mail
$html = $reportHeader + $htmlTable + $reportFooter
$Context.SendMail($to, $subject, $NULL, $html)
Comments 0
Leave a comment
Loading...

Got questions?

Support Questions & Answers