Skip to content

Commit 41f75e6

Browse files
Vasily LarionovVasily Larionov
authored andcommitted
Solving merge conflicts
2 parents d15aed6 + 09d3709 commit 41f75e6

16 files changed

Lines changed: 3126 additions & 804 deletions

DSCResources/CommonResourceHelper.psm1

Lines changed: 379 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,384 @@ function Get-LocalizedData
3838
return $localizedData
3939
}
4040

41+
<#
42+
.SYNOPSIS
43+
Removes common parameters from a hashtable
44+
.DESCRIPTION
45+
This function serves the purpose of removing common parameters and option common parameters from a parameter hashtable
46+
.PARAMETER Hashtable
47+
The parameter hashtable that should be pruned
48+
#>
49+
function Remove-CommonParameter
50+
{
51+
[OutputType([hashtable])]
52+
[cmdletbinding()]
53+
param
54+
(
55+
[Parameter(Mandatory = $true)]
56+
[hashtable]
57+
$Hashtable
58+
)
59+
60+
$inputClone = $Hashtable.Clone()
61+
$commonParameters = [System.Management.Automation.PSCmdlet]::CommonParameters
62+
$commonParameters += [System.Management.Automation.PSCmdlet]::OptionalCommonParameters
63+
64+
$Hashtable.Keys | Where-Object { $_ -in $commonParameters } | ForEach-Object {
65+
$inputClone.Remove($_)
66+
}
67+
68+
return $inputClone
69+
}
70+
71+
<#
72+
.SYNOPSIS
73+
Tests the status of DSC resource parameters
74+
.DESCRIPTION
75+
This function tests the parameter status of DSC resource parameters against the current values present on the system
76+
.PARAMETER CurrentValues
77+
A hashtable with the current values on the system, obtained by e.g. Get-TargetResource
78+
.PARAMETER DesiredValues
79+
The hashtable of desired values
80+
.PARAMETER ValuesToCheck
81+
The values to check if not all values should be checked
82+
.PARAMETER TurnOffTypeChecking
83+
Indicates that the type of the parameter should not be checked
84+
#>
85+
function Test-DscParameterState
86+
{
87+
[CmdletBinding()]
88+
param
89+
(
90+
[Parameter(Mandatory = $true)]
91+
[hashtable]
92+
$CurrentValues,
93+
94+
[Parameter(Mandatory = $true)]
95+
[object]
96+
$DesiredValues,
97+
98+
[string[]]
99+
$ValuesToCheck,
100+
101+
[switch]
102+
$TurnOffTypeChecking
103+
)
104+
105+
$returnValue = $true
106+
107+
$types = 'System.Management.Automation.PSBoundParametersDictionary', 'System.Collections.Hashtable', 'Microsoft.Management.Infrastructure.CimInstance'
108+
109+
if ($DesiredValues.GetType().FullName -notin $types)
110+
{
111+
throw ("Property 'DesiredValues' in Test-DscParameterState must be either a Hashtable or CimInstance. Type detected was $($DesiredValues.GetType().FullName)")
112+
}
113+
114+
if ($DesiredValues -is [Microsoft.Management.Infrastructure.CimInstance] -and -not $ValuesToCheck)
115+
{
116+
throw ("If 'DesiredValues' is a CimInstance then property 'ValuesToCheck' must contain a value")
117+
}
118+
119+
$desiredValuesClean = Remove-CommonParameter -Hashtable $DesiredValues
120+
121+
if (-not $ValuesToCheck)
122+
{
123+
$keyList = $desiredValuesClean.Keys
124+
}
125+
else
126+
{
127+
$keyList = $ValuesToCheck
128+
}
129+
130+
foreach ($key in $keyList)
131+
{
132+
if ($null -ne $desiredValuesClean.$key)
133+
{
134+
$desiredType = $desiredValuesClean.$key.GetType()
135+
}
136+
else
137+
{
138+
$desiredType = [psobject]@{
139+
Name = 'Unknown'
140+
}
141+
}
142+
143+
if ($null -ne $CurrentValues.$key)
144+
{
145+
$currentType = $CurrentValues.$key.GetType()
146+
}
147+
else
148+
{
149+
$currentType = [psobject]@{
150+
Name = 'Unknown'
151+
}
152+
}
153+
154+
if ($currentType.Name -ne 'Unknown' -and $desiredType.Name -eq 'PSCredential')
155+
{
156+
# This is a credential object. Compare only the user name
157+
if ($currentType.Name -eq 'PSCredential' -and $CurrentValues.$key.UserName -eq $desiredValuesClean.$key.UserName)
158+
{
159+
Write-Verbose -Message ('MATCH: PSCredential username match. Current state is {0} and desired state is {1}' -f $CurrentValues.$key.UserName, $desiredValuesClean.$key.UserName)
160+
continue
161+
}
162+
else
163+
{
164+
Write-Verbose -Message ('NOTMATCH: PSCredential username mismatch. Current state is {0} and desired state is {1}' -f $CurrentValues.$key.UserName, $desiredValuesClean.$key.UserName)
165+
$returnValue = $false
166+
}
167+
168+
# Assume the string is our username when the matching desired value is actually a credential
169+
if ($currentType.Name -eq 'string' -and $CurrentValues.$key -eq $desiredValuesClean.$key.UserName)
170+
{
171+
Write-Verbose -Message ('MATCH: PSCredential username match. Current state is {0} and desired state is {1}' -f $CurrentValues.$key, $desiredValuesClean.$key.UserName)
172+
continue
173+
}
174+
else
175+
{
176+
Write-Verbose -Message ('NOTMATCH: PSCredential username mismatch. Current state is {0} and desired state is {1}' -f $CurrentValues.$key, $desiredValuesClean.$key.UserName)
177+
$returnValue = $false
178+
}
179+
}
180+
181+
if (-not $TurnOffTypeChecking)
182+
{
183+
if (($desiredType.Name -ne 'Unknown' -and $currentType.Name -ne 'Unknown') -and
184+
$desiredType.FullName -ne $currentType.FullName)
185+
{
186+
Write-Verbose -Message "NOTMATCH: Type mismatch for property '$key' Current state type is '$($currentType.Name)' and desired type is '$($desiredType.Name)'"
187+
continue
188+
}
189+
}
190+
191+
if ($CurrentValues.$key -eq $desiredValuesClean.$key -and -not $desiredType.IsArray)
192+
{
193+
Write-Verbose -Message "MATCH: Value (type $($desiredType.Name)) for property '$key' does match. Current state is '$($CurrentValues.$key)' and desired state is '$($desiredValuesClean.$key)'"
194+
continue
195+
}
196+
197+
if ($desiredValuesClean.GetType().Name -in 'HashTable', 'PSBoundParametersDictionary')
198+
{
199+
$checkDesiredValue = $desiredValuesClean.ContainsKey($key)
200+
}
201+
else
202+
{
203+
$checkDesiredValue = Test-DSCObjectHasProperty -Object $desiredValuesClean -PropertyName $key
204+
}
205+
206+
if (-not $checkDesiredValue)
207+
{
208+
Write-Verbose -Message "MATCH: Value (type $($desiredType.Name)) for property '$key' does match. Current state is '$($CurrentValues.$key)' and desired state is '$($desiredValuesClean.$key)'"
209+
continue
210+
}
211+
212+
if ($desiredType.IsArray)
213+
{
214+
Write-Verbose -Message "Comparing values in property '$key'"
215+
if (-not $CurrentValues.ContainsKey($key) -or -not $CurrentValues.$key)
216+
{
217+
Write-Verbose -Message "NOTMATCH: Value (type $($desiredType.Name)) for property '$key' does not match. Current state is '$($CurrentValues.$key)' and desired state is '$($desiredValuesClean.$key)'"
218+
$returnValue = $false
219+
continue
220+
}
221+
elseif ($CurrentValues.$key.Count -ne $DesiredValues.$key.Count)
222+
{
223+
Write-Verbose -Message "NOTMATCH: Value (type $($desiredType.Name)) for property '$key' does have a different count. Current state count is '$($CurrentValues.$key.Count)' and desired state count is '$($desiredValuesClean.$key.Count)'"
224+
$returnValue = $false
225+
continue
226+
}
227+
else
228+
{
229+
$desiredArrayValues = $DesiredValues.$key
230+
$currentArrayValues = $CurrentValues.$key
231+
232+
for ($i = 0; $i -lt $desiredArrayValues.Count; $i++)
233+
{
234+
if ($null -ne $desiredArrayValues[$i])
235+
{
236+
$desiredType = $desiredArrayValues[$i].GetType()
237+
}
238+
else
239+
{
240+
$desiredType = [psobject]@{
241+
Name = 'Unknown'
242+
}
243+
}
244+
245+
if ($null -ne $currentArrayValues[$i])
246+
{
247+
$currentType = $currentArrayValues[$i].GetType()
248+
}
249+
else
250+
{
251+
$currentType = [psobject]@{
252+
Name = 'Unknown'
253+
}
254+
}
255+
256+
if (-not $TurnOffTypeChecking)
257+
{
258+
if (($desiredType.Name -ne 'Unknown' -and $currentType.Name -ne 'Unknown') -and
259+
$desiredType.FullName -ne $currentType.FullName)
260+
{
261+
Write-Verbose -Message "`tNOTMATCH: Type mismatch for property '$key' Current state type of element [$i] is '$($currentType.Name)' and desired type is '$($desiredType.Name)'"
262+
$returnValue = $false
263+
continue
264+
}
265+
}
266+
267+
if ($desiredArrayValues[$i] -ne $currentArrayValues[$i])
268+
{
269+
Write-Verbose -Message "`tNOTMATCH: Value [$i] (type $($desiredType.Name)) for property '$key' does match. Current state is '$($currentArrayValues[$i])' and desired state is '$($desiredArrayValues[$i])'"
270+
$returnValue = $false
271+
continue
272+
}
273+
else
274+
{
275+
Write-Verbose -Message "`tMATCH: Value [$i] (type $($desiredType.Name)) for property '$key' does match. Current state is '$($currentArrayValues[$i])' and desired state is '$($desiredArrayValues[$i])'"
276+
continue
277+
}
278+
}
279+
280+
}
281+
}
282+
else
283+
{
284+
if ($desiredValuesClean.$key -ne $CurrentValues.$key)
285+
{
286+
Write-Verbose -Message "NOTMATCH: Value (type $($desiredType.Name)) for property '$key' does not match. Current state is '$($CurrentValues.$key)' and desired state is '$($desiredValuesClean.$key)'"
287+
$returnValue = $false
288+
}
289+
290+
}
291+
}
292+
293+
Write-Verbose -Message "Result is '$returnValue'"
294+
return $returnValue
295+
}
296+
297+
<#
298+
.SYNOPSIS
299+
Tests of an object has a property
300+
.PARAMETER Object
301+
The object to test
302+
.PARAMETER PropertyName
303+
The property name
304+
#>
305+
function Test-DSCObjectHasProperty
306+
{
307+
[CmdletBinding()]
308+
[OutputType([bool])]
309+
param
310+
(
311+
[Parameter(Mandatory = $true)]
312+
[object]
313+
$Object,
314+
315+
[Parameter(Mandatory = $true)]
316+
[string]
317+
$PropertyName
318+
)
319+
320+
if ($Object.PSObject.Properties.Name -contains $PropertyName)
321+
{
322+
return [bool] $Object.$PropertyName
323+
}
324+
325+
return $false
326+
}
327+
328+
<#
329+
.SYNOPSIS
330+
Creates and throws an invalid argument exception
331+
332+
.PARAMETER Message
333+
The message explaining why this error is being thrown
334+
335+
.PARAMETER ArgumentName
336+
The name of the invalid argument that is causing this error to be thrown
337+
#>
338+
function New-InvalidArgumentException
339+
{
340+
[CmdletBinding()]
341+
param
342+
(
343+
[Parameter(Mandatory = $true)]
344+
[ValidateNotNullOrEmpty()]
345+
[String]
346+
$Message,
347+
348+
[Parameter(Mandatory = $true)]
349+
[ValidateNotNullOrEmpty()]
350+
[String]
351+
$ArgumentName
352+
)
353+
354+
$argumentException = New-Object -TypeName 'ArgumentException' `
355+
-ArgumentList @($Message, $ArgumentName)
356+
$newObjectParams = @{
357+
TypeName = 'System.Management.Automation.ErrorRecord'
358+
ArgumentList = @($argumentException, $ArgumentName, 'InvalidArgument', $null)
359+
}
360+
$errorRecord = New-Object @newObjectParams
361+
362+
throw $errorRecord
363+
}
364+
365+
<#
366+
.SYNOPSIS
367+
Creates and throws an invalid operation exception
368+
369+
.PARAMETER Message
370+
The message explaining why this error is being thrown
371+
372+
.PARAMETER ErrorRecord
373+
The error record containing the exception that is causing this terminating error
374+
#>
375+
function New-InvalidOperationException
376+
{
377+
[CmdletBinding()]
378+
param
379+
(
380+
[ValidateNotNullOrEmpty()]
381+
[String]
382+
$Message,
383+
384+
[ValidateNotNull()]
385+
[System.Management.Automation.ErrorRecord]
386+
$ErrorRecord
387+
)
388+
389+
if ($null -eq $Message)
390+
{
391+
$invalidOperationException = New-Object -TypeName 'InvalidOperationException'
392+
}
393+
elseif ($null -eq $ErrorRecord)
394+
{
395+
$invalidOperationException = New-Object -TypeName 'InvalidOperationException' `
396+
-ArgumentList @($Message)
397+
}
398+
else
399+
{
400+
$invalidOperationException = New-Object -TypeName 'InvalidOperationException' `
401+
-ArgumentList @($Message, $ErrorRecord.Exception)
402+
}
403+
404+
$newObjectParams = @{
405+
TypeName = 'System.Management.Automation.ErrorRecord'
406+
ArgumentList = @( $invalidOperationException.ToString(), 'MachineStateIncorrect',
407+
'InvalidOperation', $null )
408+
}
409+
410+
$errorRecordToThrow = New-Object @newObjectParams
411+
throw $errorRecordToThrow
412+
}
413+
41414
Export-ModuleMember -Function @(
42415
'Get-LocalizedData'
43-
)
416+
'Remove-CommonParameter'
417+
'Test-DscParameterState'
418+
'Test-DSCObjectHasProperty'
419+
'New-InvalidOperationException'
420+
'New-InvalidArgumentException'
421+
)

0 commit comments

Comments
 (0)