Preamble
It’s a day before Christmas. Everything is fine. Or so it seems. But suddenly, no one can access their UPM profile.
A quick look at the UPM profile folder, and the CREATOR OWNER permission has been removed accidentally by someone and propagated to all subfolders. The users have been “locked out” from their own profiles.
P1 has been triggered. It’s time to use one of these “magic” PowerShell script to restore the situation quickly.
The script
Now that you have restored the correct permission on the main UPM profile folder and share, which is:
– CREATOR OWNER | Subfolders and Files only | Full Control
– Domain Users | This Folder | Read only + Create Folders
– Domain Admins | This folder and subfolders | Full Control
– SYSTEM | This folder and subfolders | Full Control
And the owner is set to SYSTEM
It is time to propagate this again to all subfolders (user profiles folder) with the following script:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
Try { $Path = "Q:\Profiles" #Start the job that will reset permissions for each file, don't even start if there are no direct sub-files $SubFiles = Get-ChildItem $Path -File If ($SubFiles) { $Job = Start-Job -ScriptBlock {$args[0] | %{icacls $_.FullName /Reset /C}} -ArgumentList $SubFiles } #Now go through each $Path's direct folder (if there's any) and start a process to reset the permissions, for each folder. $Processes = @() $SubFolders = Get-ChildItem $Path -Directory If ($SubFolders) { Foreach ($SubFolder in $SubFolders) { #Start a process rather than a job, icacls should take way less memory than Powershell+icacls $Processes += Start-Process -Wait icacls -WindowStyle Hidden -ArgumentList """$($SubFolder.FullName)"" /Reset /T /C" -PassThru } } #Now that all processes/jobs have been started, let's wait for them (first check if there was any subfile/subfolder) #Wait for $Job If ($SubFiles) { Wait-Job $Job -ErrorAction SilentlyContinue | Out-Null Remove-Job $Job } #Wait for all the processes to end, if there's any still active If ($SubFolders) { Wait-Process -Id $Processes.Id -ErrorAction SilentlyContinue } Write-Host "The script has completed resetting permissions under $($Path)." } Catch { $ErrorMessage = $_.Exception.Message Throw "There was an error during the script: $($ErrorMessage)" } |
And this will run for quite a long time, a couple of hours depending on the number of profiles and the storage / file server performance. It is possible to remove the “-wait” option from the Start-Process, but very carefully as this will create thousands, ten of thousands, of icacls threads. I have seen servers dying under the load and crashing into a BSOD without the “-wait” argument.
Finally the result can be checked manually on each profile folder, and see the inheritance in place. Problem solved, Christmas is saved.
Nice, I like it.