This script queries multiple Windows computers for their file shares, and writes this information to a csv file and the screen:
- the share permissions
- the folder permissions of the folder which is shared
- the count of files in this folder and subfolders
- the total file size
This information was chosen because we wanted to know: how many shares do we have? How big are they? Who has permissions for them?

It uses WMI so it can also work with servers running older versions of Windows.

The permissions for a share or folder are formatted as a long string of individual permissions separated by semicolons. This was so that the csv file can contain 1 row per file share. Each permission is made up of the user/group and their permission. If a  permission is a deny then "DENY" appears before the permission, for example:

MYDOMAIN\MyUserName1: DENY FullControl; MYDOMAIN\MyUserName2: ReadAndExecute, Synchronize; BUILTIN\Administrators: FullControl

The parameters are an array of server names and the folder where the output file will be created. The output file name is generated - it appears on the screen.

No particular permissions are needed on the computer where the script runs, but the user account running the script must be an admin on the servers being queried.

I've copied ideas and code from some very clever people...
stej in
Another guy blogging as "big"someone had a great idea which I've used, I can't find his web page now to credit him which I'm sorry about

- No particular rights on the computer the script runs on, just enough to create the csv file
- Administrator rights on the remote computers
- I used Powershell v5, I know it can't run on v2, not tested on v3 or v4

- Copy the file to a computer with powershell v5 installed
- Use Run As to run powershell as a user account with admin rights on the server(s) to be queried
- Type the command as:
Get-SharePermissions.ps1 -Computers MyFileServer -FolderToCreateOutputFile C:\scripts\OutputFiles
Get-SharePermissions.ps1 -Computers MyFileServer1,MyFileServer2,MyFileServer3 -FolderToCreateOutputFile C:\scripts\OutputFiles

- The built-in administrative shares are excluded (C$, ADMIN$ etc)
- The count of files and their total size should be the same as the values shown in Explorer, they both include hidden or system files
- I've put error handling round the files part so the script can record the error and continue, but not for querying the server for its shares. If that fails (firewall, not admin) the script terminates with an error.
- The permissions in the output file just have a space next to the user/group for "special" permissions, just the standard ones appear
- If a username isn't present on the ACE (perhaps because the user was deleted) the SID is used instead.

The snippet below contains the 2 functions which do most of the work, getting the information about the files and permissions.



# Function to recursively get the count and total size of files in a directory 
# Basically copied from stej in 
function Get-FilesTotals { 
    function go($dir$stats) { 
        foreach ($File in $dir.GetFiles()) 
            $stats.Size +$File.Length 
        foreach ($Directory in $dir.GetDirectories()) 
            go $Directory $stats 
    $statistics = New-Object PsObject -Property @{Count = 0; Size = [long]0 } 
    go (New-Object IO.DirectoryInfo $Path$statistics 
    return $statistics 
# Function to return an array of strings in the form "user/group permission" from a Win32_LogicalShareSecuritySetting or Win32_LogicalFileSecuritySetting object 
Function Get-PermissionsFromSecuritySetting { 
    $Permissions = @() 
    foreach ($Ace in $SecuritySettingObject.GetSecurityDescriptor().Descriptor.DACL) { 
        if ($Ace.Trustee.Name -and $Ace.Trustee.Domain) { 
            $UserName = "$($Ace.Trustee.Domain)\$($Ace.Trustee.Name)" 
        } elseif ($Ace.Trustee.Name) { 
            $UserName = $Ace.Trustee.Name 
        } else { 
            $UserName = $Ace.Trustee.SIDString 
        if ($Ace.Acetype -eq 0) { 
            $Permissions +"$UserName`: $($Ace.AccessMask -as [Security.AccessControl.FileSystemRights])" 
        } else { 
            $Permissions +"$UserName`: DENY $($Ace.AccessMask -as [Security.AccessControl.FileSystemRights])" 
    return $Permissions