I have a typical "Account Unknown" on many files from old/other Windows installations and there are a ton of typical answers everywhere.
However, I'm not looking for typical takeown, subinacl, xcacls or GUI solution. I'd like to change those unknown SIDs to known local SID but maintain permission types and inheritance.

So far the only thing close to what I'm looking for is PowerShell script: http://poshcode.org/2081 wich allows deleting unknown SIDs in network shares. It contains basic logic for finding unknown SIDs but I have yet to find a way to replace SID in FileSystemAccessRule object but I'm not that fluent in PowerShell or .NET.
If I'm not wrong, this article on MS TechNet is suggesting construction of FileSystemAccessRule and that can be accomplished.

Does anyone know if there is a better solution to this? Maybe there is an application, command line tool or cmdlet for this job?

  • 3
    Why eliminate using subinacl when it is actually the right answer?
    – JdeBP
    Feb 4 '12 at 11:45
  • That would work only in cases when unknown accounts can be obtained.
    – AndyDeGroo
    Feb 4 '12 at 16:23
  • Otherwise it would take alot of batch coding to obtain all known accounts and compare them to each ACL. But maybe I can use combination of PowerShell and subinacl
    – AndyDeGroo
    Feb 4 '12 at 16:31
  • @JdeBP Probably because many people still believe that it can be used only up to Windows Server 2003 or Windows XP - the newest version is from mid 2004 (microsoft.com/en-us/download/details.aspx?id=23510). Additionally, IMHO this beast is very complex and very badly documented by Microsoft. However, I have read many articles which explicitly state that it can be used in any client and server version since then, so I'll go this way.
    – Binarus
    Dec 29 '19 at 19:16

In Powershell using Get-Acl and Set-Acl you can modify the ACL by manipulating the SDDL string.

First get the ACL object.

$acl = Get-Acl -Path C:\YourFile.txt

Now get the SDDL string:

$sddl = $acl.sddl

Now you can replace the SID in the string with what you want. This uses a regular expression to update partial matches.

$sddl2 = $sddl -replace "S-1-5-21-[0-9-]+", "ExistingSIDHere"

Then update the ACL object:


Then set the object's ACL:

Set-Acl -AclObject $acl -Path C:\YourFile.txt
  • I think I overlooked SDDL option before. This must be it. The only problem is that your regex trows Invalid regular expression pattern: S-1-5-21-.+?) and after escaping that closing bracket it does not work as intended. I changed pattern to S-1-5-21-[0-9-]+ and it works.
    – AndyDeGroo
    Feb 6 '12 at 6:27
  • @AndyDeGroo Sorry, I didn't test the regex. Glad this worked for you! It was an interesting question :-) Feb 6 '12 at 7:11
  • this solved the problem only partialy, because now it replaces any matched SIDs which can be existing users or well known group SID with domain part like S-1-5-21-{domain}-513 (Domain Users). I noticed this when it replaced owner group SID in SDDL string.
    – AndyDeGroo
    Feb 6 '12 at 7:56
  • @AndyDeGroo Right, either your regex search needs to be more specific or you can enumerate the SIDs and test if they exist and if they don't update the specific ones that don't. Feb 6 '12 at 8:28
  • @AndyDeGroo I liked the question so I wrote a little post about it here. In the post I give you a way to dynamically determine which SID's can't be unresolved. Enjoy. Feb 13 '12 at 4:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.