• Welcome to Overclockers Forums! Join us to reply in threads, receive reduced ads, and to customize your site experience!

vb/powershell script to modify windows shared folder permissions

Overclockers is supported by our readers. When you click a link to make a purchase, we may earn a commission. Learn More.

I.M.O.G.

Glorious Leader
Joined
Nov 12, 2002
Location
Rootstown, OH
I need a script which given a UNC path will go through each top level folder in that path and set it to inherit permissions from its parent folder. Existing permissions applied explicitly to each directory should remain intact.

Anyone got something similar? I have a directory full of folders named after userid's, and security permission inheritance from parent folders is inconsistent - basically the script I use needs to pound through every top level folder it finds and ensure it is set to inherit permissions from its parent.

I'm going through here and seeing what I might be able to glue together from the bits and pieces:
http://gallery.technet.microsoft.com/ScriptCenter/en-us/

I'll post back here with what I come up with.
 
Everything I've seen seems to point toward the "cacls" utility. Here's a page that describes using xcacls.vbs to set inheritance: http://mcpmag.com/articles/2006/08/01/cacls-catastrophe.aspx

Once you've downloaded xcacls, you might try something like the following:
Code:
cscript c:\windows\xcacls.vbs //path/to/parent/dir/* /s /i ENABLE

[disclaimer]I'm absolutely not a windows sysadmin, nor have I used these utilities, ever. I'd test that command out somewhere less than critical first.[/disclaimer]

/EDIT: One wonders if the utility isn't pronounced "cackles" as in "Steve Ballmer cackles as your carefully set permissions disappear."
 
Last edited:
It is pronounced cackles. :)

That's definitely what I'll be using, except the icacls version rather than xcacls... icacls is more robust/current/better to use for whatever reason. I haven't looked into the specifics.

That part I'm familiar with, but scripting the part where I gather the list of directories and cycle through each folder to set permissions isn't something I've done personally before. Typically we have scripts which do the magic for us, but I don't have one for this specific purpose yet. It's not real complicated I know, but I also don't have any scripting skills to speak of.

I know powershell can likely make short work of it, and straight vbscript is probably the harder way to do the same thing, but I need to look at the specifics when I have time.
 
The scanning through and finding directories is what I was hoping to avoid, tbh :) The /s switch in the command above tells it to apply the change to all subdirectories of the chosen path but no further. Between that and the * wildcard at the end of the path, it should select all subdirectories (as well as files, I think) of //path/to/parent/dir/ and apply the inherit bit to their subdirectories. That could just be an over-optimistic parsing of the docs, though.
 
The following JScript might help (JScript makes waaay more sense to me than VBScript):

Code:
function get_subdirs(path)
{
    // Returns an array of subdirs in path.
    // Param 'path' should be a string.
    //
    // ** NOTE: Backslashes in path need to be escaped, 
    //  as per normal JScript syntax.  Double each backslash in the path
    var dirs = new Array();
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    // Make sure the path is a dir.
    if( !fso.FolderExists(path) )
        return dirs;
    var dir = fso.GetFolder(path);
    
    f_enum = new Enumerator(dir.SubFolders);
    for( ; !f_enum.atEnd(); f_enum.moveNext() )
        dirs.push(f_enum.item());

    return dirs;
}

For a test, this displays a dialog showing all the subdirs in C:\
Code:
WScript.Echo(get_subdirs("C:\\").join("\n"));
 
Here's a vbscript version that I made that parses through a directory.

Code:
Option Explicit

Call Main()

Sub Main()

	Dim objFSO
	Set objFSO = CreateObject("Scripting.FileSystemObject")

	'Get the path, could also prompt for it
	Dim strRootPath
	'strRootPath = InputBox("Enter a path.")
	strRootPath = "C:\Temp\"
	
	Dim objRootFolder
	If objFSO.FolderExists(strRootPath) = False Then
		MsgBox "Root Path does not exist."
		Set objFSO = Nothing
		Exit Sub
	Else
		Set objRootFolder = objFSO.GetFolder(strRootPath)
	End If
	
	Call GetChildNodes(objRootFolder)
	
	Set objRootFolder = Nothing
	Set objFSO = Nothing

