From 3250c7c29f16e84022d77de03813ee3ad2e2e632 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andi=20Kr=C3=BCger?= Date: Tue, 21 Jan 2020 11:06:31 +0100 Subject: [PATCH 01/14] New Resource SPOHomeSite --- .../MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 | 195 ++++++++++++++++++ .../MSFT_SPOHomeSite.schema.mof | 9 + .../DSCResources/MSFT_SPOHomeSite/readme.md | 10 + .../SPOHomeSite/1-ConfigureSPOHomeSite.ps1 | 25 +++ .../Office365DSC.SPOHomeSite.Tests.ps1 | 145 +++++++++++++ 5 files changed, 384 insertions(+) create mode 100644 Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 create mode 100644 Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof create mode 100644 Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/readme.md create mode 100644 Modules/Office365DSC/Examples/Resources/SPOHomeSite/1-ConfigureSPOHomeSite.ps1 create mode 100644 Tests/Unit/Office365DSC/Office365DSC.SPOHomeSite.Tests.ps1 diff --git a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 new file mode 100644 index 0000000000..fb78d4f8c9 --- /dev/null +++ b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 @@ -0,0 +1,195 @@ +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [ValidateSet("Yes")] + [String] + $IsSingleInstance, + + [Parameter()] + [System.String] + $Url, + + [Parameter()] + [ValidateSet("Present", "Absent")] + [System.String] + $Ensure = "Present", + + [Parameter(Mandatory = $true)] + [System.Management.Automation.PSCredential] + $GlobalAdminAccount + ) + + Write-Verbose -Message "Getting configuration for hub site collection $Url" + + Test-MSCloudLogin -O365Credential $GlobalAdminAccount ` + -Platform PnP + + $nullReturn = @{ + $IsSingleInstance = $IsSingleInstance + Ensure = "Absent" + GlobalAdminAccount = $GlobalAdminAccount + } + + try + { + Write-Verbose -Message "Getting current home site collection settings" + $homeSiteUrl = Get-SPOHomeSite + if ($null -eq $url) + { + Write-Verbose -Message "There is no Home Site Collection set." + return $nullReturn + } + + $nullReturn = @{ + $IsSingleInstance = $IsSingleInstance + $Url = $homeSiteUrl + Ensure = "Present" + GlobalAdminAccount = $GlobalAdminAccount + } + return $result + } + catch + { + Write-Verbose -Message "There was an error in the SPOHomeSite resource." + return $nullReturn + } +} + +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [ValidateSet("Yes")] + [String] + $IsSingleInstance, + + [Parameter()] + [System.String] + $Url, + + [Parameter()] + [ValidateSet("Present", "Absent")] + [System.String] + $Ensure = "Present", + + [Parameter(Mandatory = $true)] + [System.Management.Automation.PSCredential] + $GlobalAdminAccount + ) + + Write-Verbose -Message "Setting configuration for home site '$Url'" + + Test-MSCloudLogin -O365Credential $GlobalAdminAccount ` + -Platform SharePointOnline + + Test-MSCloudLogin -O365Credential $GlobalAdminAccount ` + -Platform PnP + + $currentValues = Get-TargetResource @PSBoundParameters + + if ($Ensure -eq "Present" -and $currentValues.Ensure -eq "Absent" ` + -or $Ensure -eq "Present" -and $currentValues.Ensure -eq "Present") + { + try + { + Write-Verbose -Message "Setting home site collection $Url" + Get-SPOSite $Url + } + catch + { + $Message = "The specified Site Collection {$Url} for SPOHomeSite doesn't exist." + New-Office365DSCLogEntry -Error $_ -Message $Message + throw $Message + } + + Write-Verbose -Message "Configuring site collection as Home Site" + Set-PnPHomeSite -Url $Url + } + else + { + # Remove home site + Remove-PnPHomeSite -Force + } +} + +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [ValidateSet("Yes")] + [String] + $IsSingleInstance, + + [Parameter()] + [System.String] + $Url, + + [Parameter()] + [ValidateSet("Present", "Absent")] + [System.String] + $Ensure = "Present", + + [Parameter(Mandatory = $true)] + [System.Management.Automation.PSCredential] + $GlobalAdminAccount + ) + + Write-Verbose -Message "Testing configuration for home site collection" + + $CurrentValues = Get-TargetResource @PSBoundParameters + + Write-Verbose -Message "Current Values: $(Convert-O365DscHashtableToString -Hashtable $CurrentValues)" + Write-Verbose -Message "Target Values: $(Convert-O365DscHashtableToString -Hashtable $PSBoundParameters)" + + $valuesToCheck = @("Ensure") + if ($PSBoundParameters.ContainsKey("Url")) + { + $valuesToCheck += "Url" + } + + $TestResult = Test-Office365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $valuesToCheck + + Write-Verbose -Message "Test-TargetResource returned $TestResult" + + return $TestResult +} + +function Export-TargetResource +{ + [CmdletBinding()] + [OutputType([System.String])] + param + ( + [Parameter(Mandatory = $true)] + [ValidateSet("Yes")] + [String] + $IsSingleInstance, + + [Parameter(Mandatory = $true)] + [System.Management.Automation.PSCredential] + $GlobalAdminAccount + ) + $result = Get-TargetResource @PSBoundParameters + $result.GlobalAdminAccount = "`$Credsglobaladmin" + + $content = " SPOHomeSite " + (New-GUID).ToString() + "`r`n" + $content += " {`r`n" + $currentDSCBlock = Get-DSCBlock -Params $result -ModulePath $PSScriptRoot + $content += Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName "GlobalAdminAccount" + $content += " }`r`n" + return $content +} + +Export-ModuleMember -Function *-TargetResource diff --git a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof new file mode 100644 index 0000000000..a008dad08e --- /dev/null +++ b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof @@ -0,0 +1,9 @@ +[ClassVersion("1.0.0.0"), FriendlyName("SPOHomeSite")] +class MSFT_SPOHubSite : OMI_BaseResource +{ + [Key, Description("Specifies the resource is a single instance, the value must be 'Yes'"), ValueMap{"Yes"}, Values{"Yes"}] String IsSingleInstance; + [Write, Description("The URL of the home site collection")] string HomeSiteUrl; + [Write, Description("Present ensures the site collection is registered as hub site, absent ensures it is unregistered"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] string Ensure; + [Required, Description("Credentials of the SharePoint Global Admin"), EmbeddedInstance("MSFT_Credential")] string GlobalAdminAccount; +}; + diff --git a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/readme.md b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/readme.md new file mode 100644 index 0000000000..be1e055b0f --- /dev/null +++ b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/readme.md @@ -0,0 +1,10 @@ +# Description + +This resource allows administrators to configure a Site Collection as the Home +Site of the tenant. The menu of this SharePoint Site Collection will be shown on +SharePoint Home. + +> NOTE: +> This setting is not applied immediately and can take several hours to be fully +> available within the tenant. Please use this resource with caution, as a direct +> test run can lead to incorrect status results. diff --git a/Modules/Office365DSC/Examples/Resources/SPOHomeSite/1-ConfigureSPOHomeSite.ps1 b/Modules/Office365DSC/Examples/Resources/SPOHomeSite/1-ConfigureSPOHomeSite.ps1 new file mode 100644 index 0000000000..e6702a5763 --- /dev/null +++ b/Modules/Office365DSC/Examples/Resources/SPOHomeSite/1-ConfigureSPOHomeSite.ps1 @@ -0,0 +1,25 @@ +<# +This example is used to test new resources and showcase the usage of new resources being worked on. +It is not meant to use as a production baseline. +#> + +Configuration Example +{ + param( + [Parameter(Mandatory = $true)] + [PSCredential] + $credsGlobalAdmin + ) + Import-DscResource -ModuleName Office365DSC + + node localhost + { + SPOHomeSite "ff4a977d-4d7d-4968-9238-2a1702aa699c" + { + IsSingleInstance = "Yes" + Url = "https://office365dsc.sharepoint.com/sites/Marketing" + Ensure = "Present" + GlobalAdminAccount = $credsGlobalAdmin + } + } +} diff --git a/Tests/Unit/Office365DSC/Office365DSC.SPOHomeSite.Tests.ps1 b/Tests/Unit/Office365DSC/Office365DSC.SPOHomeSite.Tests.ps1 new file mode 100644 index 0000000000..24b109fdfa --- /dev/null +++ b/Tests/Unit/Office365DSC/Office365DSC.SPOHomeSite.Tests.ps1 @@ -0,0 +1,145 @@ +[CmdletBinding()] +param( + [Parameter()] + [string] + $CmdletModule = (Join-Path -Path $PSScriptRoot ` + -ChildPath "..\Stubs\Office365.psm1" ` + -Resolve) +) +$GenericStubPath = (Join-Path -Path $PSScriptRoot ` + -ChildPath "..\Stubs\Generic.psm1" ` + -Resolve) + +Import-Module -Name (Join-Path -Path $PSScriptRoot ` + -ChildPath "..\UnitTestHelper.psm1" ` + -Resolve) + +$Global:DscHelper = New-O365DscUnitTestHelper -StubModule $CmdletModule ` + -DscResource "SPOHomeSite" -GenericStubModule $GenericStubPath + +Describe -Name $Global:DscHelper.DescribeHeader -Fixture { + InModuleScope -ModuleName $Global:DscHelper.ModuleName -ScriptBlock { + Invoke-Command -ScriptBlock $Global:DscHelper.InitializeScript -NoNewScope + + $secpasswd = ConvertTo-SecureString "test@password1" -AsPlainText -Force + $GlobalAdminAccount = New-Object System.Management.Automation.PSCredential ("tenantadmin", $secpasswd) + + Mock -CommandName Test-MSCloudLogin -MockWith { } + + # Test contexts + Context -Name "When there should be no home site set" -Fixture { + $testParams = @{ + IsSingleInstance = "Yes" + GlobalAdminAccount = $GlobalAdminAccount + Ensure = "Absent" + } + + Mock -CommandName Get-SPOHomeSite -MockWith { + return $null + } + + It "Should return absent from the Get method" { + (Get-TargetResource @testParams).Ensure | Should Be "Absent" + } + + It "Should return true from the Test method" { + Test-TargetResource @testParams | Should Be $true + } + } + + Context -Name "When there is a home site and there should not be" -Fixture { + $testParams = @{ + IsSingleInstance = "Yes" + GlobalAdminAccount = $GlobalAdminAccount + Ensure = "Absent" + } + + Mock -CommandName Get-SPOHomeSite -MockWith { + return "https://contoso.sharepoint.com/sites/homesite" + } + + Mock -CommandName Remove-PnPHomeSite -MockWith { + + } + + It "Should return present from the Get method" { + (Get-TargetResource @testParams).Ensure | Should Be "Present" + } + + It "Should return false from the Test method" { + Test-TargetResource @testParams | Should Be $false + } + + It "Should call Remove-PnPHomeSite" { + Set-TargetResource @testParams + Assert-MockCalled Remove-PnPHomeSite + } + } + + Context -Name "When there should be a home site set and there is not or it's the wrong one" -Fixture { + $testParams = @{ + IsSingleInstance = "Yes" + Url = "https://contoso.sharepoint.com/sites/homesite" + GlobalAdminAccount = $GlobalAdminAccount + Ensure = "Present" + } + + Mock -CommandName Get-SPOHomeSite -MockWith { + return "https://contoso.sharepoint.com/sites/homesite" + } + + Mock -CommandName Get-SPOSite -MockWith { + throw + } + + Mock -CommandName Set-PnPHomeSite -MockWith { + } + + + Mock -CommandName New-Office365DSCLogEntry -MockWith { + } + + + It "Should return Present from the Get method" { + (Get-TargetResource @testParams).Ensure | Should Be "Present" + } + + It "Should return false from the Test method" { + Test-TargetResource @testParams | Should Be $false + } + + It "Should set the correct site" { + Set-TargetResource @testParams | Should Throw "The specified Site Collection $($testParams.Url) for SPOHomeSite doesn't exist." + Assert-MockCalled Get-SPOSite + Assert-MockCalled New-Office365DSCLogEntry + } + + Mock -CommandName Get-SPOSite -MockWith { + return "" + } + + It "Should set the correct site" { + Set-TargetResource @testParams + Assert-MockCalled Get-SPOSite + Assert-MockCalled Set-PnPHomeSite + } + } + + Context -Name "ReverseDSC Tests" -Fixture { + $testParams = @{ + IsSingleInstance = "Yes" + GlobalAdminAccount = $GlobalAdminAccount + } + + Mock -CommandName Get-SPOHomeSite -MockWith { + return "https://contoso.sharepoint.com/sites/TestSite" + } + + It "Should Reverse Engineer resource from the Export method" { + Export-TargetResource @testParams + } + } + } +} + +Invoke-Command -ScriptBlock $Global:DscHelper.CleanupScript -NoNewScope From 039428170ba25271c6229c71d506ac86c96aee26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andi=20Kr=C3=BCger?= Date: Tue, 21 Jan 2020 11:07:18 +0100 Subject: [PATCH 02/14] New Resource SPOHomeSite --- CHANGELOG.md | 2 + .../DSCResources/MSFT_SPOHomeSite/readme.md | 1 + .../Office365DSC/Modules/O365DSCReverse.psm1 | 58 ++++++++++++++----- .../Modules/O365DSCReverseGUI.psm1 | 9 +++ 4 files changed, 55 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9690d61ec3..5f1061cda7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,8 @@ 16.0.19515.12000; * Updated ReverseDSC dependency to version 2.0.0.2; * Updated SharePointPnPPowerShellOnline to version 3.17.2001.2; +* SPOHomeSite + * Initial Release; ## 1.0.1.1395 diff --git a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/readme.md b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/readme.md index be1e055b0f..5246126b48 100644 --- a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/readme.md +++ b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/readme.md @@ -8,3 +8,4 @@ SharePoint Home. > This setting is not applied immediately and can take several hours to be fully > available within the tenant. Please use this resource with caution, as a direct > test run can lead to incorrect status results. +> For more details about setting the home site, go to> aka.ms/homesites diff --git a/Modules/Office365DSC/Modules/O365DSCReverse.psm1 b/Modules/Office365DSC/Modules/O365DSCReverse.psm1 index 6e00e6fccc..2188feea9c 100644 --- a/Modules/Office365DSC/Modules/O365DSCReverse.psm1 +++ b/Modules/Office365DSC/Modules/O365DSCReverse.psm1 @@ -106,28 +106,56 @@ function Start-O365ConfigurationExtract Save-Credentials -UserName "globaladmin" $ResourcesPath = Join-Path -Path $PSScriptRoot ` - -ChildPath "..\DSCResources\" ` - -Resolve - $AllResources = Get-ChildItem $ResourcesPath -Recurse | Where-Object {$_.Name -like 'MSFT_*.psm1'} + -ChildPath "..\DSCResources\" ` + -Resolve + $AllResources = Get-ChildItem $ResourcesPath -Recurse | Where-Object { $_.Name -like 'MSFT_*.psm1' } foreach ($ResourceModule in $AllResources) { try { $resourceName = $ResourceModule.Name.Split('.')[0].Replace('MSFT_', '') - $currentWorkload = $ResourceName.Substring(0,2) + $currentWorkload = $ResourceName.Substring(0, 2) switch ($currentWorkload) { - 'O3' {$currentWorkload = 'O365'; break} - 'OD' {$currentWorkload = 'OD'; break} - 'PP' {$currentWorkload = 'PP'; break} - 'SC' {$currentWorkload = 'SC'; break} - 'SP' {$currentWorkload = 'SPO'; break} - 'TE' {$currentWorkload = 'TEAMS'; break} - default {$currentWorkload = $null; break} + 'O3' + { + $currentWorkload = 'O365'; + break + } + 'OD' + { + $currentWorkload = 'OD'; + break + } + 'PP' + { + $currentWorkload = 'PP'; + break + } + 'SC' + { + $currentWorkload = 'SC'; + break + } + 'SP' + { + $currentWorkload = 'SPO'; + break + } + 'TE' + { + $currentWorkload = 'TEAMS'; + break + } + default + { + $currentWorkload = $null; + break + } } if (($null -ne $ComponentsToExtract -and - $ComponentsToExtract.Contains("chck" + $resourceName)) -or + $ComponentsToExtract.Contains("chck" + $resourceName)) -or $AllComponents -or ($null -ne $Workloads -and $Workloads.Contains($currentWorkload))) { Import-Module $ResourceModule.FullName | Out-Null @@ -215,9 +243,9 @@ function Start-O365ConfigurationExtract #endregion #region Copy Downloaded files back into output folder - ($null -ne $ComponentsToExtract -and - $ComponentsToExtract.Contains("chckSPOApp")) -or - $AllComponents -or ($null -ne $Workloads -and $Workloads.Contains('SPO')) + if ($null -ne $ComponentsToExtract -and + $ComponentsToExtract.Contains("chckSPOApp")) -or + $AllComponents -or ($null -ne $Workloads -and $Workloads.Contains('SPO')) { $filesToDownload = Get-AllSPOPackages -GlobalAdminAccount $GlobalAdminAccount if ($filesToDownload.Count -gt 0) diff --git a/Modules/Office365DSC/Modules/O365DSCReverseGUI.psm1 b/Modules/Office365DSC/Modules/O365DSCReverseGUI.psm1 index 1d7490a67c..52b6dc4695 100644 --- a/Modules/Office365DSC/Modules/O365DSCReverseGUI.psm1 +++ b/Modules/Office365DSC/Modules/O365DSCReverseGUI.psm1 @@ -353,6 +353,15 @@ function Show-O365GUI $chckSPOHubSite.Text = "Hub Sites" $pnlSPO.Controls.Add($chckSPOHubSite) + $chckSPOHomeSite = New-Object System.Windows.Forms.CheckBox + $chckSPOHomeSite.Top = 40 + $chckSPOHomeSite.AutoSize = $true; + $chckSPOHomeSite.Name = "chckSPOHomeSite" + $chckSPOHomeSite.Checked = $true + $chckSPOHomeSite.Enabled = $true + $chckSPOHomeSite.Text = "Home Site" + $pnlSPO.Controls.Add($chckSPOHomeSite) + $chckSPOPropertyBag = New-Object System.Windows.Forms.CheckBox $chckSPOPropertyBag.Top = 60 $chckSPOPropertyBag.AutoSize = $true; From bae00ca6b417eb807a58290c66271c7b112d0983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andi=20Kr=C3=BCger?= Date: Tue, 21 Jan 2020 14:45:04 +0100 Subject: [PATCH 03/14] Fix for missing () --- Modules/Office365DSC/Modules/O365DSCReverse.psm1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/Office365DSC/Modules/O365DSCReverse.psm1 b/Modules/Office365DSC/Modules/O365DSCReverse.psm1 index 2188feea9c..7c97deca78 100644 --- a/Modules/Office365DSC/Modules/O365DSCReverse.psm1 +++ b/Modules/Office365DSC/Modules/O365DSCReverse.psm1 @@ -243,9 +243,9 @@ function Start-O365ConfigurationExtract #endregion #region Copy Downloaded files back into output folder - if ($null -ne $ComponentsToExtract -and - $ComponentsToExtract.Contains("chckSPOApp")) -or - $AllComponents -or ($null -ne $Workloads -and $Workloads.Contains('SPO')) + if (($null -ne $ComponentsToExtract -and + $ComponentsToExtract.Contains("chckSPOApp")) -or + $AllComponents -or ($null -ne $Workloads -and $Workloads.Contains('SPO'))) { $filesToDownload = Get-AllSPOPackages -GlobalAdminAccount $GlobalAdminAccount if ($filesToDownload.Count -gt 0) From 7989be8f217aea8459cb58fc5df32ce2c0da60c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andi=20Kr=C3=BCger?= Date: Tue, 21 Jan 2020 15:53:21 +0100 Subject: [PATCH 04/14] unit test fixes --- .../MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 | 22 ++++++++------- .../Office365DSC.SPOHomeSite.Tests.ps1 | 28 +++++++++++++++---- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 index fb78d4f8c9..2274ba174e 100644 --- a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 +++ b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 @@ -38,25 +38,27 @@ function Get-TargetResource { Write-Verbose -Message "Getting current home site collection settings" $homeSiteUrl = Get-SPOHomeSite - if ($null -eq $url) + if ($null -eq $homeSiteUrl) { Write-Verbose -Message "There is no Home Site Collection set." return $nullReturn } - - $nullReturn = @{ - $IsSingleInstance = $IsSingleInstance - $Url = $homeSiteUrl - Ensure = "Present" - GlobalAdminAccount = $GlobalAdminAccount + else + { + $result = @{ + $IsSingleInstance = $IsSingleInstance + $Url = $homeSiteUrl + Ensure = "Present" + GlobalAdminAccount = $GlobalAdminAccount + } + return $result } - return $result } catch { Write-Verbose -Message "There was an error in the SPOHomeSite resource." - return $nullReturn } + return $nullReturn } function Set-TargetResource @@ -103,7 +105,7 @@ function Set-TargetResource } catch { - $Message = "The specified Site Collection {$Url} for SPOHomeSite doesn't exist." + $Message = "The specified Site Collection $($Url) for SPOHomeSite doesn't exist." New-Office365DSCLogEntry -Error $_ -Message $Message throw $Message } diff --git a/Tests/Unit/Office365DSC/Office365DSC.SPOHomeSite.Tests.ps1 b/Tests/Unit/Office365DSC/Office365DSC.SPOHomeSite.Tests.ps1 index 24b109fdfa..5ec3232117 100644 --- a/Tests/Unit/Office365DSC/Office365DSC.SPOHomeSite.Tests.ps1 +++ b/Tests/Unit/Office365DSC/Office365DSC.SPOHomeSite.Tests.ps1 @@ -38,7 +38,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { return $null } - It "Should return absent from the Get method" { + It "Should return Absent from the Get method" { (Get-TargetResource @testParams).Ensure | Should Be "Absent" } @@ -58,7 +58,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { return "https://contoso.sharepoint.com/sites/homesite" } - Mock -CommandName Remove-PnPHomeSite -MockWith { + Mock -CommandName Remove-PnPHomeSite -MockWith { } @@ -108,14 +108,30 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Test-TargetResource @testParams | Should Be $false } - It "Should set the correct site" { - Set-TargetResource @testParams | Should Throw "The specified Site Collection $($testParams.Url) for SPOHomeSite doesn't exist." + It "Should throw an error" { + { Set-TargetResource @testParams } | Should Throw "The specified Site Collection $($testParams.Url) for SPOHomeSite doesn't exist." Assert-MockCalled Get-SPOSite Assert-MockCalled New-Office365DSCLogEntry } + } + + Context -Name "It should set the home site" -Fixture { + $testParams = @{ + IsSingleInstance = "Yes" + Url = "https://contoso.sharepoint.com/sites/homesite" + GlobalAdminAccount = $GlobalAdminAccount + Ensure = "Present" + } + + Mock -CommandName Get-SPOHomeSite -MockWith { + return "https://contoso.sharepoint.com/sites/homesite1" + } + + Mock -CommandName Set-PnPHomeSite -MockWith { + } Mock -CommandName Get-SPOSite -MockWith { - return "" + } It "Should set the correct site" { @@ -127,7 +143,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Context -Name "ReverseDSC Tests" -Fixture { $testParams = @{ - IsSingleInstance = "Yes" + IsSingleInstance = "Yes" GlobalAdminAccount = $GlobalAdminAccount } From 5b2189774d043da6b710edb488c83d81f81f561c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andi=20Kr=C3=BCger?= <15608729+andikrueger@users.noreply.github.com> Date: Tue, 21 Jan 2020 20:01:23 +0100 Subject: [PATCH 05/14] Update MSFT_SPOHomeSite.schema.mof Fixed naming issue --- .../DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof index a008dad08e..75a3474695 100644 --- a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof +++ b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof @@ -1,9 +1,9 @@ [ClassVersion("1.0.0.0"), FriendlyName("SPOHomeSite")] -class MSFT_SPOHubSite : OMI_BaseResource +class MSFT_SPOHomeSite : OMI_BaseResource { [Key, Description("Specifies the resource is a single instance, the value must be 'Yes'"), ValueMap{"Yes"}, Values{"Yes"}] String IsSingleInstance; [Write, Description("The URL of the home site collection")] string HomeSiteUrl; - [Write, Description("Present ensures the site collection is registered as hub site, absent ensures it is unregistered"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] string Ensure; + [Write, Description("Present ensures the site collection is registered as home site, absent ensures it is unregistered"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] string Ensure; [Required, Description("Credentials of the SharePoint Global Admin"), EmbeddedInstance("MSFT_Credential")] string GlobalAdminAccount; }; From b77395703e4dbb4a49abf0bd8a9d9bd920bc97c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andi=20Kr=C3=BCger?= <15608729+andikrueger@users.noreply.github.com> Date: Tue, 21 Jan 2020 20:02:36 +0100 Subject: [PATCH 06/14] Update MSFT_SPOHomeSite.schema.mof Fixed parameter name --- .../DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof index 75a3474695..7f18635103 100644 --- a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof +++ b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof @@ -2,7 +2,7 @@ class MSFT_SPOHomeSite : OMI_BaseResource { [Key, Description("Specifies the resource is a single instance, the value must be 'Yes'"), ValueMap{"Yes"}, Values{"Yes"}] String IsSingleInstance; - [Write, Description("The URL of the home site collection")] string HomeSiteUrl; + [Write, Description("The URL of the home site collection")] string Url; [Write, Description("Present ensures the site collection is registered as home site, absent ensures it is unregistered"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] string Ensure; [Required, Description("Credentials of the SharePoint Global Admin"), EmbeddedInstance("MSFT_Credential")] string GlobalAdminAccount; }; From ff0d72c8d92ff978e6350995257389795a34c0ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andi=20Kr=C3=BCger?= Date: Tue, 21 Jan 2020 11:06:31 +0100 Subject: [PATCH 07/14] New Resource SPOHomeSite --- .../MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 | 195 ++++++++++++++++++ .../MSFT_SPOHomeSite.schema.mof | 9 + .../DSCResources/MSFT_SPOHomeSite/readme.md | 10 + .../SPOHomeSite/1-ConfigureSPOHomeSite.ps1 | 25 +++ .../Office365DSC.SPOHomeSite.Tests.ps1 | 145 +++++++++++++ 5 files changed, 384 insertions(+) create mode 100644 Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 create mode 100644 Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof create mode 100644 Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/readme.md create mode 100644 Modules/Office365DSC/Examples/Resources/SPOHomeSite/1-ConfigureSPOHomeSite.ps1 create mode 100644 Tests/Unit/Office365DSC/Office365DSC.SPOHomeSite.Tests.ps1 diff --git a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 new file mode 100644 index 0000000000..fb78d4f8c9 --- /dev/null +++ b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 @@ -0,0 +1,195 @@ +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [ValidateSet("Yes")] + [String] + $IsSingleInstance, + + [Parameter()] + [System.String] + $Url, + + [Parameter()] + [ValidateSet("Present", "Absent")] + [System.String] + $Ensure = "Present", + + [Parameter(Mandatory = $true)] + [System.Management.Automation.PSCredential] + $GlobalAdminAccount + ) + + Write-Verbose -Message "Getting configuration for hub site collection $Url" + + Test-MSCloudLogin -O365Credential $GlobalAdminAccount ` + -Platform PnP + + $nullReturn = @{ + $IsSingleInstance = $IsSingleInstance + Ensure = "Absent" + GlobalAdminAccount = $GlobalAdminAccount + } + + try + { + Write-Verbose -Message "Getting current home site collection settings" + $homeSiteUrl = Get-SPOHomeSite + if ($null -eq $url) + { + Write-Verbose -Message "There is no Home Site Collection set." + return $nullReturn + } + + $nullReturn = @{ + $IsSingleInstance = $IsSingleInstance + $Url = $homeSiteUrl + Ensure = "Present" + GlobalAdminAccount = $GlobalAdminAccount + } + return $result + } + catch + { + Write-Verbose -Message "There was an error in the SPOHomeSite resource." + return $nullReturn + } +} + +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [ValidateSet("Yes")] + [String] + $IsSingleInstance, + + [Parameter()] + [System.String] + $Url, + + [Parameter()] + [ValidateSet("Present", "Absent")] + [System.String] + $Ensure = "Present", + + [Parameter(Mandatory = $true)] + [System.Management.Automation.PSCredential] + $GlobalAdminAccount + ) + + Write-Verbose -Message "Setting configuration for home site '$Url'" + + Test-MSCloudLogin -O365Credential $GlobalAdminAccount ` + -Platform SharePointOnline + + Test-MSCloudLogin -O365Credential $GlobalAdminAccount ` + -Platform PnP + + $currentValues = Get-TargetResource @PSBoundParameters + + if ($Ensure -eq "Present" -and $currentValues.Ensure -eq "Absent" ` + -or $Ensure -eq "Present" -and $currentValues.Ensure -eq "Present") + { + try + { + Write-Verbose -Message "Setting home site collection $Url" + Get-SPOSite $Url + } + catch + { + $Message = "The specified Site Collection {$Url} for SPOHomeSite doesn't exist." + New-Office365DSCLogEntry -Error $_ -Message $Message + throw $Message + } + + Write-Verbose -Message "Configuring site collection as Home Site" + Set-PnPHomeSite -Url $Url + } + else + { + # Remove home site + Remove-PnPHomeSite -Force + } +} + +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [ValidateSet("Yes")] + [String] + $IsSingleInstance, + + [Parameter()] + [System.String] + $Url, + + [Parameter()] + [ValidateSet("Present", "Absent")] + [System.String] + $Ensure = "Present", + + [Parameter(Mandatory = $true)] + [System.Management.Automation.PSCredential] + $GlobalAdminAccount + ) + + Write-Verbose -Message "Testing configuration for home site collection" + + $CurrentValues = Get-TargetResource @PSBoundParameters + + Write-Verbose -Message "Current Values: $(Convert-O365DscHashtableToString -Hashtable $CurrentValues)" + Write-Verbose -Message "Target Values: $(Convert-O365DscHashtableToString -Hashtable $PSBoundParameters)" + + $valuesToCheck = @("Ensure") + if ($PSBoundParameters.ContainsKey("Url")) + { + $valuesToCheck += "Url" + } + + $TestResult = Test-Office365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $valuesToCheck + + Write-Verbose -Message "Test-TargetResource returned $TestResult" + + return $TestResult +} + +function Export-TargetResource +{ + [CmdletBinding()] + [OutputType([System.String])] + param + ( + [Parameter(Mandatory = $true)] + [ValidateSet("Yes")] + [String] + $IsSingleInstance, + + [Parameter(Mandatory = $true)] + [System.Management.Automation.PSCredential] + $GlobalAdminAccount + ) + $result = Get-TargetResource @PSBoundParameters + $result.GlobalAdminAccount = "`$Credsglobaladmin" + + $content = " SPOHomeSite " + (New-GUID).ToString() + "`r`n" + $content += " {`r`n" + $currentDSCBlock = Get-DSCBlock -Params $result -ModulePath $PSScriptRoot + $content += Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName "GlobalAdminAccount" + $content += " }`r`n" + return $content +} + +Export-ModuleMember -Function *-TargetResource diff --git a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof new file mode 100644 index 0000000000..a008dad08e --- /dev/null +++ b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof @@ -0,0 +1,9 @@ +[ClassVersion("1.0.0.0"), FriendlyName("SPOHomeSite")] +class MSFT_SPOHubSite : OMI_BaseResource +{ + [Key, Description("Specifies the resource is a single instance, the value must be 'Yes'"), ValueMap{"Yes"}, Values{"Yes"}] String IsSingleInstance; + [Write, Description("The URL of the home site collection")] string HomeSiteUrl; + [Write, Description("Present ensures the site collection is registered as hub site, absent ensures it is unregistered"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] string Ensure; + [Required, Description("Credentials of the SharePoint Global Admin"), EmbeddedInstance("MSFT_Credential")] string GlobalAdminAccount; +}; + diff --git a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/readme.md b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/readme.md new file mode 100644 index 0000000000..be1e055b0f --- /dev/null +++ b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/readme.md @@ -0,0 +1,10 @@ +# Description + +This resource allows administrators to configure a Site Collection as the Home +Site of the tenant. The menu of this SharePoint Site Collection will be shown on +SharePoint Home. + +> NOTE: +> This setting is not applied immediately and can take several hours to be fully +> available within the tenant. Please use this resource with caution, as a direct +> test run can lead to incorrect status results. diff --git a/Modules/Office365DSC/Examples/Resources/SPOHomeSite/1-ConfigureSPOHomeSite.ps1 b/Modules/Office365DSC/Examples/Resources/SPOHomeSite/1-ConfigureSPOHomeSite.ps1 new file mode 100644 index 0000000000..e6702a5763 --- /dev/null +++ b/Modules/Office365DSC/Examples/Resources/SPOHomeSite/1-ConfigureSPOHomeSite.ps1 @@ -0,0 +1,25 @@ +<# +This example is used to test new resources and showcase the usage of new resources being worked on. +It is not meant to use as a production baseline. +#> + +Configuration Example +{ + param( + [Parameter(Mandatory = $true)] + [PSCredential] + $credsGlobalAdmin + ) + Import-DscResource -ModuleName Office365DSC + + node localhost + { + SPOHomeSite "ff4a977d-4d7d-4968-9238-2a1702aa699c" + { + IsSingleInstance = "Yes" + Url = "https://office365dsc.sharepoint.com/sites/Marketing" + Ensure = "Present" + GlobalAdminAccount = $credsGlobalAdmin + } + } +} diff --git a/Tests/Unit/Office365DSC/Office365DSC.SPOHomeSite.Tests.ps1 b/Tests/Unit/Office365DSC/Office365DSC.SPOHomeSite.Tests.ps1 new file mode 100644 index 0000000000..24b109fdfa --- /dev/null +++ b/Tests/Unit/Office365DSC/Office365DSC.SPOHomeSite.Tests.ps1 @@ -0,0 +1,145 @@ +[CmdletBinding()] +param( + [Parameter()] + [string] + $CmdletModule = (Join-Path -Path $PSScriptRoot ` + -ChildPath "..\Stubs\Office365.psm1" ` + -Resolve) +) +$GenericStubPath = (Join-Path -Path $PSScriptRoot ` + -ChildPath "..\Stubs\Generic.psm1" ` + -Resolve) + +Import-Module -Name (Join-Path -Path $PSScriptRoot ` + -ChildPath "..\UnitTestHelper.psm1" ` + -Resolve) + +$Global:DscHelper = New-O365DscUnitTestHelper -StubModule $CmdletModule ` + -DscResource "SPOHomeSite" -GenericStubModule $GenericStubPath + +Describe -Name $Global:DscHelper.DescribeHeader -Fixture { + InModuleScope -ModuleName $Global:DscHelper.ModuleName -ScriptBlock { + Invoke-Command -ScriptBlock $Global:DscHelper.InitializeScript -NoNewScope + + $secpasswd = ConvertTo-SecureString "test@password1" -AsPlainText -Force + $GlobalAdminAccount = New-Object System.Management.Automation.PSCredential ("tenantadmin", $secpasswd) + + Mock -CommandName Test-MSCloudLogin -MockWith { } + + # Test contexts + Context -Name "When there should be no home site set" -Fixture { + $testParams = @{ + IsSingleInstance = "Yes" + GlobalAdminAccount = $GlobalAdminAccount + Ensure = "Absent" + } + + Mock -CommandName Get-SPOHomeSite -MockWith { + return $null + } + + It "Should return absent from the Get method" { + (Get-TargetResource @testParams).Ensure | Should Be "Absent" + } + + It "Should return true from the Test method" { + Test-TargetResource @testParams | Should Be $true + } + } + + Context -Name "When there is a home site and there should not be" -Fixture { + $testParams = @{ + IsSingleInstance = "Yes" + GlobalAdminAccount = $GlobalAdminAccount + Ensure = "Absent" + } + + Mock -CommandName Get-SPOHomeSite -MockWith { + return "https://contoso.sharepoint.com/sites/homesite" + } + + Mock -CommandName Remove-PnPHomeSite -MockWith { + + } + + It "Should return present from the Get method" { + (Get-TargetResource @testParams).Ensure | Should Be "Present" + } + + It "Should return false from the Test method" { + Test-TargetResource @testParams | Should Be $false + } + + It "Should call Remove-PnPHomeSite" { + Set-TargetResource @testParams + Assert-MockCalled Remove-PnPHomeSite + } + } + + Context -Name "When there should be a home site set and there is not or it's the wrong one" -Fixture { + $testParams = @{ + IsSingleInstance = "Yes" + Url = "https://contoso.sharepoint.com/sites/homesite" + GlobalAdminAccount = $GlobalAdminAccount + Ensure = "Present" + } + + Mock -CommandName Get-SPOHomeSite -MockWith { + return "https://contoso.sharepoint.com/sites/homesite" + } + + Mock -CommandName Get-SPOSite -MockWith { + throw + } + + Mock -CommandName Set-PnPHomeSite -MockWith { + } + + + Mock -CommandName New-Office365DSCLogEntry -MockWith { + } + + + It "Should return Present from the Get method" { + (Get-TargetResource @testParams).Ensure | Should Be "Present" + } + + It "Should return false from the Test method" { + Test-TargetResource @testParams | Should Be $false + } + + It "Should set the correct site" { + Set-TargetResource @testParams | Should Throw "The specified Site Collection $($testParams.Url) for SPOHomeSite doesn't exist." + Assert-MockCalled Get-SPOSite + Assert-MockCalled New-Office365DSCLogEntry + } + + Mock -CommandName Get-SPOSite -MockWith { + return "" + } + + It "Should set the correct site" { + Set-TargetResource @testParams + Assert-MockCalled Get-SPOSite + Assert-MockCalled Set-PnPHomeSite + } + } + + Context -Name "ReverseDSC Tests" -Fixture { + $testParams = @{ + IsSingleInstance = "Yes" + GlobalAdminAccount = $GlobalAdminAccount + } + + Mock -CommandName Get-SPOHomeSite -MockWith { + return "https://contoso.sharepoint.com/sites/TestSite" + } + + It "Should Reverse Engineer resource from the Export method" { + Export-TargetResource @testParams + } + } + } +} + +Invoke-Command -ScriptBlock $Global:DscHelper.CleanupScript -NoNewScope From 678e31e8bbce0b67c36f4059dc17e2a2e2cacd0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andi=20Kr=C3=BCger?= Date: Tue, 21 Jan 2020 11:07:18 +0100 Subject: [PATCH 08/14] New Resource SPOHomeSite --- CHANGELOG.md | 2 + .../DSCResources/MSFT_SPOHomeSite/readme.md | 1 + .../Office365DSC/Modules/O365DSCReverse.psm1 | 56 ++++++++++++++----- .../Modules/O365DSCReverseGUI.psm1 | 9 +++ 4 files changed, 54 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6603b7f929..8d7bd63935 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,8 @@ 16.0.19515.12000; * Updated ReverseDSC dependency to version 2.0.0.2; * Updated SharePointPnPPowerShellOnline to version 3.17.2001.2; +* SPOHomeSite + * Initial Release; ## 1.0.1.1395 diff --git a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/readme.md b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/readme.md index be1e055b0f..5246126b48 100644 --- a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/readme.md +++ b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/readme.md @@ -8,3 +8,4 @@ SharePoint Home. > This setting is not applied immediately and can take several hours to be fully > available within the tenant. Please use this resource with caution, as a direct > test run can lead to incorrect status results. +> For more details about setting the home site, go to> aka.ms/homesites diff --git a/Modules/Office365DSC/Modules/O365DSCReverse.psm1 b/Modules/Office365DSC/Modules/O365DSCReverse.psm1 index cafe210e00..7c97deca78 100644 --- a/Modules/Office365DSC/Modules/O365DSCReverse.psm1 +++ b/Modules/Office365DSC/Modules/O365DSCReverse.psm1 @@ -106,28 +106,56 @@ function Start-O365ConfigurationExtract Save-Credentials -UserName "globaladmin" $ResourcesPath = Join-Path -Path $PSScriptRoot ` - -ChildPath "..\DSCResources\" ` - -Resolve - $AllResources = Get-ChildItem $ResourcesPath -Recurse | Where-Object {$_.Name -like 'MSFT_*.psm1'} + -ChildPath "..\DSCResources\" ` + -Resolve + $AllResources = Get-ChildItem $ResourcesPath -Recurse | Where-Object { $_.Name -like 'MSFT_*.psm1' } foreach ($ResourceModule in $AllResources) { try { $resourceName = $ResourceModule.Name.Split('.')[0].Replace('MSFT_', '') - $currentWorkload = $ResourceName.Substring(0,2) + $currentWorkload = $ResourceName.Substring(0, 2) switch ($currentWorkload) { - 'O3' {$currentWorkload = 'O365'; break} - 'OD' {$currentWorkload = 'OD'; break} - 'PP' {$currentWorkload = 'PP'; break} - 'SC' {$currentWorkload = 'SC'; break} - 'SP' {$currentWorkload = 'SPO'; break} - 'TE' {$currentWorkload = 'TEAMS'; break} - default {$currentWorkload = $null; break} + 'O3' + { + $currentWorkload = 'O365'; + break + } + 'OD' + { + $currentWorkload = 'OD'; + break + } + 'PP' + { + $currentWorkload = 'PP'; + break + } + 'SC' + { + $currentWorkload = 'SC'; + break + } + 'SP' + { + $currentWorkload = 'SPO'; + break + } + 'TE' + { + $currentWorkload = 'TEAMS'; + break + } + default + { + $currentWorkload = $null; + break + } } if (($null -ne $ComponentsToExtract -and - $ComponentsToExtract.Contains("chck" + $resourceName)) -or + $ComponentsToExtract.Contains("chck" + $resourceName)) -or $AllComponents -or ($null -ne $Workloads -and $Workloads.Contains($currentWorkload))) { Import-Module $ResourceModule.FullName | Out-Null @@ -216,8 +244,8 @@ function Start-O365ConfigurationExtract #region Copy Downloaded files back into output folder if (($null -ne $ComponentsToExtract -and - $ComponentsToExtract.Contains("chckSPOApp")) -or - $AllComponents -or ($null -ne $Workloads -and $Workloads.Contains('SPO'))) + $ComponentsToExtract.Contains("chckSPOApp")) -or + $AllComponents -or ($null -ne $Workloads -and $Workloads.Contains('SPO'))) { $filesToDownload = Get-AllSPOPackages -GlobalAdminAccount $GlobalAdminAccount if ($filesToDownload.Count -gt 0) diff --git a/Modules/Office365DSC/Modules/O365DSCReverseGUI.psm1 b/Modules/Office365DSC/Modules/O365DSCReverseGUI.psm1 index 1d7490a67c..52b6dc4695 100644 --- a/Modules/Office365DSC/Modules/O365DSCReverseGUI.psm1 +++ b/Modules/Office365DSC/Modules/O365DSCReverseGUI.psm1 @@ -353,6 +353,15 @@ function Show-O365GUI $chckSPOHubSite.Text = "Hub Sites" $pnlSPO.Controls.Add($chckSPOHubSite) + $chckSPOHomeSite = New-Object System.Windows.Forms.CheckBox + $chckSPOHomeSite.Top = 40 + $chckSPOHomeSite.AutoSize = $true; + $chckSPOHomeSite.Name = "chckSPOHomeSite" + $chckSPOHomeSite.Checked = $true + $chckSPOHomeSite.Enabled = $true + $chckSPOHomeSite.Text = "Home Site" + $pnlSPO.Controls.Add($chckSPOHomeSite) + $chckSPOPropertyBag = New-Object System.Windows.Forms.CheckBox $chckSPOPropertyBag.Top = 60 $chckSPOPropertyBag.AutoSize = $true; From 0382fcc10c4f1759a26efdc6dcf0a8bc04d50e7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andi=20Kr=C3=BCger?= Date: Tue, 21 Jan 2020 15:53:21 +0100 Subject: [PATCH 09/14] unit test fixes --- .../MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 | 22 ++++++++------- .../Office365DSC.SPOHomeSite.Tests.ps1 | 28 +++++++++++++++---- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 index fb78d4f8c9..2274ba174e 100644 --- a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 +++ b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 @@ -38,25 +38,27 @@ function Get-TargetResource { Write-Verbose -Message "Getting current home site collection settings" $homeSiteUrl = Get-SPOHomeSite - if ($null -eq $url) + if ($null -eq $homeSiteUrl) { Write-Verbose -Message "There is no Home Site Collection set." return $nullReturn } - - $nullReturn = @{ - $IsSingleInstance = $IsSingleInstance - $Url = $homeSiteUrl - Ensure = "Present" - GlobalAdminAccount = $GlobalAdminAccount + else + { + $result = @{ + $IsSingleInstance = $IsSingleInstance + $Url = $homeSiteUrl + Ensure = "Present" + GlobalAdminAccount = $GlobalAdminAccount + } + return $result } - return $result } catch { Write-Verbose -Message "There was an error in the SPOHomeSite resource." - return $nullReturn } + return $nullReturn } function Set-TargetResource @@ -103,7 +105,7 @@ function Set-TargetResource } catch { - $Message = "The specified Site Collection {$Url} for SPOHomeSite doesn't exist." + $Message = "The specified Site Collection $($Url) for SPOHomeSite doesn't exist." New-Office365DSCLogEntry -Error $_ -Message $Message throw $Message } diff --git a/Tests/Unit/Office365DSC/Office365DSC.SPOHomeSite.Tests.ps1 b/Tests/Unit/Office365DSC/Office365DSC.SPOHomeSite.Tests.ps1 index 24b109fdfa..5ec3232117 100644 --- a/Tests/Unit/Office365DSC/Office365DSC.SPOHomeSite.Tests.ps1 +++ b/Tests/Unit/Office365DSC/Office365DSC.SPOHomeSite.Tests.ps1 @@ -38,7 +38,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { return $null } - It "Should return absent from the Get method" { + It "Should return Absent from the Get method" { (Get-TargetResource @testParams).Ensure | Should Be "Absent" } @@ -58,7 +58,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { return "https://contoso.sharepoint.com/sites/homesite" } - Mock -CommandName Remove-PnPHomeSite -MockWith { + Mock -CommandName Remove-PnPHomeSite -MockWith { } @@ -108,14 +108,30 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Test-TargetResource @testParams | Should Be $false } - It "Should set the correct site" { - Set-TargetResource @testParams | Should Throw "The specified Site Collection $($testParams.Url) for SPOHomeSite doesn't exist." + It "Should throw an error" { + { Set-TargetResource @testParams } | Should Throw "The specified Site Collection $($testParams.Url) for SPOHomeSite doesn't exist." Assert-MockCalled Get-SPOSite Assert-MockCalled New-Office365DSCLogEntry } + } + + Context -Name "It should set the home site" -Fixture { + $testParams = @{ + IsSingleInstance = "Yes" + Url = "https://contoso.sharepoint.com/sites/homesite" + GlobalAdminAccount = $GlobalAdminAccount + Ensure = "Present" + } + + Mock -CommandName Get-SPOHomeSite -MockWith { + return "https://contoso.sharepoint.com/sites/homesite1" + } + + Mock -CommandName Set-PnPHomeSite -MockWith { + } Mock -CommandName Get-SPOSite -MockWith { - return "" + } It "Should set the correct site" { @@ -127,7 +143,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Context -Name "ReverseDSC Tests" -Fixture { $testParams = @{ - IsSingleInstance = "Yes" + IsSingleInstance = "Yes" GlobalAdminAccount = $GlobalAdminAccount } From 8be9e4e9b053cd103a13305a706bc49fd5c5ff23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andi=20Kr=C3=BCger?= <15608729+andikrueger@users.noreply.github.com> Date: Tue, 21 Jan 2020 20:01:23 +0100 Subject: [PATCH 10/14] Update MSFT_SPOHomeSite.schema.mof Fixed naming issue --- .../DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof index a008dad08e..75a3474695 100644 --- a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof +++ b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof @@ -1,9 +1,9 @@ [ClassVersion("1.0.0.0"), FriendlyName("SPOHomeSite")] -class MSFT_SPOHubSite : OMI_BaseResource +class MSFT_SPOHomeSite : OMI_BaseResource { [Key, Description("Specifies the resource is a single instance, the value must be 'Yes'"), ValueMap{"Yes"}, Values{"Yes"}] String IsSingleInstance; [Write, Description("The URL of the home site collection")] string HomeSiteUrl; - [Write, Description("Present ensures the site collection is registered as hub site, absent ensures it is unregistered"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] string Ensure; + [Write, Description("Present ensures the site collection is registered as home site, absent ensures it is unregistered"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] string Ensure; [Required, Description("Credentials of the SharePoint Global Admin"), EmbeddedInstance("MSFT_Credential")] string GlobalAdminAccount; }; From cc7ab944bdaff3f4adfeb5df7c6da50eb1706e9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andi=20Kr=C3=BCger?= <15608729+andikrueger@users.noreply.github.com> Date: Tue, 21 Jan 2020 20:02:36 +0100 Subject: [PATCH 11/14] Update MSFT_SPOHomeSite.schema.mof Fixed parameter name --- .../DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof index 75a3474695..7f18635103 100644 --- a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof +++ b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.schema.mof @@ -2,7 +2,7 @@ class MSFT_SPOHomeSite : OMI_BaseResource { [Key, Description("Specifies the resource is a single instance, the value must be 'Yes'"), ValueMap{"Yes"}, Values{"Yes"}] String IsSingleInstance; - [Write, Description("The URL of the home site collection")] string HomeSiteUrl; + [Write, Description("The URL of the home site collection")] string Url; [Write, Description("Present ensures the site collection is registered as home site, absent ensures it is unregistered"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] string Ensure; [Required, Description("Credentials of the SharePoint Global Admin"), EmbeddedInstance("MSFT_Credential")] string GlobalAdminAccount; }; From 3cbfd124a5338f799bd8051743eec47995117346 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andi=20Kr=C3=BCger?= Date: Wed, 22 Jan 2020 09:55:35 +0100 Subject: [PATCH 12/14] Formatting fix --- Modules/Office365DSC/Modules/O365DSCReverse.psm1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/Office365DSC/Modules/O365DSCReverse.psm1 b/Modules/Office365DSC/Modules/O365DSCReverse.psm1 index 7c97deca78..a314139c35 100644 --- a/Modules/Office365DSC/Modules/O365DSCReverse.psm1 +++ b/Modules/Office365DSC/Modules/O365DSCReverse.psm1 @@ -225,7 +225,8 @@ function Start-O365ConfigurationExtract Write-Information "Directory `"$OutputDSCPath`" doesn't exist; creating..." New-Item -Path $OutputDSCPath -ItemType Directory | Out-Null if ($?) - { break + { + break } } catch From 48d7f5b5e801ef9919358ee2cdfefc9d39aebb29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andi=20Kr=C3=BCger?= Date: Wed, 22 Jan 2020 14:45:56 +0100 Subject: [PATCH 13/14] Review Changes --- .../MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 | 26 +++++++++---------- .../SPOHomeSite/1-ConfigureSPOHomeSite.ps1 | 2 +- .../Office365DSC.SPOHomeSite.Tests.ps1 | 19 +++++++------- 3 files changed, 22 insertions(+), 25 deletions(-) diff --git a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 index 2274ba174e..bc2327279e 100644 --- a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 +++ b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 @@ -37,7 +37,7 @@ function Get-TargetResource try { Write-Verbose -Message "Getting current home site collection settings" - $homeSiteUrl = Get-SPOHomeSite + $homeSiteUrl = Get-PnPHomeSite if ($null -eq $homeSiteUrl) { Write-Verbose -Message "There is no Home Site Collection set." @@ -87,21 +87,17 @@ function Set-TargetResource Write-Verbose -Message "Setting configuration for home site '$Url'" - Test-MSCloudLogin -O365Credential $GlobalAdminAccount ` - -Platform SharePointOnline - Test-MSCloudLogin -O365Credential $GlobalAdminAccount ` -Platform PnP $currentValues = Get-TargetResource @PSBoundParameters - if ($Ensure -eq "Present" -and $currentValues.Ensure -eq "Absent" ` - -or $Ensure -eq "Present" -and $currentValues.Ensure -eq "Present") + if ($Ensure -eq "Present") { try { Write-Verbose -Message "Setting home site collection $Url" - Get-SPOSite $Url + Get-PnPTenantSite -Url $Url } catch { @@ -113,7 +109,8 @@ function Set-TargetResource Write-Verbose -Message "Configuring site collection as Home Site" Set-PnPHomeSite -Url $Url } - else + + if ($Ensure -eq "Absent" -and $currentValues.Ensure -eq "Present") { # Remove home site Remove-PnPHomeSite -Force @@ -174,16 +171,17 @@ function Export-TargetResource [OutputType([System.String])] param ( - [Parameter(Mandatory = $true)] - [ValidateSet("Yes")] - [String] - $IsSingleInstance, - [Parameter(Mandatory = $true)] [System.Management.Automation.PSCredential] $GlobalAdminAccount ) - $result = Get-TargetResource @PSBoundParameters + + $params = @{ + IsSingleInstance = "Yes" + GlobalAdminAccount = $GlobalAdminAccount + } + + $result = Get-TargetResource @params $result.GlobalAdminAccount = "`$Credsglobaladmin" $content = " SPOHomeSite " + (New-GUID).ToString() + "`r`n" diff --git a/Modules/Office365DSC/Examples/Resources/SPOHomeSite/1-ConfigureSPOHomeSite.ps1 b/Modules/Office365DSC/Examples/Resources/SPOHomeSite/1-ConfigureSPOHomeSite.ps1 index e6702a5763..9eb0c1282f 100644 --- a/Modules/Office365DSC/Examples/Resources/SPOHomeSite/1-ConfigureSPOHomeSite.ps1 +++ b/Modules/Office365DSC/Examples/Resources/SPOHomeSite/1-ConfigureSPOHomeSite.ps1 @@ -14,7 +14,7 @@ Configuration Example node localhost { - SPOHomeSite "ff4a977d-4d7d-4968-9238-2a1702aa699c" + SPOHomeSite "SetMarketingSiteCollectionAsHomeSite" { IsSingleInstance = "Yes" Url = "https://office365dsc.sharepoint.com/sites/Marketing" diff --git a/Tests/Unit/Office365DSC/Office365DSC.SPOHomeSite.Tests.ps1 b/Tests/Unit/Office365DSC/Office365DSC.SPOHomeSite.Tests.ps1 index 5ec3232117..e20cb11bd2 100644 --- a/Tests/Unit/Office365DSC/Office365DSC.SPOHomeSite.Tests.ps1 +++ b/Tests/Unit/Office365DSC/Office365DSC.SPOHomeSite.Tests.ps1 @@ -34,7 +34,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Ensure = "Absent" } - Mock -CommandName Get-SPOHomeSite -MockWith { + Mock -CommandName Get-PnPHomeSite -MockWith { return $null } @@ -54,7 +54,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Ensure = "Absent" } - Mock -CommandName Get-SPOHomeSite -MockWith { + Mock -CommandName Get-PnPHomeSite -MockWith { return "https://contoso.sharepoint.com/sites/homesite" } @@ -84,11 +84,11 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Ensure = "Present" } - Mock -CommandName Get-SPOHomeSite -MockWith { + Mock -CommandName Get-PnPHomeSite -MockWith { return "https://contoso.sharepoint.com/sites/homesite" } - Mock -CommandName Get-SPOSite -MockWith { + Mock -CommandName Get-PnPTenantSite -MockWith { throw } @@ -110,7 +110,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { It "Should throw an error" { { Set-TargetResource @testParams } | Should Throw "The specified Site Collection $($testParams.Url) for SPOHomeSite doesn't exist." - Assert-MockCalled Get-SPOSite + Assert-MockCalled Get-PnPTenantSite Assert-MockCalled New-Office365DSCLogEntry } } @@ -123,31 +123,30 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Ensure = "Present" } - Mock -CommandName Get-SPOHomeSite -MockWith { + Mock -CommandName Get-PnPHomeSite -MockWith { return "https://contoso.sharepoint.com/sites/homesite1" } Mock -CommandName Set-PnPHomeSite -MockWith { } - Mock -CommandName Get-SPOSite -MockWith { + Mock -CommandName Get-PnPTenantSite -MockWith { } It "Should set the correct site" { Set-TargetResource @testParams - Assert-MockCalled Get-SPOSite + Assert-MockCalled Get-PnPTenantSite Assert-MockCalled Set-PnPHomeSite } } Context -Name "ReverseDSC Tests" -Fixture { $testParams = @{ - IsSingleInstance = "Yes" GlobalAdminAccount = $GlobalAdminAccount } - Mock -CommandName Get-SPOHomeSite -MockWith { + Mock -CommandName Get-PnPHomeSite -MockWith { return "https://contoso.sharepoint.com/sites/TestSite" } From aa3ce88049716ef6dfd08a11e87044bc0b7c8e14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andi=20Kr=C3=BCger?= Date: Wed, 22 Jan 2020 15:14:32 +0100 Subject: [PATCH 14/14] Removed $ in Hashtable --- .../DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 index bc2327279e..354ad8bbd4 100644 --- a/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 +++ b/Modules/Office365DSC/DSCResources/MSFT_SPOHomeSite/MSFT_SPOHomeSite.psm1 @@ -29,7 +29,7 @@ function Get-TargetResource -Platform PnP $nullReturn = @{ - $IsSingleInstance = $IsSingleInstance + IsSingleInstance = $IsSingleInstance Ensure = "Absent" GlobalAdminAccount = $GlobalAdminAccount } @@ -46,7 +46,7 @@ function Get-TargetResource else { $result = @{ - $IsSingleInstance = $IsSingleInstance + IsSingleInstance = $IsSingleInstance $Url = $homeSiteUrl Ensure = "Present" GlobalAdminAccount = $GlobalAdminAccount