Jump to content

Recommended Posts

Posted

The server which stored our profiles died recently, so they're all been restored to another. However, in that transition the folder ownership details have all vanished... No problem, I thought, a small bit of c# will do it but no. Windows doesn't let you programatically set the ownership of a folder to anything other than the account the program/script is running in or an administrator.

 

So, has anyone got a quicker way that I can set the directory ownership of 107 profiles rather than me having to manually go through them all?

  • Thanks 1
Posted
Is there not an option in your backup software so you can restore the data with the permissions/ownership intact?

 

Yep, it just doesn't do anything. They get restored without any permissions whatever settings I tick.

 

The permissions isn't an issue, as a script fixes that straight away. But the ownership, that is a pain...

Posted

Could you produce a script that is run by the user when they login?

 

Then the person running the script is the person who needs the ownership.

Posted
SetACL does do ownership changes too, have done it at another site. Have no longer got the automated script I made for it though :(

 

SetACL seems to do the trick. Now just to include it in my existing app, so it does it automatically :)

Posted (edited)

Right, the following c# application seems to do the trick.

 

It can do 2 things - without the 'all' argument, it will add full control permissions to each directory for the user with the account of the same name as that directory. It also then uses SetACLs to set ownership (recursively) to those directories.

 

With the 'all' argument, it will add full control to the System and Domain Admins groups, and remove access to the everyone group, if it exists.

 

So, if this is any use to anyone else, feel free to use it.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Diagnostics;

namespace UserProfilePermissionProvider
{
   class Program
   {
       static void Main(string[] args)
       {
           bool all = false;
           foreach (string s in args)
           {
               if (s == "all")
               {
                   all = true;
               }
           }
           Console.WriteLine("Path: " + Directory.GetCurrentDirectory());
           string[] dirs = Directory.GetDirectories(Directory.GetCurrentDirectory());
           Console.WriteLine(dirs.Length.ToString() + " Directories");
           foreach (string s in dirs)
           {
               string at = "";
               Console.WriteLine(s);
               try {
                   string name = new DirectoryInfo(s).Name;
                   Console.WriteLine("In: " + name);
                   DirectorySecurity dirSec = Directory.GetAccessControl(s);
                   if (all)
                   {
                       at = "SYSTEM";
                       dirSec.AddAccessRule(new FileSystemAccessRule("SYSTEM", FileSystemRights.FullControl, AccessControlType.Allow));
                       at = Environment.UserDomainName + "\\Domain Admins";
                       dirSec.AddAccessRule(new FileSystemAccessRule(Environment.UserDomainName + "\\Domain Admins", FileSystemRights.FullControl, AccessControlType.Allow));
                       at = "Everyone";
                       dirSec.PurgeAccessRules(new NTAccount("Everyone"));
                   }
                   at = Environment.UserDomainName + "\\" + name;
                   dirSec.AddAccessRule(new FileSystemAccessRule(Environment.UserDomainName + "\\" + name, FileSystemRights.FullControl,InheritanceFlags.ObjectInherit,PropagationFlags.InheritOnly,AccessControlType.Allow));
                   
                   at = "SetACL";
                   ProcessStartInfo p = new ProcessStartInfo();
                   p.FileName = "SetACL.exe";
                   p.Arguments = " -silent -on \"" + s + "\" -ot file -actn setprot -op \"dacl:np;sacl:np\" -rec cont_obj -actn setowner -ownr \"n:" + Environment.UserDomainName + "\\" + name + ";s:n\"";
                   Process.Start(p);

                   DirectoryInfo d = new DirectoryInfo(s);
                   d.SetAccessControl(dirSec);
                   Console.WriteLine(name + " set");

               }
               catch (Exception ex)
               {
                   Console.WriteLine("Error: " + ex.Message + " At " + at);
               }
           }
               

       }
   }
}

Edited by localzuk
Changed from SID use to NTAccount use. Removed comment about being untested, as it is now tested. Fix
  • Thanks 2
Posted (edited)
It also then uses SetACLs to set ownership (recursively) to those directories.

 

I did (j)script for this kind of thing a while back. I've got one hooked into the ADUC user object context menu, but the "bulk reset all" script enumerates AD to get user folders and then points SetACL at them like this:

 

'SetACL.exe -on "' + root + '" -ot file -actn setprot -op "dacl:np;sacl:nc" -rec cont_obj -actn setowner -ownr "n:' + SID +';s:y"'

 

"root" is the root of a given user's folder. "SID" is their SID.

 

SetACL does my head in a bit. This is slightly different to yours, maybe that's why I couldn't get it to work with an account name as opposed to a SID.

 

Edit: Having just re-learnt why I made my line:

 

sacl:nc => No Change. I'm skipped changing SACLs (auditing etc.)

SID + ";s:y" => I'm using a SID (was changed to 'y' *after* the account name wasn't working).

 

So it's just the SACL bit that's different. ::shrug:

Edited by PiqueABoo

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now



×
×
  • Create New...