diff --git a/DscResources/MSFT_xSmbShare/MSFT_xSmbShare.psm1 b/DscResources/MSFT_xSmbShare/MSFT_xSmbShare.psm1 index 642855f..52f4afb 100644 --- a/DscResources/MSFT_xSmbShare/MSFT_xSmbShare.psm1 +++ b/DscResources/MSFT_xSmbShare/MSFT_xSmbShare.psm1 @@ -21,7 +21,7 @@ function Get-TargetResource if ($smbShare -ne $null) { $smbShareAccess = Get-SmbShareAccess -Name $Name - $smbShareAccess | % { + $smbShareAccess | ForEach-Object { $access = $_; if ($access.AccessRight -eq 'Change' -and $access.AccessControlType -eq 'Allow') { @@ -30,7 +30,7 @@ function Get-TargetResource elseif ($access.AccessRight -eq 'Read' -and $access.AccessControlType -eq 'Allow') { $readAccess += $access.AccountName - } + } elseif ($access.AccessRight -eq 'Full' -and $access.AccessControlType -eq 'Allow') { $fullAccess += $access.AccountName @@ -44,24 +44,24 @@ function Get-TargetResource else { Write-Verbose "Share with name $Name does not exist" - } + } $returnValue = @{ - Name = $smbShare.Name - Path = $smbShare.Path - Description = $smbShare.Description - ConcurrentUserLimit = $smbShare.ConcurrentUserLimit - EncryptData = $smbShare.EncryptData - FolderEnumerationMode = $smbShare.FolderEnumerationMode - ShareState = $smbShare.ShareState - ShareType = $smbShare.ShareType - ShadowCopy = $smbShare.ShadowCopy - Special = $smbShare.Special - ChangeAccess = $changeAccess - ReadAccess = $readAccess - FullAccess = $fullAccess - NoAccess = $noAccess - Ensure = if($smbShare) {"Present"} else {"Absent"} + Name = $smbShare.Name + Path = $smbShare.Path + Description = $smbShare.Description + ConcurrentUserLimit = $smbShare.ConcurrentUserLimit + EncryptData = $smbShare.EncryptData + FolderEnumerationMode = $smbShare.FolderEnumerationMode + ShareState = $smbShare.ShareState + ShareType = $smbShare.ShareType + ShadowCopy = $smbShare.ShadowCopy + Special = $smbShare.Special + ChangeAccess = $changeAccess + ReadAccess = $readAccess + FullAccess = $fullAccess + NoAccess = $noAccess + Ensure = if($smbShare) {"Present"} else {"Absent"} } $returnValue @@ -71,7 +71,7 @@ function Set-AccessPermission { [CmdletBinding()] Param - ( + ( $ShareName, [string[]] @@ -94,11 +94,52 @@ function Set-AccessPermission } } +Function Set-BoundParameters +{ + # Define parameters + Param + ( + $BoundParameters + ) + + # Check for null access before passing to New-SmbShare + if (($BoundParameters.ContainsKey("ChangeAccess")) -and ([string]::IsNullOrEmpty($BoundParameters["ChangeAccess"]))) + { + Write-Verbose "Parameter ChangeAccess is null or empty, removing from collection." + # Remove the parameter + $BoundParameters.Remove("ChangeAccess") + } + + if (($BoundParameters.ContainsKey("ReadAccess")) -and ([string]::IsNullOrEmpty($BoundParameters["ReadAccess"]))) + { + Write-Verbose "Paramater ReadAccess is null or empty, removing from collection." + # Remove the parameter + $BoundParameters.Remove("ReadAccess") + } + + if (($BoundParameters.ContainsKey("FullAccess")) -and ([string]::IsNullOrEmpty($BoundParameters["FullAccess"]))) + { + Write-Verbose "Parameter FullAccess is null or empty, removing from collection." + # Remove the parameter + $BoundParameters.Remove("FullAccess") + } + + if (($BoundParameters.ContainsKey("NoAccess")) -and ([string]::IsNullOrEmpty($BoundParameters["NoAccess"]))) + { + Write-Verbose "Parameter NoAccess is null or empty, removing from collection." + # Remove the parameter + $BoundParameters.Remove("NoAccess") + } + + # Return the parameter collection + return $BoundParameters +} + function Remove-AccessPermission { [CmdletBinding()] Param - ( + ( $ShareName, [string[]] @@ -114,7 +155,8 @@ function Remove-AccessPermission if ($AccessPermission -eq "Change" -or $AccessPermission -eq "Read" -or $AccessPermission -eq "Full") { Revoke-SmbShareAccess -Name $Name -AccountName $UserName -Force - } + +} else { UnBlock-SmbShareAccess -Name $Name -AccountName $userName -Force @@ -164,7 +206,7 @@ function Set-TargetResource $Ensure = 'Present' ) - $psboundparameters.Remove("Debug") + $PSBoundParameters.Remove("Debug") $shareExists = $false $smbShare = Get-SmbShare -Name $Name -ErrorAction SilentlyContinue @@ -177,94 +219,115 @@ function Set-TargetResource { if ($shareExists -eq $false) { - $psboundparameters.Remove("Ensure") + $PSBoundParameters.Remove("Ensure") Write-Verbose "Creating share $Name to ensure it is Present" - New-SmbShare @psboundparameters + + # Alter bound parameters + $newShareParameters = Set-BoundParameters -BoundParameters $PSBoundParameters + + # Pass the parameter collection to New-SmbShare + New-SmbShare @newShareParameters } else { # Need to call either Set-SmbShare or *ShareAccess cmdlets - if ($psboundparameters.ContainsKey("ChangeAccess")) + if ($PSBoundParameters.ContainsKey("ChangeAccess")) { - $changeAccessValue = $psboundparameters["ChangeAccess"] - $psboundparameters.Remove("ChangeAccess") + $changeAccessValue = $PSBoundParameters["ChangeAccess"] + $PSBoundParameters.Remove("ChangeAccess") } - if ($psboundparameters.ContainsKey("ReadAccess")) + if ($PSBoundParameters.ContainsKey("ReadAccess")) { - $readAccessValue = $psboundparameters["ReadAccess"] - $psboundparameters.Remove("ReadAccess") + $readAccessValue = $PSBoundParameters["ReadAccess"] + $PSBoundParameters.Remove("ReadAccess") } - if ($psboundparameters.ContainsKey("FullAccess")) + if ($PSBoundParameters.ContainsKey("FullAccess")) { - $fullAccessValue = $psboundparameters["FullAccess"] - $psboundparameters.Remove("FullAccess") + $fullAccessValue = $PSBoundParameters["FullAccess"] + $PSBoundParameters.Remove("FullAccess") } - if ($psboundparameters.ContainsKey("NoAccess")) + if ($PSBoundParameters.ContainsKey("NoAccess")) { - $noAccessValue = $psboundparameters["NoAccess"] - $psboundparameters.Remove("NoAccess") + $noAccessValue = $PSBoundParameters["NoAccess"] + $PSBoundParameters.Remove("NoAccess") } - + # Use Set-SmbShare for performing operations other than changing access - $psboundparameters.Remove("Ensure") - $psboundparameters.Remove("Path") + $PSBoundParameters.Remove("Ensure") + $PSBoundParameters.Remove("Path") Set-SmbShare @PSBoundParameters -Force - + # Use *SmbShareAccess cmdlets to change access - $smbshareAccessValues = Get-SmbShareAccess -Name $Name + $smbShareAccessValues = Get-SmbShareAccess -Name $Name + + # Remove Change permissions + $smbShareAccessValues | Where-Object {$_.AccessControlType -eq 'Allow' -and $_.AccessRight -eq 'Change'} ` + | ForEach-Object { + Remove-AccessPermission -ShareName $Name -UserName $_.AccountName -AccessPermission Change + } + if ($ChangeAccess -ne $null) { - # Blow off whatever is in there and replace it with this list - $smbshareAccessValues | ? {$_.AccessControlType -eq 'Allow' -and $_.AccessRight -eq 'Change'} ` - | % { - Remove-AccessPermission -ShareName $Name -UserName $_.AccountName -AccessPermission Change - } - - $changeAccessValue | % { + # Add change permissions + $changeAccessValue | ForEach-Object { Set-AccessPermission -ShareName $Name -AccessPermission "Change" -Username $_ } } - $smbshareAccessValues = Get-SmbShareAccess -Name $Name + + $smbShareAccessValues = Get-SmbShareAccess -Name $Name + + # Remove read access + $smbShareAccessValues | Where-Object {$_.AccessControlType -eq 'Allow' -and $_.AccessRight -eq 'Read'} ` + | ForEach-Object { + Remove-AccessPermission -ShareName $Name -UserName $_.AccountName -AccessPermission Read + } + if ($ReadAccess -ne $null) { - # Blow off whatever is in there and replace it with this list - $smbshareAccessValues | ? {$_.AccessControlType -eq 'Allow' -and $_.AccessRight -eq 'Read'} ` - | % { - Remove-AccessPermission -ShareName $Name -UserName $_.AccountName -AccessPermission Read - } - - $readAccessValue | % { - Set-AccessPermission -ShareName $Name -AccessPermission "Read" -Username $_ + # Add read access + $readAccessValue | ForEach-Object { + Set-AccessPermission -ShareName $Name -AccessPermission "Read" -Username $_ } } - $smbshareAccessValues = Get-SmbShareAccess -Name $Name + + + $smbShareAccessValues = Get-SmbShareAccess -Name $Name + + # Remove full access + $smbShareAccessValues | Where-Object {$_.AccessControlType -eq 'Allow' -and $_.AccessRight -eq 'Full'} ` + | ForEach-Object { + Remove-AccessPermission -ShareName $Name -UserName $_.AccountName -AccessPermission Full + } + + if ($FullAccess -ne $null) { - # Blow off whatever is in there and replace it with this list - $smbshareAccessValues | ? {$_.AccessControlType -eq 'Allow' -and $_.AccessRight -eq 'Full'} ` - | % { - Remove-AccessPermission -ShareName $Name -UserName $_.AccountName -AccessPermission Full - } - - $fullAccessValue | % { - Set-AccessPermission -ShareName $Name -AccessPermission "Full" -Username $_ + + # Add full access + $fullAccessValue | ForEach-Object { + Set-AccessPermission -ShareName $Name -AccessPermission "Full" -Username $_ } } - $smbshareAccessValues = Get-SmbShareAccess -Name $Name + + $smbShareAccessValues = Get-SmbShareAccess -Name $Name + + # Remove explicit deny + $smbShareAccessValues | Where-Object {$_.AccessControlType -eq 'Deny'} ` + | ForEach-Object { + Remove-AccessPermission -ShareName $Name -UserName $_.AccountName -AccessPermission No + } + + if ($NoAccess -ne $null) { - # Blow off whatever is in there and replace it with this list - $smbshareAccessValues | ? {$_.AccessControlType -eq 'Deny'} ` - | % { - Remove-AccessPermission -ShareName $Name -UserName $_.AccountName -AccessPermission No - } - $noAccessValue | % { + # Add explicit deny + $noAccessValue | ForEach-Object { Set-AccessPermission -ShareName $Name -AccessPermission "No" -Username $_ } } } } - else + else { Write-Verbose "Removing share $Name to ensure it is Absent" Remove-SmbShare -name $Name -Force @@ -314,8 +377,13 @@ function Test-TargetResource [System.String] $Ensure = 'Present' ) + + # Alter the bound parameters, removing anything that is null or emtpy + $alteredBoundParameters = Set-BoundParameters -boundparameters $PSBoundParameters + $testResult = $false; $share = Get-TargetResource -Name $Name -Path $Path -ErrorAction SilentlyContinue -ErrorVariable ev + $differences = @() if ($Ensure -ne "Absent") { if ($share.Ensure -eq "Absent") @@ -325,9 +393,27 @@ function Test-TargetResource elseif ($share.Ensure -eq "Present") { $Params = 'Name', 'Path', 'Description', 'ChangeAccess', 'ConcurrentUserLimit', 'EncryptData', 'FolderEnumerationMode', 'FullAccess', 'NoAccess', 'ReadAccess', 'Ensure' - if ($PSBoundParameters.Keys.Where({$_ -in $Params}) | ForEach-Object {Compare-Object -ReferenceObject $PSBoundParameters.$_ -DifferenceObject $share.$_}) - { - $testResult = $false + + # Get all matching parameters from alteredBoundParameters that are in Params + $matchingParameters = $alteredBoundParameters.Keys.Where({($_ -in $Params)}) + + if ($null -ne $matchingParameters) + { + foreach ($matchingParameter in $matchingParameters) + { + $differences += Compare-Object -ReferenceObject $alteredBoundParameters[$matchingParameter] -DifferenceObject $share.$matchingParameter #; $differences + } + + # Check to see if there is anything in $differences + if (($null -ne $differences) -and ($differences.Length -gt 0)) + { + $differences | ForEach-Object {Write-Verbose -Message "$_"} + $testResult = $false + } + else + { + $testResult = $true + } } else { @@ -351,4 +437,3 @@ function Test-TargetResource } Export-ModuleMember -Function *-TargetResource - diff --git a/README.md b/README.md index 82ae067..6c8aa40 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -[![Build status](https://ci.appveyor.com/api/projects/status/ttp6jlhjyef83sic/branch/master?svg=true)](https://ci.appveyor.com/project/PowerShell/xsmbshare/branch/master) +# xSmbShare Resource -# xSmbShare +[![Build status](https://ci.appveyor.com/api/projects/status/ttp6jlhjyef83sic/branch/master?svg=true)](https://ci.appveyor.com/project/PowerShell/xsmbshare/branch/master) The **xSmbShare** module contains the **xSmbShare** DSC resource for setting up and configuring an [SMB share](http://technet.microsoft.com/en-us/library/cc734393%28v=WS.10%29.aspx). @@ -8,8 +8,8 @@ This project has adopted the [Microsoft Open Source Code of Conduct](https://ope For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. ## Contributing -Please check out common DSC Resources [contributing guidelines](https://github.com/PowerShell/DscResource.Kit/blob/master/CONTRIBUTING.md). +Please check out common DSC Resources [contributing guidelines](https://github.com/PowerShell/DscResource.Kit/blob/master/CONTRIBUTING.md). ## Resources @@ -34,33 +34,36 @@ The default value is 0. * **Special**: Specifies if this share is a Special Share. Admin shares, default shares, IPC$ share are examples. - ## Versions ### Unreleased +* Improved Code logic & cosmetic changes * Update appveyor.yml to use the default template. * Added default template files .codecov.yml, .gitattributes, and .gitignore, and .vscode folder. ### 2.1.0.0 + * Corrected typo on ShareState and ShareType descriptions (Specfies -> Specifies) ### 2.0.0.0 + * Converted appveyor.yml to install Pester from PSGallery instead of from Chocolatey. * Added default value of "Present" for the Ensure parameter. (Note: due to how the module's logic is written, this is a breaking change; DSC configs that did not specify a value for Ensure would have behaved as though it were set to Present in the Test-TargetResource function, but to absent in Set-TargetResource, removing the share instead of creating it.) ### 1.1.0.0 + * Fixed bug in xSmbShare resource which was causing Test-TargetResource to return false negatives when more than three parameters were specified. ### 1.0.0.0 * Initial release with the following resources - - xSmbShare - + * xSmbShare ## Examples -#### Ensure the an SMB share exists + +### Ensure the an SMB share exists This configuration ensures that there is a share with the description of "This is a test SMB Share". diff --git a/Tests/Unit/xSmbShare.tests.ps1 b/Tests/Unit/xSmbShare.tests.ps1 new file mode 100644 index 0000000..75f585e --- /dev/null +++ b/Tests/Unit/xSmbShare.tests.ps1 @@ -0,0 +1,386 @@ +$script:DSCModuleName = 'xSmbShare' +$script:DSCResourceName = 'MSFT_xSmbShare' + +# Unit Test Template Version: 1.2.2 +$script:moduleRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot) +if ( (-not (Test-Path -Path (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests'))) -or ` + (-not (Test-Path -Path (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1'))) ) +{ + & git @('clone','https://github.com/PowerShell/DscResource.Tests.git',(Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests')) +} + +Import-Module -Name (Join-Path -Path $script:moduleRoot -ChildPath (Join-Path -Path 'DSCResource.Tests' -ChildPath 'TestHelper.psm1')) -Force + +$TestEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $script:DSCModuleName ` + -DSCResourceName $script:DSCResourceName ` + -ResourceType 'Mof' ` + -TestType Unit + +#endregion HEADER + +function Invoke-TestSetup +{ +} + +function Invoke-TestCleanup +{ + # Restore the test environment + Restore-TestEnvironment -TestEnvironment $TestEnvironment +} + + +# Begin Testing +try +{ + + Invoke-TestSetup + + InModuleScope $script:DSCResourceName { + + # Define test user accounts + $mockUserAccounts = @( + "User1", + "User2", + "User3", + "User4", + "User5" + ) + + # Declare mock objects + $mockChangeAccess = @("User1") + $mockReadAccess = @("User2") + $mockFullAccess = @("User3", "User5") + $mockNoAcess = @("User4") + $mockDefaultChangeAccess = @("User2") + $mockDefaultReadAccess = @("User3") + $mockDefaultFullAccess = @("User1") + $mockDefaultNoAccess = @() + + + $mockSmbShare = ( + New-Object -TypeName Object | + Add-Member -MemberType NoteProperty -Name 'Name' -Value 'DummyShare' -PassThru | + Add-Member -MemberType NoteProperty -Name 'ScopeName' -Value '*' -PassThru | + Add-Member -MemberType NoteProperty -Name 'Path' -Value 'c:\temp' -PassThru | + Add-Member -MemberType NoteProperty -Name 'Description' 'Dummy share for unit testing' -PassThru | + Add-Member -MemberType NoteProperty -Name 'ConcurrentUserLimit' -Value 10 -PassThru | + Add-Member -MemberType NoteProperty -Name 'EncryptData' -Value $false -PassThru | + Add-Member -MemberType NoteProperty -Name 'FolderEnumerationMode' -Value "AccessBased" -PassThru | # 0 AccessBased | 1 Unrestricted, but method expects text + Add-Member -MemberType NoteProperty -Name 'SharedState' -Value 1 -PassThru | # 0 Pending | 1 Online | 2 Offline + Add-Member -MemberType NoteProperty -Name 'ShadowCopy' -Value $false -PassThru | + Add-Member -MemberType NoteProperty -Name 'Special' -Value $false -PassThru + ) + + $mockSmbShareAccess = @(( + New-Object -TypeName Object | + Add-Member -MemberType NoteProperty -Name 'Name' -Value 'DummyShare' -PassThru | + Add-Member -MemberType NoteProperty -Name 'ScopName' -Value '*' -PassThru | + #Add-Member -MemberType NoteProperty -Name 'AccountName' -Value "$($env:COMPUTERNAME)\User1" -PassThru | + Add-Member -MemberType NoteProperty -Name 'AccountName' -Value @("User1") -PassThru | + Add-Member -MemberType NoteProperty -Name 'AccessControlType' -Value 'Allow' -PassThru | + Add-Member -MemberType NoteProperty -Name 'AccessRight' -Value 'Full' -PassThru + ), + ( + New-Object -TypeName Object | + Add-Member -MemberType NoteProperty -Name 'Name' -Value 'DummyShare' -PassThru | + Add-Member -MemberType NoteProperty -Name 'ScopName' -Value '*' -PassThru | + #Add-Member -MemberType NoteProperty -Name 'AccountName' -Value "$($env:COMPUTERNAME)\User2" -PassThru | + Add-Member -MemberType NoteProperty -Name 'AccountName' -Value @("User2") -PassThru | + Add-Member -MemberType NoteProperty -Name 'AccessControlType' -Value 'Allow' -PassThru | + Add-Member -MemberType NoteProperty -Name 'AccessRight' -Value 'Change' -PassThru + ), + ( + New-Object -TypeName Object | + Add-Member -MemberType NoteProperty -Name 'Name' -Value 'DummyShare' -PassThru | + Add-Member -MemberType NoteProperty -Name 'ScopName' -Value '*' -PassThru | + #Add-Member -MemberType NoteProperty -Name 'AccountName' -Value "$($env:COMPUTERNAME)\User3" -PassThru | + Add-Member -MemberType NoteProperty -Name 'AccountName' -Value @("User3") -PassThru | + Add-Member -MemberType NoteProperty -Name 'AccessControlType' -Value 'Allow' -PassThru | + Add-Member -MemberType NoteProperty -Name 'AccessRight' -Value 'Read' -PassThru + ) + ) + + Describe 'MSFT_xSmbShare\Get-TargetResource' -Tag 'Get' { + + Context 'When the system is in the desired state' { + BeforeAll { + # Per context-block initialization + } + + # Mock the command to get the acl + Mock -CommandName Get-SmbShare -MockWith { return @($mockSmbShare)} + Mock -CommandName Get-SmbShareAccess -MockWith { return @($mockSmbShareAccess)} + + # Set testParameters + $testParameters = @{ + Name = $mockSmbShare.Name + Path = $mockSmbShare.Path + } + + # Call Get-TargetResource + + + It 'Should mock call to Get-SmbShare and return membership' { + $result = Get-TargetResource @testParameters + $result.ChangeAccess[0] | Should Be ($mockSmbShareAccess | Where-Object {$_.AccessRight -eq 'Change'}).AccountName + $result.ReadAccess[0] | Should Be ($mockSmbShareAccess | Where-Object {$_.AccessRight -eq 'Read'}).AccountName + $result.FullAccess[0] | Should Be ($mockSmbShareAccess | Where-Object {$_.AccessRight -eq 'Full'}).AccountName + $result.NoAccess[0] | Should BeNullOrEmpty + } + + It 'Should call the mock function Get-SmbShare' { + $result = Get-TargetResource @testParameters + Assert-MockCalled Get-SmbShare -Exactly -Times 1 -Scope It + } + + It 'Should Call the mock function Get-SmbShareAccess' { + $result = Get-TargetResource @testParameters + Assert-MockCalled Get-SmbShareAccess -Exactly -Times 1 -Scope It + } + } + } + + Describe 'MSFT_xSmbShare\Set-TargetResource' -Tag 'Set' { + Context 'When the system is not in the desired state' { + BeforeAll { + # Per context-block initialization + } + + # Set the testParameter collection + $testParameters = @{ + ChangeAccess = $mockChangeAccess + ReadAccess = $mockReadAccess + FullAccess = $mockFullAccess + NoAccess = $mockNoAccess + Name = $mockSmbShare.Name + Path = $mockSmbShare.Path + Description = $mockSmbShare.Description + ConcurrentUserLimit = $mockSmbShare.ConcurrentUserLimit + EncryptData = $mockSmbShare.EncryptData + FolderEnumerationMode = $mockSmbShare.FolderEnumerationMode + Ensure = "Present" + } + + # Init the script variables + $script:ChangeAccess = @() + $script:ReadAccess = @() + $script:FullAccess = @() + $script:NoAccess = @() + $script:ChangeAccess += $mockDefaultChangeAccess + $script:ReadAccess += $mockDefaultReadAccess + $script:FullAccess += $mockDefaultFullAccess + $script:NoAccess += $mockDefaultNoAccess + + + # Set mock function calls + Mock -CommandName Get-SmbShare -MockWith { return @($mockSmbShare)} + Mock -CommandName Get-SmbShareAccess -MockWith { return @($mockSmbShareAccess)} + Mock -CommandName Set-SmbShare -MockWith { return $null} + Mock -CommandName Grant-SmbShareAccess -MockWith { + # Declare local array -- use of this variable was necessary as the script: context was losing the fact it was an array in the mock + $localArray = @() + + switch($AccessPermission) + { + "Change" + { + $localArray += $script:ChangeAccess + if ($localArray -notcontains $UserName) + { + $localArray += $UserName + } + + $script:ChangeAccess = $localArray + break + } + "Read" + { + $localArray += $script:ReadAccess + if($localArray -notcontains $UserName) + { + $localArray += $UserName + } + $script:ReadAccess = $localArray + break + } + "Full" + { + $localArray += $script:FullAccess + if($localArray -notcontains $UserName) + { + $localArray += $UserName + } + $script:FullAccess = $localArray + break + } + } + } + Mock Block-SmbShareAccess -MockWith { + $script:NoAccess += $UserName + } + Mock Revoke-SmbShareAccess -MockWith { + switch($AccessPermission) + { + "Change" + { + # Remove from array + $script:ChangeAccess = $script:ChangeAccess | Where-Object {$_ -ne $UserName} + break + } + "Read" + { + $script:ReadAccess = $script:ReadAccess | Where-Object {$_ -ne $UserName} + break + } + "Full" + { + $script:FullAccess = $script:FullAccess | Where-Object {$_ -ne $UserName} + break + } + } + } + Mock -CommandName Unblock-SmbShareAccess -MockWith { + $script:NoAccess = $script:NoAccess | Where-Object {$_ -ne $UserName} + } + + + + It 'Should alter permissions' { + $result = Set-TargetResource @testParameters + $script:ChangeAccess | Should Be $mockChangeAccess + $script:ReadAccess | Should Be $mockReadAccess + $script:FullAccess | Should Be $mockFullAccess + #$script:NoAccess | Should Be $mockNoAcess + } + + It 'Should call the mock function Get-SmbShare' { + $result = Set-TargetResource @testParameters + Assert-MockCalled Get-SmbShare -Exactly -Times 1 -Scope It + } + + It 'Should Call the mock function Get-SmbShareAccess' { + $result = Set-TargetResource @testParameters + Assert-MockCalled Get-SmbShareAccess -Exactly -Times 4 -Scope It + } + + It 'Should call the mock function Set-SmbShare' { + $result = Set-TargetResource @testParameters + Assert-MockCalled Set-SmbShare -Exactly -Times 1 -Scope It + } + } + } + + Describe 'MSFT_xSmbShare\Test-TargetResource' -Tag 'Test' { + Context 'When the system is not in the desired state' { + + # Set the testParameter collection + $testParameters = @{ + ChangeAccess = $mockChangeAccess + ReadAccess = $mockReadAccess + FullAccess = $mockFullAccess + NoAccess = $mockNoAcess + Name = $mockSmbShare.Name + Path = $mockSmbShare.Path + Description = $mockSmbShare.Description + ConcurrentUserLimit = $mockSmbShare.ConcurrentUserLimit + EncryptData = $mockSmbShare.EncryptData + FolderEnumerationMode = $mockSmbShare.FolderEnumerationMode + Ensure = "Present" + } + + BeforeAll { + # Per context-block initialization + } + + # Set mock function calls + Mock -CommandName Get-SmbShare -MockWith { return @($mockSmbShare)} + Mock -CommandName Get-SmbShareAccess -MockWith { return @($mockSmbShareAccess)} + Mock -CommandName Get-TargetResource -MockWith { return @{ + Name = $mocksmbShare.Name + Path = $mocksmbShare.Path + Description = $mocksmbShare.Description + ConcurrentUserLimit = $mocksmbShare.ConcurrentUserLimit + EncryptData = $mocksmbShare.EncryptData + FolderEnumerationMode = $mocksmbShare.FolderEnumerationMode + ShareState = $mocksmbShare.ShareState + ShareType = $mocksmbShare.ShareType + ShadowCopy = $mocksmbShare.ShadowCopy + Special = $mocksmbShare.Special + ChangeAccess = $mockDefaultchangeAccess + ReadAccess = $mockDefaultreadAccess + FullAccess = $mockDefaultfullAccess + NoAccess = $mockDefaultnoAccess + Ensure = "Present" + } + } + + It 'Should return false' { + # Call the Test-TargetResource + $result = Test-TargetResource @testParameters + + # Result should be false + $result | Should be $false + } + } + + Context 'When the system is in the desired state' { + + # Set the testParameter collection + $testParameters = @{ + ChangeAccess = $mockDefaultChangeAccess + ReadAccess = $mockDefaultReadAccess + FullAccess = $mockDefaultFullAccess + #NoAccess = $null + Name = $mockSmbShare.Name + Path = $mockSmbShare.Path + Description = $mockSmbShare.Description + ConcurrentUserLimit = $mockSmbShare.ConcurrentUserLimit + EncryptData = $mockSmbShare.EncryptData + FolderEnumerationMode = $mockSmbShare.FolderEnumerationMode + Ensure = "Present" + } + + # Set mock function calls + Mock -CommandName Get-SmbShare -MockWith { return @($mockSmbShare)} + Mock -CommandName Get-SmbShareAccess -MockWith { return @($mockSmbShareAccess)} + Mock -CommandName Get-TargetResource -MockWith { return @{ + Name = $mocksmbShare.Name + Path = $mocksmbShare.Path + Description = $mocksmbShare.Description + ConcurrentUserLimit = $mocksmbShare.ConcurrentUserLimit + EncryptData = $mocksmbShare.EncryptData + FolderEnumerationMode = $mocksmbShare.FolderEnumerationMode + ShareState = $mocksmbShare.ShareState + ShareType = $mocksmbShare.ShareType + ShadowCopy = $mocksmbShare.ShadowCopy + Special = $mocksmbShare.Special + ChangeAccess = $mockDefaultchangeAccess + ReadAccess = $mockDefaultreadAccess + FullAccess = $mockDefaultfullAccess + NoAccess = $mockDefaultnoAccess + Ensure = "Present" + } + } + + + It 'Should return true' { + $result = Test-TargetResource @testParameters + + # Result should be true + $result | Should be $true + } + + It 'Should call the mock function Get-TargetResource' { + $result = Test-TargetResource @testParameters + Assert-MockCalled Get-TargetResource -Exactly -Times 1 -Scope It + } + + } + } + } +} +finally +{ + Invoke-TestCleanup +}