Managing Windows file shares with PowerShell

Lingareddy Chandrakanth Reddy 1 Reputation point
2021-11-12T07:30:33.043+00:00

I have a requirement where my IS Security Team wants us to remove the "Everyone" Group from the shared folders and add the "Authenticated Users" group instead. Our Environment is Windows 2012 and Windows 10 on clients and server-side.

I got the script below from one of the forums but it doesn't work for me. This script does list the folder which has Everyone added in share permission But doesn't remediate the permissions and add the "Authenticated user" instead of "Everyone"

It would be great if someone can please help me achieve this...

Regards,

Chandrakanth.

****Code****

$ComputerList = Get-Content "C:\users\a-lchandrakanthredd\Desktop\Test\Servers.txt"

Invoke-Command -ComputerName $ComputerList -ScriptBlock $ScriptBlock

$ExclusionList = 'ADMIN\$','IPC\$' -join '|'

$ScriptBlock = {

    $ShareList = Get-CimInstance -ClassName Win32_Share |
            Where-Object -FilterScript {
                #keeps only object from the FileSystem
                $PSItem.Path -notmatch '^\w:\\$' -and
                #excludes administrative shares like C$
                $PSItem.Path -match '^\w:\\\.*' -and
                #excludes a custom list
                $PSItem.Name -notmatch $using:ExclusionList
            }

    foreach ($Share in $ShareList) {

        $Filter = "name='{0}'" -f $Share.Name
        $SecuritySettings = Get-WmiObject -Class Win32_LogicalShareSecuritySetting -Filter $Filter
        $Descriptor = $SecuritySettings.GetSecurityDescriptor().descriptor
        $CurrentDacl = $Descriptor.dacl       

        [System.Management.ManagementBaseObject[]]$NewDacl = $CurrentDacl.Where({$_.Trustee.Name -ne 'Everyone'})

        $ComputerName = $env:COMPUTERNAME

        #AccessPermissions
        $accessFlags = @{
            FullControl = 2032127
            Change = 1245631
            Read = 1179817
        }

        #Build the Trustee objects
        $Trustee = ([wmiclass] "\\$ComputerName\root\cimv2:Win32_Trustee").CreateInstance()
        $Trustee.Name = 'Authenticated Users'
        $Trustee.Domain = ''

        # Build the Access Control Entry object
        $Ace = ([wmiclass] "\\$ComputerName\root\cimv2:Win32_ACE").CreateInstance()
        $Ace.AccessMask = $accessFlags['Read']
        $Ace.AceFlags = 3 # ContainerInherit + ObjectInherit
        $Ace.AceType = 0 # 0 Allow, 1 = Deny
        $Ace.Trustee = $Trustee

        [array]::Resize([ref]$NewDacl, $NewDacl.Count + 1)
        $NewDacl[$NewDacl.Count-1] = $Ace

        $Descriptor.dacl = $NewDacl
        $SecuritySettings.SetSecurityDescriptor($Descriptor)
    }
}
Windows Server PowerShell
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
5,389 questions
0 comments No comments
{count} votes

5 answers

