Setting network share permissions on subdirectory with PowerShell - powershell

I want to setup a network share granting READ only permissions to the root, but READ/WRITE permissions to a sub directory within it.
I can do this manually, but I want to be able to do it using PowerShell.
\\myserver\MyShare (READ access here for user TESTUSER)
\\myserver\MyShare\subfolder (READ/WRITE access here for user TESTUSER)
Manual steps in Windows Explorer - open folder properties dialog, "Sharing" tab, "Share..." button, I can then add my user and set the permissions. I can do this to BOTH the root of the network share and the "subfolder".
The closest thing I have managed in PowerShell is the following, which sets up the root only:
New-SmbShare –Name MyShare –Path e:\MyShare -ReadAccess "Domain\TESTUSER"
However, this seems to do the equivalent of the "Advanced sharing" options that appear on the folder properties dialog, which only apply when setting up a NEW network share, and not to folders WITHIN an existing network share. When I run this script, the TESTUSER isn't added to the list of users in the simple "Share..." dialog so there must be another way of setting up the permissions.
My question: How do I setup permissions using PowerShell in the same way Windows does from the "Share..." button on the folder properties?
I'm using Windows Server 2012 R2.

Share permissions apply to shares as a whole, meaning they affect the shared folder and everything it contains. It's not possible to apply different share permissions to a subfolder without publishing that subfolder as a different share, and even then the modified permissions would only become effective when accessing the subfolder through the new share, not when accessing it as a subfolder of the original share.
For fine-grained access control you MUST use filesystem ACLs. However, if the share is defined as read-only via share permissions, the user will be denied write access even if the filesystem ACLs would allow it.
Because of these limitations it's common practice to set share permissions to full control for everyone and do the entire permission handling on the filesystem level. The simplest way of setting file ACLs is still the icacls command:
icacls C:\path\to\shared_folder /grant "DOMAIN\testuser:(CI)(OI)RX"
icacls C:\path\to\shared_folder\subfolder /grant "DOMAIN\testuser:(CI)(OI)M"
You could also use Set-Acl to the same end, but it'd require more code:
function New-Ace($user, $permission) {
New-Object Security.AccessControl.FileSystemAccessRule $user, $permission, 'ContainerInherit, ObjectInherit', 'None', 'Allow'
}
$acl = Get-Acl -LiteralPath 'C:\path\to\shared_folder'
$acl.AddAccessRule((New-Ace 'DOMAIN\testuser' 'ReadOrExecute')
Set-Acl -AclObject $acl -LiteralPath 'C:\path\to\shared_folder'
$acl = Get-Acl -LiteralPath 'C:\path\to\shared_folder\subfolder'
$acl.AddAccessRule((New-Ace 'DOMAIN\testuser' 'Modify'))
Set-Acl -AclObject $acl -LiteralPath 'C:\path\to\shared_folder\subfolder'
By enabling access-based enumeration you can make sure users will only see those folders and files they actually have access to (avoiding confusion from trying to access an object only to get an "access denied" error).

Related

How to grant directory permissions in a Powershell script

I click the right mouse button on my site in the IIS manager and choose 'Edit permissions' and then I click the security tab. There I have the user IUSR with the following permissions: Read & execute, List folder contents, Read. I can also verify this in Powershell using the command Get-Acl <path> |fl , which displays:
Access : NT AUTHORITY\IUSR Allow ReadAndExecute, Synchronize
Now I delete the ACL entry for IUSR completely. I want to set it with a Powershell script, using the following lines:
$path=<path to directory>
$acl = Get-Acl "$path"
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("NT AUTHORITY\IUSR","ReadAndExecute","Allow")
$acl.SetAccessRule($AccessRule)
$acl | Set-Acl "$path"
Again verifying with Get-Acl <path> |fl , I shows exactly the same information, as expected. But in the IIS manager, the previously checked rights are not set. Instead 'Special permissions' is checked. When I click on 'Advanced' and pick IUSR from the list, it shows the same permissions have been granted: Read & execute, List folder contents, Read
But my website does not work (the browser throws error: HTTP-Errror 401.3 - Unauthorized). It works only if I grant these permissions in the permissions windows manually. How can I set the required permissions correctly in a Powershell script?
Turning my comment into an answer, this sounds like you need to also specify the Inheritance and Propagation flags for the accessrule, so child objects of the folder inherit the permission.
$AccessRule = [System.Security.AccessControl.FileSystemAccessRule]::new("NT AUTHORITY\IUSR", "ReadAndExecute", "ContainerInherit,ObjectInherit", "None", "Allow")

Using PowerShell to grant access to a folder for an "IIS AppPool"

I Writing a script to automate the deployment of my platform but i cant figure out how to set an app pool to have the permissions with the code i have below it just inserts the text below with the app pool name. I assume this is because this is a frendily name and when you click check names normally it will fetch the correct user but i cant figure out hot to do this in powershell.
function Set_iis_perms {
param (
[parameter(position=0)]
$AppPoolName,
[parameter(position=1)]
$FileName
)
$acl = Get-Acl $FileName
$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule(("iis apppool\$Apppool_Name"),"Modify","Allow")))
$acl | Set-Acl $FileName
}
Even if someone can point me in the right direction i would be most thankful.
Kind Regards
Dom
Setting ACL via Get/Set-ACL and icacls is a really common thing and covered in many resources. Example(s):
Setting ACL on folder or file using PowerShell
This script will set folder permission on a folder (c:\1 and C:2) and
its sub folder. If the folder does not exist, it will create the
folder, set as shared and add the groups to the folder. Group_Name
has to be replaced with Actual Group.
Application Pool Identities
Setting permissions for ASP.NET application on IIS with
PowerShell
As per this StackOverflow Q&A
How can I add ACL permissions for IIS APPPOOL* accounts via
Powershell?
Set-Acl $directory $acl $user = New-Object
System.Security.Principal.NTAccount("$domain\\$username")
UPDATE: Seems that it won't accept the "IIS APPPOOL\AppPoolName" as an
NTAccount identifier. Now, there are two ways to accomplish what you
are trying to do:
Create a new SID object with the AppPoolIdentities SID and translate
it into an NTAccount, like this:
http://iformattable.blogspot.com/2007/12/convert-sid-to-ntaccount-with.html,
and you should be able to treat it like any other NTAccount object. If
you still want to be able to pass domain/usernames for real accounts,
built in some simple logic that defaults to the AppPool SID if
username is "AweSomeAppPool" and domain is empty, just as an example.
Use PowerShell to invoke icacls.exe, and use it to grant/revoke
whatever permissions you want, like this (first normal icacls form
command prompt, then powershell, notice the difference):
icacls.exe test.txt /grant "IIS AppPool\DefaultAppPool":(OI)(CI)M
cmd /c icacls test.txt /grant "IIS AppPool\DefaultAppPool:(OI)(CI)M"

