diff --git a/DSCResources/ResourceController/ResourceController.psm1 b/DSCResources/ResourceController/ResourceController.psm1 index 21b03ca..62f4b49 100644 --- a/DSCResources/ResourceController/ResourceController.psm1 +++ b/DSCResources/ResourceController/ResourceController.psm1 @@ -17,6 +17,10 @@ function Get-TargetResource [System.String] $ResourceName, + [Parameter()] + [System.String] + $ResourceModuleName, + [Parameter()] [System.String] $Properties, @@ -34,7 +38,7 @@ function Get-TargetResource $ResourceVersion, [Parameter()] - [Microsoft.Management.Infrastructure.CimInstance[]] + [Microsoft.Management.Infrastructure.CimInstance[]] $Credentials ) @@ -43,7 +47,14 @@ function Get-TargetResource $PropertiesHashTable = [scriptblock]::Create($Properties).Invoke() $PropertiesHashTable = ConvertTo-Hashtable -Hashtable $PropertiesHashTable -Credentials $Credentials - $dscResource = (Get-DscResource -Name $ResourceName).Where( {$_.Version -eq $ResourceVersion})[0] + if ($ResourceModuleName) + { + $dscResource = (Get-DscResource -Name $ResourceName -Module $ResourceModuleName).Where( {$_.Version -eq $ResourceVersion})[0] + } + else + { + $dscResource = (Get-DscResource -Name $ResourceName).Where( {$_.Version -eq $ResourceVersion})[0] + } try { @@ -114,6 +125,10 @@ function Test-TargetResource [string] $ResourceName, + [Parameter()] + [System.String] + $ResourceModuleName, + [Parameter()] [System.String] $Properties, @@ -131,7 +146,7 @@ function Test-TargetResource $ResourceVersion, [Parameter()] - [Microsoft.Management.Infrastructure.CimInstance[]] + [Microsoft.Management.Infrastructure.CimInstance[]] $Credentials ) @@ -140,7 +155,14 @@ function Test-TargetResource $PropertiesHashTable = [scriptblock]::Create($Properties).Invoke() $PropertiesHashTable = ConvertTo-Hashtable -Hashtable $PropertiesHashTable -Credentials $Credentials - $dscResource = (Get-DscResource -Name $ResourceName).Where( {$_.Version -eq $ResourceVersion})[0] + if ($ResourceModuleName) + { + $dscResource = (Get-DscResource -Name $ResourceName -Module $ResourceModuleName).Where( {$_.Version -eq $ResourceVersion})[0] + } + else + { + $dscResource = (Get-DscResource -Name $ResourceName).Where( {$_.Version -eq $ResourceVersion})[0] + } try { @@ -184,6 +206,10 @@ function Set-TargetResource [string] $ResourceName, + [Parameter()] + [System.String] + $ResourceModuleName, + [Parameter()] [System.String] $Properties, @@ -201,7 +227,7 @@ function Set-TargetResource $ResourceVersion, [Parameter()] - [Microsoft.Management.Infrastructure.CimInstance[]] + [Microsoft.Management.Infrastructure.CimInstance[]] $Credentials ) @@ -238,12 +264,19 @@ function Set-TargetResource return } - $functionName = "Set-TargetResource" + $functionName = "Set-TargetResource" $PropertiesHashTable = [scriptblock]::Create($Properties).Invoke() $PropertiesHashTable = ConvertTo-Hashtable -Hashtable $PropertiesHashTable -Credentials $Credentials - $dscResource = (Get-DscResource -Name $ResourceName).Where( {$_.Version -eq $ResourceVersion})[0] + if ($ResourceModuleName) + { + $dscResource = (Get-DscResource -Name $ResourceName -Module $ResourceModuleName).Where( {$_.Version -eq $ResourceVersion})[0] + } + else + { + $dscResource = (Get-DscResource -Name $ResourceName).Where( {$_.Version -eq $ResourceVersion})[0] + } try { @@ -550,7 +583,7 @@ function ConvertTo-Hashtable $Hashtable, [Parameter()] - [Microsoft.Management.Infrastructure.CimInstance[]] + [Microsoft.Management.Infrastructure.CimInstance[]] $Credentials ) @@ -561,7 +594,7 @@ function ConvertTo-Hashtable { $split = $Hashtable.$row -split ':', 2 $credential = $Credentials | Where-Object -FilterScript { $_.Name -eq $split[1] } | Select-Object -First 1 - + $password = ConvertTo-SecureString -String $credential.Credential.Password -AsPlainText -Force $credentialObject = [PsCredential]::new($credential.Credential.UserName, $password) diff --git a/DSCResources/ResourceController/ResourceController.schema.mof b/DSCResources/ResourceController/ResourceController.schema.mof index 3396294..6cba3e0 100644 --- a/DSCResources/ResourceController/ResourceController.schema.mof +++ b/DSCResources/ResourceController/ResourceController.schema.mof @@ -3,7 +3,8 @@ class ResourceController : OMI_BaseResource { [Key] String InstanceName; [Required] String ResourceName; - [Write, Description("")] String Properties; + [Write] String ResourceModuleName; + [Write, Description("")] String Properties; [Read, EmbeddedInstance("MSFT_KeyValuePair"), Description("")] String Result[]; [Write] Boolean SuppressReboot; [Write, EmbeddedInstance("MaintenanceWindow")] string MaintenanceWindow[]; @@ -26,7 +27,7 @@ class MaintenanceWindow [ClassVersion("1.0.0.0")] class Credential -{ +{ [Required] String Name; [Required,EmbeddedInstance("MSFT_Credential")] string Credential; }; diff --git a/Examples/ResourceController_Examples.ps1 b/Examples/ResourceController_Examples.ps1 index 28ec263..63dae2b 100644 --- a/Examples/ResourceController_Examples.ps1 +++ b/Examples/ResourceController_Examples.ps1 @@ -1,15 +1,16 @@ ResourceController 'newtest' { - InstanceName = 'newtest' - ResourceName = 'Registry' - ResourceVersion = '1.1' - Credentials = @( + InstanceName = 'newtest' + ResourceName = 'Registry' + ResourceModuleName = 'PSDscResources' + ResourceVersion = '1.1' + Credentials = @( Credential { - Name = 'Cred1' + Name = 'Cred1' Credential = $cred } Credential { - Name = 'Cred2' + Name = 'Cred2' Credential = $cred2 } ) diff --git a/ResourceControllerDSC.psd1 b/ResourceControllerDSC.psd1 index fbef8d4..14c497e 100644 --- a/ResourceControllerDSC.psd1 +++ b/ResourceControllerDSC.psd1 @@ -13,7 +13,7 @@ # Version number of this module. -ModuleVersion = '2.0.1' +ModuleVersion = '2.0.2' # Supported PSEditions # CompatiblePSEditions = @() diff --git a/Tests/Unit/ResourceController.Tests.ps1 b/Tests/Unit/ResourceController.Tests.ps1 index 52d1850..cc251b5 100644 --- a/Tests/Unit/ResourceController.Tests.ps1 +++ b/Tests/Unit/ResourceController.Tests.ps1 @@ -20,7 +20,7 @@ InModuleScope 'ResourceController' { $ResourceName = 'xRegistry2' Mock -CommandName Import-Module -MockWith {} -ModuleName $DSCResourceName Mock -CommandName Remove-Module -MockWith {} -ModuleName $DSCResourceName - Mock -CommandName Get-DSCResource -MockWith { + Mock -CommandName Get-DSCResource -MockWith { @{ Path = 'FilePath' Version = '1.0' @@ -29,25 +29,25 @@ InModuleScope 'ResourceController' { @{ Name = 'ValueName' PropertyType = '[String]' - }, + }, @{ Name = 'Key' PropertyType = '[String]' - }, + }, @{ Name = 'Ensure' PropertyType = '[String]' - }, + }, @{ Name = 'ValueData' PropertyType = '[String]' - }, + }, @{ Name = 'ValueType' PropertyType = '[String]' - } + } ) - } + } } -ModuleName $DSCResourceName Mock -CommandName Test-ParameterValidation -MockWith {} -Verifiable -ModuleName $DSCResourceName Mock -CommandName Get-ValidParameter -MockWith {@{ValueName = 'Test2'; Key = 'HKEY_LOCAL_MACHINE\SOFTWARE\test'; ValueData = 'Test String'; ValueType = 'String'}} -ModuleName $DSCResourceName -Verifiable @@ -85,7 +85,7 @@ InModuleScope 'ResourceController' { $ResourceName = 'xRegistry2' Mock -CommandName Import-Module -MockWith {} -ModuleName $DSCResourceName Mock -CommandName Remove-Module -MockWith {} -ModuleName $DSCResourceName - Mock -CommandName Get-DSCResource -MockWith { + Mock -CommandName Get-DSCResource -MockWith { @{ Path = 'FilePath' Version = '1.0' @@ -94,25 +94,25 @@ InModuleScope 'ResourceController' { @{ Name = 'ValueName' PropertyType = '[String]' - }, + }, @{ Name = 'Key' PropertyType = '[String]' - }, + }, @{ Name = 'Ensure' PropertyType = '[String]' - }, + }, @{ Name = 'ValueData' PropertyType = '[String]' - }, + }, @{ Name = 'ValueType' PropertyType = '[String]' - } + } ) - } + } } -ModuleName $DSCResourceName Mock -CommandName Test-ParameterValidation -MockWith {throw 'Missing Mandatory parameter'} -Verifiable -ModuleName $DSCResourceName Mock -CommandName Get-ValidParameter -MockWith {@{ValueName = 'Test2'; Key = 'HKEY_LOCAL_MACHINE\SOFTWARE\test'; ValueData = 'Test String'; ValueType = 'String'}} -ModuleName $DSCResourceName -Verifiable @@ -136,7 +136,7 @@ InModuleScope 'ResourceController' { function Test-xRegistry2TargetResource {} Mock -CommandName Import-Module -MockWith {} -ModuleName $DSCResourceName Mock -CommandName Remove-Module -MockWith {} -ModuleName $DSCResourceName - Mock -CommandName Get-DSCResource -MockWith { + Mock -CommandName Get-DSCResource -MockWith { @{ Path = 'FilePath' Version = '1.0' @@ -145,25 +145,25 @@ InModuleScope 'ResourceController' { @{ Name = 'ValueName' PropertyType = '[String]' - }, + }, @{ Name = 'Key' PropertyType = '[String]' - }, + }, @{ Name = 'Ensure' PropertyType = '[String]' - }, + }, @{ Name = 'ValueData' PropertyType = '[String]' - }, + }, @{ Name = 'ValueType' PropertyType = '[String]' - } + } ) - } + } } -ModuleName $DSCResourceName Context "Calling Test-TargetResource on xRegistry where Key does not exist" { @@ -227,7 +227,39 @@ InModuleScope 'ResourceController' { } } - + Context "Calling Test-TargetResource on xRegistry where Key does exist and resource module name is provided" { + $ComputerName = Get-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName -Name ComputerName + Mock -CommandName Test-ParameterValidation -MockWith {} -Verifiable -ModuleName $DSCResourceName + Mock -CommandName Get-ValidParameter -MockWith {@{ValueType = 'String'; ValueData = "ComputerName"; ValueName = 'ComputerName'; Key = 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName'}} -ModuleName $DSCResourceName -Verifiable + Mock -CommandName Test-xRegistry2TargetResource -MockWith {return $true} + $ContextParams = @{ + InstanceName = 'Test' + ResourceName = 'xRegistry2' + ResourceModuleName = 'DscModule' + ResourceVersion = '1.0' + Properties = "@{ + ValueName = 'ComputerName' + Key = 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName' + ValueData = '$($ComputerName.ComputerName)' + ValueType = 'String' + }" + } + + $TestResult = & Test-TargetResource @ContextParams + + It 'Should call Test-ParameterValidation once' { + Assert-MockCalled -CommandName 'Test-ParameterValidation' -ModuleName $DSCResourceName -Times 1 -Scope 'Context' + } + + It 'Should call Get-ValidParameter once' { + Assert-MockCalled -CommandName 'Get-ValidParameter' -ModuleName $DSCResourceName -Times 1 -Scope 'Context' + } + + It 'Should return true' { + $TestResult | Should Be $true + } + } + Context "Calling Test-TargetResource on xRegistry missing mandatory params" { Mock -CommandName Test-ParameterValidation -MockWith {throw 'Missing Params'} -Verifiable -ModuleName $DSCResourceName Mock -CommandName Get-ValidParameter -MockWith {@{ValueType = 'String'; ValueData = "ComputerName"; ValueName = 'ComputerName'; Key = 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName'}} -ModuleName $DSCResourceName -Verifiable @@ -251,7 +283,7 @@ InModuleScope 'ResourceController' { function Set-xRegistry2TargetResource {} Mock -CommandName Import-Module -MockWith {} -ModuleName $DSCResourceName Mock -CommandName Remove-Module -MockWith {} -ModuleName $DSCResourceName - Mock -CommandName Get-DSCResource -MockWith { + Mock -CommandName Get-DSCResource -MockWith { @{ Path = 'FilePath' Version = '1.0' @@ -260,26 +292,27 @@ InModuleScope 'ResourceController' { @{ Name = 'ValueName' PropertyType = '[String]' - }, + }, @{ Name = 'Key' PropertyType = '[String]' - }, + }, @{ Name = 'Ensure' PropertyType = '[String]' - }, + }, @{ Name = 'ValueData' PropertyType = '[String]' - }, + }, @{ Name = 'ValueType' PropertyType = '[String]' - } + } ) - } + } } -ModuleName $DSCResourceName + Context "Calling Set-TargetResource on xRegistry inside maintenace window" { Mock -CommandName Test-ParameterValidation -MockWith {} -Verifiable -ModuleName $DSCResourceName Mock -CommandName Get-ValidParameter -MockWith {@{ValueName = 'Test'; Key = 'HKEY_LOCAL_MACHINE\SOFTWARE\TestRegistryKey'}} -ModuleName $DSCResourceName -Verifiable @@ -319,6 +352,46 @@ InModuleScope 'ResourceController' { } } + Context "Calling Set-TargetResource on xRegistry inside maintenace window and resource module name is provided" { + Mock -CommandName Test-ParameterValidation -MockWith {} -Verifiable -ModuleName $DSCResourceName + Mock -CommandName Get-ValidParameter -MockWith {@{ValueName = 'Test'; Key = 'HKEY_LOCAL_MACHINE\SOFTWARE\TestRegistryKey'}} -ModuleName $DSCResourceName -Verifiable + Mock -CommandName Set-xRegistry2TargetResource -MockWith {} + Mock -CommandName Test-MaintenanceWindow -MockWith {$true} -ModuleName $DSCResourceName + + $Windows = @( + New-CIMWindow -Frequency 'Daily' + ) + $ContextParams = @{ + InstanceName = 'Test' + ResourceName = 'xRegistry2' + ResourceModuleName = 'DscModule' + ResourceVersion = '1.0' + Properties = "@{ + ValueName = 'Test' + Key = 'HKEY_LOCAL_MACHINE\SOFTWARE\TestRegistryKey' + }" + MaintenanceWindow = $Windows + } + + & Set-TargetResource @ContextParams + + It 'Should call Test-ParameterValidation once' { + Assert-MockCalled -CommandName 'Test-ParameterValidation' -ModuleName $DSCResourceName -Times 1 -Scope 'Context' + } + + It 'Should call Get-ValidParameter once' { + Assert-MockCalled -CommandName 'Get-ValidParameter' -ModuleName $DSCResourceName -Times 1 -Scope 'Context' + } + + It 'Should call Set-xRegistryTargetResource once' { + Assert-MockCalled -CommandName 'Set-xRegistry2TargetResource' -Times 1 -Scope 'Context' + } + + It 'Should call Test-MaintenanceWindow once' { + Assert-MockCalled -CommandName 'Test-MaintenanceWindow' -ModuleName $DSCResourceName -Times 1 -Scope 'Context' + } + } + Context "Calling Set-TargetResource on xRegistry outside maintenace window" { Mock -CommandName Test-ParameterValidation -MockWith {} -Verifiable -ModuleName $DSCResourceName Mock -CommandName Get-ValidParameter -MockWith {@{ValueName = 'Test'; Key = 'HKEY_LOCAL_MACHINE\SOFTWARE\TestRegistryKey'}} -ModuleName $DSCResourceName -Verifiable @@ -497,7 +570,7 @@ InModuleScope 'ResourceController' { $window | should be $false } } - + Context "Calling Test-MaintenanceWindow outside of window Weekly without Week" { Mock Get-Date {return [DateTime]::new("2018", "01", "02")} -ParameterFilter {$PSBoundParameters.Count -eq 0} $ContextParams = @{ @@ -511,7 +584,7 @@ InModuleScope 'ResourceController' { $window | should be $false } } - + Context "Calling Test-MaintenanceWindow outside of window Weekly with Week equal to 0" { Mock Get-Date {return [DateTime]::new("2018", "01", "23")} -ParameterFilter {$PSBoundParameters.Count -eq 0} $ContextParams = @{ @@ -616,7 +689,7 @@ InModuleScope 'ResourceController' { $window | should be $true } } - + Context "Calling Test-MaintenanceWindow inside of window Daily without DayofWeek" { Mock Get-Date {return [DateTime]::new("2018", "01", "01")} -ParameterFilter {$PSBoundParameters.Count -eq 0} $ContextParams = @{ @@ -660,7 +733,7 @@ InModuleScope 'ResourceController' { $window | should be $true } } - + Context "Calling Test-MaintenanceWindow inside of window Weekly with Week equal to 0" { Mock Get-Date {return [DateTime]::new("2018", "01", "29")} -ParameterFilter {$PSBoundParameters.Count -eq 0} $ContextParams = @{ diff --git a/readme.md b/readme.md index 43cc514..57c92db 100644 --- a/readme.md +++ b/readme.md @@ -29,8 +29,10 @@ Please check out common DSC Resources [contributing guidelines]( * **[String] ResourceName**: The name of the resource you want to run. +* **[String] ResourceModuleName**: (Optional) The name of the resource module that contains the resource you want to run. + * **[Scriptblock] Properties:** A Scriptblock that returns a Hashtable of the properties for the resource you are calling. - + * **[Credential] Credentials:** Credentials you want to use as properties in the Properties Scriptblock. * **[String] Name:** The name of the credential. Used to reference the credential in the properties. * **[PSCredential] Credential:** The Credential object. @@ -56,6 +58,8 @@ Please check out common DSC Resources [contributing guidelines]( https://github.com/mcollera/ResourceControllerDsc/blob/master/Examples/ResourceController_Examples.ps1) ## Versions +### 2.0.2 + * Added optional resource module name parameter to decrease resource import time during execution. ### 2.0.1 * Removed parameter validation to avoid potential issues with ValidateScript