2

In need to get the ACL object and replace an Access.IdentityReference.Value and keep the rest of the object intact so I can apply the Set-Acl to another system.

$acl = Get-Acl -Path "C:\Temp"
$h = New-Object -TypeName PSObject
ForEach-Object -InputObject $acl -Process {
    if ($_.Access.IdentityReference.Value -contains "BUILTIN\Users") {
        "found"
        $h += @($_.Access.IdentityReference.Value.Replace("BUILTIN\Users", "new\name"))
    } else {
        $h += @($_)
    }
}
$h.Access

I have so many ways to do this and the best I have been able to get is finding and replacing the target value but losing the rest of the original object.


Edit: when I try this code:

$acl = Get-Acl -Path 'C:\Temp'

$ace = $acl.Access | Where-Object { $_.IdentityReference -eq 'BUILTIN\Users' }
$newAce = New-Object System.Security.AccessControl.FileSystemAccessRule (
    'new\name',
    $ace.FileSystemRights,
    $ace.InheritanceFlags,
    $ace.PropagationFlags,
    $ace.AccessControlType
)
$acl.RemoveAccessRule($ace)
$acl.AddAccessRule($newAce)

Set-Acl -Path 'C:\Temp' -AclObject $acl

I'm getting the following error:

Exception calling "AddAccessRule" with "1" argument(s): "Some or all identity
references could not be translated."
At line:12 char:1
+ $acl.AddAccessRule($newAce)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
     + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
     + FullyQualifiedErrorId : IdentityNotMappedException

Edit2: New script, but not quite there yet:

$Ssid = "S-1-5-21-2214593661-3374179426-1523454523-1133"
$Tsid = "S-1-5-21-2227185791-3254421074-497073356-1005"
$Spath = "\\clw01\dept\CLW_Site"
$Tpath = "\\clw03\dept\CLW_Site"

$acl = Get-Acl -Path $Spath

$ace = $acl.Access | Where-Object { $_.IdentityReference -eq $Ssid }
$newAce = New-Object System.Security.AccessControl.FileSystemAccessRule (
    $Tsid,
    $ace.FileSystemRights,
    $ace.InheritanceFlags,
    $ace.PropagationFlags,
    $ace.AccessControlType
)
$acl.RemoveAccessRule($ace)
$acl.AddAccessRule($newAce)

Set-Acl -Path $Tpath -AclObject $acl

I'm getting the following error:

Exception calling "AddAccessRule" with "1" argument(s): "The trust relationship
between the primary domain and the trusted domain failed."
At line:9 char:1
+ $acl.AddAccessRule($newAce)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SystemException
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
David C
  • 21
  • 3
  • Is `new\name` actually resolvable on the computer? Is `new` a different host? A trusted domain? External or in the same forest? – Ansgar Wiechers Dec 19 '16 at 19:32
  • no, it is not resolvable on the computer it is running on, but it would be on the local computer that has the local group. Basically we have server1 (old server), server2(new server) and AdmWs1(workstation running the script). Server1 has many folders with local groups permissions to them, I need to copy the folders and local groups to server2, then copy the ACLs – David C Dec 19 '16 at 19:52
  • It must be resolvable on the computer where you're running the code, otherwise it's not going to work. If you want to change a local group on a remote host you may want to run the code remotely, e.g. via `Invoke-Command`. – Ansgar Wiechers Dec 19 '16 at 19:56
  • Or reference the local group by SID? – David C Dec 19 '16 at 20:32
  • You can try, but I'm not sure it'll work. – Ansgar Wiechers Dec 19 '16 at 21:06
  • I tried the invoke-command and the with a get-acl | set-acl and it still put the sid form the server1 on to server2.. I had hope for that because it translates the sid to the screen. – David C Dec 19 '16 at 22:03
  • See Dave Wyatt's solution here: https://powershell.org/forums/topic/set-acl-on-resource-cross-trusted-forest/ – JohnLBevan Aug 20 '19 at 20:07

1 Answers1

1

You can't replace the identity reference on an existing ACE, you need to replace the entire ACE with a new one.

$acl = Get-Acl -Path 'C:\Temp'

$ace = $acl.Access | Where-Object { $_.IdentityReference -eq 'BUILTIN\Users' }
$newAce = New-Object System.Security.AccessControl.FileSystemAccessRule (
    'new\name',
    $ace.FileSystemRights,
    $ace.InheritanceFlags,
    $ace.PropagationFlags,
    $ace.AccessControlType
)
$acl.RemoveAccessRule($ace)
$acl.AddAccessRule($newAce)

Set-Acl -Path 'C:\Temp' -AclObject $acl
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328