Having seen how to read the permissions on a share its time to turn to one of the other common tasks associated with shares – adding permissions. This is usually done when the share is created but there are scenarios where you need to add extra permissions.
I’ve written the function Add-SharePermission to accomplish this task:
#requires -Version 3.0
function Add-SharePermission {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[string]$sharename,
[string]$domain = $env:COMPUTERNAME,
[Parameter(Mandatory=$true)]
[string]$trusteeName,
[Parameter(Mandatory=$true)]
[ValidateSet(“Read”, “Change”, “FullControl”)]
[string]$permission = “Read”,
[string]$computername = $env:COMPUTERNAME
)
switch ($permission) {
‘Read’ {$accessmask = 1179817}
‘Change’ {$accessmask = 1245631}
‘FullControl’ {$accessmask = 2032127}
}
$tclass = [wmiclass]”\\$computername\root\cimv2:Win32_Trustee”
$trustee = $tclass.CreateInstance()
$trustee.Domain = $domain
$trustee.Name = $trusteeName
$aclass = [wmiclass]”\\$computername\root\cimv2:Win32_ACE”
$ace = $aclass.CreateInstance()
$ace.AccessMask = $accessmask
$ace.AceFlags = 0
$ace.AceType = 0
$ace.Trustee = $trustee
$shss = Get-WmiObject -Class Win32_LogicalShareSecuritySetting -Filter “Name=’$sharename'” -ComputerName $computername
$sd = Invoke-WmiMethod -InputObject $shss -Name GetSecurityDescriptor |
select -ExpandProperty Descriptor
$sclass = [wmiclass]”\\$computername\root\cimv2:Win32_SecurityDescriptor”
$newsd = $sclass.CreateInstance()
$newsd.ControlFlags = $sd.ControlFlags
foreach ($oace in $sd.DACL){$newsd.DACL += $oace}
$newsd.DACL += $ace
$share = Get-WmiObject -Class Win32_LogicalShareSecuritySetting -Filter “Name=’$sharename'”
$share.SetSecurityDescriptor($newsd)
} # end function
The function starts with a requires restricting the function to version 3 and above. The function would run on version 2 so this is for consistency with the Get-SharePermission function I showed last time.
The parameter block includes a mandatory sharename and trusteename (user or group). Optional parameters allow a domain and computername to be set – both default to the local machine. A final mandatory parameter allows the specification of the permissions to be applied – read, change or full control – these values are validated at input using the ValidateSet option.
The next step in the function is to take the permission and turn it into an access mask using a switch – its the inverse of the one you saw in Get-SharePermission.
I’ve had to use the [wmiclass] type accelerator to to create the Win32_Trustee and Win32_ACE instances I need. The CIM cmdlets can’t be used because these classes don’t have keys defined.
The properties are set on the 2 objects.
Get-WmiObject is used to get the SecurityDescriptor of the share.
A new security descriptor is created with the relevant properties from the existing one copied across – the current ACEs have to be copied individually as shown. The new ACE is added to the DACL
Finally Get-WmiObject is used to retrieve the share object and the SetSEcurityDescriptor method is used to apply the new security descriptor.
Some interesting uses the wmiclass accelerator to make this work but the function shows it is doable without too much effort.