TUTOS.EU

PowerShell - gerer les ACL

Comment gerer en powershell la securite sur les repertoires et fichiers

PowerShell - gerer les ACL ./videos/43powershellacl.flv

Télécharger la vidéo: clic droit ici

Un premier exemple simple pour lister les droits sur C:\Program Files

get-acl "C:\Program Files" | select -expand access | Out-GridView
Lien vers le fichier : cliquez ici

Ici on désactive l'héritage sur le répertoire D:\Test sans perdre les droits en place, cad que les droits hérités seront traduits en droits explicites

Clear-Host
$acl = get-acl "D:\Test"
$acl.SetAccessRuleProtection($true,$true) #desactiver l'heritage
$acl |Set-Acl #Appliquer les droits
Lien vers le fichier : cliquez ici

Ici on active l'héritage sur le répertoire D:\Test
Les droits qui étaient en place resteront. Il va donc s'ajouter les droits hérités, ce qui peut faire doublon.

Clear-Host
$acl = get-acl "D:\Test"
$acl.SetAccessRuleProtection($false,$false) # activer l'heritage
$acl |Set-Acl #Appliquer les droits
Lien vers le fichier : cliquez ici

Note sur SetAccessRuleProtection

SetAccessRuleProtection utilise 2 paramètres :

  • Le premier paramètre,  isProtected, supprime l'héritage si on est à $true. On se protège de l'héritage. Cela réactive l'héritage si la valeur est $false.
  • Le deuxième paramètre, PreserveInheritance, permet de conserver les règles dont on héritait si la valeur est $true

Donner les droits de lecture à robert sur D:\Test

Clear-Host
$acl = get-acl "D:\Test"

#Paramètres dans l'ordre : Le compte, FileSystemRights (Read, ReadAndExecute, Write, Modify, ListDirectory, FullControl etc), InheritanceFlags (ContainerInherit None ou ObjectInherit), PropagationFlags (InheritOnly, None ou NoPropagateInherit) , AccessControlType (Allow, Deny)
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("robert","ReadAndExecute", "ContainerInherit, ObjectInherit", "None", "Allow")
$Acl.addAccessRule($rule) #ajout de la régle

$acl |Set-Acl #Appliquer les droits
Lien vers le fichier : cliquez ici

Extraction des droits avec un code sur plusieurs ligne et en utilisant une fonction

Clear-Host

#Valeurs nécessaire dans tous les cas
$ObjectToProcess = "C:\Program Files"

function ListACL(){
	param([string]$ObjectToProcess)

	#On recupere les droits de l objet a traiter
	$objACL = Get-ACL $ObjectToProcess

	foreach ($MySubACL in $objACL.Access)
	{
		Write-Host "___________________________"
		Write-Host $MySubACL.IdentityReference
		Write-Host $MySubACL.AccessControlType
		Write-Host $MySubACL.FileSystemRights
		Write-Host $MySubACL.IsInherited
		Write-Host $MySubACL.PropagationFlags
	}
}

ListACL  -ObjectToProcess $ObjectToProcess
Lien vers le fichier : cliquez ici

Il est possible de stocker les résultats dans un objet perso comme ici avec ListeACL

clear-host
$MesACLs = get-acl "C:\"

$ListeACL = @()

ForEach ($OneACL in $MesACLs.Access) {
    $OneAclResult = New-Object -TypeName PSObject
    $MaVariable = [string] $OneACL.IdentityReference
    $OneAclResult | Add-Member -Type NoteProperty -Name IdentityReference -Value $OneACL.IdentityReference #$MaVariable
    $OneAclResult | Add-Member -Type NoteProperty -Name FileOneAclResultRights -Value $OneACL.FileOneAclResultRights
    $OneAclResult | Add-Member -Type NoteProperty -Name IsInherited -Value $OneACL.IsInherited
    $OneAclResult | Add-Member -Type NoteProperty -Name AccessControlType -Value $OneACL.AccessControlType
    $OneAclResult | Add-Member -Type NoteProperty -Name InheritanceFlags -Value $OneACL.InheritanceFlags
    $ListeACL += $OneAclResult
}

$ListeACL | Format-Table
$ListeACL | Where-Object {$_.IdentityReference -match "adm"} | Format-Table
Lien vers le fichier : cliquez ici

Ici on liste les objets non résolus. Il y a des chances que cela correspond a des comptes supprimés, qui n'existent plus

Clear-Host

#Valeurs nécessaire dans tous les cas
$ObjectToProcess = "d:\test"

function DelUnknowACL(){
	param([string]$ObjectToProcess)

	#On recupere les droits de l objet a traiter
	$objACL = Get-ACL $ObjectToProcess

	$AclModifiee = 0
	foreach ($MySubACL in $objACL.Access)
	{
		if ($MySubACL.IsInherited -ieq $false){
			$NomACLenAccess = [String]$MySubACL.IdentityReference 
			if ($NomACLenAccess.substring(0,9) -ieq "S-1-5-21-"){
				Write-Host "___________________________"
				Write-Host $MySubACL.IdentityReference
				Write-Host $MySubACL.AccessControlType
				Write-Host $MySubACL.FileSystemRights
				Write-Host $MySubACL.IsInherited
				Write-Host $MySubACL.PropagationFlags

				$objACL.RemoveAccessRule($MySubACL)
				$AclModifiee = 1
				Write-Host "$MySubACL.IdentityReference retiré des accès de $ObjectToProcess"
			}	
		}
	}

	if ($AclModifiee -ieq 1){
	#On applique les droits sur le répertoire/objet
	Set-ACL $ObjectToProcess $objACL	
	}
}

DelUnknowACL  -ObjectToProcess $ObjectToProcess
Lien vers le fichier : cliquez ici

