From 49beec359c838bf107a6cc932dcb572ec22954cd Mon Sep 17 00:00:00 2001 From: Daniel Scott-Raynsford Date: Thu, 14 May 2020 16:37:27 +1200 Subject: [PATCH] Convert to use DSCResource.Common Module (#334) * Updated to use DSCResource.Common module * Fix conversion issues * Fix how error thrown in DSC_Computer * Try again to fix exception * Removed default culture * Revert change * Another try * Remove changes to culture * Revert again --- CHANGELOG.md | 5 + RequiredModules.psd1 | 1 + build.yaml | 16 +- .../DSC_Computer/DSC_Computer.psm1 | 6 +- .../DSC_IEEnhancedSecurityConfiguration.psm1 | 4 +- .../DSC_OfflineDomainJoin.psm1 | 4 +- .../DSC_PendingReboot/DSC_PendingReboot.psm1 | 10 +- .../DSC_PowerPlan/DSC_PowerPlan.psm1 | 4 +- .../DSC_PowerShellExecutionPolicy.psm1 | 4 +- .../DSC_RemoteDesktopAdmin.psm1 | 4 +- .../DSC_ScheduledTask/DSC_ScheduledTask.psm1 | 4 +- .../DSC_SmbServerConfiguration.psm1 | 7 +- .../DSC_SmbShare/DSC_SmbShare.psm1 | 7 +- .../DSC_SystemLocale/DSC_SystemLocale.psm1 | 7 +- .../DSC_TimeZone/DSC_TimeZone.psm1 | 4 +- .../DSC_UserAccountControl.psm1 | 4 +- .../DSC_VirtualMemory/DSC_VirtualMemory.psm1 | 4 +- .../DSC_WindowsCapability.psm1 | 4 +- .../DSC_WindowsEventLog.psm1 | 4 +- .../ComputerManagementDsc.Common.psm1 | 725 +-------- .../ComputerManagementDsc.Common.strings.psd1 | 16 - .../ComputerManagementDsc.Common.Tests.ps1 | 1338 ----------------- tests/Unit/DSC_Computer.Tests.ps1 | 4 +- 23 files changed, 76 insertions(+), 2110 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2c771cb..a0bb3805 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- ComputerManagementDsc + - Updated to use the common module _DscResource.Common_ - Fixes [Issue #327](https://github.com/dsccommunity/ComputerManagementDsc/issues/327). + - Fixed build failures caused by changes in `ModuleBuilder` module v1.7.0 + by changing `CopyDirectories` to `CopyPaths` - Fixes [Issue #332](https://github.com/dsccommunity/ComputerManagementDsc/issues/332). + ## [8.2.0] - 2020-05-05 ### Changed diff --git a/RequiredModules.psd1 b/RequiredModules.psd1 index d8565aae..50ba674e 100644 --- a/RequiredModules.psd1 +++ b/RequiredModules.psd1 @@ -18,6 +18,7 @@ 'DscResource.Test' = 'latest' 'DscResource.AnalyzerRules' = 'latest' 'DscResource.DocGenerator' = 'latest' + 'DscResource.Common' = 'latest' xDscResourceDesigner = 'latest' LoopbackAdapter = 'latest' } diff --git a/build.yaml b/build.yaml index 7974feaf..86139e9d 100644 --- a/build.yaml +++ b/build.yaml @@ -2,13 +2,24 @@ #################################################### # ModuleBuilder Configuration # #################################################### -CopyDirectories: +CopyPaths: - en-US - DSCResources - Modules Encoding: UTF8 VersionedOutputDirectory: true +#################################################### +# ModuleBuilder Dependent Modules Configuration # +#################################################### + +NestedModule: + DscResource.Common: + CopyOnly: true + Path: ./output/RequiredModules/DscResource.Common + AddToManifest: false + Exclude: PSGetModuleInfo.xml + #################################################### # Pipeline Configuration # #################################################### @@ -47,6 +58,7 @@ BuildWorkflow: Pester: OutputFormat: NUnitXML ExcludeFromCodeCoverage: + - Modules/DscResource.Common Script: - tests/Unit ExcludeTag: @@ -59,6 +71,8 @@ DscTest: - 'Common Tests - New Error-Level Script Analyzer Rules' ExcludeSourceFile: - output + ExcludeModuleFile: + - Modules/DscResource.Common Resolve-Dependency: Gallery: 'PSGallery' diff --git a/source/DSCResources/DSC_Computer/DSC_Computer.psm1 b/source/DSCResources/DSC_Computer/DSC_Computer.psm1 index 9664928f..94b246ff 100644 --- a/source/DSCResources/DSC_Computer/DSC_Computer.psm1 +++ b/source/DSCResources/DSC_Computer/DSC_Computer.psm1 @@ -10,8 +10,10 @@ Import-Module -Name (Join-Path -Path $modulePath ` -ChildPath (Join-Path -Path 'ComputerManagementDsc.Common' ` -ChildPath 'ComputerManagementDsc.Common.psm1')) +Import-Module -Name (Join-Path -Path $modulePath -ChildPath 'DscResource.Common') + # Import Localization Strings -$script:localizedData = Get-LocalizedData -ResourceName 'DSC_Computer' +$script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' $FailToRenameAfterJoinDomainErrorId = 'FailToRenameAfterJoinDomain,Microsoft.PowerShell.Commands.AddComputerCommand' @@ -265,7 +267,7 @@ function Set-TargetResource } else { - New-InvalidOperationException -ErrorRecord $_ + New-InvalidOperationException -Message $_.Exception.Message -ErrorRecord $_ } } catch diff --git a/source/DSCResources/DSC_IEEnhancedSecurityConfiguration/DSC_IEEnhancedSecurityConfiguration.psm1 b/source/DSCResources/DSC_IEEnhancedSecurityConfiguration/DSC_IEEnhancedSecurityConfiguration.psm1 index 192205f1..0a2506d2 100644 --- a/source/DSCResources/DSC_IEEnhancedSecurityConfiguration/DSC_IEEnhancedSecurityConfiguration.psm1 +++ b/source/DSCResources/DSC_IEEnhancedSecurityConfiguration/DSC_IEEnhancedSecurityConfiguration.psm1 @@ -5,8 +5,10 @@ Import-Module -Name (Join-Path -Path $modulePath ` -ChildPath (Join-Path -Path 'ComputerManagementDsc.Common' ` -ChildPath 'ComputerManagementDsc.Common.psm1')) +Import-Module -Name (Join-Path -Path $modulePath -ChildPath 'DscResource.Common') + # Import Localization Strings -$script:localizedData = Get-LocalizedData -ResourceName 'DSC_IEEnhancedSecurityConfiguration' +$script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' $script:registryKey_Administrators = 'HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}' $script:registryKey_Users = 'HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}' diff --git a/source/DSCResources/DSC_OfflineDomainJoin/DSC_OfflineDomainJoin.psm1 b/source/DSCResources/DSC_OfflineDomainJoin/DSC_OfflineDomainJoin.psm1 index 4000af22..ecd48e28 100644 --- a/source/DSCResources/DSC_OfflineDomainJoin/DSC_OfflineDomainJoin.psm1 +++ b/source/DSCResources/DSC_OfflineDomainJoin/DSC_OfflineDomainJoin.psm1 @@ -10,8 +10,10 @@ Import-Module -Name (Join-Path -Path $modulePath ` -ChildPath (Join-Path -Path 'ComputerManagementDsc.Common' ` -ChildPath 'ComputerManagementDsc.Common.psm1')) +Import-Module -Name (Join-Path -Path $modulePath -ChildPath 'DscResource.Common') + # Import Localization Strings -$script:localizedData = Get-LocalizedData -ResourceName 'DSC_OfflineDomainJoin' +$script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' <# .SYNOPSIS diff --git a/source/DSCResources/DSC_PendingReboot/DSC_PendingReboot.psm1 b/source/DSCResources/DSC_PendingReboot/DSC_PendingReboot.psm1 index 8436157b..c6d01f6d 100644 --- a/source/DSCResources/DSC_PendingReboot/DSC_PendingReboot.psm1 +++ b/source/DSCResources/DSC_PendingReboot/DSC_PendingReboot.psm1 @@ -8,17 +8,19 @@ Import-Module -Name (Join-Path -Path $modulePath ` -ChildPath (Join-Path -Path 'ComputerManagementDsc.Common' ` -ChildPath 'ComputerManagementDsc.Common.psm1')) +Import-Module -Name (Join-Path -Path $modulePath -ChildPath 'DscResource.Common') + # Import Localization Strings -$script:localizedData = Get-LocalizedData -ResourceName 'DSC_PendingReboot' +$script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' <# This data file contains a list of reboot triggers that will be checked when determining if reboot is required. This is stored in a separate data file so that it can also be used in testing. #> -$script:localizedResourceData = Get-LocalizedData ` - -ResourceName 'DSC_PendingReboot' ` - -Postfix 'data' +$script:localizedResourceData = Import-LocalizedData ` + -BaseDirectory $PSScriptRoot ` + -FileName 'DSC_PendingReboot.data.psd1' $script:rebootTriggers = $script:localizedResourceData.RebootTriggers <# .SYNOPSIS diff --git a/source/DSCResources/DSC_PowerPlan/DSC_PowerPlan.psm1 b/source/DSCResources/DSC_PowerPlan/DSC_PowerPlan.psm1 index f6cc17f8..1f8a7119 100644 --- a/source/DSCResources/DSC_PowerPlan/DSC_PowerPlan.psm1 +++ b/source/DSCResources/DSC_PowerPlan/DSC_PowerPlan.psm1 @@ -5,8 +5,10 @@ Import-Module -Name (Join-Path -Path $modulePath ` -ChildPath (Join-Path -Path 'ComputerManagementDsc.Common' ` -ChildPath 'ComputerManagementDsc.Common.psm1')) +Import-Module -Name (Join-Path -Path $modulePath -ChildPath 'DscResource.Common') + # Import Localization Strings -$script:localizedData = Get-LocalizedData -ResourceName 'DSC_PowerPlan' +$script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' <# .SYNOPSIS diff --git a/source/DSCResources/DSC_PowerShellExecutionPolicy/DSC_PowerShellExecutionPolicy.psm1 b/source/DSCResources/DSC_PowerShellExecutionPolicy/DSC_PowerShellExecutionPolicy.psm1 index 1bbb6a8b..b858d2f9 100644 --- a/source/DSCResources/DSC_PowerShellExecutionPolicy/DSC_PowerShellExecutionPolicy.psm1 +++ b/source/DSCResources/DSC_PowerShellExecutionPolicy/DSC_PowerShellExecutionPolicy.psm1 @@ -5,8 +5,10 @@ Import-Module -Name (Join-Path -Path $modulePath ` -ChildPath (Join-Path -Path 'ComputerManagementDsc.Common' ` -ChildPath 'ComputerManagementDsc.Common.psm1')) +Import-Module -Name (Join-Path -Path $modulePath -ChildPath 'DscResource.Common') + # Import Localization Strings -$script:localizedData = Get-LocalizedData -ResourceName 'DSC_PowershellExecutionPolicy' +$script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' <# .SYNOPSIS diff --git a/source/DSCResources/DSC_RemoteDesktopAdmin/DSC_RemoteDesktopAdmin.psm1 b/source/DSCResources/DSC_RemoteDesktopAdmin/DSC_RemoteDesktopAdmin.psm1 index 078d6a27..98534e89 100644 --- a/source/DSCResources/DSC_RemoteDesktopAdmin/DSC_RemoteDesktopAdmin.psm1 +++ b/source/DSCResources/DSC_RemoteDesktopAdmin/DSC_RemoteDesktopAdmin.psm1 @@ -5,8 +5,10 @@ Import-Module -Name (Join-Path -Path $modulePath ` -ChildPath (Join-Path -Path 'ComputerManagementDsc.Common' ` -ChildPath 'ComputerManagementDsc.Common.psm1')) +Import-Module -Name (Join-Path -Path $modulePath -ChildPath 'DscResource.Common') + # Import Localization Strings -$script:localizedData = Get-LocalizedData -ResourceName 'DSC_RemoteDesktopAdmin' +$script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' $script:tSRegistryKey = 'HKLM:\System\CurrentControlSet\Control\Terminal Server' $script:winStationsRegistryKey = 'HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' diff --git a/source/DSCResources/DSC_ScheduledTask/DSC_ScheduledTask.psm1 b/source/DSCResources/DSC_ScheduledTask/DSC_ScheduledTask.psm1 index 29e35b55..1ac366e7 100644 --- a/source/DSCResources/DSC_ScheduledTask/DSC_ScheduledTask.psm1 +++ b/source/DSCResources/DSC_ScheduledTask/DSC_ScheduledTask.psm1 @@ -21,8 +21,10 @@ Import-Module -Name (Join-Path -Path $modulePath ` -ChildPath (Join-Path -Path 'ComputerManagementDsc.Common' ` -ChildPath 'ComputerManagementDsc.Common.psm1')) +Import-Module -Name (Join-Path -Path $modulePath -ChildPath 'DscResource.Common') + # Import Localization Strings -$script:localizedData = Get-LocalizedData -ResourceName 'DSC_ScheduledTask' +$script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' <# .SYNOPSIS diff --git a/source/DSCResources/DSC_SmbServerConfiguration/DSC_SmbServerConfiguration.psm1 b/source/DSCResources/DSC_SmbServerConfiguration/DSC_SmbServerConfiguration.psm1 index 824e8a85..2413bdf2 100644 --- a/source/DSCResources/DSC_SmbServerConfiguration/DSC_SmbServerConfiguration.psm1 +++ b/source/DSCResources/DSC_SmbServerConfiguration/DSC_SmbServerConfiguration.psm1 @@ -5,13 +5,10 @@ Import-Module -Name (Join-Path -Path $modulePath ` -ChildPath (Join-Path -Path 'ComputerManagementDsc.Common' ` -ChildPath 'ComputerManagementDsc.Common.psm1')) -Force -# Import the ComputerManagementDsc Resource Helper Module -Import-Module -Name (Join-Path -Path $modulePath ` - -ChildPath (Join-Path -Path 'ComputerManagementDsc.Common' ` - -ChildPath 'ComputerManagementDsc.Common.psm1')) +Import-Module -Name (Join-Path -Path $modulePath -ChildPath 'DscResource.Common') # Import Localization Strings -$script:localizedData = Get-LocalizedData -ResourceName 'DSC_SmbServerConfiguration' +$script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' $resourceData = Import-LocalizedData ` -BaseDirectory $PSScriptRoot ` diff --git a/source/DSCResources/DSC_SmbShare/DSC_SmbShare.psm1 b/source/DSCResources/DSC_SmbShare/DSC_SmbShare.psm1 index 53ac25a2..06fd5394 100644 --- a/source/DSCResources/DSC_SmbShare/DSC_SmbShare.psm1 +++ b/source/DSCResources/DSC_SmbShare/DSC_SmbShare.psm1 @@ -5,13 +5,10 @@ Import-Module -Name (Join-Path -Path $modulePath ` -ChildPath (Join-Path -Path 'ComputerManagementDsc.Common' ` -ChildPath 'ComputerManagementDsc.Common.psm1')) -Force -# Import the ComputerManagementDsc Resource Helper Module -Import-Module -Name (Join-Path -Path $modulePath ` - -ChildPath (Join-Path -Path 'ComputerManagementDsc.Common' ` - -ChildPath 'ComputerManagementDsc.Common.psm1')) +Import-Module -Name (Join-Path -Path $modulePath -ChildPath 'DscResource.Common') # Import Localization Strings -$script:localizedData = Get-LocalizedData -ResourceName 'DSC_SmbShare' +$script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' <# .SYNOPSIS diff --git a/source/DSCResources/DSC_SystemLocale/DSC_SystemLocale.psm1 b/source/DSCResources/DSC_SystemLocale/DSC_SystemLocale.psm1 index 4c5a3890..0b408659 100644 --- a/source/DSCResources/DSC_SystemLocale/DSC_SystemLocale.psm1 +++ b/source/DSCResources/DSC_SystemLocale/DSC_SystemLocale.psm1 @@ -5,13 +5,10 @@ Import-Module -Name (Join-Path -Path $modulePath ` -ChildPath (Join-Path -Path 'ComputerManagementDsc.Common' ` -ChildPath 'ComputerManagementDsc.Common.psm1')) -Force -# Import the ComputerManagementDsc Resource Helper Module -Import-Module -Name (Join-Path -Path $modulePath ` - -ChildPath (Join-Path -Path 'ComputerManagementDsc.Common' ` - -ChildPath 'ComputerManagementDsc.Common.psm1')) +Import-Module -Name (Join-Path -Path $modulePath -ChildPath 'DscResource.Common') # Import Localization Strings -$script:localizedData = Get-LocalizedData -ResourceName 'DSC_SystemLocale' +$script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' <# .SYNOPSIS diff --git a/source/DSCResources/DSC_TimeZone/DSC_TimeZone.psm1 b/source/DSCResources/DSC_TimeZone/DSC_TimeZone.psm1 index b0ee6a90..d7aee5ed 100644 --- a/source/DSCResources/DSC_TimeZone/DSC_TimeZone.psm1 +++ b/source/DSCResources/DSC_TimeZone/DSC_TimeZone.psm1 @@ -5,8 +5,10 @@ Import-Module -Name (Join-Path -Path $modulePath ` -ChildPath (Join-Path -Path 'ComputerManagementDsc.Common' ` -ChildPath 'ComputerManagementDsc.Common.psm1')) +Import-Module -Name (Join-Path -Path $modulePath -ChildPath 'DscResource.Common') + # Import Localization Strings. -$script:localizedData = Get-LocalizedData -ResourceName 'DSC_TimeZone' +$script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' <# .SYNOPSIS diff --git a/source/DSCResources/DSC_UserAccountControl/DSC_UserAccountControl.psm1 b/source/DSCResources/DSC_UserAccountControl/DSC_UserAccountControl.psm1 index c3e49684..b740d7ca 100644 --- a/source/DSCResources/DSC_UserAccountControl/DSC_UserAccountControl.psm1 +++ b/source/DSCResources/DSC_UserAccountControl/DSC_UserAccountControl.psm1 @@ -5,8 +5,10 @@ Import-Module -Name (Join-Path -Path $modulePath ` -ChildPath (Join-Path -Path 'ComputerManagementDsc.Common' ` -ChildPath 'ComputerManagementDsc.Common.psm1')) +Import-Module -Name (Join-Path -Path $modulePath -ChildPath 'DscResource.Common') + # Import Localization Strings -$script:localizedData = Get-LocalizedData -ResourceName 'DSC_UserAccountControl' +$script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' $script:registryKey = 'HKLM:\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System' diff --git a/source/DSCResources/DSC_VirtualMemory/DSC_VirtualMemory.psm1 b/source/DSCResources/DSC_VirtualMemory/DSC_VirtualMemory.psm1 index 721852e3..84cb785c 100644 --- a/source/DSCResources/DSC_VirtualMemory/DSC_VirtualMemory.psm1 +++ b/source/DSCResources/DSC_VirtualMemory/DSC_VirtualMemory.psm1 @@ -8,8 +8,10 @@ Import-Module -Name (Join-Path -Path $modulePath ` -ChildPath (Join-Path -Path 'ComputerManagementDsc.Common' ` -ChildPath 'ComputerManagementDsc.Common.psm1')) +Import-Module -Name (Join-Path -Path $modulePath -ChildPath 'DscResource.Common') + # Import Localization Strings -$script:localizedData = Get-LocalizedData -ResourceName 'DSC_VirtualMemory' +$script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' <# .SYNOPSIS diff --git a/source/DSCResources/DSC_WindowsCapability/DSC_WindowsCapability.psm1 b/source/DSCResources/DSC_WindowsCapability/DSC_WindowsCapability.psm1 index 92ae611f..64f8f485 100644 --- a/source/DSCResources/DSC_WindowsCapability/DSC_WindowsCapability.psm1 +++ b/source/DSCResources/DSC_WindowsCapability/DSC_WindowsCapability.psm1 @@ -5,8 +5,10 @@ Import-Module -Name (Join-Path -Path $modulePath ` -ChildPath (Join-Path -Path 'ComputerManagementDsc.Common' ` -ChildPath 'ComputerManagementDsc.Common.psm1')) +Import-Module -Name (Join-Path -Path $modulePath -ChildPath 'DscResource.Common') + # Import Localization Strings -$script:localizedData = Get-LocalizedData -ResourceName 'DSC_WindowsCapability' +$script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' <# .SYNOPSIS diff --git a/source/DSCResources/DSC_WindowsEventLog/DSC_WindowsEventLog.psm1 b/source/DSCResources/DSC_WindowsEventLog/DSC_WindowsEventLog.psm1 index e5281517..813fd150 100644 --- a/source/DSCResources/DSC_WindowsEventLog/DSC_WindowsEventLog.psm1 +++ b/source/DSCResources/DSC_WindowsEventLog/DSC_WindowsEventLog.psm1 @@ -5,8 +5,10 @@ Import-Module -Name (Join-Path -Path $modulePath ` -ChildPath (Join-Path -Path 'ComputerManagementDsc.Common' ` -ChildPath 'ComputerManagementDsc.Common.psm1')) +Import-Module -Name (Join-Path -Path $modulePath -ChildPath 'DscResource.Common') + # Import Localization Strings -$script:localizedData = Get-LocalizedData -ResourceName 'DSC_WindowsEventLog' +$script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' <# .SYNOPSIS diff --git a/source/Modules/ComputerManagementDsc.Common/ComputerManagementDsc.Common.psm1 b/source/Modules/ComputerManagementDsc.Common/ComputerManagementDsc.Common.psm1 index 39afab86..9976f09c 100644 --- a/source/Modules/ComputerManagementDsc.Common/ComputerManagementDsc.Common.psm1 +++ b/source/Modules/ComputerManagementDsc.Common/ComputerManagementDsc.Common.psm1 @@ -1,663 +1,8 @@ -<# - .SYNOPSIS - Retrieves the localized string data based on the machine's culture. - Falls back to en-US strings if the machine's culture is not supported. - - .PARAMETER ResourceName - The name of the resource as it appears before '.strings.psd1' of the localized string file. - For example: - For WindowsOptionalFeature: DSC_WindowsOptionalFeature - For Service: DSC_ServiceResource - For Registry: DSC_RegistryResource - For Helper: SqlServerDscHelper - - .PARAMETER ScriptRoot - Optional. The root path where to expect to find the culture folder. This is only needed - for localization in helper modules. This should not normally be used for resources. - - .PARAMETER Postfix - Optional. The default string to postfix to the resource name to generate the name of the - localized file. - - .NOTES - To be able to use localization in the helper function, this function must - be first in the file, before Get-LocalizedData is used by itself to load - localized data for this helper module (see directly after this function). -#> -function Get-LocalizedData -{ - [CmdletBinding()] - param - ( - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [System.String] - $ResourceName, - - [Parameter()] - [ValidateNotNullOrEmpty()] - [System.String] - $ScriptRoot, - - [Parameter()] - [ValidateNotNullOrEmpty()] - [System.String] - $Postfix = 'strings' - ) - - if (-not $ScriptRoot) - { - $dscResourcesFolder = Join-Path -Path (Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent) -ChildPath 'DSCResources' - $resourceDirectory = Join-Path -Path $dscResourcesFolder -ChildPath $ResourceName - } - else - { - $resourceDirectory = $ScriptRoot - } - - $localizedStringFileLocation = Join-Path -Path $resourceDirectory -ChildPath $PSUICulture - - if (-not (Test-Path -Path $localizedStringFileLocation)) - { - # Fallback to en-US - $localizedStringFileLocation = Join-Path -Path $resourceDirectory -ChildPath 'en-US' - } - - Import-LocalizedData ` - -BindingVariable 'localizedData' ` - -FileName "$ResourceName.$Postfix.psd1" ` - -BaseDirectory $localizedStringFileLocation - - return $localizedData -} - -<# - .SYNOPSIS - Tests if the current machine is a Nano server. -#> -function Test-IsNanoServer -{ - if (Test-Command -Name Get-ComputerInfo -Module 'Microsoft.PowerShell.Management') - { - $computerInfo = Get-ComputerInfo - - if ('Server' -eq $computerInfo.OsProductType ` - -and 'NanoServer' -eq $computerInfo.OsServerLevel) - { - return $true - } - } - - return $false -} - -<# - .SYNOPSIS - Creates and throws an invalid argument exception - - .PARAMETER Message - The message explaining why this error is being thrown - - .PARAMETER ArgumentName - The name of the invalid argument that is causing this error to be thrown -#> -function New-InvalidArgumentException -{ - [CmdletBinding()] - param - ( - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [String] - $Message, - - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [String] - $ArgumentName - ) - - $argumentException = New-Object -TypeName 'ArgumentException' -ArgumentList @( $Message, - $ArgumentName ) - $newObjectParams = @{ - TypeName = 'System.Management.Automation.ErrorRecord' - ArgumentList = @( $argumentException, $ArgumentName, 'InvalidArgument', $null ) - } - $errorRecord = New-Object @newObjectParams - - throw $errorRecord -} - -<# - .SYNOPSIS - Creates and throws an invalid operation exception - - .PARAMETER Message - The message explaining why this error is being thrown - - .PARAMETER ErrorRecord - The error record containing the exception that is causing this terminating error -#> -function New-InvalidOperationException -{ - [CmdletBinding()] - param - ( - [Parameter()] - [ValidateNotNullOrEmpty()] - [String] - $Message, - - [Parameter()] - [ValidateNotNull()] - [System.Management.Automation.ErrorRecord] - $ErrorRecord - ) - - if ($null -eq $ErrorRecord) - { - $invalidOperationException = - New-Object -TypeName 'InvalidOperationException' -ArgumentList @( $Message ) - } - else - { - $invalidOperationException = - New-Object -TypeName 'InvalidOperationException' -ArgumentList @( $Message, - $ErrorRecord.Exception ) - } - - $newObjectParams = @{ - TypeName = 'System.Management.Automation.ErrorRecord' - ArgumentList = @( $invalidOperationException.ToString(), 'MachineStateIncorrect', - 'InvalidOperation', $null ) - } - $errorRecordToThrow = New-Object @newObjectParams - throw $errorRecordToThrow -} - -<# - .SYNOPSIS - Removes common parameters from a hashtable - - .DESCRIPTION - This function serves the purpose of removing common parameters and option common parameters from a parameter hashtable - - .PARAMETER Hashtable - The parameter hashtable that should be pruned -#> -function Remove-CommonParameter -{ - [OutputType([System.Collections.Hashtable])] - [CmdletBinding()] - param - ( - [Parameter(Mandatory = $true)] - [System.Collections.Hashtable] - $Hashtable - ) - - $inputClone = $Hashtable.Clone() - $commonParameters = [System.Management.Automation.PSCmdlet]::CommonParameters - $commonParameters += [System.Management.Automation.PSCmdlet]::OptionalCommonParameters - - $Hashtable.Keys | Where-Object -FilterScript { $_ -in $commonParameters } | ForEach-Object -Process { - $inputClone.Remove($_) - } - - return $inputClone -} - -<# - .SYNOPSIS - Tests the status of DSC resource parameters. - - .DESCRIPTION - This function tests the parameter status of DSC resource parameters against the current values present on the system. - - .PARAMETER CurrentValues - A hashtable with the current values on the system, obtained by e.g. Get-TargetResource. - - .PARAMETER DesiredValues - The hashtable of desired values. - - .PARAMETER ValuesToCheck - The values to check if not all values should be checked. - - .PARAMETER TurnOffTypeChecking - Indicates that the type of the parameter should not be checked. - - .PARAMETER ReverseCheck - Indicates that a reverse check should be done. The current and desired state are swapped for another test. - - .PARAMETER SortArrayValues - If the sorting of array values does not matter, values are sorted internally before doing the comparison. -#> -function Test-DscParameterState -{ - [CmdletBinding()] - param - ( - [Parameter(Mandatory = $true)] - [System.Object] - $CurrentValues, - - [Parameter(Mandatory = $true)] - [System.Object] - $DesiredValues, - - [Parameter()] - [System.String[]] - $ValuesToCheck, - - [Parameter()] - [switch] - $TurnOffTypeChecking, - - [Parameter()] - [switch] - $ReverseCheck, - - [Parameter()] - [switch] - $SortArrayValues - ) - - $returnValue = $true - - if ($CurrentValues -is [Microsoft.Management.Infrastructure.CimInstance] -or - $CurrentValues -is [Microsoft.Management.Infrastructure.CimInstance[]]) - { - $CurrentValues = ConvertTo-HashTable -CimInstance $CurrentValues - } - - if ($DesiredValues -is [Microsoft.Management.Infrastructure.CimInstance] -or - $DesiredValues -is [Microsoft.Management.Infrastructure.CimInstance[]]) - { - $DesiredValues = ConvertTo-HashTable -CimInstance $DesiredValues - } - - $types = 'System.Management.Automation.PSBoundParametersDictionary', 'System.Collections.Hashtable', 'Microsoft.Management.Infrastructure.CimInstance' - - if ($DesiredValues.GetType().FullName -notin $types) - { - New-InvalidArgumentException ` - -Message ($script:localizedData.InvalidDesiredValuesError -f $DesiredValues.GetType().FullName) ` - -ArgumentName 'DesiredValues' - } - - if ($CurrentValues.GetType().FullName -notin $types) - { - New-InvalidArgumentException ` - -Message ($script:localizedData.InvalidCurrentValuesError -f $CurrentValues.GetType().FullName) ` - -ArgumentName 'CurrentValues' - } - - if ($DesiredValues -is [Microsoft.Management.Infrastructure.CimInstance] -and -not $ValuesToCheck) - { - New-InvalidArgumentException ` - -Message $script:localizedData.InvalidValuesToCheckError ` - -ArgumentName 'ValuesToCheck' - } - - $desiredValuesClean = Remove-CommonParameter -Hashtable $DesiredValues - - if (-not $ValuesToCheck) - { - $keyList = $desiredValuesClean.Keys - } - else - { - $keyList = $ValuesToCheck - } - - foreach ($key in $keyList) - { - $desiredValue = $desiredValuesClean.$key - $currentValue = $CurrentValues.$key - - if ($desiredValue -is [Microsoft.Management.Infrastructure.CimInstance] -or - $desiredValue -is [Microsoft.Management.Infrastructure.CimInstance[]]) - { - $desiredValue = ConvertTo-HashTable -CimInstance $desiredValue - } - if ($currentValue -is [Microsoft.Management.Infrastructure.CimInstance] -or - $currentValue -is [Microsoft.Management.Infrastructure.CimInstance[]]) - { - $currentValue = ConvertTo-HashTable -CimInstance $currentValue - } - - if ($null -ne $desiredValue) - { - $desiredType = $desiredValue.GetType() - } - else - { - $desiredType = @{ - Name = 'Unknown' - } - } - - if ($null -ne $currentValue) - { - $currentType = $currentValue.GetType() - } - else - { - $currentType = @{ - Name = 'Unknown' - } - } - - if ($currentType.Name -ne 'Unknown' -and $desiredType.Name -eq 'PSCredential') - { - # This is a credential object. Compare only the user name - if ($currentType.Name -eq 'PSCredential' -and $currentValue.UserName -eq $desiredValue.UserName) - { - Write-Verbose -Message ($script:localizedData.MatchPsCredentialUsernameMessage -f $currentValue.UserName, $desiredValue.UserName) - continue - } - else - { - Write-Verbose -Message ($script:localizedData.NoMatchPsCredentialUsernameMessage -f $currentValue.UserName, $desiredValue.UserName) - $returnValue = $false - } - - # Assume the string is our username when the matching desired value is actually a credential - if ($currentType.Name -eq 'string' -and $currentValue -eq $desiredValue.UserName) - { - Write-Verbose -Message ($script:localizedData.MatchPsCredentialUsernameMessage -f $currentValue, $desiredValue.UserName) - continue - } - else - { - Write-Verbose -Message ($script:localizedData.NoMatchPsCredentialUsernameMessage -f $currentValue, $desiredValue.UserName) - $returnValue = $false - } - } - - if (-not $TurnOffTypeChecking) - { - if (($desiredType.Name -ne 'Unknown' -and $currentType.Name -ne 'Unknown') -and - $desiredType.FullName -ne $currentType.FullName) - { - Write-Verbose -Message ($script:localizedData.NoMatchTypeMismatchMessage -f $key, $currentType.FullName, $desiredType.FullName) - $returnValue = $false - continue - } - } - - if ($currentValue -eq $desiredValue -and -not $desiredType.IsArray) - { - Write-Verbose -Message ($script:localizedData.MatchValueMessage -f $desiredType.FullName, $key, $currentValue, $desiredValue) - continue - } - - if ($desiredValuesClean.GetType().Name -in 'HashTable', 'PSBoundParametersDictionary') - { - $checkDesiredValue = $desiredValuesClean.ContainsKey($key) - } - else - { - $checkDesiredValue = Test-DscObjectHasProperty -Object $desiredValuesClean -PropertyName $key - } - - if (-not $checkDesiredValue) - { - Write-Verbose -Message ($script:localizedData.MatchValueMessage -f $desiredType.FullName, $key, $currentValue, $desiredValue) - continue - } - - if ($desiredType.IsArray) - { - Write-Verbose -Message ($script:localizedData.TestDscParameterCompareMessage -f $key, $desiredType.FullName) - - if (-not $currentValue -and -not $desiredValue) - { - Write-Verbose -Message ($script:localizedData.MatchValueMessage -f $desiredType.FullName, $key, 'empty array', 'empty array') - continue - } - elseif (-not $currentValue) - { - Write-Verbose -Message ($script:localizedData.NoMatchValueMessage -f $desiredType.FullName, $key, $currentValue, $desiredValue) - $returnValue = $false - continue - } - elseif ($currentValue.Count -ne $desiredValue.Count) - { - Write-Verbose -Message ($script:localizedData.NoMatchValueDifferentCountMessage -f $desiredType.FullName, $key, $currentValue.Count, $desiredValue.Count) - $returnValue = $false - continue - } - else - { - $desiredArrayValues = $desiredValue - $currentArrayValues = $currentValue - - if ($SortArrayValues) - { - $desiredArrayValues = $desiredArrayValues | Sort-Object - $currentArrayValues = $currentArrayValues | Sort-Object - } - - for ($i = 0; $i -lt $desiredArrayValues.Count; $i++) - { - if ($null -ne $desiredArrayValues[$i]) - { - $desiredType = $desiredArrayValues[$i].GetType() - } - else - { - $desiredType = @{ - Name = 'Unknown' - } - } - - if ($null -ne $currentArrayValues[$i]) - { - $currentType = $currentArrayValues[$i].GetType() - } - else - { - $currentType = @{ - Name = 'Unknown' - } - } - - if (-not $TurnOffTypeChecking) - { - if (($desiredType.Name -ne 'Unknown' -and $currentType.Name -ne 'Unknown') -and - $desiredType.FullName -ne $currentType.FullName) - { - Write-Verbose -Message ($script:localizedData.NoMatchElementTypeMismatchMessage -f $key, $i, $currentType.FullName, $desiredType.FullName) - $returnValue = $false - continue - } - } - - if ($desiredArrayValues[$i] -ne $currentArrayValues[$i]) - { - Write-Verbose -Message ($script:localizedData.NoMatchElementValueMismatchMessage -f $i, $desiredType.FullName, $key, $currentArrayValues[$i], $desiredArrayValues[$i]) - $returnValue = $false - continue - } - else - { - Write-Verbose -Message ($script:localizedData.MatchElementValueMessage -f $i, $desiredType.FullName, $key, $currentArrayValues[$i], $desiredArrayValues[$i]) - continue - } - } - - } - } - elseif ($desiredType -eq [System.Collections.Hashtable] -and $currentType -eq [System.Collections.Hashtable]) - { - $param = $PSBoundParameters - $param.CurrentValues = $currentValue - $param.DesiredValues = $desiredValue - $null = $param.Remove('ValuesToCheck') - - if ($returnValue) - { - $returnValue = Test-DscParameterState @param - } - else - { - Test-DscParameterState @param | Out-Null - } - continue - } - else - { - if ($desiredValue -ne $currentValue) - { - Write-Verbose -Message ($script:localizedData.NoMatchValueMessage -f $desiredType.FullName, $key, $currentValue, $desiredValue) - $returnValue = $false - } - } - } - - if ($ReverseCheck) - { - Write-Verbose -Message $script:localizedData.StartingReverseCheck - $reverseCheckParameters = $PSBoundParameters - $reverseCheckParameters.CurrentValues = $DesiredValues - $reverseCheckParameters.DesiredValues = $CurrentValues - $null = $reverseCheckParameters.Remove('ReverseCheck') - - if ($returnValue) - { - $returnValue = Test-DscParameterState @reverseCheckParameters - } - else - { - $null = Test-DscParameterState @reverseCheckParameters - } - } - - Write-Verbose -Message ($script:localizedData.TestDscParameterResultMessage -f $returnValue) - return $returnValue -} - -<# - .SYNOPSIS - Tests of an object has a property - - .PARAMETER Object - The object to test - - .PARAMETER PropertyName - The property name -#> -function Test-DscObjectHasProperty -{ - [CmdletBinding()] - [OutputType([System.Boolean])] - param - ( - [Parameter(Mandatory = $true)] - [System.Object] - $Object, - - [Parameter(Mandatory = $true)] - [System.String] - $PropertyName - ) - - if ($Object.PSObject.Properties.Name -contains $PropertyName) - { - return [System.Boolean] $Object.$PropertyName - } - - return $false -} - -<# - .SYNOPSIS - Converts a hashtable into a CimInstance array. - - .DESCRIPTION - This function is used to convert a hashtable into MSFT_KeyValuePair objects. These are stored as an CimInstance array. - DSC cannot handle hashtables but CimInstances arrays storing MSFT_KeyValuePair. - - .PARAMETER Hashtable - A hashtable with the values to convert. - - .OUTPUTS - An object array with CimInstance objects. -#> -function ConvertTo-CimInstance -{ - [CmdletBinding()] - [OutputType([System.Object[]])] - param - ( - [Parameter(Mandatory = $true, ValueFromPipeline = $true)] - [System.Collections.Hashtable] - $Hashtable - ) - - process - { - foreach ($item in $Hashtable.GetEnumerator()) - { - New-CimInstance -ClassName MSFT_KeyValuePair -Namespace root/microsoft/Windows/DesiredStateConfiguration -Property @{ - Key = $item.Key - Value = if ($item.Value -is [array]) - { - $item.Value -join ',' - } - else - { - $item.Value - } - } -ClientOnly - } - } -} +$modulePath = Join-Path -Path (Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent) -ChildPath 'Modules' +Import-Module -Name (Join-Path -Path $modulePath -ChildPath 'DscResource.Common') -<# - .SYNOPSIS - Converts CimInstances into a hashtable. - - .DESCRIPTION - This function is used to convert a CimInstance array containing MSFT_KeyValuePair objects into a hashtable. - - .PARAMETER CimInstance - An array of CimInstances or a single CimInstance object to convert. - - .OUTPUTS - Hashtable -#> -function ConvertTo-HashTable -{ - [CmdletBinding()] - [OutputType([System.Collections.Hashtable])] - param - ( - [Parameter(Mandatory = $true, ValueFromPipeline = $true)] - [AllowEmptyCollection()] - [Microsoft.Management.Infrastructure.CimInstance[]] - $CimInstance - ) - - begin - { - $result = @{ } - } - - process - { - foreach ($ci in $CimInstance) - { - $result.Add($ci.Key, $ci.Value) - } - } - - end - { - $result - } -} +# Import Localization Strings +$script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' <# .SYNOPSIS @@ -1277,64 +622,7 @@ function Get-RegistryPropertyValue return $getItemPropertyResult } -<# - .SYNOPSIS - Throws an error if there is a bound parameter that exists in both the - mutually exclusive lists. - - .PARAMETER BoundParameterList - The parameters that should be evaluated against the mutually exclusive - lists MutuallyExclusiveList1 and MutuallyExclusiveList2. This parameter is - normally set to the $PSBoundParameters variable. - - .PARAMETER MutuallyExclusiveList1 - An array of parameter names that are not allowed to be bound at the - same time and those in MutuallyExclusiveList2. - - .PARAMETER MutuallyExclusiveList2 - An array of parameter names that are not allowed to be bound at the - same time and those in MutuallyExclusiveList1. -#> -function Assert-BoundParameter -{ - [CmdletBinding()] - param - ( - [Parameter(Mandatory = $true)] - [AllowEmptyCollection()] - [System.Collections.Hashtable] - $BoundParameterList, - - [Parameter(Mandatory = $true)] - [System.String[]] - $MutuallyExclusiveList1, - - [Parameter(Mandatory = $true)] - [System.String[]] - $MutuallyExclusiveList2 - ) - - $itemFoundFromList1 = $BoundParameterList.Keys.Where({ $_ -in $MutuallyExclusiveList1 }) - $itemFoundFromList2 = $BoundParameterList.Keys.Where({ $_ -in $MutuallyExclusiveList2 }) - - if ($itemFoundFromList1.Count -gt 0 -and $itemFoundFromList2.Count -gt 0) - { - $errorMessage = ` - $script:localizedData.ParameterUsageWrong ` - -f ($MutuallyExclusiveList1 -join "','"), ($MutuallyExclusiveList2 -join "','") - - New-InvalidArgumentException -ArgumentName 'Parameters' -Message $errorMessage - } -} - -# Import Localization Strings -$script:localizedData = Get-LocalizedData ` - -ResourceName 'ComputerManagementDsc.Common' ` - -ScriptRoot $PSScriptRoot - Export-ModuleMember -Function @( - 'Test-DscParameterState' - 'Test-DscObjectHasProperty' 'Test-Command' 'Get-TimeZoneId' 'Test-TimeZoneId' @@ -1343,10 +631,5 @@ Export-ModuleMember -Function @( 'Get-PowerPlan' 'Get-ActivePowerPlan' 'Set-ActivePowerPlan' - 'Test-IsNanoServer' - 'New-InvalidArgumentException' - 'New-InvalidOperationException' - 'Get-LocalizedData' 'Get-RegistryPropertyValue' - 'Assert-BoundParameter' ) diff --git a/source/Modules/ComputerManagementDsc.Common/en-US/ComputerManagementDsc.Common.strings.psd1 b/source/Modules/ComputerManagementDsc.Common/en-US/ComputerManagementDsc.Common.strings.psd1 index a55eca25..54298d4c 100644 --- a/source/Modules/ComputerManagementDsc.Common/en-US/ComputerManagementDsc.Common.strings.psd1 +++ b/source/Modules/ComputerManagementDsc.Common/en-US/ComputerManagementDsc.Common.strings.psd1 @@ -1,19 +1,4 @@ ConvertFrom-StringData @' - InvalidCurrentValuesError = Property 'CurrentValues' in Test-DscParameterState must be either a Hashtable, CimInstance or CimIntance[]. Type detected was '{0}'. - InvalidDesiredValuesError = Property 'DesiredValues' in Test-DscParameterState must be either a Hashtable or CimInstance. Type detected was '{0}'. - InvalidValuesToCheckError = If 'DesiredValues' is a CimInstance then property 'ValuesToCheck' must contain a value. - TestDscParameterCompareMessage = Comparing values in property '{0}' of type '{1}'. - MatchPsCredentialUsernameMessage = MATCH: PSCredential username match. Current state is '{0}' and desired state is '{1}'. - NoMatchPsCredentialUsernameMessage = NOTMATCH: PSCredential username mismatch. Current state is '{0}' and desired state is '{1}'. - NoMatchTypeMismatchMessage = NOTMATCH: Type mismatch for property '{0}' Current state type is '{1}' and desired type is '{2}'. - MatchValueMessage = MATCH: Value (type '{0}') for property '{1}' does match. Current state is '{2}' and desired state is '{3}'. - NoMatchValueMessage = NOTMATCH: Value (type '{0}') for property '{1}' does not match. Current state is '{2}' and desired state is '{3}'. - NoMatchValueDifferentCountMessage = NOTMATCH: Value (type '{0}') for property '{1}' does have a different count. Current state count is '{2}' and desired state count is '{3}'. - NoMatchElementTypeMismatchMessage = NOTMATCH: Type mismatch for property '{0}' Current state type of element [{1}] is '{2}' and desired type is '{3}'. - NoMatchElementValueMismatchMessage = NOTMATCH: Value [{0}] (type '{1}') for property '{2}' does match. Current state is '{3}' and desired state is '{4}'. - MatchElementValueMessage = MATCH: Value [{0}] (type '{1}') for property '{2}' does match. Current state is '{3}' and desired state is '{4}'. - TestDscParameterResultMessage = Test-DscParameter result is '{0}'. - StartingReverseCheck = Starting with a reverse check. CurrentTimeZoneMessage = Current time zone is set to '{0}'. GettingTimeZoneMessage = Getting current time zone using '{0}'. SettingTimeZoneMessage = Setting time zone to '{0}' using '{1}'. @@ -27,5 +12,4 @@ ConvertFrom-StringData @' PowerPlanFound = Found power scheme '{0}'. Getting friendly name. PowerPlanFriendlyNameFound = Friendly name is '{0}'. AllPowerPlansFound = Enumerating of available power schemes done. - ParameterUsageWrong = None of the parameter(s) '{0}' may be used at the same time as any of the parameter(s) '{1}'. '@ diff --git a/tests/Unit/ComputerManagementDsc.Common.Tests.ps1 b/tests/Unit/ComputerManagementDsc.Common.Tests.ps1 index cdb4baae..0bfc9395 100644 --- a/tests/Unit/ComputerManagementDsc.Common.Tests.ps1 +++ b/tests/Unit/ComputerManagementDsc.Common.Tests.ps1 @@ -23,1054 +23,6 @@ Import-Module $script:subModuleFile -Force -ErrorAction Stop #endregion HEADER InModuleScope $script:subModuleName { - Describe 'ComputerManagementDsc.Common\Remove-CommonParameter' { - $removeCommonParameter = @{ - Parameter1 = 'value1' - Parameter2 = 'value2' - Verbose = $true - Debug = $true - ErrorAction = 'Stop' - WarningAction = 'Stop' - InformationAction = 'Stop' - ErrorVariable = 'errorVariable' - WarningVariable = 'warningVariable' - OutVariable = 'outVariable' - OutBuffer = 'outBuffer' - PipelineVariable = 'pipelineVariable' - InformationVariable = 'informationVariable' - WhatIf = $true - Confirm = $true - UseTransaction = $true - } - - Context 'Hashtable contains all common parameters' { - It 'Should not throw exception' { - { $script:result = Remove-CommonParameter -Hashtable $removeCommonParameter -Verbose } | Should -Not -Throw - } - - It 'Should have retained parameters in the hashtable' { - $script:result.Contains('Parameter1') | Should -BeTrue - $script:result.Contains('Parameter2') | Should -BeTrue - } - - It 'Should have removed the common parameters from the hashtable' { - $script:result.Contains('Verbose') | Should -BeFalse - $script:result.Contains('Debug') | Should -BeFalse - $script:result.Contains('ErrorAction') | Should -BeFalse - $script:result.Contains('WarningAction') | Should -BeFalse - $script:result.Contains('InformationAction') | Should -BeFalse - $script:result.Contains('ErrorVariable') | Should -BeFalse - $script:result.Contains('WarningVariable') | Should -BeFalse - $script:result.Contains('OutVariable') | Should -BeFalse - $script:result.Contains('OutBuffer') | Should -BeFalse - $script:result.Contains('PipelineVariable') | Should -BeFalse - $script:result.Contains('InformationVariable') | Should -BeFalse - $script:result.Contains('WhatIf') | Should -BeFalse - $script:result.Contains('Confirm') | Should -BeFalse - $script:result.Contains('UseTransaction') | Should -BeFalse - } - } - } - - Describe 'ComputerManagementDsc.Common\Test-DscParameterState' { - $verbose = $true - - Context 'When testing single values' { - $currentValues = @{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a', 'b', 'c' - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v1', 'v2', 'v3' - } - } - - Context 'When all values match' { - $desiredValues = [PSObject] @{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a', 'b', 'c' - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v1', 'v2', 'v3' - } - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $true' { - $script:result | Should -Be $true - } - } - - Context 'When a string is mismatched' { - $desiredValues = [PSObject] @{ - String = 'different string' - Bool = $true - Int = 99 - Array = 'a', 'b', 'c' - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v1', 'v2', 'v3' - } - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $false' { - $script:result | Should -Be $false - } - } - - Context 'When a boolean is mismatched' { - $desiredValues = [PSObject] @{ - String = 'a string' - Bool = $false - Int = 99 - Array = 'a', 'b', 'c' - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v1', 'v2', 'v3' - } - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $false' { - $script:result | Should -Be $false - } - } - - Context 'When an int is mismatched' { - $desiredValues = [PSObject] @{ - String = 'a string' - Bool = $true - Int = 1 - Array = 'a', 'b', 'c' - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v1', 'v2', 'v3' - } - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $false' { - $script:result | Should -Be $false - } - } - - Context 'When a type is mismatched' { - $desiredValues = [PSObject] @{ - String = 'a string' - Bool = $true - Int = '99' - Array = 'a', 'b', 'c' - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $false' { - $script:result | Should -Be $false - } - } - - Context 'When a type is mismatched but TurnOffTypeChecking is used' { - $desiredValues = [PSObject] @{ - String = 'a string' - Bool = $true - Int = '99' - Array = 'a', 'b', 'c' - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -TurnOffTypeChecking ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $true' { - $script:result | Should -Be $true - } - } - - Context 'When a value is mismatched but valuesToCheck is used to exclude them' { - $desiredValues = [PSObject] @{ - String = 'a string' - Bool = $false - Int = 1 - Array = @( 'a', 'b' ) - } - - $valuesToCheck = @( - 'String' - ) - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -ValuesToCheck $valuesToCheck ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $true' { - $script:result | Should -Be $true - } - } - } - - Context 'When testing array values' { - BeforeAll { - $currentValues = @{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a', 'b', 'c', 1 - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v1', 'v2', 'v3' - } - } - } - - Context 'When array is missing a value' { - $desiredValues = [PSObject]@{ - String = 'a string' - Bool = $true - Int = 1 - Array = 'a', 'b', 'c' - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v1', 'v2', 'v3' - } - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $false' { - $script:result | Should -Be $false - } - } - - Context 'When array has an additional value' { - $desiredValues = [PSObject] @{ - String = 'a string' - Bool = $true - Int = 1 - Array = 'a', 'b', 'c', 1, 2 - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $false' { - $script:result | Should -Be $false - } - } - - Context 'When array has a different value' { - $desiredValues = [PSObject] @{ - String = 'a string' - Bool = $true - Int = 1 - Array = 'a', 'x', 'c', 1 - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $false' { - $script:result | Should -Be $false - } - } - - Context 'When array has different order' { - $desiredValues = [PSObject] @{ - String = 'a string' - Bool = $true - Int = 1 - Array = 'c', 'b', 'a', 1 - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $false' { - $script:result | Should -Be $false - } - } - - Context 'When array has different order but SortArrayValues is used' { - $desiredValues = [PSObject] @{ - String = 'a string' - Bool = $true - Int = 1 - Array = 'c', 'b', 'a', 1 - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -SortArrayValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $false' { - $script:result | Should -Be $false - } - } - - - Context 'When array has a value with a different type' { - $desiredValues = [PSObject] @{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a', 'b', 'c', '1' - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $false' { - $script:result | Should -Be $false - } - } - - Context 'When array has a value with a different type but TurnOffTypeChecking is used' { - $desiredValues = [PSObject] @{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a', 'b', 'c', '1' - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -TurnOffTypeChecking ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $true' { - $script:result | Should -Be $true - } - } - - Context 'When both arrays are empty' { - $currentValues = @{ - String = 'a string' - Bool = $true - Int = 99 - Array = @() - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = @() - } - } - - $desiredValues = [PSObject]@{ - String = 'a string' - Bool = $true - Int = 99 - Array = @() - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = @() - } - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $true' { - $script:result | Should -Be $true - } - } - } - - Context 'When testing hashtables' { - $currentValues = @{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a', 'b', 'c' - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v1', 'v2', 'v3', 99 - } - } - - Context 'When hashtable is missing a value' { - $desiredValues = [PSObject]@{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a', 'b', 'c' - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v1', 'v2', 'v3' - } - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $false' { - $script:result | Should -Be $false - } - } - - Context 'When hashtable has an additional value' { - $desiredValues = [PSObject]@{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a', 'b', 'c' - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v1', 'v2', 'v3', 99, 100 - } - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $false' { - $script:result | Should -Be $false - } - } - - Context 'When hashtable has a different value' { - $desiredValues = [PSObject]@{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a', 'b', 'c' - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'xx', 'v2', 'v3', 99 - } - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $false' { - $script:result | Should -Be $false - } - } - - Context 'When an array in hashtable has different order' { - $desiredValues = [PSObject]@{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a', 'b', 'c' - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v3', 'v2', 'v1', 99 - } - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $false' { - $script:result | Should -Be $false - } - } - - Context 'When an array in hashtable has different order but SortArrayValues is used' { - $desiredValues = [PSObject]@{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a', 'b', 'c' - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v3', 'v2', 'v1', 99 - } - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -SortArrayValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $true' { - $script:result | Should -Be $true - } - } - - - Context 'When hashtable has a value with a different type' { - $desiredValues = [PSObject]@{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a', 'b', 'c' - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v1', 'v2', 'v3', '99' - } - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $false' { - $script:result | Should -Be $false - } - } - - Context 'When hashtable has a value with a different type but TurnOffTypeChecking is used' { - $desiredValues = [PSObject]@{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a', 'b', 'c' - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v1', 'v2', 'v3', 99 - } - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -TurnOffTypeChecking ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $true' { - $script:result | Should -Be $true - } - } - } - - Context 'When testing CimInstances / hashtables' { - $currentValues = @{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a', 'b', 'c' - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v1', 'v2', 'v3', 99 - } - CimInstances = [CimInstance[]](ConvertTo-CimInstance -Hashtable @{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a, b, c' - }) - } - - Context 'When everything matches' { - $desiredValues = [PSObject]@{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a', 'b', 'c' - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v1', 'v2', 'v3', 99 - } - CimInstances = [CimInstance[]](ConvertTo-CimInstance -Hashtable @{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a, b, c' - }) - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $true' { - $script:result | Should -Be $true - } - } - - Context 'When CimInstances missing a value in the desired state (not recognized)' { - $desiredValues = [PSObject]@{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a', 'b', 'c' - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v1', 'v2', 'v3', 99 - } - CimInstances = @{ - String = 'a string' - Bool = $true - Array = 'a, b, c' - } - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $true' { - $script:result | Should -Be $true - } - } - - Context 'When CimInstances missing a value in the desired state (recognized using ReverseCheck)' { - $desiredValues = [PSObject]@{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a', 'b', 'c' - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v1', 'v2', 'v3', 99 - } - CimInstances = @{ - String = 'a string' - Bool = $true - Array = 'a, b, c' - } - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -ReverseCheck ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $false' { - $script:result | Should -Be $false - } - } - - Context 'When CimInstances have an additional value' { - $desiredValues = [PSObject]@{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a', 'b', 'c' - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v1', 'v2', 'v3', 99 - } - CimInstances = @{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a, b, c' - Test = 'Some string' - } - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $false' { - $script:result | Should -Be $false - } - } - - Context 'When CimInstances have a different value' { - $desiredValues = [PSObject]@{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a', 'b', 'c' - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v1', 'v2', 'v3', 99 - } - CimInstances = @{ - String = 'some other string' - Bool = $true - Int = 99 - Array = 'a, b, c' - } - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $false' { - $script:result | Should -Be $false - } - } - - Context 'When CimInstances have a value with a different type' { - $desiredValues = [PSObject]@{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a', 'b', 'c' - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v1', 'v2', 'v3', 99 - } - CimInstances = @{ - String = 'a string' - Bool = $true - Int = '99' - Array = 'a, b, c' - } - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $false' { - $script:result | Should -Be $false - } - } - - Context 'When CimInstances have a value with a different type but TurnOffTypeChecking is used' { - $desiredValues = [PSObject]@{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a', 'b', 'c' - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v1', 'v2', 'v3', 99 - } - CimInstances = @{ - String = 'a string' - Bool = $true - Int = '99' - Array = 'a, b, c' - } - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -TurnOffTypeChecking ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $true' { - $script:result | Should -Be $true - } - } - } - - Context 'When reverse checking' { - $currentValues = @{ - String = 'a string' - Bool = $true - Int = 99 - Array = 'a', 'b', 'c', 1 - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v1', 'v2', 'v3' - } - } - - Context 'When even if missing property in the desired state' { - $desiredValues = [PSObject] @{ - Array = 'a', 'b', 'c', 1 - Hashtable = @{ - k1 = 'Test' - k2 = 123 - k3 = 'v1', 'v2', 'v3' - } - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $true' { - $script:result | Should -Be $true - } - } - - Context 'When missing property in the desired state' { - $currentValues = @{ - String = 'a string' - Bool = $true - } - - $desiredValues = [PSObject] @{ - String = 'a string' - } - - It 'Should not throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -ReverseCheck ` - -Verbose:$verbose } | Should -Not -Throw - } - - It 'Should return $false' { - $script:result | Should -Be $false - } - } - } - - Context 'When testing parameter types' { - Context 'When desired value is of the wrong type' { - $currentValues = @{ - String = 'a string' - } - - $desiredValues = 1, 2, 3 - - It 'Should throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Throw - } - } - - Context 'When current value is of the wrong type' { - $currentValues = 1, 2, 3 - - $desiredValues = @{ - String = 'a string' - } - - It 'Should throw exception' { - { $script:result = Test-DscParameterState ` - -CurrentValues $currentValues ` - -DesiredValues $desiredValues ` - -Verbose:$verbose } | Should -Throw - } - } - } - } - - Describe 'ComputerManagementDsc.Common\Test-DscObjectHasProperty' { - # Use the Get-Verb cmdlet to just get a simple object fast - $testDscObject = (Get-Verb)[0] - - Context 'When the object contains the expected property' { - It 'Should not throw exception' { - { $script:result = Test-DscObjectHasProperty -Object $testDscObject -PropertyName 'Verb' -Verbose } | Should -Not -Throw - } - - It 'Should return $true' { - $script:result | Should -Be $true - } - } - - Context 'When the object does not contain the expected property' { - It 'Should not throw exception' { - { $script:result = Test-DscObjectHasProperty -Object $testDscObject -PropertyName 'Missing' -Verbose } | Should -Not -Throw - } - - It 'Should return $false' { - $script:result | Should -Be $false - } - } - } - - Describe 'ComputerManagementDsc.Common\ConvertTo-CimInstance' { - $hashtable = @{ - k1 = 'v1' - k2 = 100 - k3 = 1, 2, 3 - } - - Context 'When the array contains the expected record count' { - It 'Should not throw exception' { - { $script:result = [CimInstance[]]($hashtable | ConvertTo-CimInstance) } | Should -Not -Throw - } - - It "Should record count should be $($hashTable.Count)" { - $script:result.Count | Should -Be $hashtable.Count - } - - It 'Should return result of type CimInstance[]' { - $script:result.GetType().Name | Should -Be 'CimInstance[]' - } - - It 'Should return value "k1" in the CimInstance array should be "v1"' { - ($script:result | Where-Object Key -eq k1).Value | Should -Be 'v1' - } - - It 'Should return value "k2" in the CimInstance array should be "100"' { - ($script:result | Where-Object Key -eq k2).Value | Should -Be 100 - } - - It 'Should return value "k3" in the CimInstance array should be "1,2,3"' { - ($script:result | Where-Object Key -eq k3).Value | Should -Be '1,2,3' - } - } - } - - Describe 'ComputerManagementDsc.Common\ConvertTo-HashTable' { - [CimInstance[]]$cimInstances = ConvertTo-CimInstance -Hashtable @{ - k1 = 'v1' - k2 = 100 - k3 = 1, 2, 3 - } - - Context 'When the array contains the expected record count' { - It 'Should not throw exception' { - { $script:result = $cimInstances | ConvertTo-HashTable } | Should -Not -Throw - } - - It "Should return record count of $($cimInstances.Count)" { - $script:result.Count | Should -Be $cimInstances.Count - } - - It 'Should return result of type [System.Collections.Hashtable]' { - $script:result | Should -BeOfType [System.Collections.Hashtable] - } - - It 'Should return value "k1" in the hashtable should be "v1"' { - $script:result.k1 | Should -Be 'v1' - } - - It 'Should return value "k2" in the hashtable should be "100"' { - $script:result.k2 | Should -Be 100 - } - - It 'Should return value "k3" in the hashtable should be "1,2,3"' { - $script:result.k3 | Should -Be '1,2,3' - } - } - } - Describe 'ComputerManagementDsc.Common\Get-TimeZoneId' { Context '"Get-TimeZone" not available and current timezone is set to "Pacific Standard Time"' { Mock ` @@ -1601,183 +553,6 @@ InModuleScope $script:subModuleName { } } - Describe 'ComputerManagementDsc.Common\Get-LocalizedData' { - $mockTestPath = { - return $mockTestPathReturnValue - } - - $mockImportLocalizedData = { - $BaseDirectory | Should -Be $mockExpectedLanguagePath - } - - BeforeEach { - Mock -CommandName Test-Path -MockWith $mockTestPath -Verifiable - Mock -CommandName Import-LocalizedData -MockWith $mockImportLocalizedData -Verifiable - } - - Context 'When loading localized data for Swedish' { - $mockExpectedLanguagePath = 'sv-SE' - $mockTestPathReturnValue = $true - - It 'Should call Import-LocalizedData with sv-SE language' { - Mock -CommandName Join-Path -MockWith { - return 'sv-SE' - } -Verifiable - - { Get-LocalizedData -ResourceName 'DummyResource' } | Should -Not -Throw - - Assert-MockCalled -CommandName Join-Path -Exactly -Times 3 -Scope It - Assert-MockCalled -CommandName Test-Path -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Import-LocalizedData -Exactly -Times 1 -Scope It - } - - $mockExpectedLanguagePath = 'en-US' - $mockTestPathReturnValue = $false - - It 'Should call Import-LocalizedData and fallback to en-US if sv-SE language does not exist' { - Mock -CommandName Join-Path -MockWith { - return $ChildPath - } -Verifiable - - { Get-LocalizedData -ResourceName 'DummyResource' } | Should -Not -Throw - - Assert-MockCalled -CommandName Join-Path -Exactly -Times 4 -Scope It - Assert-MockCalled -CommandName Test-Path -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Import-LocalizedData -Exactly -Times 1 -Scope It - } - - Context 'When $ScriptRoot is set to a path' { - $mockExpectedLanguagePath = 'sv-SE' - $mockTestPathReturnValue = $true - - It 'Should call Import-LocalizedData with sv-SE language' { - Mock -CommandName Join-Path -MockWith { - return 'sv-SE' - } -Verifiable - - { Get-LocalizedData -ResourceName 'DummyResource' -ScriptRoot '.' } | Should -Not -Throw - - Assert-MockCalled -CommandName Join-Path -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Test-Path -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Import-LocalizedData -Exactly -Times 1 -Scope It - } - - $mockExpectedLanguagePath = 'en-US' - $mockTestPathReturnValue = $false - - It 'Should call Import-LocalizedData and fallback to en-US if sv-SE language does not exist' { - Mock -CommandName Join-Path -MockWith { - return $ChildPath - } -Verifiable - - { Get-LocalizedData -ResourceName 'DummyResource' -ScriptRoot '.' } | Should -Not -Throw - - Assert-MockCalled -CommandName Join-Path -Exactly -Times 2 -Scope It - Assert-MockCalled -CommandName Test-Path -Exactly -Times 1 -Scope It - Assert-MockCalled -CommandName Import-LocalizedData -Exactly -Times 1 -Scope It - } - } - } - - Context 'When loading localized data for English' { - Mock -CommandName Join-Path -MockWith { - return 'en-US' - } -Verifiable - - $mockExpectedLanguagePath = 'en-US' - $mockTestPathReturnValue = $true - - It 'Should call Import-LocalizedData with en-US language' { - { Get-LocalizedData -ResourceName 'DummyResource' } | Should -Not -Throw - } - } - - Assert-VerifiableMock - } - - Describe 'ComputerManagementDsc.Common\New-InvalidOperationException' { - Context 'When calling with Message parameter only' { - It 'Should throw the correct error' { - $mockErrorMessage = 'Mocked error' - - { New-InvalidOperationException -Message $mockErrorMessage } | Should -Throw $mockErrorMessage - } - } - - Context 'When calling with both the Message and ErrorRecord parameter' { - It 'Should throw the correct error' { - $mockErrorMessage = 'Mocked error' - $mockExceptionErrorMessage = 'Mocked exception error message' - - $mockException = New-Object -TypeName System.Exception -ArgumentList $mockExceptionErrorMessage - $mockErrorRecord = New-Object -TypeName System.Management.Automation.ErrorRecord -ArgumentList $mockException, $null, 'InvalidResult', $null - - { New-InvalidOperationException -Message $mockErrorMessage -ErrorRecord $mockErrorRecord } | Should -Throw ('System.InvalidOperationException: {0} ---> System.Exception: {1}' -f $mockErrorMessage, $mockExceptionErrorMessage) - } - } - - Assert-VerifiableMock - } - - Describe 'ComputerManagementDsc.Common\New-InvalidArgumentException' { - Context 'When calling with both the Message and ArgumentName parameter' { - It 'Should throw the correct error' { - $mockErrorMessage = 'Mocked error' - $mockArgumentName = 'MockArgument' - - { New-InvalidArgumentException -Message $mockErrorMessage -ArgumentName $mockArgumentName } | Should -Throw ('Parameter name: {0}' -f $mockArgumentName) - } - } - - Assert-VerifiableMock - } - - Describe 'ComputerManagementDsc.Common\Test-IsNanoServer' { - Context 'When the cmdlet Get-ComputerInfo does not exist' { - BeforeAll { - Mock -CommandName Test-Command { - return $false - } - } - - Test-IsNanoServer | Should -BeFalse - } - - Context 'When the current computer is a Nano server' { - BeforeAll { - Mock -CommandName Test-Command { - return $true - } - - Mock -CommandName Get-ComputerInfo { - return @{ - OsProductType = 'Server' - OsServerLevel = 'NanoServer' - } - } - } - - Test-IsNanoServer | Should -BeTrue - } - - Context 'When the current computer is not a Nano server' { - BeforeAll { - Mock -CommandName Test-Command { - return $true - } - - Mock -CommandName Get-ComputerInfo { - return @{ - OsProductType = 'Server' - OsServerLevel = 'FullServer' - } - } - } - - Test-IsNanoServer | Should -BeFalse - } - } - Describe 'ComputerManagementDsc.Common\Get-RegistryPropertyValue' -Tag 'GetRegistryPropertyValue' { BeforeAll { $mockWrongRegistryPath = 'HKLM:\SOFTWARE\AnyPath' @@ -1844,117 +619,4 @@ InModuleScope $script:subModuleName { } } } - - Describe 'ComputerManagementDsc.Common\Assert-BoundParameter' -Tag 'AssertBoundParameter' { - Context 'When the assert is successful' { - Context 'When there are no bound parameters' { - It 'Should not throw an error' { - { - $assertBoundParameterParameters = @{ - BoundParameterList = @{} - MutuallyExclusiveList1 = @('a') - MutuallyExclusiveList2 = @('b') - } - - Assert-BoundParameter @assertBoundParameterParameters - } | Should -Not -Throw - } - } - - Context 'When there are one bound parameters' { - It 'Should not throw an error' { - { - $assertBoundParameterParameters = @{ - BoundParameterList = @{ - param1 = 'value1' - } - MutuallyExclusiveList1 = @('a') - MutuallyExclusiveList2 = @('b') - } - - Assert-BoundParameter @assertBoundParameterParameters - } | Should -Not -Throw - } - } - - Context 'When there are two bound parameters' { - It 'Should not throw an error' { - { - $assertBoundParameterParameters = @{ - BoundParameterList = @{ - param1 = 'value1' - param2 = 'value2' - } - MutuallyExclusiveList1 = @('a', 'b') - MutuallyExclusiveList2 = @('c', 'd') - } - - Assert-BoundParameter @assertBoundParameterParameters - } | Should -Not -Throw - } - } - - Context 'When there are only one parameter matching a value in an exclusive list' { - It 'Should not throw an error' { - { - $assertBoundParameterParameters = @{ - BoundParameterList = @{ - param1 = 'value1' - } - MutuallyExclusiveList1 = @('param1') - MutuallyExclusiveList2 = @('param2') - } - - Assert-BoundParameter @assertBoundParameterParameters - } | Should -Not -Throw - } - } - } - - Context 'When the assert fails' { - Context 'When using parameters that are mutually exclusive' { - It 'Should throw an error' { - $errorMessage = ` - $script:localizedData.ParameterUsageWrong ` - -f 'param1', 'param2' - - { - $assertBoundParameterParameters = @{ - BoundParameterList = @{ - param1 = 'value1' - param2 = 'value1' - } - MutuallyExclusiveList1 = @('param1') - MutuallyExclusiveList2 = @('param2') - } - - Assert-BoundParameter @assertBoundParameterParameters - } | Should -Throw $errorMessage - } - } - - Context 'When using several parameters that are mutually exclusive' { - It 'Should throw an error' { - $errorMessage = ` - $script:localizedData.ParameterUsageWrong ` - -f "param1','param2", "param3','param4" - - { - $assertBoundParameterParameters = @{ - BoundParameterList = @{ - param1 = 'value1' - param2 = 'value2' - param3 = 'value3' - param4 = 'value4' - } - MutuallyExclusiveList1 = @('param1','param2') - MutuallyExclusiveList2 = @('param3','param4') - } - - Assert-BoundParameter @assertBoundParameterParameters - } | Should -Throw $errorMessage - } - } - } - } } diff --git a/tests/Unit/DSC_Computer.Tests.ps1 b/tests/Unit/DSC_Computer.Tests.ps1 index 97d7c5f6..eeb6339d 100644 --- a/tests/Unit/DSC_Computer.Tests.ps1 +++ b/tests/Unit/DSC_Computer.Tests.ps1 @@ -734,11 +734,11 @@ try } Mock -CommandName Add-Computer -MockWith { - Throw $errorRecord + throw $errorRecord } Mock -CommandName New-InvalidOperationException -MockWith { - Throw $errorRecord + throw $errorRecord } { Set-TargetResource `