<# .SYNOPSIS Applies an AD security group to all child objects in a specified folder, including those with disabled inheritance. .DESCRIPTION This script recursively processes all files and folders within a specified directory, applying the specified AD security group with the chosen permissions. It handles objects with inheritance disabled and provides detailed logging. .PARAMETER TargetFolder The folder path to process (must be provided) .PARAMETER SecurityGroup The Active Directory security group name to apply (must be provided) .PARAMETER Permission The permission to grant (e.g., "Read", "Modify", "FullControl") - defaults to "Read" .EXAMPLE .\ApplySecurityGroupToFolder.ps1 -TargetFolder "C:\Shared" -SecurityGroup "DOMAIN\File Access" -Permission "Modify" #> param ( [Parameter(Mandatory=$true)] [string]$TargetFolder, [Parameter(Mandatory=$true)] [string]$SecurityGroup, [Parameter(Mandatory=$false)] [string]$Permission = "Read" ) #region Initialization # Create log directory if it doesn't exist $logDir = "C:\Logs\ApplySecurityGroup" if (-not (Test-Path -Path $logDir)) { New-Item -ItemType Directory -Path $logDir -Force | Out-Null } # Set up log file with date format DD-MM-YYYY $logDate = Get-Date -Format "dd-MM-yyyy" $logFile = Join-Path -Path $logDir -ChildPath "ApplySecurityGroup_$logDate.log" # Clear any existing log for today if (Test-Path -Path $logFile) { Clear-Content -Path $logFile } # Function for consistent logging function Write-Log { param ( [string]$Message, [string]$Level = "INFO" ) $timestamp = Get-Date -Format "dd-MM-yyyy HH:mm:ss" $logEntry = "$timestamp $Level`: $Message" # Write to log file Add-Content -Path $logFile -Value $logEntry # Write to console with appropriate coloring switch ($Level) { "INFO" { Write-Host $logEntry -ForegroundColor Green } "WARNING" { Write-Host $logEntry -ForegroundColor Yellow } "ERROR" { Write-Host $logEntry -ForegroundColor Red } default { Write-Host $logEntry } } } # Validate parameters if (-not (Test-Path -Path $TargetFolder)) { Write-Log -Message "Target folder '$TargetFolder' does not exist" -Level "ERROR" exit 1 } try { $group = [System.Security.Principal.NTAccount]($SecurityGroup) $group.Translate([System.Security.Principal.SecurityIdentifier]) | Out-Null } catch { Write-Log -Message "Security group '$SecurityGroup' is invalid or cannot be resolved: $_" -Level "ERROR" exit 1 } $validPermissions = @("Read", "ReadAndExecute", "Write", "Modify", "FullControl") if ($Permission -notin $validPermissions) { Write-Log -Message "Invalid permission '$Permission'. Valid values are: $($validPermissions -join ', ')" -Level "ERROR" exit 1 } #endregion #region Main Processing Write-Log -Message "Starting security group application process" Write-Log -Message "Target Folder: $TargetFolder" Write-Log -Message "Security Group: $SecurityGroup" Write-Log -Message "Permission: $Permission" $fileSystemRights = [System.Security.AccessControl.FileSystemRights]$Permission $inheritanceFlags = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit" $propagationFlags = [System.Security.AccessControl.PropagationFlags]::None $accessControlType = [System.Security.AccessControl.AccessControlType]::Allow $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule( $SecurityGroup, $fileSystemRights, $inheritanceFlags, $propagationFlags, $accessControlType ) $processedItems = 0 $failedItems = 0 # Process folders first $folders = Get-ChildItem -Path $TargetFolder -Recurse -Directory -Force $totalItems = $folders.Count + (Get-ChildItem -Path $TargetFolder -Recurse -File -Force).Count Write-Log -Message "Found $($folders.Count) folders and $($totalItems - $folders.Count) files to process" foreach ($folder in $folders) { try { $acl = Get-Acl -Path $folder.FullName $acl.AddAccessRule($accessRule) Set-Acl -Path $folder.FullName -AclObject $acl Write-Log -Message "Applied permissions to folder: $($folder.FullName)" $processedItems++ } catch { Write-Log -Message "Failed to apply permissions to folder '$($folder.FullName)': $_" -Level "ERROR" $failedItems++ } } # Process files $files = Get-ChildItem -Path $TargetFolder -Recurse -File -Force foreach ($file in $files) { try { $acl = Get-Acl -Path $file.FullName $acl.AddAccessRule($accessRule) Set-Acl -Path $file.FullName -AclObject $acl Write-Log -Message "Applied permissions to file: $($file.FullName)" $processedItems++ } catch { Write-Log -Message "Failed to apply permissions to file '$($file.FullName)': $_" -Level "ERROR" $failedItems++ } } # Summary Write-Log -Message "Processing complete. Successfully processed $processedItems items, $failedItems failures." Write-Log -Message "Total items: $totalItems" Write-Log -Message "Log file created at: $logFile" if ($failedItems -gt 0) { Write-Log -Message "Warning: Some items failed to process. Check the log for details." -Level "WARNING" } #endregion