0 votes

We have our user folders set up in an "odd" way - everyone's main user drive is open to everyone, with the exception of a Private subfolder.

Right now I'm using a VBScript that kinda works (but doesn't do everything it's supposed to). I was wondering if there is some way to get this working in either PowerShell or Adaxes itself so that it can be automated and work correctly as we're trying to automate as much of this process as we can (we sometimes get 30+ new hires in a manner of a few weeks for our peak season).

So the folder permissions should look like the following (and nobody wants to change this):

<fileserver>\users\<username> - Domain Users read/modify, Domain Admins read/modify, Backup Operators read (works as designed)
<fileserver>\users\<username>\Private - <username> read/modify, Domain Admins read/modify, Backup Operators read (Domain admins is here so we can place files here from backup or print PDFs of new login info). (works as designed)
<fileserver>\users\<username>\desktop.ini - Needs to be read only for Administrators so the display of <username> doesn't change to "My Documents" in Windows 7. (doesn't work - however if we manually make the file read only, it fixes this issue too, so that would work).

Here is my current script (I didn't write it):

Option Explicit
Dim WSHSHELL, FILESYS, WSHSHELLEXEC, USERDRIVE, COMMAND, USERLOC, SUBINACL, CURRENTDIR, WRITER
'Set Data
Set WSHSHELL = CreateObject("WScript.Shell")
Set FILESYS = CreateObject("Scripting.FileSystemObject")
if WScript.Arguments.Count = 0 then
    WScript.Echo "Missing parameters"
    wscript.exit
end if

USERDRIVE = WScript.Arguments(0)
USERLOC = "\<fileserver>\USERS\" & USERDRIVE
SUBINACL = "\<fileserver>\Users\subinacl.exe"
CURRENTDIR = FILESYS.GetParentFolderName(Wscript.ScriptFullName)
if NOT RIGHT(currentdir, 1) = "\" then
    currentdir = currentdir & "\"
end if

If FILESYS.FolderExists(USERLOC) then
    WScript.Echo "This folder (" & USERDRIVE & ") currently exists.  Please either archive or delete folder."
    WSCRIPT.QUIT
end if

'Create user's home directory
FILESYS.CreateFolder(USERLOC)
'Create user's private folder
FILESYS.CreateFolder(USERLOC & "\Private")

'Set permissions
WRITER = "%COMSPEC% /C " & SUBINACL & " /subdirectories " & USERLOC & " /setowner=""<domain>\Domain Admins"""
COMMAND = WSHShell.Run(WRITER,0, false)
WRITER = "%COMSPEC% /C " & SUBINACL & " /subdirectories " & USERLOC & "\*.* /setowner=""<domain>\Domain Admins"""
COMMAND = WSHShell.Run(WRITER,0, false)

WRITER = "%COMSPEC% /C ECHO Y|CACLS " & USERLOC & " /T /C /G " & USERDRIVE & ":C"
COMMAND = WSHSHELL.Run(WRITER, 0, TRUE)
WRITER = "%COMSPEC% /C ECHO Y|CACLS " & USERLOC & " /T /C /E /G ""Backup Operators"":F"
COMMAND = WSHSHELL.Run(WRITER, 0, TRUE)
WRITER = "%COMSPEC% /C ECHO Y|CACLS " & USERLOC & " /T /C /E /G ""Domain Admins"":F"
COMMAND = WSHSHELL.Run(WRITER, 0, TRUE)
WRITER = "%COMSPEC% /C ECHO Y|CACLS " & USERLOC & " /T /C /E /G ""Domain Users"":C"
COMMAND = WSHSHELL.Run(WRITER, 0, TRUE)
WRITER = "%COMSPEC% /C ECHO Y|CACLS " & USERLOC & " /T /C /E /G SYSTEM:F"
COMMAND = WSHSHELL.Run(WRITER, 0, TRUE)
WRITER = "%COMSPEC% /C ECHO Y|XCOPY " & CurrentDir & "desktop.ini " & USERLOC
COMMAND = WSHSHELL.Run(WRITER, 0, TRUE)
WRITER = "%COMSPEC% /C ECHO Y|CACLS " & USERLOC & "\Private /T /C /G " & USERDRIVE & ":C"
COMMAND = WSHSHELL.Run(WRITER, 0, TRUE)
WRITER = "%COMSPEC% /C ECHO Y|CACLS " & USERLOC & "\Private /T /C /E /G ""Backup Operators"":F"
COMMAND = WSHSHELL.Run(WRITER, 0, TRUE)
WRITER = "%COMSPEC% /C ECHO Y|CACLS " & USERLOC & "\Private /T /C /E /G ""Domain Admins"":F"
COMMAND = WSHSHELL.Run(WRITER, 0, TRUE)
WRITER = "%COMSPEC% /C ECHO Y|CACLS " & USERLOC & "\Private /T /C /E /G SYSTEM:F"
COMMAND = WSHSHELL.Run(WRITER, 0, TRUE)
WRITER = "%COMSPEC% /C " & SUBINACL & " /subdirectories " & USERLOC & " /setowner=""<domain>\" & USERDRIVE & ""
COMMAND = WSHSHELL.Run(WRITER, 0, TRUE)
WRITER = "%COMSPEC% /C " & SUBINACL & " /subdirectories " & USERLOC & "\*.* /setowner=""<domain>\" & USERDRIVE & ""
COMMAND = WSHSHELL.Run(WRITER, 0, TRUE)
'Deny read access to Administrators to desktop.ini to fix file display as My Documents instead of user name.
WRITER = "%COMSPEC% /C " & SUBINACL & " /file " & USERLOC & "desktop.ini /deny=""<domain>\Administrators""=R"
COMMAND = WSHSHELL.Run(WRITER, 0, TRUE)

Set Writer = nothing
Set FILESYS = nothing
Set WSHShell = nothing
by (440 points)
0

Hello,

This can be done in Adaxes with PowerShell scripts. To help you with a solution, we need to ask you a couple of questions for clarification.

At what time is this done? The Private subfolder and the desktop.ini file are usually created by Windows when a user logs on to a Windows session for the first time. So, this should occur not right after the home folder is created. Or is the desktop.ini file copied from some template? If so, where is the source path for the file?

0

This is usually done after we create a new user - the next step is to create their user drive and private subfolder.

For the desktop.ini file we usually just copy in or create a blank text file and rename it to desktop.ini, mark it as read only and hidden.

1 Answer

0 votes
by (216k points)
selected by
Best answer

Hello,

Our script guys have completed the job. Find the PowerShell script that they came up with below. The script creates the user's folder, the Private subfolder, the desktop.ini file and sets appropriate permissions for the folders and the file.

In the script:

  • $userDirectoryPath - specifies the template for the user's directory path,
  • $modifyUserFolder - specifies the groups that should have the Modify permission for the user's folder,
  • $readUserFolder - specifies the groups that should have the Read permission for the user's folder,
  • $modifyPrivateFolder - specifies the groups that should have the Modify permission for the Private subfolder,
  • $readPrivateFolder - specifies the groups that should have the Read permission for the Private subfolder.

Modify it to your requirements.

$userDirectoryPath = "\\server\users\%username%" # TODO: modify me

$modifyUserFolder = @("domain\Domain Users", "domain\Domain Admins") # TODO: modify me
$readUserFolder = @("BUILTIN\Backup Operators") # TODO: modify me
$modifyPrivateFolder = @("domain\Domain Users", "domain\Domain Admins", "domain\%username%") # TODO: modify me
$readPrivateFolder = @("BUILTIN\Backup Operators") # TODO: modify me

# Function to set the Modify permission
function SetModifyPermission($objectName, $folderPath)
{
    $rights = [System.Security.AccessControl.FileSystemRights]"Modify"
    $objType = [System.Security.AccessControl.AccessControlType]::Allow
    $inheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::ContainerInherit
    $propagationFlag = [System.Security.AccessControl.PropagationFlags]::InheritOnly

    $object = New-Object System.Security.Principal.NTAccount($objectName)
    $objACE = New-Object System.Security.AccessControl.FileSystemAccessRule ($object, $rights, $inheritanceFlag, $propagationFlag, $objType)
    $objACL = Get-ACL $folderPath

    try
    {
        $objACL.AddAccessRule($objACE)
    }
    catch
    {
        $Context.LogMessage("The object $objectName does not exist", "Warning")
    }

    Set-ACL $folderPath $objACL
}

# Function to set the Read permission
function SetReadPermission($objectName, $folderPath)
{
    $rights = [System.Security.AccessControl.FileSystemRights]"Read"
    $objType = [System.Security.AccessControl.AccessControlType]::Allow
    $inheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::ContainerInherit
    $propagationFlag = [System.Security.AccessControl.PropagationFlags]::InheritOnly

    $object = New-Object System.Security.Principal.NTAccount($objectName)
    $objACE = New-Object System.Security.AccessControl.FileSystemAccessRule ($object, $rights, $inheritanceFlag, $propagationFlag, $objType)
    $objACL = Get-ACL $folderPath

    try
    {
        $objACL.AddAccessRule($objACE)
    }
    catch
    {
        $Context.LogMessage("The object $objectName does not exist", "Warning")
    }

    Set-ACL $folderPath $objACL 
}

# Give error and exit if the folder already exists
if (Test-Path -Path $userDirectoryPath)
{
    $Context.LogMessage("User folder already exists", "Error")
    return
}

# Create folder for the user
New-Item -Path $userDirectoryPath -Type Directory | Out-Null

# Set the Modify permission for the user's folder
foreach ($objectName in $modifyUserFolder)
{
    SetModifyPermission $objectName $userDirectoryPath
}

# Set the Read permission for the user's folder
foreach ($objectName in $readUserFolder)
{
    SetModifyPermission $objectName $userDirectoryPath
}

# Create the 'Private' subfolder
$subFolderPath = "$userDirectoryPath\Private"
New-Item $subFolderPath -Type Directory | Out-Null

# Set the Modify permission for the 'Private' subfolder
foreach ($objectName in $modifyPrivateFolder)
{
    SetModifyPermission $objectName $subFolderPath
}
# Set the Read permission for the 'Private' subfolder
foreach ($objectName in $readPrivateFolder)
{
    SetModifyPermission $objectName $subFolderPath
}

# Create the 'desktop.ini' file, make it hidden and set appropriate permissions
$filePath = "$userDirectoryPath\desktop.ini"
$file = New-Item $filePath -Type File
$file.attributes="Hidden"

$rights = [System.Security.AccessControl.FileSystemRights]"Read"
$objType = [System.Security.AccessControl.AccessControlType]::Deny
$inheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::None
$propagationFlag = [System.Security.AccessControl.PropagationFlags]::None

$everyone = New-Object System.Security.Principal.NTAccount("Everyone")
$objACE = New-Object System.Security.AccessControl.FileSystemAccessRule ($everyone, $rights, $inheritanceFlag, $propagationFlag, $objType)
$objACL = Get-ACL $filePath
$objACL.SetAccessRuleProtection($True, $True)
$objACL.PurgeAccessRules($everyone)
$objACL.AddAccessRule($objACE)
Set-ACL $filePath $objACL

To execute the script every time a user is created, you need to create a Business Rule that will launch the script and will be executed after creating a user. To do this:

  1. Create a new Business Rule.
  2. On the 2nd step of the Create Business Rule wizard, select User and After Creating a User.
  3. On the 3rd step, add the Run a program or PowerShell script and paste the above script in the Script field.
0

Thanks, I'll have them try it out.

0

Sorry to jump onto an older thread, but this script is exactly what I needed. Can you tell me what I would need to add in order to set the folder owner to be %username%?

Thanks
Ryan

0

Hello Ryan,

We've asked our script guys to modify the script for you. We'll update you as soon as they come up with something.

0

Ryan,

Here you are:

$userDirectoryPath = "\\server\users\%username%" # TODO: modify me

$userFolderPermissions = @{"domain\Domain Users" = "Modify";
                      "domain\Domain Admins" = "Modify";
                      "BUILTIN\Backup Operators" = "Read"} # TODO: modify me

$privateFolderPermissions = @{"domain\Domain Admins" = "Modify";
                          "BUILTIN\Backup Operators" = "Read"} # TODO: modify me

# Function to set permissions
function AddACE($objectName, $permissions, $folderPath, $objACL)
{
$rights = [System.Security.AccessControl.FileSystemRights]$permissions
$objType = [System.Security.AccessControl.AccessControlType]::Allow
$inheritanceFlag = @([System.Security.AccessControl.InheritanceFlags]::ObjectInherit, [System.Security.AccessControl.InheritanceFlags]::ContainerInherit)
$propagationFlag = [System.Security.AccessControl.PropagationFlags]::None

$object = New-Object System.Security.Principal.NTAccount($objectName)
$objACE = New-Object System.Security.AccessControl.FileSystemAccessRule($object, $rights, $inheritanceFlag, $propagationFlag, $objType)

try
{
    $objACL.AddAccessRule($objACE)
}
catch
{
    $Context.LogMessage("The object $objectName does not exist", "Warning")

}

return $objACL
}

# Give error and exit if the folder already exists
if (Test-Path -Path $userDirectoryPath)
{
$Context.LogMessage("User folder already exists", "Error")
return
}

# Create folder for the user
$userFolder = New-Item -Path $userDirectoryPath -Type Directory

# Set permissions for the user's folder
$objACL = Get-ACL $userDirectoryPath
$objACL.SetAccessRuleProtection($True, $False)
foreach ($objectName in $userFolderPermissions.Keys)
{
AddACE $objectName $userFolderPermissions[$objectName] $userDirectoryPath $objACL
}
Set-ACL $userDirectoryPath $objACL

# Set user as the directory owner
$ownerAcl = New-Object "System.Security.AccessControl.DirectorySecurity"
$ownerAcl.SetOwner($userSid)
$userFolder.SetAccessControl($ownerAcl)

# Create the 'Private' subfolder
$subFolderPath = "$userDirectoryPath\Private"
New-Item $subFolderPath -Type Directory | Out-Null

# Set permissions for the 'Private' subfolder
$objACL = Get-ACL $subFolderPath
$objACL.SetAccessRuleProtection($True, $False)
foreach ($objectName in $privateFolderPermissions.Keys)
{
AddACE $objectName $privateFolderPermissions[$objectName] $subFolderPath $objACL
}
Set-ACL $subFolderPath $objACL

# Set permissions for the target user
$userSidBinary = $Context.TargetObject.Get("objectSid")
$userSid = New-Object System.Security.Principal.SecurityIdentifier($userSidBinary, 0)
$acl = Get-ACL $subFolderPath
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule($userSid, "Modify", "ContainerInherit, ObjectInherit", "None", "Allow")
$acl.AddAccessRule($rule)
Set-ACL $subFolderPath $acl

# Create the 'desktop.ini' file, make it hidden and set permissions
$filePath = "$userDirectoryPath\desktop.ini"
$file = New-Item $filePath -Type File
$file.attributes="Hidden"

$rights = [System.Security.AccessControl.FileSystemRights]"Read"
$objType = [System.Security.AccessControl.AccessControlType]::Deny
$inheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::None
$propagationFlag = [System.Security.AccessControl.PropagationFlags]::None

$everyone = New-Object System.Security.Principal.NTAccount("Everyone")
$objACE = New-Object System.Security.AccessControl.FileSystemAccessRule ($everyone, $rights, $inheritanceFlag, $propagationFlag, $objType)
$objACL = Get-ACL $filePath
$objACL.SetAccessRuleProtection($True, $False)
$objACL.PurgeAccessRules($everyone)
$objACL.AddAccessRule($objACE)
Set-ACL $filePath $objACL
0

Thank you so much! You guys are wonderful!

Related questions

0 votes
1 answer

Hi, I need a script that will retrospectively create a sub-folder on file server's shared folder with following permissions: employee his/hers manager (taken from AD) specific ... for more pre-existing users that don't have them. Thanks for any feedback.

asked Nov 3, 2020 by roberttryba (70 points)
0 votes
1 answer

Hello Adaxes Support, is there any way you could help me with a script that changes the permissions on a users home folder? I need to remove the permission to delete the folder and add the permission to delete subfolders and files.

asked Aug 1 by dominik.stawny (280 points)
0 votes
1 answer

I am having an issue with home folder moves between servers. When I move a folder between servers, using Adaxes, the user permissions are lost. I know that this is expected ... to re-assign the user permissions so they can access their home folder again :?:

asked Sep 23, 2014 by rmedeiros (380 points)
0 votes
1 answer

How would a script be written that accomplishes the following task? In this scenario, UserA would be selected with the Modify user action, then UserB would be input to ... rule that runs the script to allow reviewer permissions on UserA's calendar for UserB

asked Dec 6, 2012 by mdeflice (350 points)
0 votes
1 answer

Hi When reading the REST API documentation it does not mention working directly against Azure AD and Exchange Online. Will this be added? Thanks /Peter Sonander

asked Jan 26, 2023 by Sonander (40 points)
3,538 questions
3,229 answers
8,224 comments
547,747 users