End Sub

Sub GetChildNodes(InFolder)

	Dim objChildren, objFolder
	Set objChildren = InFolder.SubFolders
	For Each objFolder In objChildren
		'MsgBox "Looking at: " & objFolder.Name
		Call GetChildNodes(objFolder)		
	Next
	Set objChildren = Nothing

End Sub
 
Thanks for the suggestions. I ended up going a different route which requires very few lines of code.

Instructions

  1. Map a drive to the folder containing the users home directories
  2. Place homedir.cmd, changeuseracl.cmd, and icacls.exe in the root of the mapped folder
  3. Open a command prompt window and change to the drive you just mapped
  4. Run homedir.cmd
  5. ????
  6. profit!?!?

The code this runs is in 2 files. One file to do the looping, one file to do the icacls magic:

homedir.cmd (looping thru directories)
Code:
::USAGE homedir.cmd
::This script should be run from the users directory on the file server.

@echo off

:: all my users directories are in the root of the mapped drive
:: and match their username
set userdir=H:
cd %1

:: loop through all user directories and run 
:: the script that changes permissions

for /d %%a in (*) do (call \\servername\sharedfoldername\changeuseracl.cmd %%a)

changeuseracl.cmd (does the icacls magic):

Code:
::changeuseracl.cmd

@echo off

set uuid=%1
set uuid2=%1:(OI)(CI)(F)

TITLE Changing Permissions on %userdir%\%uuid% 
:: make sure permissions on the user directory are set 
:: according to Microsoft’s documentation before running script.
:: reset all permissions on folder to only inherited permissions. 
echo icacls %userdir%\%uuid% /reset /t /c 
icacls %userdir%\%uuid% /reset /t /c 
:: give each user full control over their directory 
echo icacls %userdir%\%uuid% /grant %uuid2% /t /c
icacls %userdir%\%uuid% /grant %uuid2% /t /c

Use this at your own risk - I tested it and it seemed to work. If it blows up, I'll be posting my resume for a new job tomorrow.
 
Thanks for the suggestions. I ended up going a different route which requires very few lines of code.

Instructions

  1. Map a drive to the folder containing the users home directories
  2. Place homedir.cmd, changeuseracl.cmd, and icacls.exe in the root of the mapped folder
  3. Open a command prompt window and change to the drive you just mapped
  4. Run homedir.cmd
  5. ????
  6. profit!?!?

The code this runs is in 2 files. One file to do the looping, one file to do the icacls magic:

homedir.cmd (looping thru directories)
Code:
::USAGE homedir.cmd
::This script should be run from the users directory on the file server.

@echo off

:: all my users directories are in the root of the mapped drive
:: and match their username
set userdir=H:
cd %1

:: loop through all user directories and run 
:: the script that changes permissions

for /d %%a in (*) do (call \\servername\sharedfoldername\changeuseracl.cmd %%a)

changeuseracl.cmd (does the icacls magic):

Code:
::changeuseracl.cmd

@echo off

set uuid=%1
set uuid2=%1:(OI)(CI)(F)

TITLE Changing Permissions on %userdir%\%uuid% 
:: make sure permissions on the user directory are set 
:: according to Microsoft’s documentation before running script.
:: reset all permissions on folder to only inherited permissions. 
echo icacls %userdir%\%uuid% /reset /t /c 
icacls %userdir%\%uuid% /reset /t /c 
:: give each user full control over their directory 
echo icacls %userdir%\%uuid% /grant %uuid2% /t /c
icacls %userdir%\%uuid% /grant %uuid2% /t /c

Use this at your own risk - I tested it and it seemed to work. If it blows up, I'll be posting my resume for a new job tomorrow.

Lol that is how you know you are doing a good job coding, when what you are trying to do risks blowing up a network or server or both ;)

Good luck with the script though!
 
Back