profile image

Kevin LaBranche

Teacher @

It’s important to have everything possible defined in your release or in an Infrastructure As Code (IAC) process.   The holy grail is immutable infrastructure but that isn’t always possible and maybe not worth trying to achieve. We still have many on premise IIS virtual machines that host several applications and the IAC setup handles the basic setup and configuration of IIS and the Windows environment itself only.  Nothing for the applications.

In this situation, we have tried to setup our releases to be Application Infrastructure As Code (AIAC). If we have to move to another IIS environment we can change our deployment group and/or environment and deploy.  We get the added benefit of the release serving as further documentation to the requirements for the application that often go undocumented and makes for lift and shifts an exercise in frustration and rediscovery.  I call that application archeology.  Really not a position anyone wants to be in.

In an earlier post I described how one could add a separate virtual directory as part of the release.  A few of our applications also have file shares including a case where a virtual directory is also an upload folder for staff to include some very large files for the application to use.  Let’s get that into the release.

A PowerShell task is well suited to accomplish this.  I’ve included links in the Learn More section that goes over the nuances of file share rights and setup with PowerShell.

Create a PowerShell task that is after the task that creates the folder you want to share.  That’s about the only prerequisite.  It can go anywhere in the task step order otherwise.

share-management-ps-task

We chose to use the inline type with the below code:

$shareExists = Get-SmbShare -Name upload -ErrorAction Ignore

if($shareExists -eq $null)
{
   New-SmbShare -Name upload -Description "Upload For ABC App" -Path c:\somefolderpath
   Grant-SmbShareAccess -Name upload -AccountName domain\adgroup1 -AccessRight Change -Force
   Grant-SmbShareAccess -Name upload -AccountName domain\adgroup2 -AccessRight Change -Force
   Revoke-SmbShareAccess -Name upload -AccountName Everyone -Force
}
else
{
   Set-SmbShare -Name upload -Description "Upload For ABC App" -Force
   Grant-SmbShareAccess -Name upload -AccountName domain\adgroup1 -AccessRight Change -Force
   Grant-SmbShareAccess -Name upload -AccountName domain\adgroup2 -AccessRight Change -Force
   Revoke-SmbShareAccess -Name upload -AccountName Everyone -Force
}

$ACL = Get-ACL -Path "c:\somefolderpath"
$AccessRuleOwner = New-Object System.Security.AccessControl.FileSystemAccessRule("domain\adgroup1","FullControl","ContainerInherit,ObjectInherit","None","Allow")
$AccessRuleStaff = New-Object System.Security.AccessControl.FileSystemAccessRule("domain\adgroup2","Modify","ContainerInherit,ObjectInherit","InheritOnly","Allow")
$ACL.SetAccessRule($AccessRuleOwner)
$ACL.SetAccessRule($AccessRuleStaff)
$ACL | Set-Acl -Path "c:\somefolderpath"

First, we try to get the share and if it doesn’t exist we set it up (New-SmbShare) and then setup the rights to the share, not the underlying folder/files.  If it does exist, we update the share.  Then we setup the folder/files in the underlying path for the share’s access rights.  We have an “owner” we setup with full rights, say our team member’s group and then a second group that represents the users and carefully set them up with change rights to everything below the root path but not the root itself.

Share access rights and folder/file access rights are different and the most restrictive rights will win.

Share access for the adgroup2 will have contribute since they can’t modify the root path but adgroup1 has read/write since they can as we granted them full rights to the root and below.

Share rights

share-rights

Folder/File rights:

share-folder-perms

The PowerShell could be improved upon.  Instead of forcing an update we could interrogate the settings and only update if it’s changed.  Additionally, what if we wanted to use a new folder path or share name?  We’d want to add some concept of old/new and clean up after ourselves.  We didn’t do either in our case since these are long established paths and shares.  We don’t plan on changing them anytime soon and if we did the existing release is now clearly documented making it easy to amend for such a change.

Learn More

Managing Windows file shares with PowerShell
How To Manage NTFS Permissions With PowerShell
Differences Between Share and NTFS Permissions
NTFS ACL's: What is the difference between object and container inheritance?
ACL Propagation Rules
PropagationFlags Enum
InheritanceFlags Enum
Setting Inheritance and Propagation flags with set-acl and powershell