Ici un exemple de script qui permet au choix d'ajouter ou supprimer un droit

Clear-Host

#Valeurs nécessaire dans tous les cas
$ObjectToProcess = "C:\d"
$Operation = "del"
$UserNameToProcess = "Tout le monde"

#Valeurs supplémentaires nécessaires pour un ajout
$FileSystemRightsValue = "Modify, Synchronize"
$InheritanceFlagsValue = "ContainerInherit, ObjectInherit"
#Valeurs par défaut que l'on peut décommenter et modifier au besoin
#$PropagationFlagValue = "None"
#$objAccessControlTypeValue = "Allow"

function ModifyACL(){

	param([string]$ObjectToProcess, [string]$Operation, [string]$UserNameToProcess, [string]$FileSystemRightsValue = "Modify, Synchronize", [string]$InheritanceFlagsValue = "ContainerInherit, ObjectInherit", [string]$PropagationFlagValue = "None", [string]$objAccessControlTypeValue = "Allow")

	#On recupere les droits de l objet a traiter
	$objACL = Get-ACL $ObjectToProcess

	switch ($Operation) 
	{ 
		"add" {

			#On prealable, on retirer tous les anciens accès de ce compte
			foreach ($MySubACL in $objACL.Access)
			{
				#					Write-Host "___________________________"
				#				    Write-Host $MySubACL.AccessControlType
				#					Write-Host $MySubACL.FileSystemRights
				#					Write-Host $MySubACL.IsInherited
				#					Write-Host $MySubACL.PropagationFlags
				#					Write-Host $MySubACL.InheritanceFlags.value__
				#					Write-Host $MySubACL.IdentityReference

				if ($MySubACL.IdentityReference -eq $UserNameToProcess){
					#						$objUserToDelete = New-Object System.Security.Principal.NTAccount($UserNameToProcess) 
					#
					#						$objACEToDelete = New-Object System.Security.AccessControl.FileSystemAccessRule `
					#						($objUserToDelete, $MySubACL.FileSystemRights, $MySubACL.InheritanceFlags, $MySubACL.PropagationFlags, $MySubACL.AccessControlType)
					#						$objACL.RemoveAccessRule($objACEToDelete)

					#Si l'objet n'est pas hérité
					if ($MySubACL.IsInherited -eq $false){
						$objACL.RemoveAccessRule($MySubACL)
						Write-Host "Ancienne référence retirée"
					}
				}
			}
			#Maintenant on donne les accès au compte voulu
			$objUser = New-Object System.Security.Principal.NTAccount($UserNameToProcess) 
			#$FileSystemRights = [System.Security.AccessControl.FileSystemRights]"ReadAndExecute, Synchronize"
			$FileSystemRights = [System.Security.AccessControl.FileSystemRights]$FileSystemRightsValue
			$InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]$InheritanceFlagsValue
			$PropagationFlag = [System.Security.AccessControl.PropagationFlags]::$PropagationFlagValue
			$objAccessControlType =[System.Security.AccessControl.AccessControlType]::$objAccessControlTypeValue

			$objACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
			($objUser, $FileSystemRights, $InheritanceFlag, $PropagationFlag, $objAccessControlType) 

			$objACL.AddAccessRule($objACE)
			Write-Host "$UserNameToProcess ajouté aux accès de $ObjectToProcess"
		} 
		"del" {
			foreach ($MySubACL in $objACL.Access)
			{
				if ($MySubACL.IdentityReference -eq $UserNameToProcess){
					#						$objUserToDelete = New-Object System.Security.Principal.NTAccount($UserNameToProcess) 
					#
					#						$objACEToDelete = New-Object System.Security.AccessControl.FileSystemAccessRule `
					#						($objUserToDelete, $MySubACL.FileSystemRights, $MySubACL.InheritanceFlags, $MySubACL.PropagationFlags, $MySubACL.AccessControlType)
					#						$objACL.RemoveAccessRule($objACEToDelete)

					#Si l'objet n'est pas hérité
					if ($MySubACL.IsInherited -eq $false){
						$objACL.RemoveAccessRule($MySubACL)
						Write-Host "$MySubACL.IdentityReference retiré des accès de $ObjectToProcess"
					}

				}
			}			
		} 
		default {"Operation is not recognized"}
	}

	#On applique les droits sur le répertoire/objet
	Set-ACL $ObjectToProcess $objACL
}

#Suivant qu'on demande un ajout ou une suppression
switch ($Operation) 
{ 
	"add" {
		#Pour un ajout
		#			$AllChildObjectToProcess = Get-ChildItem $ObjectToProcess -recurse | Where-Object {$_.Attributes -eq "Directory"}
		#			foreach ($OneObject in $AllChildObjectToProcess){
		#				ModifyACL -ObjectToProcess $OneObject.FullName -Operation $Operation -UserNameToProcess $UserNameToProcess -FileSystemRightsValue $FileSystemRightsValue -InheritanceFlagsValue $InheritanceFlagsValue
		#			}
		ModifyACL -ObjectToProcess $ObjectToProcess -Operation $Operation -UserNameToProcess $UserNameToProcess -FileSystemRightsValue $FileSystemRightsValue -InheritanceFlagsValue $InheritanceFlagsValue
	}			
	"del" {
		#Pour une suppression
		ModifyACL -ObjectToProcess $ObjectToProcess -Operation $Operation -UserNameToProcess $UserNameToProcess
		$AllChildObjectToProcess = Get-ChildItem $ObjectToProcess -recurse #| Where-Object {$_.Attributes -eq "Directory"}
		foreach ($OneObject in $AllChildObjectToProcess){
			ModifyACL -ObjectToProcess $OneObject.FullName -Operation $Operation -UserNameToProcess $UserNameToProcess
		}
	}			
}
Lien vers le fichier : cliquez ici