2015-11-06 08:26:49 +00:00
#!powershell
# This file is part of Ansible
# Copyright 2015, Hans-Joachim Kliemeck <git@kliemeck.de>
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
# WANT_JSON
# POWERSHELL_COMMON
#Functions
Function UserSearch
{
2016-12-08 05:34:16 +00:00
Param ( [ string ] $accountName )
2015-11-06 08:26:49 +00:00
#Check if there's a realm specified
2016-12-08 05:34:16 +00:00
$searchDomain = $false
$searchDomainUPN = $false
if ( $accountName . Split ( " \ " ) . count -gt 1 )
2016-12-08 14:38:05 +00:00
{
2016-12-08 05:34:16 +00:00
if ( $accountName . Split ( " \ " ) [ 0 ] -ne $env:COMPUTERNAME )
2015-11-06 08:26:49 +00:00
{
2016-12-08 05:34:16 +00:00
$searchDomain = $true
$accountName = $accountName . split ( " \ " ) [ 1 ]
2015-11-06 08:26:49 +00:00
}
}
2016-12-08 05:34:16 +00:00
Elseif ( $accountName . contains ( " @ " ) )
2015-11-06 08:26:49 +00:00
{
2016-12-08 05:34:16 +00:00
$searchDomain = $true
$searchDomainUPN = $true
2015-11-06 08:26:49 +00:00
}
Else
{
#Default to local user account
2016-12-08 05:34:16 +00:00
$accountName = $env:COMPUTERNAME + " \ " + $accountName
2015-11-06 08:26:49 +00:00
}
2016-12-08 05:34:16 +00:00
if ( $searchDomain -eq $false )
2015-11-06 08:26:49 +00:00
{
# do not use Win32_UserAccount, because e.g. SYSTEM (BUILTIN\SYSTEM or COMPUUTERNAME\SYSTEM) will not be listed. on Win32_Account groups will be listed too
2016-12-08 05:34:16 +00:00
$localaccount = get-wmiobject -class " Win32_Account " -namespace " root\CIMV2 " -filter " (LocalAccount = True) " | where { $_ . Caption -eq $accountName }
2015-11-06 08:26:49 +00:00
if ( $localaccount )
{
return $localaccount . SID
}
}
2016-12-08 05:34:16 +00:00
Else
2015-11-06 08:26:49 +00:00
{
#Search by samaccountname
$Searcher = [ adsisearcher ] " "
2016-12-08 05:34:16 +00:00
If ( $searchDomainUPN -eq $false ) {
$Searcher . Filter = " sAMAccountName= $( $accountName ) "
2015-11-06 08:26:49 +00:00
}
Else {
2016-12-08 05:34:16 +00:00
$Searcher . Filter = " userPrincipalName= $( $accountName ) "
2015-11-06 08:26:49 +00:00
}
2017-03-02 06:36:05 +00:00
$result = $Searcher . FindOne ( )
2015-11-06 08:26:49 +00:00
if ( $result )
{
$user = $result . GetDirectoryEntry ( )
# get binary SID from AD account
$binarySID = $user . ObjectSid . Value
# convert to string SID
return ( New-Object System . Security . Principal . SecurityIdentifier ( $binarySID , 0 ) ) . Value
}
}
}
Function NormalizeAccounts
{
param (
[ parameter ( valuefrompipeline = $true ) ]
$users
)
$users = $users . Trim ( )
If ( $users -eq " " ) {
$splittedUsers = [ Collections.Generic.List[String] ] @ ( )
}
Else {
$splittedUsers = [ Collections.Generic.List[String] ] $users . Split ( " , " )
}
$normalizedUsers = [ Collections.Generic.List[String] ] @ ( )
ForEach ( $splittedUser in $splittedUsers ) {
$sid = UserSearch $splittedUser
If ( ! $sid ) {
Fail-Json $result " $splittedUser is not a valid user or group on the host machine or domain "
}
$normalizedUser = ( New-Object System . Security . Principal . SecurityIdentifier ( $sid ) ) . Translate ( [ System.Security.Principal.NTAccount ] )
$normalizedUsers . Add ( $normalizedUser )
}
return , $normalizedUsers
}
2017-02-24 07:31:09 +00:00
$result = @ {
changed = $false
}
2015-11-06 08:26:49 +00:00
2017-02-24 07:31:09 +00:00
$params = Parse-Args $args
2015-11-06 08:26:49 +00:00
2017-02-24 07:31:09 +00:00
$name = Get-AnsibleParam -obj $params -name " name " -type " str " -failifempty $true
$state = Get-AnsibleParam -obj $params -name " state " -type " str " -default " present " -validateset " present " , " absent "
2015-11-06 08:26:49 +00:00
Try {
$share = Get-SmbShare $name -ErrorAction SilentlyContinue
If ( $state -eq " absent " ) {
If ( $share ) {
Remove-SmbShare -Force -Name $name
2017-02-24 07:31:09 +00:00
$result . changed = $true
2015-11-06 08:26:49 +00:00
}
}
Else {
2017-02-24 07:31:09 +00:00
$path = Get-AnsibleParam -obj $params -name " path " -type " path " -failifempty $true
$description = Get-AnsibleParam -obj $params -name " description " -type " str " -default " "
2015-11-06 08:26:49 +00:00
2017-02-24 07:31:09 +00:00
$permissionList = Get-AnsibleParam -obj $params -name " list " -type " bool " -default " no " -validateset " no " , " yes " -resultobj $result
2015-11-06 08:26:49 +00:00
$folderEnum = if ( $permissionList ) { " Unrestricted " } else { " AccessBased " }
2017-02-24 07:31:09 +00:00
$permissionRead = Get-AnsibleParam -obj $params -name " read " -type " str " -default " " | NormalizeAccounts
$permissionChange = Get-AnsibleParam -obj $params -name " change " -type " str " -default " " | NormalizeAccounts
$permissionFull = Get-AnsibleParam -obj $params -name " full " -type " str " -default " " | NormalizeAccounts
$permissionDeny = Get-AnsibleParam -obj $params -name " deny " -type " str " -default " " | NormalizeAccounts
2015-11-06 08:26:49 +00:00
2017-03-23 22:08:53 +00:00
$cachingMode = Get-AnsibleParam -obj $params -name " caching_mode " -type " str " -default " Manual " -validateSet " BranchCache " , " Documents " , " Manual " , " None " , " Programs " , " Unknown "
2017-03-02 06:36:05 +00:00
2015-11-06 08:26:49 +00:00
If ( -Not ( Test-Path -Path $path ) ) {
Fail-Json $result " $path directory does not exist on the host "
}
2015-11-06 13:29:11 +00:00
# normalize path and remove slash at the end
2015-11-11 11:51:24 +00:00
$path = ( Get-Item $path ) . FullName -replace " \\ $ "
2015-11-06 13:29:11 +00:00
2015-11-06 08:26:49 +00:00
# need to (re-)create share
2017-02-24 07:31:09 +00:00
If ( -not $share ) {
2015-11-06 08:26:49 +00:00
New-SmbShare -Name $name -Path $path
$share = Get-SmbShare $name -ErrorAction SilentlyContinue
2017-02-24 07:31:09 +00:00
$result . changed = $true
2015-11-06 08:26:49 +00:00
}
If ( $share . Path -ne $path ) {
Remove-SmbShare -Force -Name $name
New-SmbShare -Name $name -Path $path
$share = Get-SmbShare $name -ErrorAction SilentlyContinue
2017-02-24 07:31:09 +00:00
$result . changed = $true
2015-11-06 08:26:49 +00:00
}
# updates
If ( $share . Description -ne $description ) {
Set-SmbShare -Force -Name $name -Description $description
2017-02-24 07:31:09 +00:00
$result . changed = $true
2015-11-06 08:26:49 +00:00
}
If ( $share . FolderEnumerationMode -ne $folderEnum ) {
Set-SmbShare -Force -Name $name -FolderEnumerationMode $folderEnum
2017-02-24 07:31:09 +00:00
$result . changed = $true
2015-11-06 08:26:49 +00:00
}
2017-03-02 06:36:05 +00:00
if ( $share . CachingMode -ne $cachingMode ) {
Set-SmbShare -Force -Name $name -CachingMode $cachingMode
Set-Attr $result " changed " $true ;
}
2015-11-06 08:26:49 +00:00
# clean permissions that imply others
ForEach ( $user in $permissionFull ) {
$permissionChange . remove ( $user )
$permissionRead . remove ( $user )
}
ForEach ( $user in $permissionChange ) {
$permissionRead . remove ( $user )
}
# remove permissions
$permissions = Get-SmbShareAccess -Name $name
ForEach ( $permission in $permissions ) {
If ( $permission . AccessControlType -eq " Deny " ) {
If ( ! $permissionDeny . Contains ( $permission . AccountName ) ) {
Unblock-SmbShareAccess -Force -Name $name -AccountName $permission . AccountName
2017-02-24 07:31:09 +00:00
$result . changed = $true
2015-11-06 08:26:49 +00:00
}
}
ElseIf ( $permission . AccessControlType -eq " Allow " ) {
If ( $permission . AccessRight -eq " Full " ) {
If ( ! $permissionFull . Contains ( $permission . AccountName ) ) {
Revoke-SmbShareAccess -Force -Name $name -AccountName $permission . AccountName
2017-02-24 07:31:09 +00:00
$result . changed = $true
2015-11-06 08:26:49 +00:00
Continue
}
# user got requested permissions
$permissionFull . remove ( $permission . AccountName )
}
ElseIf ( $permission . AccessRight -eq " Change " ) {
If ( ! $permissionChange . Contains ( $permission . AccountName ) ) {
Revoke-SmbShareAccess -Force -Name $name -AccountName $permission . AccountName
2017-02-24 07:31:09 +00:00
$result . changed = $true
2015-11-06 08:26:49 +00:00
Continue
}
# user got requested permissions
$permissionChange . remove ( $permission . AccountName )
}
ElseIf ( $permission . AccessRight -eq " Read " ) {
If ( ! $permissionRead . Contains ( $permission . AccountName ) ) {
Revoke-SmbShareAccess -Force -Name $name -AccountName $permission . AccountName
2017-02-24 07:31:09 +00:00
$result . changed = $true
2015-11-06 08:26:49 +00:00
Continue
}
# user got requested permissions
$permissionRead . Remove ( $permission . AccountName )
}
}
}
2017-02-24 07:31:09 +00:00
2015-11-06 08:26:49 +00:00
# add missing permissions
ForEach ( $user in $permissionRead ) {
Grant-SmbShareAccess -Force -Name $name -AccountName $user -AccessRight " Read "
2017-02-24 07:31:09 +00:00
$result . changed = $true
2015-11-06 08:26:49 +00:00
}
ForEach ( $user in $permissionChange ) {
Grant-SmbShareAccess -Force -Name $name -AccountName $user -AccessRight " Change "
2017-02-24 07:31:09 +00:00
$result . changed = $true
2015-11-06 08:26:49 +00:00
}
ForEach ( $user in $permissionFull ) {
Grant-SmbShareAccess -Force -Name $name -AccountName $user -AccessRight " Full "
2017-02-24 07:31:09 +00:00
$result . changed = $true
2015-11-06 08:26:49 +00:00
}
ForEach ( $user in $permissionDeny ) {
Block-SmbShareAccess -Force -Name $name -AccountName $user
2017-02-24 07:31:09 +00:00
$result . changed = $true
2015-11-06 08:26:49 +00:00
}
}
}
Catch {
2017-03-23 22:08:53 +00:00
Fail-Json $result " an error occurred when attempting to create share $( $name ) : $( $_ . Exception . Message ) "
2015-11-06 08:26:49 +00:00
}
2016-12-11 02:50:09 +00:00
Exit-Json $result