Vous voulez vous approprier tous les profils itinérants Windows XP ? Mais si vous faites ça, les utilisateurs n'auront plus accès à leur profils itinérant et obtiendrons une erreur à l'ouverture de session.
Le profil itinérant possède une
ACL NTFS qui indique que l'utilisateur du profil est le propriétaire du répertoire et des fichiers. L'administrateur ne peut pas accéder à ces fichiers, car il ne figure pas dans l'ACL par défaut. Une
GPO existe pour rajouter le groupe Administrateurs dans l'ACL à la création du répertoire, mais admettons que cette GPO ne s'applique pas ou a été créée après les répertoires.
Le but du jeu est d'ajouter le groupe
Administrateurs dans l'ACL de chaque répertoire. Or, pour modifier une ACL, il faut pouvoir y accéder, ce qui n'est pas le cas... La seule façon est de s'approprier le répertoire (ce qui va remplacer l'ACL existante par une ACL vierge, avec pour seule entrée le nouveau propriétaire). En faisant cela, les utilisateurs n'auront donc plus le droit d'accéder à leur propre profil. Il faut rajouter l'utilisateur dans l'ACL en contrôle total, et ce, récursivement pour les fichiers existants.
Attention : pour que Windows autorise de charger un profil itinérant, même si l'utilisateur a un contrôle total sur tous ses fichiers, il faut que le propriétaire du répertoire soit : soit le compte utilisateur soit le groupe Administrateurs. S'il s'agit d'un autre compte, même le compte
Administrateur, le chargement échouera.
Voici le script powershell :
# répertoire à scanner
$dir = "D:\profils"
$profils = Get-ChildItem -Path $dir -Force -ea 0
$profils | ForEach-Object {
$rep = $_
if($rep.Mode.startsWith('d')) { # on ignore les fichiers
$user = $_.Fullname.Split('\')[2]
$owner = $acl = $null
$acl = $rep.GetAccessControl()
$owner = $acl.Owner
if($owner -ne 'BUILTIN\Administrateurs' -and $owner -ne 'BUILTIN\Administrators') { # le propriétaire n'est pas déjà administrateur, on ne fait rien
echo "$user MAUVAIS OWNER!"
}
else {
$found = $false
$acl.Access|Where-Object{$_.IdentityReference.ToString() -ieq $user}|ForEach-Object{$found=$true} # on vérifie si le répertoire possède déjà l'ACL...
if($found) {
Write-Host -fore gray "$user have rights ($owner)"
}
else {
write-host -fore blue "Il faut ajouter DOMAINE\$user."
$NTuser = New-Object System.Security.Principal.NTAccount("DOMAINE\$user")
$access = [System.Security.AccessControl.FileSystemRights]::FullControl
$heritage = [System.Security.AccessControl.InheritanceFlags]::ContainerInherit -bor [System.Security.AccessControl.InheritanceFlags]::ObjectInherit
$heritagefile = [System.Security.AccessControl.InheritanceFlags]::None
$propa = [System.Security.AccessControl.PropagationFlags]::None
$allow = [System.Security.AccessControl.AccessControlType]::Allow
$ace = New-Object System.Security.AccessControl.FileSystemAccessRule("DOMAINE\$user",$access,$heritage,$propa,$allow) # on cré une ACE pour répertoire
$acefile = New-Object System.Security.AccessControl.FileSystemAccessRule("DOMAINE\$user",$access,$heritagefile,$propa,$allow) # on cré une ACE pour les fichiers
$acl.AddAccessRule($ace)
if(!$?) {
echo "Impossible de créer l'ACL"
}
else { # l'ACL est OK, on l'applique
$rep.SetAccessControl($acl)
if($?) { # on répète récursivement aux fichiers et répertoires déjà existants
echo "Appropriation récursive de $($rep.Fullname)."
$aclfile = $null
Get-ChildItem -Path $rep.FullName -Force -Recurse | ForEach-Object {
if($_.Mode.StartsWith('d')) { # répertoire...
$_.SetAccessControl($acl)
}
else { # fichier...
$aclfile = $_.GetAccessControl() # doit recréer l'ACL à chaque fois pour les fichiers
$aclfile.AddAccessRule($acefile)
$_.SetAccessControl($aclfile)
}
}
Write-Host -fore green "`r`n$user : OK"
}
else {
Write-Host -fore red "`r`n$user : ERR"
}
}
}
}
}
}
Il est utile pour l'administrateur d'avoir accès au contenu des profils pour vérifier les abus de stockage de fichiers (notamment car le contenu du profil est "streamé" à l'ouverture de la session, contrairement au contenu d'un lecteur réseau ou d'une redirection de
Mes documents).