Sharing a folder for a specific machine/user using powershell

I'm trying to share a folder to a specific machine/user using Powershell.
Some background: I've many Windows machines which have a folder (data folders) that needs to be backed up. These folders are shared with a "special" machine running backup software. This software daily checks the contents of the data folders and backup the data to its local harddisks. When a new machine arrives, we share the folder by hand using Explorer. (Properties -> sharing -> share ...). All the machines are part of a large network, and we don't want to share the data with all the machines. Therefore we only allow read access to the data folder by the backup machine (let's call the user on the backup machine domain\BackupUser). I want to move the creation of these shared data folders into some script which we can run from Powershell.
The command I found is: New-SmbShare -Path C:\Data\ -Name Data -ReadAccess "domain\BackupUser". The command will create the (smb) share as expected, and I can observe it via the backup machine. But on access it, the permission is denied.
When listing the shared folder access (Get-SmbShareAccess -Name "Data") it does show the expected user.
I've also tried to create the shared folder with: net share Data=C:\Data /grant:BackupUser,FULL but still got the permission is denied error.
The weird thing is when the folder is shared using explorer and list the access (`Get-SmbShareAccess -Name "Data"). The user (BackupUser) is not listed, but an "Everyone" is shown. But when trying to access the data folder from another (random) machine, it does not give access, as desired. The backup machine does have access.
So, the main question: What powershell command(s) creates a new shared folder to a specific machine/user?
Share permissions are not the same as file system permissions.
Set the SHARE permission, then apply the FOLDER/FILE permissions:
$FolderName = 'C:\Data'
$UserId = 'DOMAIN\BackupUser'
New-SmbShare -Path $FolderName -Name Data -ReadAccess $UserId
$Acl = Get-Acl $FolderName
$NewAccessRule = New-Object system.security.accesscontrol.filesystemaccessrule($UserId,"Read","Allow")
$Acl.SetAccessRule($NewAccessRule)
Set-Acl $FolderName $Acl

How to set Write permission on a folder for Everyone Using Powershell

I am trying to share a folder with everyone and using the below command but it is not working.
NET SHARE Movies=C:\foldername "/GRANT:Everyone,FULL"
After runnign this command a message comes 'Movies Shared Successfully' but When i check folder permission it does not show the same.
Can anyone tell me the correct command?
your net share works just fine. To set the folder permissions you need to set the ACL permissions:
$sharepath = "C:\foldername"
$Acl = Get-ACL $SharePath
$AccessRule= New-Object System.Security.AccessControl.FileSystemAccessRule("everyone","FullControl","ContainerInherit,Objectinherit","none","Allow")
$Acl.AddAccessRule($AccessRule)
Set-Acl $SharePath $Acl
You will notice that "Everyone" will show up with full access permissions on the security tab of the folder.

Sharing in Win2012 via PowerShell

I'm newbie in PowerShell and I need create script, which create folder on Windows Server 2012 and set it as share with permission: Everyone Read, NETWORK SERVICE Full.
I wrote following script
Import-Module SmbShare
Import-Module SmbWitness
function CreateFolderIfNotExists([string]$Path)
{
if (!(Test-Path $Path))
{
New-Item -ItemType Directory -Force -Path $Path
return $True
}
return $False
}
if (CreateFolderIfNotExists -Path "C:\DataExport")
{
New-SmbShare –Name "DataExport" –Path "C:\DataExport" –FullAccess "NETWORK SERVICE" –ReadAccess "Everyone"
}
The script create folder, enable sharing, but set up folder permissions and not set up sharing permissions - it means, that if I display properties of DataExport folder, tab Sharing. If I use Advanced Sharing ... button and Permissions button, I see permissions correctly, but if I use Share... button, permissions aren't set.
If I try to connect to shared folder, I don't have permissions to access to share folder.
Is there some way how to set sharing of folder?
Finaly I found tool CACLS (which is currently deprecated, but works) and via this tool I can set sharing permissions:
function GrantSharePermission([string]$Path, [string]$User, [string]$Permission)
{
$Command = "cacls " + $Path + " /G " + $User + ":" + $Permission + " /T /E"
iex $Command
}
cacls is a good tool, but it sets file permissions (shown on the Security tab when you right click on a file or folder), not share permissions. You should understand that a user or group's effective permission on a share is the more restrictive of the two. So if you give a user Change in the share permissions, but only Read/Execute on the file system, that user's effective permissions are Read/Execute in that area.
If you liked working with cacls, rmtshare.exe is another deprecated tool that can do what you want. cacls will set the file permissions and rmtshare will deal with the share. You will have to look around to find it, at my work we use an older copy from the resource kit.
Example rmtshare usage:
rmtshare \\servername\sharename=C:\Websites\wwwroot /remark:"Website Share"
rmtshare \\servername\sharename /grant Administrators:F /grant system:f /remove everyone
rmtshare \\servername\sharename /grant "servername\Local Website Users":C
rmtshare \\servername\sharename /grant "servername\Local Website Viewers":R