The object of this is to add it to a larger script in order to create a new user. Part of the new user script will be setting up their “U:\” drive. Which is a file share on a server where they only have access. So let’s start. GPO does the share creation so that part we will not be doing, instead, I have a special treat for you at the end of this.
What do we need? That’s a fantastic way to start just about any script. We need to start a path to the server we intend to add the directory to. We also need the samAccountName for this to work. Let’s build those out now.
$baselevel = '\\File Server\Share\Drives\' $User = Get-ADUser USERNAME
Now let’s build our directory name. Which will be our $baselevel and our $User, but not all of users. When we used Get-ADUser above it returned all of these results inside the $User variable. We only need to grab one of these and that is SamAccountName. To do that we can easily just give that data to a new variable.
When we We are going to dot(.) source it. Here’s what I mean.
$samAccount1 = $User.SamAccountName
You can see that the new $samAccount1 has the correct username associated with it now, pulled from AD directly.
Let’s concatenate the new folder like shown above.
$newFolderFull = $baselevel+$samAccount1
Done, the hardest part is complete. Normally when I am building a new script I like having my variables written out using Write-Host for verification.
#Visual Verification Write-Host Full Directory Path: $newFolderFull Write-Host Write-Host User Account: $samAccount1 Write-Host Write-Output Creating Directory.. $newFolderFull Write-Host
Once we can see that our variable assignations are all correct we need to build out creating the directory. There are a countless number of ways to create a directory. I use New-Item as shown below. We used New-Item and the path \\File Server\Share\Drives\anewingham and told it to create a new item with the type “Directory”
New-Item $newFolderFull -ItemType Directory
The directory is created, what is next? We now need to give them access to this directory. In the organization, I am in I have it set to a specific directory. With which the default accounts do not get automatically added to each subdirectory so I do not have to remove the “creation” permissions from the newly-created directory. Next, we are going to be modifying the R/W attributes using Get-ACL and Set-ACL.
Microsoft’s Description: The Get-Acl cmdlet gets objects that represent the security descriptor of a file or resource. The security descriptor contains the access control lists (ACLs) of the resource. The ACL specifies the permissions that users and user groups have to access the resource. Beginning in Windows PowerShell 3.0, you can use the InputObject parameter of Get-Acl to get the security descriptor of objects that do not have a path.
So all of that said, how do we need to use it in this instance? We assign it’s output to a variable for later consumption.
$Acl = Get-Acl "$newFolderFull"
You might be asking yourself what data is inside $Acl. Glad you asked! (This is a local drive I looked up so permissions do not match our file server)
Next we need to set the appropriate permissions. To continue, we assign these values to a variable for later use, $AccessRequest
$AccessRequest = New-Object System.Security.AccessControl.FileSystemAccessRule("$samAccount1", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow")
Above we create the variable $AccessRequest. We create a new object inside it. Supplying it with the information to provide my account full control to the directory. It is important to note you can get a
$AccessRequest = New-Object System.Security.AccessControl.FileSystemAccessRule ("user","FullControl","Allow")
The issue with the above command is it creates “Special Permissions” and does not modify the Permissions we need. So we add “ContainerInherit,ObjectInherit”, “None”, and that command is completed. You might be asking youself what does the $AccessRequest variable look like now? Let’s take a peek.
Now that things are looking up and up, we are going to set the access rule on the $Acl variable. To do that we dot(.) source it again, but this time differently. It is important to know that we are not actually making any changes to the ACL yet, this is all still prep work.
$Acl.SetAccessRule($AccessRequest)
That’s it, we are almost done. You might be asking yourself, how does this merge the new permissions with the old permissions? We know this because if you run:
$acl.SetAccessRule
You will notice that the “System.Security.AccessControl.FileSystemAccessRule” is a “rule“. Not only is it a rule, but it is using the same “System.Security.AccessControl.FileSystemAccessRule” that we used in $AccessRequest.
Now that all of the prep work is squared away we are ready to finally change the ACL on this directory. We do that with this command:
Set-Acl "$newFolderFull" $Acl
The Set-Acl cmdlet changes the security descriptor of a specified item we tell it the target is $newFolderFull and the new ACL we want to set is $Acl. Now that the directory and ACL are set for the new user we are done. Or are we? Let us add some verification to the script at the end. Let’s verify the directory is valid to start. To do that we will use an if statement. In the If we will run Test-Path. Test-Path comes back with $True/$False so it’s perfect to use here.
if (Test-Path $newFolderFull) {
If the new directory is there = $True. If $True = True then let’s build a new COM object and this one, in particular, is a Shell.Application.
$o = new-object -com Shell.Application
Next we define the directory like so:
$folder = $o.NameSpace("$newFolderFull")
Lastly we tell PowerShell to open the Properties of the directory using dot(.) sourcing and Self.InvokeVerb. If we use Verbs() method to FolderItem object we can get a list of applicable verbs. I found this to be a very valuable resource: https://devblogs.microsoft.com/scripting/use-powershell-to-work-with-windows-explorer/
$folder.Self.InvokeVerb("Properties")
The above command lastly opens the properties of our $newFolderFull directory so we can visually inspect the changes or change anything else that is needed. Let’s finish this script with the last code block. Close the IF statement, write an else and output to the console if directory not found.
} else { Write-Host -ForegroundColor Red "The directory has not been created." } }
That is all there is to it. Below is the final script wrapped in a function to make it easier to use.
<# Create new drive, and give user full permissions to directory. By: Alan Newingham Example: addUserDrive samAccount #> function addUserDrive { Param ( $samAccount1 ) #Colate Directory Information $baselevel = '\\File Server\Share\Drives\' $newFolderFull = $baselevel+$samAccount1 <#Visual Verification Write-Host Full Directory Path: $newFolderFull Write-Host Write-Host User Account: $samAccount1 Write-Host Write-Output Creating Directory.. $newFolderFull Write-Host #Creates Directory #> New-Item $newFolderFull -ItemType Directory <#Write-Host Write-Host Set Permissions on new Directory for $samAccount1 #Getting Ready to Set Permissions on new Directory #> $Acl = Get-Acl "$newFolderFull" $AccessRequest = New-Object System.Security.AccessControl.FileSystemAccessRule("$samAccount1", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow") $Acl.SetAccessRule($AccessRequest) #Set Permissions on new Directory Set-Acl "$newFolderFull" $Acl #If the directory can be found, open the properties window so I can verify the permissions are set. if (Test-Path $newFolderFull) { $o = new-object -com Shell.Application $folder = $o.NameSpace("$newFolderFull") $folder.Self.InvokeVerb("Properties") } else { Write-Host -ForegroundColor Red "The directory has not been created." } }