Zdarza się, że na dysku znajdziesz dzwiwaczny folder, który powstał w trakcie intalacji lub aktualizacji i chcesz go usunąć, ale pojawia się komunikat o braku uprawnień. Jak to? Ja – administrator i brak uprawnień?
Z jakiegoś powodu te „dziwne” foldery są pozabezpieczane! Dobrze się zastanów nim je rzeczywiście usuniesz lub w nich coś pozmieniasz…
No cóż, przyczyna to zwykle zupełnie inny właściciel folderu, brak włączonego dziedziczenia uprawnień i wreszcie brak nadanych uprawnień. Wszystko to można oczywiście naprawić tysiącem kliknięć, ale… można też posłużyć się PowerShellem.
Oto przykład funkcji, którą się posłużyłem – szczegóły poszczególnych kroków niżej:
function Take-Over { [CmdletBinding()] Param($path, $userName) Write-Verbose "Taking-Over: new owner: $newOwner path: $path" $fileSystemRight = [System.Security.AccessControl.FileSystemRights]::FullControl $accessControlType =[System.Security.AccessControl.AccessControlType]::Allow if(Test-Path $path -PathType Container) { $inheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::ContainerInherit $propagationFlag = [System.Security.AccessControl.PropagationFlags]::InheritOnly } else { $inheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::None $propagationFlag = [System.Security.AccessControl.PropagationFlags]::None } $ntAccount = New-Object System.Security.Principal.NTAccount($userName) $newRule = New-Object System.Security.AccessControl.FileSystemAccessRule($ntAccount, $fileSystemRight, $inheritanceFlag, $propagationFlag, $accessControlType) $objACL = Get-ACL $path $objACL.SetAccessRuleProtection($False,$False) $objACL.SetOwner($account) $objACL.AddAccessRule($newRule) Set-ACL $path $objACL }
dfdfd
Po kolei:
- $fileSystemRight = [System.Security.AccessControl.FileSystemRights]::FullControl
tak można odwoływać sie do uprawnień zdefiniowanych w Windows - $accessControlType =[System.Security.AccessControl.AccessControlType]::Allow
Uprawnienia można nadawać lub odbierać, tu wskazujemy, że uprawnienie ma być nadane - if(Test-Path $path -PathType Container)
{
$inheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::ContainerInherit
$propagationFlag = [System.Security.AccessControl.PropagationFlags]::InheritOnly
}
else
{
$inheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::None
$propagationFlag = [System.Security.AccessControl.PropagationFlags]::None
}
w przypadku folderów można zaznaczyć, że uprawnienia mają być dziedziczone na obiekty w folderze. W przypadku włączenia, można jeszcze określać co się ma dziać z aktualnie zdefiniowanymi uprawnieniami, mogą być np w całości zastąpione nowymi uprawnieniami lub dodane - $ntAccount = New-Object System.Security.Principal.NTAccount($userName)
kiedy pracujesz z kontem użytkownika, to należy mieć do tego odpowiedni obiekt – sama nazwa użytkownika to może być za mało… - $newRule = New-Object System.Security.AccessControl.FileSystemAccessRule($ntAccount, $fileSystemRight, $inheritanceFlag, $propagationFlag, $accessControlType)
tutaj tworzy się nowa reguła, która mówi – to konto (użytkownik) ma mieć nadane takie uprawnienie, z takimi opcjami dziedziczenia itp. Ta linijka tylko zdefiniowała obiekt pamięciowy, żadne uprawnienia nikomu nie zostały jeszcze na tym etapie nadane - $objACL = Get-ACL $path
teraz ciekawa rzecz – uprawnienia pliku/katalogu trzeba najpierw przeczytać (tak jak są na dysku), zmodyfikować w pamięci i wreszcie zaaplikować na nowo. Tutaj czytamy aktualne uprawnienia… - $objACL.SetAccessRuleProtection($False,$False)
… włączamy dziedziczenie uprawnień dla tego folderu z folderu nadrzędnego… - $objACL.SetOwner($account)
… zmieniamy właściciela pliku folderu… - $objACL.AddAccessRule($newRule)
… dodajemy uprawnienie zdefiniowane przez regułę utworzoną wcześniej… - Set-ACL $path $objACL
… i na zakończenie aplikujemy/zapisujemy tak przygotowane uprawnienia do pliku/folderu na dysku
A oto jak taką funkcję wywołać, a potem usunąć folder:
$startPath = "F:\371e95404831d50c8f0f60d074f256f6" $newOwner = "Admin" Take-Over -Path $startPath -userName $newOwner -verbose Get-ChildItem -Path $startPath -Recurse | foreach {Take-Over -path $_.FullName -userName $newOwner -verbose} Remove-Item -Path $startPath -Force -Recurse
I podobnie zobaczmy co się po kolei dzieje:
- $startPath = „F:\371e95404831d50c8f0f60d074f256f6”
$newOwner = „Admin”
Najpierw inicjujemy zmienne, dzięki którym łatwiej będzie w przyszłości sparametryzować ten skrypt, żeby wykorzystywać go w różnych sytuacjach - Take-Over -Path $startPath -userName $newOwner -verbose
przejmujemy na własność ten jeden folder… - Get-ChildItem -Path $startPath -Recurse | foreach {Take-Over -path $_.FullName -userName $newOwner -verbose}
… a następnie wszystkie jego podfoldery i podfoldery podfolderów itp. - Remove-Item -Path $startPath -Force -Recurse
na zakończenie – folder jest nasz i można z nim zrobić co się chce – tutaj go usuwam 🙂