@@ -15,20 +15,10 @@ function Write-DscTrace {
15
15
$host.ui.WriteErrorLine ($trace )
16
16
}
17
17
18
- # if the version of PowerShell is greater than 5, import the PSDesiredStateConfiguration module
19
- # this is necessary because the module is not included in the PowerShell 7.0+ releases;
20
- # In Windows PowerShell, we should always use version 1.1 that ships in Windows.
21
- if ($PSVersionTable.PSVersion.Major -gt 5 ) {
18
+ function Import-PSDSCModule {
22
19
$m = Get-Module PSDesiredStateConfiguration - ListAvailable | Sort-Object - Descending | Select-Object - First 1
23
20
$PSDesiredStateConfiguration = Import-Module $m - Force - PassThru
24
21
}
25
- else {
26
- $env: PSModulePath += " ;$env: windir \System32\WindowsPowerShell\v1.0\Modules"
27
- $PSDesiredStateConfiguration = Import-Module - Name ' PSDesiredStateConfiguration' - RequiredVersion ' 1.1' - Force - PassThru - ErrorAction stop - ErrorVariable $importModuleError
28
- if (-not [string ]::IsNullOrEmpty($importModuleError )) {
29
- ' ERROR: Could not import PSDesiredStateConfiguration 1.1 in Windows PowerShell. ' + $importModuleError | Write-DscTrace
30
- }
31
- }
32
22
33
23
<# public function Invoke-DscCacheRefresh
34
24
. SYNOPSIS
@@ -123,54 +113,23 @@ function Invoke-DscCacheRefresh {
123
113
# create a list object to store cache of Get-DscResource
124
114
[dscResourceCacheEntry []]$dscResourceCacheEntries = [System.Collections.Generic.List [Object ]]::new()
125
115
126
- # improve by performance by having the option to only get details for named modules
127
- # workaround for File and SignatureValidation resources that ship in Windows
128
- if ($null -ne $module -and ' PSDesiredStateConfiguration' -ne $module ) {
129
- if ($module.gettype ().name -eq ' string' ) {
130
- $module = @ ($module )
131
- }
132
- $DscResources = [System.Collections.Generic.List [Object ]]::new()
133
- $Modules = [System.Collections.Generic.List [Object ]]::new()
134
- foreach ($m in $module ) {
135
- $DscResources += Get-DscResource - Module $m
136
- $Modules += Get-Module - Name $m - ListAvailable
137
- }
138
- }
139
- elseif (' PSDesiredStateConfiguration' -eq $module -and $PSVersionTable.PSVersion.Major -le 5 ) {
140
- # the resources in Windows should only load in Windows PowerShell
141
- # workaround: the binary modules don't have a module name, so we have to special case File and SignatureValidation resources that ship in Windows
142
- $DscResources = Get-DscResource | Where-Object { $_.modulename -eq ' PSDesiredStateConfiguration' -or ( $_.modulename -eq $null -and $_.parentpath -like " $env: windir \System32\Configuration\*" ) }
143
- }
144
- else {
145
- # if no module is specified, get all resources
146
- $DscResources = Get-DscResource
147
- $Modules = Get-Module - ListAvailable
148
- }
149
-
150
- $psdscVersion = Get-Module PSDesiredStateConfiguration | Sort-Object - descending | Select-Object - First 1 | ForEach-Object Version
116
+ Import-PSDSCModule
117
+ $DscResources = Get-DscResource
151
118
152
119
foreach ($dscResource in $DscResources ) {
153
120
# resources that shipped in Windows should only be used with Windows PowerShell
154
121
if ($dscResource.ParentPath -like " $env: windir \System32\*" -and $PSVersionTable.PSVersion.Major -gt 5 ) {
155
122
continue
156
123
}
157
124
158
- # we can't run this check in PSDesiredStateConfiguration 1.1 because the property doesn't exist
159
- if ( $psdscVersion -ge ' 2.0.7' ) {
125
+ if ( $dscResource.ImplementationDetail ) {
160
126
# only support known dscResourceType
161
127
if ([dscResourceType ].GetEnumNames() -notcontains $dscResource.ImplementationDetail ) {
162
128
' WARNING: implementation detail not found: ' + $dscResource.ImplementationDetail | Write-DscTrace
163
129
continue
164
130
}
165
131
}
166
132
167
- # workaround: if the resource does not have a module name, get it from parent path
168
- # workaround: modulename is not settable, so clone the object without being read-only
169
- # workaround: we have to special case File and SignatureValidation resources that ship in Windows
170
- $binaryBuiltInModulePaths = @ (
171
- " $env: windir \system32\Configuration\Schema\MSFT_FileDirectoryConfiguration"
172
- " $env: windir \system32\Configuration\BaseRegistration"
173
- )
174
133
$DscResourceInfo = [DscResourceInfo ]::new()
175
134
$dscResource.PSObject.Properties | ForEach-Object - Process {
176
135
if ($null -ne $_.Value ) {
@@ -181,30 +140,7 @@ function Invoke-DscCacheRefresh {
181
140
}
182
141
}
183
142
184
- if ($dscResource.ModuleName ) {
185
- $moduleName = $dscResource.ModuleName
186
- }
187
- elseif ($binaryBuiltInModulePaths -contains $dscResource.ParentPath ) {
188
- $moduleName = ' PSDesiredStateConfiguration'
189
- $DscResourceInfo.Module = ' PSDesiredStateConfiguration'
190
- $DscResourceInfo.ModuleName = ' PSDesiredStateConfiguration'
191
- $DscResourceInfo.CompanyName = ' Microsoft Corporation'
192
- $DscResourceInfo.Version = ' 1.0.0'
193
- if ($PSVersionTable.PSVersion.Major -le 5 -and $DscResourceInfo.ImplementedAs -eq ' Binary' ) {
194
- $DscResourceInfo.ImplementationDetail = ' Binary'
195
- }
196
- }
197
- elseif ($binaryBuiltInModulePaths -notcontains $dscResource.ParentPath -and $null -ne $dscResource.ParentPath ) {
198
- # workaround: populate module name from parent path that is three levels up
199
- $moduleName = Split-Path $dscResource.ParentPath | Split-Path | Split-Path - Leaf
200
- $DscResourceInfo.Module = $moduleName
201
- $DscResourceInfo.ModuleName = $moduleName
202
- # workaround: populate module version from psmoduleinfo if available
203
- if ($moduleInfo = $Modules | Where-Object { $_.Name -eq $moduleName }) {
204
- $moduleInfo = $moduleInfo | Sort-Object - Property Version - Descending | Select-Object - First 1
205
- $DscResourceInfo.Version = $moduleInfo.Version.ToString ()
206
- }
207
- }
143
+ $moduleName = $dscResource.ModuleName
208
144
209
145
# fill in resource files (and their last-write-times) that will be used for up-do-date checks
210
146
$lastWriteTimes = @ {}
@@ -249,13 +185,7 @@ function Get-DscResourceObject {
249
185
' WARNING: The input has a top level property named "resources" but is not a configuration. If the input should be a configuration, include the property: "metadata": {"Microsoft.DSC": {"context": "Configuration"}}' | Write-DscTrace
250
186
}
251
187
252
- # match adapter to version of powershell
253
- if ($PSVersionTable.PSVersion.Major -le 5 ) {
254
- $adapterName = ' Microsoft.Windows/WindowsPowerShell'
255
- }
256
- else {
257
- $adapterName = ' Microsoft.DSC/PowerShell'
258
- }
188
+ $adapterName = ' Microsoft.DSC/PowerShell'
259
189
260
190
if ($null -ne $inputObj.metadata -and $null -ne $inputObj.metadata .' Microsoft.DSC' -and $inputObj.metadata .' Microsoft.DSC' .context -eq ' configuration' ) {
261
191
# change the type from pscustomobject to dscResourceObject
@@ -315,54 +245,9 @@ function Invoke-DscOperation {
315
245
if ($_.TypeNameOfValue -EQ ' System.String' ) { $addToActualState .$ ($_.Name ) = $DesiredState .($_.Name ) }
316
246
}
317
247
318
- ' DSC resource implementation: ' + [dscResourceType ]$cachedDscResourceInfo.ImplementationDetail | Write-DscTrace
319
-
320
248
# workaround: script based resources do not validate Get parameter consistency, so we need to remove any parameters the author chose not to include in Get-TargetResource
321
249
switch ([dscResourceType ]$cachedDscResourceInfo.ImplementationDetail ) {
322
- ' ScriptBased' {
323
-
324
- # For Linux/MacOS, only class based resources are supported and are called directly.
325
- if ($IsLinux ) {
326
- ' ERROR: Script based resources are only supported on Windows.' | Write-DscTrace
327
- exit 1
328
- }
329
-
330
- # imports the .psm1 file for the DSC resource as a PowerShell module and stores the list of parameters
331
- Import-Module - Scope Local - Name $cachedDscResourceInfo.path - Force - ErrorAction stop
332
- $validParams = (Get-Command - Module $cachedDscResourceInfo.ResourceType - Name ' Get-TargetResource' ).Parameters.Keys
333
-
334
- if ($Operation -eq ' Get' ) {
335
- # prune any properties that are not valid parameters of Get-TargetResource
336
- $DesiredState.properties.psobject.properties | ForEach-Object - Process {
337
- if ($validParams -notcontains $_.Name ) {
338
- $DesiredState.properties.psobject.properties.Remove ($_.Name )
339
- }
340
- }
341
- }
342
-
343
- # morph the INPUT object into a hashtable named "property" for the cmdlet Invoke-DscResource
344
- $DesiredState.properties.psobject.properties | ForEach-Object - Begin { $property = @ {} } - Process { $property [$_.Name ] = $_.Value }
345
-
346
- # using the cmdlet the appropriate dsc module, and handle errors
347
- try {
348
- $invokeResult = Invoke-DscResource - Method $Operation - ModuleName $cachedDscResourceInfo.ModuleName - Name $cachedDscResourceInfo.Name - Property $property
349
-
350
- if ($invokeResult.GetType ().Name -eq ' Hashtable' ) {
351
- $invokeResult.keys | ForEach-Object - Begin { $getDscResult = @ {} } - Process { $getDscResult [$_ ] = $invokeResult .$_ }
352
- }
353
- else {
354
- # the object returned by WMI is a CIM instance with a lot of additional data. only return DSC properties
355
- $invokeResult.psobject.Properties.name | Where-Object { ' CimClass' , ' CimInstanceProperties' , ' CimSystemProperties' -notcontains $_ } | ForEach-Object - Begin { $getDscResult = @ {} } - Process { $getDscResult [$_ ] = $invokeResult .$_ }
356
- }
357
-
358
- # set the properties of the OUTPUT object from the result of Get-TargetResource
359
- $addToActualState.properties = $getDscResult
360
- }
361
- catch {
362
- ' ERROR: ' + $_.Exception.Message | Write-DscTrace
363
- exit 1
364
- }
365
- }
250
+
366
251
' ClassBased' {
367
252
try {
368
253
# load powershell class from external module
@@ -402,42 +287,8 @@ function Invoke-DscOperation {
402
287
exit 1
403
288
}
404
289
}
405
- ' Binary' {
406
- if ($PSVersionTable.PSVersion.Major -gt 5 ) {
407
- ' To use a binary resource such as File, Log, or SignatureValidation, use the Microsoft.Windows/WindowsPowerShell adapter.' | Write-DscTrace
408
- exit 1
409
- }
410
-
411
- if (-not (($cachedDscResourceInfo.ImplementedAs -eq ' Binary' ) -and (' File' , ' Log' , ' SignatureValidation' -contains $cachedDscResourceInfo.Name ))) {
412
- ' Only File, Log, and SignatureValidation are supported as Binary resources.' | Write-DscTrace
413
- exit 1
414
- }
415
-
416
- # morph the INPUT object into a hashtable named "property" for the cmdlet Invoke-DscResource
417
- $DesiredState.properties.psobject.properties | ForEach-Object - Begin { $property = @ {} } - Process { $property [$_.Name ] = $_.Value }
418
-
419
- # using the cmdlet from PSDesiredStateConfiguration module in Windows
420
- try {
421
- $getResult = $PSDesiredStateConfiguration.invoke ({ param ($Name , $Property ) Invoke-DscResource - Name $Name - Method Get - ModuleName @ {ModuleName = ' PSDesiredStateConfiguration' ; ModuleVersion = ' 1.1' } - Property $Property - ErrorAction Stop }, $cachedDscResourceInfo.Name , $property )
422
-
423
- if ($getResult.GetType ().Name -eq ' Hashtable' ) {
424
- $getResult.keys | ForEach-Object - Begin { $getDscResult = @ {} } - Process { $getDscResult [$_ ] = $getResult .$_ }
425
- }
426
- else {
427
- # the object returned by WMI is a CIM instance with a lot of additional data. only return DSC properties
428
- $getResult.psobject.Properties.name | Where-Object { ' CimClass' , ' CimInstanceProperties' , ' CimSystemProperties' -notcontains $_ } | ForEach-Object - Begin { $getDscResult = @ {} } - Process { $getDscResult [$_ ] = $getResult .$_ }
429
- }
430
-
431
- # set the properties of the OUTPUT object from the result of Get-TargetResource
432
- $addToActualState.properties = $getDscResult
433
- }
434
- catch {
435
- ' ERROR: ' + $_.Exception.Message | Write-DscTrace
436
- exit 1
437
- }
438
- }
439
290
Default {
440
- ' Can not find implementation of type : ' + $cachedDscResourceInfo.ImplementationDetail | Write-DscTrace
291
+ ' Resource ImplementationDetail not supported : ' + $cachedDscResourceInfo.ImplementationDetail | Write-DscTrace
441
292
exit 1
442
293
}
443
294
}
0 commit comments