Initialize-DSCResource.ps1
function Initialize-DSCResource { <# .Synopsis Initializes DSC resources within a module .Description Initializes DSC resources within a module, based off of scripts named *.version.resource.ps1 (i.e. foo.1.0.resource.ps1) .Link Reset-DSCResource .Example Initialize-DSCResource $env:ProgramFiles\WindowsPowerShell\Modules\cFg .Notes The .resource.ps1 files are used as a quick way to write a DSC resource. They are expected to contain a call to Write-DSCResource, and that call will use some default parameters based off of what was provided to Initialize-DSCResource. -ModuleRoot will be the base path of the module, and -ResourceName and -ResourceVersion will be inferred from the file. #> [OutputType([Nullable])] param( # The root directory of the module. [Parameter(Mandatory=$true,Position=0,ValueFromPipelineByPropertyName=$true)] [Alias('Path')] [string] $ModuleRoot, # If set, will always recreate resources, even if they are the same version [Switch] $Force, # If provided, will not initialize resources whose version number is less then the provided value [Version] $MinimumVersion, # If provided, will not initialize resources whose version number is greater then the provided value [Version] $MaximumVersion ) process { if ($_ -is [Management.Automation.PSModuleInfo]) { $ModuleRoot = $ModuleRoot | Split-Path } $resourcePs1Files = Get-ChildItem -Recurse -Filter *resource*.ps1 -Path $ModuleRoot $oldDefault = $null $oldDefault = $PSDefaultParameterValues["Write-DSCResource:ModuleRoot"] $PSDefaultParameterValues["Write-DSCResource:ModuleRoot"] = $ModuleRoot #region Locate any resource.ps1 files $ResourceData = foreach ($rp in $resourcePs1Files) { if ($rp.Name -like "*-*") { Write-Verbose "Skipping Potential Resource File $rp, because it looks like a function" continue } $nameParts = $rp.Name.Split('.') $v = $nameParts[-6..-3] -join '.' -as [Version] $resourceName = $nameParts[0..($nameParts.Count - 7)] -join '.' if (-not $v) { $v = $nameParts[-5..-3] -join '.' -as [Version] $resourceName = $nameParts[0..($nameParts.Count - 6)] -join '.' } if (-not $v) { $v = $nameParts[-4..-3] -join '.' -as [Version] $resourceName = $nameParts[0..($nameParts.Count - 5)] -join '.' } if (-not $v) { $v = '0.0' -as [Version] $resourceName = $nameParts[0..($nameParts.Count - 2)] -join '.' } New-Object PSObject -Property @{ ResourceName = $resourceName ResourcePath = $rp.Fullname ResourceVersion = $v } } #endregion Locate any resource.ps1 files #region Run each resource file foreach ($rd in $ResourceData) { if ($MinimumVersion -and $rd.ResourceVersion -lt $MinimumVersion) { continue } if ($maximumVersion -and $rd.ResourceVersion -gt $maximumVersion) { continue } $existingResourceFiles = Get-ChildItem -Path (Join-Path $moduleRoot DSCResources) -Filter $rd.ResourceName -ErrorAction SilentlyContinue | Get-ChildItem $shouldCreate = $true if ($existingResourceFiles) { $existingMof = $existingResourceFiles | ? {$_.Extension -eq '.mof' } if ($existingMof) { $versionLine = [IO.File]::ReadAllLines($existingMof.FullName) | Where-Object {$_ -like "*ClassVersion*" } | Select-Object -First 1 $versionParts = $versionLine -split "[\[\],]" -ne '' $versionPart = $versionParts |? { $_ -like "*ClassVersion*" } $ExistingVersion = ($versionPart -split '"')[1] -as [Version] if ($ExistingVersion -lt $rd.ResourceVersion) { $shouldCreate = $true } else { $shouldCreate = $false } } } if ((-not $shouldCreate) -and -not $Force) { Write-Verbose "Skipping $($rd.ResourceName) v$($rd.ResourceVersion) because the same or a newer version exists" continue } $oldDefaultVersion = $PSDefaultParameterValues["Write-DSCResource:Version"] $oldDefaultResourceName = $PSDefaultParameterValues["Write-DSCResource:ResourceName"] $PSDefaultParameterValues["Write-DSCResource:ResourceName"] = $rd.resourceName $PSDefaultParameterValues["Write-DSCResource:Version"] = $rd.ResourceVersion & $rd.ResourcePath if ($oldDefaultVersion) { $PSDefaultParameterValues["Write-DSCResource:Version"] = $oldDefaultVersion } else { $PSDefaultParameterValues.Remove("Write-DSCResource:Version") } if ($oldDefaultResourceName) { $PSDefaultParameterValues["Write-DSCResource:ResourceName"] = $oldDefaultResourceName } else { $PSDefaultParameterValues.Remove("Write-DSCResource:ResourceName") } } #region Run each resource file if ($oldDefault) { $PSDefaultParameterValues["Write-DSCResource:ModuleRoot"] = $oldDefault } else { $PSDefaultParameterValues.Remove("Write-DSCResource:ModuleRoot") } } } |