I need to update permissions with adding, editing, and/or removing access rules from ACLs through Powershell. Normally, you would just do something like
$MyACL = Get-Acl
$MyACL.SetAccessRule($SomeNewAccessRule)
Set-Acl -LiteralPath "My Path" -AclObject $MyACL
The problem I have run in to is that the environment my code has to run in lacks the SeTakeOwnershipPrivilege
and Get-Acl
includes the ownership information. When I subsequently run Set-Acl
it fails because it is trying to overwrite the current ownership info, even if it has not changed. I solved this with the following workaround:
$MyAcl = (Get-Item).GetAccessControl("Access")
...
This works because .GetAccessControl("Access")
reads the ACL but excludes both the .Path
and the .Owner
properties and I can then use Set-Acl
without a hitch.
I just found that this no longer works in Powershell 7 and the same line instead throws:
InvalidOperation: Method invocation failed because [System.IO.DirectoryInfo] does not contain a method named 'GetAccessControl'.
It seems that Microsoft has removed this call from Powershell 7 and forward. I cannot seem to remove the .Owner
property from a Get-Acl
object either because it is read-only. How can I read ACLs excluding the .Owner
property in Powershell 7?
What happens is that .GetAccessControl()
was moved from an instance method in .NET Framework to an extension method in .NET, the type that contains it is FileSystemAclExtensions
.
Unfortunately, extension methods don't translate well into PowerShell, so, the equivalent of:
$MyAcl = (Get-Item .).GetAccessControl('Access')
Would be the following in PowerShell 7+:
$MyAcl = [System.IO.FileSystemAclExtensions]::GetAccessControl(
(Get-Item .),
[System.Security.AccessControl.AccessControlSections]::Access)
If you wanted you could also use Update-TypeData
to have a similar functionality:
$updateTypeDataSplat = @{
TypeName = 'System.IO.FileSystemInfo'
MemberName = 'GetAccessControl'
MemberType = 'ScriptMethod'
Value = {
if ($args.Count -eq 0) {
return [System.IO.FileSystemAclExtensions]::GetAccessControl($this)
}
[System.IO.FileSystemAclExtensions]::GetAccessControl(
$this, [System.Security.AccessControl.AccessControlSections] $args[0])
}
}
Update-TypeData @updateTypeDataSplat