Sort by: Most helpful
  1. Georg Matviak 176 Reputation points
    2021-11-12T14:07:25.727+00:00

    Hi there,

    After creating the share, we can view the permissions associated with it by running Get-SmbShareAccess.

    You can use Grant-SmbShareAccess to specify the users or groups we wish to have access to the share as well as what level of access they will have.

    For removing a permission for a file share, you can use the Revoke-SmbShareAccess command. This will remove the permissions for the group we specify with the ­-AccountName parameter.

    You can get more info of the commands from here https://learn.microsoft.com/en-us/powershell/module/storage/get-fileshare?view=windowsserver2019-ps

    https://learn.microsoft.com/en-us/powershell/module/smbshare/new-smbshare?view=windowsserver2019-ps

    ----------

    --If the reply is helpful, please Upvote and Accept it as an answer--


  2. MotoX80 32,076 Reputation points
    2021-11-15T14:34:10.033+00:00

    Try this.

    $ScriptBlock = {
        "Executing on {0}" -f $env:COMPUTERNAME
        $ExclusionList = 'ADMIN\$','IPC\$' -join '|'
        $Shares = Get-SmbShare  | Where-Object -Property Name -notmatch $ExclusionList | Where-Object -Property Path -notmatch '^\w:\\$' 
        "Analyzing these shares...."
        $Shares
        foreach ($Share in $Shares) {    
            $Everyone = Get-SmbShareAccess $Share.Name | Where-Object -Property AccountName -eq everyone
            if ($Everyone) {  
                Revoke-SmbShareAccess $Share.Name -AccountName 'Everyone' -Force
                Grant-SmbShareAccess $Share.Name -AccountName 'Authenticated Users' -AccessRight Full -Force
                "Share {0} has been updated." -f $Share.Name 
            }
        }
        "Complete"
    }
    
    
     $ComputerList = Get-Content "C:\users\a-lchandrakanthredd\Desktop\Test\Servers.txt"
    
     Invoke-Command -ComputerName $ComputerList -ScriptBlock $ScriptBlock
    

  3. Lingareddy Chandrakanth Reddy 1 Reputation point
    2021-11-16T06:24:48.977+00:00

    @MotoX80 : Thanks for the above script it is working as expected but it is not removing and adding the Authenticated user for the sub folders, but to validate those I have written a script wherein it will pull all the shared details which are having everyone permissions, apparently my below script should not pull anything because as we don't have any shares with Everyone permissions.

    But my script is still showing the shares are having the Everyone Permissions.

    0 comments No comments

  4. Lingareddy Chandrakanth Reddy 1 Reputation point
    2021-11-16T06:25:32.607+00:00
    ## Get Folders
    $error.clear()
    $Folders += Get-ChildItem -Path $FolderPath -Directory |  Select-Object Name,FullName,LastWriteTime,Length -ErrorAction SilentlyContinue
    foreach ($err in $Error) {
    $err.Exception.Message | Out-File $ExportPath\AccessDenied.txt -Append
    }
    
    ## Loop through folders
    foreach ($Folder in $Folders){
    
    ## Get access control list
    $Acls = Get-Acl -Path $Folder.FullName -ErrorAction SilentlyContinue
    
    ## Loop through ACL
    foreach ($Acl in $Acls.Access) {
    
    if ($Acl.IdentityReference -notlike "BUILTIN\Administrators" -and $Acl.IdentityReference -notlike "CREATOR OWNER" -and $Acl.IdentityReference -like "everyone" -and $Acl.IdentityReference -notlike "NT AUTHORITY\SYSTEM" -and $Acl.FileSystemRights -notlike "-*" -and  $Acl.FileSystemRights -notlike "268435456"`
    -and $Acl.IdentityReference -notlike "S-1-*"){
    
    ## format properties for result hash table
    $properties = @{
    FolderName = $Folder.Name
    ServerName = $comp
    FolderPath = $Folder.FullName
    IdentityReference = $Acl.IdentityReference.ToString()
    Permissions = $Acl.FileSystemRights
    AccessControlType = $Acl.AccessControlType.ToString()
    IsInherited = $Acl.IsInherited
    }
    $results += New-Object psobject -Property $properties
                        }
                    }
    
                }
            }
        }
    
    #}
    ## Export results
    $results | Select-Object ServerName,FolderName,FolderPath,IdentityReference,Permissions,AccessControlType,IsInherited | 
    Export-Csv -Path $ExportPath\Share_Permissions.csv -NoTypeInformation
    
    0 comments No comments

  5. MotoX80 32,076 Reputation points
    2021-11-16T15:39:51.197+00:00

    Share permissions and file/folder permissions are 2 different things. You asked about share permissions and that's what the script that you posted looks at.

    The share permissions act as a filter to the file/folder permissions. So if the file/folder permissions grant "everyone full", but the share permissions only have "everyone read", then no one will be able to update the files.

    So if the share permissions reference Authenticated Users, then an account that is a member of "everyone", but not "authenticated users", then they will not have any access to the files/folders. From what I remember, if you have Guest account disabled, then everyone is effectively authenticated users.

    If your auditors still want you to update the NTFS permissions, here is a script that I developed to replace one account with another.

    You should test this thoroughly on a test server before you incorporate the code into the script that I first posted.

    Do you know enough about Powershell to merge the 2 scripts?

    #-------------------------------------------------------------------------------------  
    # Script: ReplaceAcl.ps1  
    # Author: Motox80 on Microsoft Technet/Q&A Forums  
    # Notes : No warranty expressed or implied.  
    #         Use at your own risk.  
    # Function: Subinacl.exe is no more.  
    #           Ths script replaces one group with another on a given folder structure     
    #           Only directories are analyzed, not individual files.   
    #--------------------------------------------------------------------------------------  
      
    $Path = 'c:\temp\foo1'                                           # The folder to analyze   
    $LookFor = 'Everyone'                                  # "from" this group    Note \\ is required for -match to work   
    $NewGroup = 'Authenticated Users'                    # "to" this group      Only one \ is needed    
      
    $AllDirs = @()                                                   # Empty array      
    $AllDirs += Get-Item -Path $Path                                 # Add the root directory   
    $AllDirs += Get-Childitem -Directory  -Path $Path -recurse       # Add in all of the subfolders, use -Depth switch to limit how deep we analyze   
                                                                     #                               if you have hundreds of subfolders    
    Foreach ($dir in $AllDirs) {  
        $dir.fullname                                                # Comment out to reduce output   
        $acl = get-acl $dir.FullName    
        $OldAces = $acl.Access                                       # Who has access?  
        $UpdateAcl = $false                                          # Default to not update   
        foreach ($OldAce in $OldAces) {  
                #"Found $($OldAce.IdentityReference) "  
                if ($OldAce.IsInherited -eq $FALSE) {                # There is no need to touch inherited aces   
                    # "  Found uninherited ACE: {0} " -f $OldAce.IdentityReference       # Uncomment if you want to know what we found   
                    if ($OldAce.IdentityReference -match $LookFor) {         # Did we find the guy we're looking for?   
                         #"  It's a match."       
                        # Create new rule with the old rights   
                        $ArgList = $NewGroup, $OldAce.fileSystemRights, $OldAce.InheritanceFlags, $OldAce.PropagationFlags, $OldAce.AccessControlType  
                        $NewAce = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $ArgList  
                                 
                        # Remove old rule, add in new one                  
                        $Acl.SetAccessRule($NewAce)  
                        $Acl.RemoveAccessRule($OldAce) | Out-Null  
                        $UpdateAcl = $true                              # Set flag to do the update   
                    }  
                }  
         }  
      
         if ($UpdateAcl) {  
            "   *** Update ***   {0}" -f $dir.FullName        
            Set-Acl  $dir.FullName $acl  # -WhatIf                  # Update the permissions, remove -whatif to actually apply them    
         }  
    }  
     
    
      
      
      
    
    0 comments No comments