diff --git a/Add-RecurseSecurityGroup.ps1 b/Add-RecurseSecurityGroup.ps1 new file mode 100644 index 0000000..1d81d74 --- /dev/null +++ b/Add-RecurseSecurityGroup.ps1 @@ -0,0 +1,153 @@ +<# +.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 \ No newline at end of file