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.
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)