diff --git a/Tooling/cDscResourceDesigner/cDscResourceDesigner.Tests.ps1 b/Tooling/cDscResourceDesigner/cDscResourceDesigner.Tests.ps1 index a750b9b..09c636b 100644 --- a/Tooling/cDscResourceDesigner/cDscResourceDesigner.Tests.ps1 +++ b/Tooling/cDscResourceDesigner/cDscResourceDesigner.Tests.ps1 @@ -35,6 +35,784 @@ end } } } + + InModuleScope cDscResourceDesigner { + Describe 'New-cDscResourceProperty' { + Context 'An Array is a Key' { + It 'Should write an error' { + $errorMessage = New-cDscResourceProperty -Name 'SomeName' -Type 'String[]' -Attribute 'Key' 2>&1 + $errorMessage | Should Be $LocalizedData.KeyArrayError + } + } + Context 'Values is an Array Type' { + Mock -ModuleName cDscResourceDesigner Test-TypeIsArray { + return $true + } + It 'should throw an error' { + $errorMessage = New-cDscResourceProperty -Name 'Ensure' -Type 'String' -Attribute Write -Values 'Present', 'Absent' -Description 'Ensure Present or Absent' 2>&1 + $errorMessage | Should Be $LocalizedData.InvalidValidateSetUsageError + } + } + Context 'ValueMap is given the wrong type' { + Mock -ModuleName cDscResourceDesigner Test-TypeIsArray { + return $false + } + It 'should throw an error' { + $errorMessage = @() + $errorMessage += $LocalizedData.ValidateSetTypeError -f 'Present', 'Uint8' + $errorMessage += $LocalizedData.ValidateSetTypeError -f 'Absent', 'Uint8' + + $returnedError = New-cDscResourceProperty -Name 'Ensure' -Type 'Uint8' -Attribute Write -ValueMap 'Present', 'Absent' -Description 'Ensure Present or Absent' 2>&1 + + $returnedError[0] | Should Be $errorMessage[0] + } + } + + Context 'Everything is passed correctly' { + Mock -ModuleName cDscResourceDesigner Test-TypeIsArray { + return $false + } + Mock -ModuleName cDscResourceDesigner Test-Name { + return $true + } + $result = New-cDscResourceProperty -Name 'Ensure' -Type 'String' -Attribute Write -ValueMap 'Present', 'Absent' -Description 'Ensure Present or Absent' + + It 'should return the correct Name' { + $result.Name | Should Be 'Ensure' + } + + It 'should return the correct Type' { + $result.Type | Should Be 'String' + } + + It 'should return the correct Attribute' { + $result.Attribute | Should Be 'Write' + } + + It 'should return the correct ValidateSet' { + $result.ValueMap | Should Be @('Present', 'Absent') + } + + It 'should return the correct Description' { + $result.Description | Should Be 'Ensure Present or Absent' + } + } + } + + Describe 'Test-Name' { + Context 'Passed a bad name' { + It 'should return the correct property error text' { + $errorMessage = $LocalizedData.InvalidPropertyNameError -f '123' + { + $result = Test-Name '123' 'Property' + } | Should Throw $errorMessage + } + + It 'should return the correct resource error text' { + $errorMessage = $LocalizedData.InvalidResourceNameError -f '123' + { + $result = Test-Name '123' 'Resource' + } | Should Throw $errorMessage + } + } + + Context 'Passed a name that was to long' { + $name = 'a' * 256 + It 'should return the correct property error text' { + $errorMessage = $LocalizedData.PropertyNameTooLongError -f $name + { + $result = Test-Name $name 'Property' + } | Should throw $errorMessage + } + + It 'should return the correct resource error text' { + $errorMessage = $LocalizedData.ResourceNameTooLongError -f $name + { + $result = Test-Name $name 'Resource' + } | Should throw $errorMessage + } + } + } + + Describe 'Test-PropertiesForResource' { + Context 'No Key is passed' { + It 'should throw an error' { + $dscProperty = [DscResourceProperty] @{ + Name = 'Ensure' + Type = 'String' + Attribute = [DscResourcePropertyAttribute]::Write + ValueMap = @('Present', 'Absent') + Description = 'Ensure Present or Absent' + ContainsEmbeddedInstance = $false + } + + { + Test-PropertiesForResource -Properties $dscProperty + } | Should throw $LocalizedData.NoKeyError + } + } + + Context 'a non-unique name is passed' { + $dscProperty = [DscResourceProperty] @{ + Name = 'Ensure' + Type = 'String' + Attribute = [DscResourcePropertyAttribute]::Key + ValueMap = @('Present', 'Absent') + Description = 'Ensure Present or Absent' + ContainsEmbeddedInstance = $false + } + $dscPropertyArray = @($dscProperty, $dscProperty) + + It 'should throw a non-unique name error' { + $errorMessage = $LocalizedData.NonUniqueNameError -f 'Ensure' + { + Test-PropertiesForResource -Properties $dscPropertyArray + } | Should throw $errorMessage + } + } + + Context 'a unique name is passed' { + $dscProperty = [DscResourceProperty] @{ + Name = 'Ensure' + Type = 'String' + Attribute = [DscResourcePropertyAttribute]::Key + ValueMap = @('Present', 'Absent') + Description = 'Ensure Present or Absent' + ContainsEmbeddedInstance = $false + } + + It 'should return true' { + Test-PropertiesForResource -Properties $dscProperty | Should Be $true + } + } + } + + Describe 'New-cDscResource' { + $dscProperty = [DscResourceProperty] @{ + Name = 'Ensure' + Type = 'String' + Attribute = [DscResourcePropertyAttribute]::Key + ValueMap = @('Present', 'Absent') + Description = 'Ensure Present or Absent' + ContainsEmbeddedInstance = $false + } + + Mock Test-Name { return $true } -Verifiable + Mock Test-PropertiesForResource { return $true } -Verifiable + Mock New-Item { Write-Error 'SomeError'} -Verifiable + + Context 'everything should be working' { + Mock Test-Path { return $true } -Verifiable + Mock New-DscSchema { return $null } -Verifiable + Mock New-DscModule { return $null } -Verifiable + Mock Test-cDscResource { return $true } -Verifiable + + It 'does not throw' { + { + New-cDscResource -Name 'UserResource' -Property $dscProperty -Path "$pshome\Modules\UserResource" -ClassVersion 1.0 -FriendlyName 'User' -Force + } | Should Not throw + } + + $result = New-cDscResource -Name 'UserResource' -Property $dscProperty -Path "$pshome\Modules\UserResource" -ClassVersion 1.0 -FriendlyName 'User' -Force + + It 'calls Test-PropertiesForResource ' { + Assert-MockCalled Test-PropertiesForResource -Times 1 + } + + It 'calls Test-Name' { + Assert-MockCalled Test-Name -Times 1 + } + + It 'calls Test-Path' { + Assert-MockCalled Test-Path + } + + It 'calls New-DscSchema' { + Assert-MockCalled New-DscSchema + } + + It 'calls New-DscModule' { + Assert-MockCalled New-DscModule + } + + It 'calls Test-cDscResource' { + Assert-MockCalled Test-cDscResource + } + } + + Context 'a bad path is passed' { + Mock Test-Path { return $false } -Verifiable + + It 'should throw a Path is Invalid Error' { + $path = 'C:\somerandompaththatdoesactuallyexistbecausethisisatest' + $errorMessage = ($LocalizedData.PathIsInvalidError -f $path) + { + New-cDscResource -Name 'UserResource' -Property $dscProperty -Path 'C:\somerandompaththatdoesactuallyexistbecausethisisatest' -ClassVersion 1.0 -FriendlyName 'User' -Force + } | Should throw $errorMessage + } + } + + Context 'a bad module path is passed' { + It 'should throw a Path is invalid error' { + $fullPath = Join-Path -Path $pshome -ChildPath 'ModuleName\DSCResources' + Mock Test-Path { return $true } -Verifiable + Mock Test-Path { return $false } -ParameterFilter { $path -eq $fullPath -and $PathType -eq 'Container' } + $errorMessage = ($LocalizedData.PathIsInvalidError -f $fullPath) + + { + New-cDscResource -Name 'UserResource' -Property $dscProperty -Path $pshome -ModuleName 'ModuleName' -ClassVersion 1.0 -FriendlyName 'User' -Force + } | Should throw $errorMessage + } + + It 'should throw a Path is invalid error for the manifest' { + Mock Test-Path { return $true} -Verifiable + Mock Test-Path { return $true } -ParameterFilter { $path -eq "$pshome\UserResource" } + Mock Test-Path { return $false } -ParameterFilter { $path -eq "$pshome\UserResource\UserResource.psd1" } + Mock New-ModuleManifest { + Write-Error 'SomeError' + } + + $path = "$pshome\UserResource\UserResource.psd1" + $errorMessage = ($LocalizedData.PathIsInvalidError -f $path) + + { + New-cDscResource -Name 'UserResource' -Property $dscProperty -Path $pshome -ModuleName 'UserResource' -ClassVersion 1.0 -FriendlyName 'User' -Force + } | Should throw $errorMessage + } + } + + Context 'a bad DSC Resource path is passed' { + Mock New-Item { Write-Error 'SomeError' } -Verifiable + + It 'should throw a Path is invalid error' { + $dscPath = "$pshome\UserResource\DSCResources" + Mock Test-Path { return $true } -Verifiable + Mock Test-Path { return $false } -ParamterFilter { $path -eq $dscPath } + $errorMessage = ($LocalizedData.PathIsInvalidError -f $dscPath) + { + New-cDscResource -Name 'UserResource' -Property $dscProperty -Path $dscPath -ClassVersion 1.0 -FriendlyName 'User' -Force + } | Should throw $errorMessage + } + } + + Context 'a bad DSC Resource + Name path is passed' { + Mock New-Item { + Write-Error 'SomeError' + } -Verifiable + + It 'should throw a Path is invalid error' { + $dscPath = "$pshome\UserResource\DSCResources" + Mock Test-Path { return $true } -Verifiable + Mock Test-Path { return $false } -ParamterFilter { $path -eq $dscPath } + $errorMessage = ($LocalizedData.PathIsInvalidError -f $dscPath) + { + New-cDscResource -Name 'UserResource' -Property $dscProperty -Path $dscPath -ClassVersion 1.0 -FriendlyName 'User' -Force + } | Should throw $errorMessage + } + } + + Context 'Test-cDscResource does not pass' { + Mock New-DscSchema { return $null } -Verifiable + Mock New-DscModule { return $null } -Verifiable + Mock Test-cDscResource { return $false } -Verifiable + Mock Remove-Item { return $null } -Verifiable + Mock Test-Path { return $true } -Verifiable + + It 'should throw a Path is invalid error' { + $dscPath = "$pshome\UserResource\DSCResources" + { + New-cDscResource -Name 'UserResource' -Property $dscProperty -Path $dscPath -ClassVersion 1.0 -FriendlyName 'User' -Force + } | Should throw $LocalizedData.ResourceError + } + } + } + + Describe 'New-DscManifest' { + Mock New-ModuleManifest { + return $null + } -Verifiable + + Mock Test-Path { + return $true + } -Verifiable + + $newModuleManifestTest = New-DscManifest -Name 'UserResource' -Path $env:tmp -ClassVersion 1.0 -Force + + It 'should call New-ModuleManifest' { + Assert-MockCalled New-ModuleManifest + } + + $result = New-DscManifest -Name 'UserResource' -Path $env:tmp -ClassVersion 1.0 -WhatIf *>&1 + + $ManifestPath = Join-Path $env:tmp "UserResource.psd1" + $warning = ($localizedData.ManifestNotOverWrittenWarning -f $ManifestPath) + + It 'should write a warning message if file exists' { + $result.Message | Should Be $warning + } + } + + Describe 'New-DscSchema' { + Mock Add-StringBuilderLine { return $null } -Verifiable + Mock Test-Path { return $true } -Verifiable + Mock New-DscSchemaParameter {return $null} -Verifiable + + $dscProperty = [DscResourceProperty] @{ + Name = 'Ensure' + Type = 'String' + Attribute = [DscResourcePropertyAttribute]::Key + ValueMap = @('Present', 'Absent') + Description = 'Ensure Present or Absent' + ContainsEmbeddedInstance = $false + } + + $result = New-DscSchema -Name 'Test' -Path $env:temp -Parameters $dscProperty -ClassVersion 1.0 -WhatIf *>&1 + + It 'should call all the Mocks' { + Assert-VerifiableMocks + } + + $schemaPath = Join-Path $env:tmp "Test.schema.mof" + $warning = ($localizedData.SchemaNotOverWrittenWarning -f $SchemaPath) + + It 'Should throw a Warning' { + $result.Message | Should Be $warning + } + } + + Describe 'Get-TypeNameForSchema' { + Context 'get type Hashtable' { + $result = Get-TypeNameForSchema -Type 'Hashtable' + + It 'should return string' { + $result | should be 'String' + } + } + + Context 'get type int32' { + $result = Get-TypeNameForSchema -Type 'int32' + + It 'should return int32' { + $result | should be 'int32' + } + } + + Context 'get non-existant type' { + It 'should throw an error ' { + {Get-TypeNameForSchema -Type Get-Random} | Should throw + } + } + } + + Describe 'Test-TypeIsArray' { + Context 'Passed a hashtable' { + $result = Test-TypeIsArray -Type 'Int32[]' + It 'Should return true' { + $result | should be $true + } + } + + Context 'not passed a hashtable' { + $result = Test-TypeIsArray -Type 'String' + it 'should return false' { + $result | should be $false + } + } + } + + Describe 'New-DscSchemaParameter' { + Context 'dscProperty only contains the minimum properties' { + $dscProperty = [DscResourceProperty] @{ + Name = 'Ensure' + Type = 'String' + Attribute = [DscResourcePropertyAttribute]::Key + } + + $result = New-DscSchemaParameter -Parameter $dscProperty + $expected = "`t[Key] String Ensure;" + + It 'should return the correct string' { + $result | should be $expected + } + } + + Context 'dscProperty has an embeded instance' { + $dscProperty = [DscResourceProperty] @{ + Name = 'Ensure' + Type = 'Hashtable' + Attribute = [DscResourcePropertyAttribute]::Key + } + + $result = New-DscSchemaParameter -Parameter $dscProperty + $expected = "`t[Key, EmbeddedInstance(`"MSFT_KeyValuePair`")] String Ensure[];" + + It 'should return the correct string' { + $result | should be $expected + } + } + + Context 'dscProperty has a Description' { + $dscProperty = [DscResourceProperty] @{ + Name = 'Ensure' + Type = 'String' + Attribute = [DscResourcePropertyAttribute]::Key + Description = 'Ensure Present or Absent' + } + + $result = New-DscSchemaParameter -Parameter $dscProperty + $expected = "`t[Key, Description(`"Ensure Present or Absent`")] String Ensure;" + + It 'should return the correct string' { + $result | should be $expected + } + } + + Context 'dscProperty has a value map' { + $dscProperty = [DscResourceProperty] @{ + Name = 'Ensure' + Type = 'String' + Attribute = [DscResourcePropertyAttribute]::Key + Description = 'Ensure Present or Absent' + ValueMap = @('Present', 'Absent') + } + + $result = New-DscSchemaParameter -Parameter $dscProperty + $expected = "`t[Key, Description(`"Ensure Present or Absent`"), ValueMap{`"Present`",`"Absent`"}] String Ensure;" + + It 'should return the correct string' { + $result | should be $expected + } + } + + Context 'dscProperty has values' { + $dscProperty = [DscResourceProperty] @{ + Name = 'Ensure' + Type = 'String' + Attribute = [DscResourcePropertyAttribute]::Key + Description = 'Ensure Present or Absent' + ValueMap = @('Present', 'Absent') + Values = @('Present', 'Absent') + } + + $result = New-DscSchemaParameter -Parameter $dscProperty + $expected = "`t[Key, Description(`"Ensure Present or Absent`"), ValueMap{`"Present`",`"Absent`"}, Values{`"Present`",`"Absent`"}] String Ensure;" + + It 'should return the correct string' { + $result | should be $expected + } + } + } + + Describe 'New-DelimitedList' { + Context 'a list of numbers is passed in' { + $result = New-DelimitedList -list @(1,2,3,4,5) + $expected = '1,2,3,4,5' + + It 'should return the numbers' { + $result | Should Be $expected + } + } + + Context 'the string switch is used' { + $result = New-DelimitedList -list @(1,2,3,4,5) -String + $expected = '"1","2","3","4","5"' + + It 'should return the numbers wrapped in quotes' { + $result | Should Be $expected + } + } + + Context 'the seperator parameter is used' { + $result = New-DelimitedList -list @(1,2,3,4,5) -String -Separator ';' + $expected = '"1";"2";"3";"4";"5"' + + It 'should return the numbers wrapped in qoutes, seperated by semicolons' { + $result | Should Be $expected + } + } + } + + Describe 'New-DscModule' { + $dscProperty = [DscResourceProperty] @{ + Name = 'Ensure' + Type = 'String' + Attribute = [DscResourcePropertyAttribute]::Key + ValueMap = @('Present', 'Absent') + Description = 'Ensure Present or Absent' + ContainsEmbeddedInstance = $false + } + + Context 'writing out to a file' { + Mock New-GetTargetResourceFunction { return $null } -Verifiable + Mock New-SetTargetResourceFunction { return $null } -Verifiable + Mock New-TestTargetResourceFunction { return $null } -Verifiable + + Mock Out-File { return $null } -Verifiable + + $result = New-DscModule -Name 'Test' -Path $env:temp -Parameters $dscProperty + + It 'should call all the Mocks' { + Assert-VerifiableMocks + } + } + + Context 'unable to overwrite module' { + Mock New-GetTargetResourceFunction { return $null } -Verifiable + Mock New-SetTargetResourceFunction { return $null } -Verifiable + Mock New-TestTargetResourceFunction { return $null } -Verifiable + + Mock Test-Path { return $true } -Verifiable + + $result = New-DscModule -Name 'Test' -Path $env:temp -Parameters $dscProperty -WhatIf *>&1 + + $ModulePath = Join-Path $env:tmp "Test.psm1" + $warning = ($localizedData.ModuleNotOverWrittenWarning -f $ModulePath) + + It 'Should throw a Warning' { + $result.Message | Should Be $warning + } + } + } + + Describe 'Add-StringBuilderLine' { + $StringBuilder = New-Object -TypeName System.Text.StringBuilder + $Line = 'Line'; + + Context 'A line is passed' { + $result = Add-StringBuilderLine -Builder $StringBuilder -Line $Line + $expect = 'Line' + + It 'should return the correct line' { + $result | should be $expected + } + } + + Context 'No line is passed' { + $result = Add-StringBuilderLine -Builder $StringBuilder + + $expect = $Line + [Environment]::NewLine + + It 'should return the correct line' { + $result | should be $expected + } + } + + Context 'Append is Passed' { + $result = Add-StringBuilderLine -Builder $StringBuilder -Line $Line -Append + + $expect = $Line + [Environment]::NewLine + $Line + + It 'should return the correct line' { + $result | should be $expected + } + } + } + + Describe 'New-TestTargetResourceFunction' { + $dscProperty = [DscResourceProperty] @{ + Name = 'Ensure' + Type = 'String' + Attribute = [DscResourcePropertyAttribute]::Key + ValueMap = @('Present', 'Absent') + Description = 'Ensure Present or Absent' + ContainsEmbeddedInstance = $false + } + + $result = New-DscModuleFunction 'Test-TargetResource' ($dscProperty | Where-Object {([DscResourcePropertyAttribute]::Read -ne $_.Attribute)}) 'Boolean'` -FunctionContent $functionContent + + $expected = "function Test-TargetResource`r`n{`r`n`t[CmdletBinding()]`r`n`t[OutputType([System.Boolean])]`r`n`tparam`r`n`t(`r`n`t`t[parameter(Mandatory = `$true)]`r`n`t`t[System.String]`r`n`t`t`$Ensure`r`n`t)`r`n`r`n`t#Write-Verbose `"Use this cmdlet to deliver information about command processing.`"`r`n`r`n`t#Write-Debug `"Use this cmdlet to write debug information while troubleshooting.`"`r`n`r`n`r`n`t<#`r`n`t`$result = [System.Boolean]`r`n`t`r`n`t`$result`r`n`t#>`r`n}`r`n`r`n" + + It 'returns the correct string' { + $result | Should Be $expected + } + } + + Describe 'New-GetTargetResourceFunction' { + $dscProperty = [DscResourceProperty] @{ + Name = 'Ensure' + Type = 'String' + Attribute = [DscResourcePropertyAttribute]::Key + ValueMap = @('Present', 'Absent') + Description = 'Ensure Present or Absent' + ContainsEmbeddedInstance = $false + } + + $result = New-DscModuleFunction 'Get-TargetResource' ($dscProperty | Where-Object {([DscResourcePropertyAttribute]::Key -eq $_.Attribute) -or ([DscResourcePropertyAttribute]::Required -eq $_.Attribute)}) 'System.Collections.Hashtable' ($dscProperty) -FunctionContent $functionContent + + $expected = "function Get-TargetResource`r`n{`r`n`t[CmdletBinding()]`r`n`t[OutputType([System.Collections.Hashtable])]`r`n`tparam`r`n`t(`r`n`t`t[parameter(Mandatory = `$true)]`r`n`t`t[System.String]`r`n`t`t`$Ensure`r`n`t)`r`n`r`n`t#Write-Verbose `"Use this cmdlet to deliver information about command processing.`"`r`n`r`n`t#Write-Debug `"Use this cmdlet to write debug information while troubleshooting.`"`r`n`r`n`r`n`t<#`r`n`t`$returnValue = @{`r`n`t`tEnsure = [System.String]`r`n`t}`r`n`r`n`t`$returnValue`r`n`t#>`r`n}`r`n`r`n" + + It 'returns the correct string' { + $result | Should Be $expected + } + } + + Describe 'New-SetTargetResourceFunction' { + $dscProperty = [DscResourceProperty] @{ + Name = 'Ensure' + Type = 'String' + Attribute = [DscResourcePropertyAttribute]::Key + ValueMap = @('Present', 'Absent') + Description = 'Ensure Present or Absent' + ContainsEmbeddedInstance = $false + } + + $result = New-DscModuleFunction 'Set-TargetResource' ($dscProperty | Where-Object {([DscResourcePropertyAttribute]::Read -ne $_.Attribute)}) -FunctionContent $functionContent + + $expected = "function Set-TargetResource`r`n{`r`n`t[CmdletBinding()]`r`n`tparam`r`n`t(`r`n`t`t[parameter(Mandatory = `$true)]`r`n`t`t[System.String]`r`n`t`t`$Ensure`r`n`t)`r`n`r`n`t#Write-Verbose `"Use this cmdlet to deliver information about command processing.`"`r`n`r`n`t#Write-Debug `"Use this cmdlet to write debug information while troubleshooting.`"`r`n`r`n`t#Include this line if the resource requires a system reboot.`r`n`t#`$global:DSCMachineStatus = 1`r`n`r`n`r`n}`r`n`r`n" + + It 'returns the correct string' { + $result | Should Be $expected + } + } + + Describe 'New-DscModuleFunction' { + $dscProperty = [DscResourceProperty] @{ + Name = 'Ensure' + Type = 'String' + Attribute = [DscResourcePropertyAttribute]::Key + ValueMap = @('Present', 'Absent') + Description = 'Ensure Present or Absent' + ContainsEmbeddedInstance = $false + } + + Context 'Function Content is passed' { + $result = New-DscModuleFunction -Name 'Set-TargetResource' -Parameters ($dscProperty | Where-Object {([DscResourcePropertyAttribute]::Read -ne $_.Attribute)}) -FunctionContent 'Test' + + $expected = "function Set-TargetResource`r`n{`r`n`t[CmdletBinding()]`r`n`tparam`r`n`t(`r`n`t`t[parameter(Mandatory = `$true)]`r`n`t`t[System.String]`r`n`t`t`$Ensure`r`n`t)`r`nTest`r`n}`r`n" + + It 'should return the funciton content' { + $result | should be $expected + } + } + + Context 'Return Type is Passed' { + $result = New-DscModuleFunction -Name 'Set-TargetResource' -Parameters ($dscProperty | Where-Object {([DscResourcePropertyAttribute]::Read -ne $_.Attribute)}) -FunctionContent 'Test' -ReturnType 'Boolean' + $expected = "function Set-TargetResource`r`n{`r`n`t[CmdletBinding()]`r`n`t[OutputType([System.Boolean])]`r`n`tparam`r`n`t(`r`n`t`t[parameter(Mandatory = `$true)]`r`n`t`t[System.String]`r`n`t`t`$Ensure`r`n`t)`r`nTest`r`n}`r`n" + + It 'should return the return type' { + $result | Should Be $expected + } + } + + Context 'No Function Content is passed' { + $result = New-DscModuleFunction -Name 'Set-TargetResource' -Parameters ($dscProperty | Where-Object {([DscResourcePropertyAttribute]::Read -ne $_.Attribute)}) -ReturnType 'Boolean' + + $expected = "function Set-TargetResource`r`n{`r`n`t[CmdletBinding()]`r`n`t[OutputType([System.Boolean])]`r`n`tparam`r`n`t(`r`n`t`t[parameter(Mandatory = `$true)]`r`n`t`t[System.String]`r`n`t`t`$Ensure`r`n`t)`r`n`r`n`t#Write-Verbose `"Use this cmdlet to deliver information about command processing.`"`r`n`r`n`t#Write-Debug `"Use this cmdlet to write debug information while troubleshooting.`"`r`n`r`n`t#Include this line if the resource requires a system reboot.`r`n`t#`$global:DSCMachineStatus = 1`r`n`r`n`r`n`t<#`r`n`t`$result = [System.Boolean]`r`n`t`r`n`t`$result`r`n`t#>`r`n}`r`n`r`n" + + It 'should return the default function data' { + $result | Should Be $expected + } + } + } + + Describe 'New-DscModuleParameter' { + $dscProperty = [DscResourceProperty] @{ + Name = 'Ensure' + Type = 'String' + Attribute = [DscResourcePropertyAttribute]::Key + ValueMap = @('Present', 'Absent') + Values = 'Present' + Description = 'Ensure Present or Absent' + ContainsEmbeddedInstance = $false + } + + Context 'Last Parameter not passed' { + $result = New-DscModuleParameter $dscProperty[0] + $expected = "`t`t[parameter(Mandatory = `$true)]`r`n`t`t[ValidateSet(`"Present`",`"Absent`")]`r`n`t`t[System.String]`r`n`t`t`$Ensure,`r`n" + + It 'should return the correct string' { + $result | should be $expected + } + } + + Context 'Last Parameter is passed' { + $result = New-DscModuleParameter $dscProperty[0] -Last + $expected = $expected = "`t`t[parameter(Mandatory = `$true)]`r`n`t`t[ValidateSet(`"Present`",`"Absent`")]`r`n`t`t[System.String]`r`n`t`t`$Ensure" + + It 'should return the string without a comma' { + $result | should be $expected + } + } + } + + Describe 'New-DscModuleReturn' { + $dscProperty = [DscResourceProperty] @{ + Name = 'Ensure' + Type = 'String' + Attribute = [DscResourcePropertyAttribute]::Key + ValueMap = @('Present', 'Absent') + Description = 'Ensure Present or Absent' + ContainsEmbeddedInstance = $false + } + + $result = New-DscModuleReturn -Parameters $dscProperty + $expected = "`t<#`r`n`t`$returnValue = @{`r`n`t`tEnsure = [System.String]`r`n`t}`r`n`r`n`t`$returnValue`r`n`t#>" + + It 'return the correct string' { + $result | should be $expected + } + } + + Describe 'Get-FunctionParamLineNumbers' { + Context 'Function Name is found in Module'{ + # This might be an awful idea. + $path = Resolve-Path $PSScriptRoot\cDscResourceDesigner.psm1 | ForEach-Object {$_.Path} + + $functionNames = 'New-cDscResourceProperty' + + $expected = @{ + 'New-cDscResourceProperty' = 308,356,398 + } + + $result = Get-FunctionParamLineNumbers -ModulePath $path -FunctionNames $functionNames + + $testResult = Compare-Object -ReferenceObject $result -DifferenceObject $expected -PassThru + + It 'Should return the correct array' { + $testResult | should BeNullOrEmpty + } + } + + Context 'Function Name is NOT found in Module' { + $path = Resolve-Path $PSScriptRoot\cDscResourceDesigner.psm1 | ForEach-Object {$_.Path} + + $functionNames = 'none' + + $result = Get-FunctionParamLineNumbers -ModulePath $path -FunctionNames $functionNames + + It 'Should return nothing' { + $testResult | should BeNullOrEmpty + } + } + + # TODO: Not sure how to generate errors in [System.Management.Automation.Language.Parser] + # Context 'Error Processing Module' { + # } + } + + Describe 'Convert-LineNumberToIndex' { + $result = Convert-LineNumberToIndex -LineNumber 1 + $expect = 0 + + It 'Should return the correct number' { + $result | should be $expect + } + } + + Describe 'Get-SortedFunctionNames' { + $hash = @{ + 'New-cDscResourceProperty' = 356,398,308 + 'Get-Properties' = 100,398,308 + } + $result = Get-SortedFunctionNames -functionLineNumbers $hash + $expect = @('Get-Properties', 'New-cDscResourceProperty') + + It 'Should return the correct hash' { + $result | should Be $expect + } + } + } +# >>>>>>> parent of d107c61... Adding Test-ResourcePath } begin diff --git a/Tooling/cDscResourceDesigner/cDscResourceDesigner.psm1 b/Tooling/cDscResourceDesigner/cDscResourceDesigner.psm1 index 4d0e7b5..bc13ba0 100644 --- a/Tooling/cDscResourceDesigner/cDscResourceDesigner.psm1 +++ b/Tooling/cDscResourceDesigner/cDscResourceDesigner.psm1 @@ -39,7 +39,7 @@ TestResourceGetNoReadsVerbose=Result of testing Get-TargetResource for no read p ResourceError=Test-cDscResource detected an error, so the generated files will be removed. KeyArrayError=Key Properties can not be Arrays. ValidateSetTypeError=ValidateSet item {0} did not match type {1}. -InvalidValidateSetUsageError=ValidateSet can not be used for Arrays, PSCredentials, and Hashtable. +InvalidValidateSetUsageError=ValidateSet can not be used for Arrays, PSCredentials, and Hashtable. InvalidPropertyNameError=Property name {0} must start with a character and contain only characters, digits, and underscores. PropertyNameTooLongError=Property name {0} is longer than 255 characters. InvalidResourceNameError=Resource name {0} must start with a character and contain only characters, digits, and underscores. @@ -57,14 +57,14 @@ UsingWriteDebug=Use this cmdlet to write debug information while troubleshooting IfRebootRequired=Include this line if the resource requires a system reboot. BadSchemaPath=The parameter -Schema must be a path to a .schema.mof file. BadResourceMOdulePath=The parameter -ResourceModule must be a path to a .psm1 or .dll file. -SchemaParseError=There was an error parsing the Schema file. +SchemaParseError=There was an error parsing the Schema file. GetCimClass-Error=There was an error retrieving the Schema. ImportResourceModuleError=There was an error importing the Resource Module. KeyFunctionsNotDefined=The following functions were not found: {0}. MissingOMI_BaseResourceError=The Schema must be defined as "class {0} : OMI_BaseResource". ClassNameSchemaNameDifferentError=The Class name {0} does not match the Schema name {1}. UnsupportedMofTypeError=In property {0}, the mof type {1} is not supported. -ValueMapTypeMismatch=In property {0}, ValueMap value {1} is not valid for type {2}. +ValueMapTypeMismatch=In property {0}, ValueMap value {1} is not valid for type {2}. ValueMapValuesPairError=In property {0}, the qualifiers "ValueMap" and "Values" must be used together and specify identical values. NoKeyTestError=At least one property must have the qualifier "Key". EmbeddedInstanceCimTypeError=In property {0}, all EmbeddedInstances must be encoded as Strings. @@ -87,14 +87,14 @@ IllegalAttributeCombinationError=For property {0}, the attribute Read can not be GetMissingKeyOrRequiredError=The function Get-TargetResource must take all Key and Required properties, and they must be mandatory. There was an issue with property {0}. SetAndTestMissingParameterError=The functions Set-TargetResource and Test-TargetResource must take all Key, Required and Write properties. There is an issue with the parameter {0} defined in the schema. SetAndTestExtraParameterError=The functions Set-TargetResource and Test-TargetResource have an extra parameter {0} that is not defined in the schema. -GetTakesReadError=The function Get-TargetResource can not take the read property {0}, defined in the schema, as a parameter. +GetTakesReadError=The function Get-TargetResource can not take the read property {0}, defined in the schema, as a parameter. SetTestTakeReadError=The functions Set-TargetResource and Test-TargetResource can not take the read property {0} defined in the schema as a parameter. '@ } #Import-LocalizedData LocalizedData -FileName xDscResourceDesigner.strings.psd1 -Add-Type -ErrorAction Stop -TypeDefinition @" +Add-Type -ErrorAction Stop -TypeDefinition @" namespace Microsoft.PowerShell.xDesiredStateConfiguration { using System; @@ -153,33 +153,33 @@ Add-Type -ErrorAction Stop -TypeDefinition @" } } - private System.String[] valueMap; + private System.String[] valueMap; - public System.String[] ValueMap + public System.String[] ValueMap { get { - return valueMap; + return valueMap; } - + + set + { + valueMap = value; + } + } + + private System.String[] values; + + public System.String[] Values + { + get + { + return values; + } + set { - valueMap = value; - } - } - - private System.String[] values; - - public System.String[] Values - { - get - { - return values; - } - - set - { - values = value; + values = value; } } @@ -191,7 +191,7 @@ Add-Type -ErrorAction Stop -TypeDefinition @" { return description; } - + set { description = value; @@ -216,63 +216,63 @@ Add-Type -ErrorAction Stop -TypeDefinition @" } "@ -[psobject].Assembly.GetType('System.Management.Automation.TypeAccelerators')::add('DscResourcePropertyAttribute','Microsoft.PowerShell.xDesiredStateConfiguration.DscResourcePropertyAttribute') -[psobject].Assembly.GetType('System.Management.Automation.TypeAccelerators')::add('DscResourceProperty','Microsoft.PowerShell.xDesiredStateConfiguration.DscResourceProperty') +[psobject].Assembly.GetType('System.Management.Automation.TypeAccelerators')::add('DscResourcePropertyAttribute','Microsoft.PowerShell.xDesiredStateConfiguration.DscResourcePropertyAttribute') +[psobject].Assembly.GetType('System.Management.Automation.TypeAccelerators')::add('DscResourceProperty','Microsoft.PowerShell.xDesiredStateConfiguration.DscResourceProperty') $TypeMap = @{ - 'Uint8' = [System.Byte]; - 'Uint16' = [System.UInt16]; - 'Uint32' = [System.Uint32]; - 'Uint64' = [System.UInt64]; - 'Sint8' = [System.SByte]; - 'Sint16' = [System.Int16]; - 'Sint32' = [System.Int32]; - 'Sint64' = [System.Int64]; - 'Real32' = [System.Single]; - 'Real64' = [System.Double]; - 'Char16' = [System.Char]; - 'String' = [System.String]; - 'Boolean' = [System.Boolean]; - 'DateTime'= [System.DateTime]; - - 'Hashtable' = [Microsoft.Management.Infrastructure.CimInstance[]]; - 'PSCredential' = [PSCredential]; - - 'Uint8[]' = [System.Byte[]]; - 'Uint16[]' = [System.UInt16[]]; - 'Uint32[]' = [System.Uint32[]]; - 'Uint64[]' = [System.UInt64[]]; - 'Sint8[]' = [System.SByte[]]; - 'Sint16[]' = [System.Int16[]]; - 'Sint32[]' = [System.Int32[]]; - 'Sint64[]' = [System.Int64[]]; - 'Real32[]' = [System.Single[]]; - 'Real64[]' = [System.Double[]]; - 'Char16[]' = [System.Char[]]; - 'String[]' = [System.String[]]; - 'Boolean[]' = [System.Boolean[]]; - 'DateTime[]'= [System.DateTime[]]; - - 'Hashtable[]' = [Microsoft.Management.Infrastructure.CimInstance[]]; - 'PSCredential[]' = [PSCredential[]]; + 'Uint8' = [System.Byte]; + 'Uint16' = [System.UInt16]; + 'Uint32' = [System.Uint32]; + 'Uint64' = [System.UInt64]; + 'Sint8' = [System.SByte]; + 'Sint16' = [System.Int16]; + 'Sint32' = [System.Int32]; + 'Sint64' = [System.Int64]; + 'Real32' = [System.Single]; + 'Real64' = [System.Double]; + 'Char16' = [System.Char]; + 'String' = [System.String]; + 'Boolean' = [System.Boolean]; + 'DateTime'= [System.DateTime]; + + 'Hashtable' = [Microsoft.Management.Infrastructure.CimInstance[]]; + 'PSCredential' = [PSCredential]; + + 'Uint8[]' = [System.Byte[]]; + 'Uint16[]' = [System.UInt16[]]; + 'Uint32[]' = [System.Uint32[]]; + 'Uint64[]' = [System.UInt64[]]; + 'Sint8[]' = [System.SByte[]]; + 'Sint16[]' = [System.Int16[]]; + 'Sint32[]' = [System.Int32[]]; + 'Sint64[]' = [System.Int64[]]; + 'Real32[]' = [System.Single[]]; + 'Real64[]' = [System.Double[]]; + 'Char16[]' = [System.Char[]]; + 'String[]' = [System.String[]]; + 'Boolean[]' = [System.Boolean[]]; + 'DateTime[]'= [System.DateTime[]]; + + 'Hashtable[]' = [Microsoft.Management.Infrastructure.CimInstance[]]; + 'PSCredential[]' = [PSCredential[]]; } $EmbeddedInstances = @{ - 'Hashtable' = 'MSFT_KeyValuePair'; - 'PSCredential' = 'MSFT_Credential'; + 'Hashtable' = 'MSFT_KeyValuePair'; + 'PSCredential' = 'MSFT_Credential'; - 'Hashtable[]' = 'MSFT_KeyValuePair'; - 'PSCredential[]' = 'MSFT_Credential'; + 'Hashtable[]' = 'MSFT_KeyValuePair'; + 'PSCredential[]' = 'MSFT_Credential'; - 'HashtableArray' = 'MSFT_KeyValuePair'; - 'PSCredentialArray' = 'MSFT_Credential'; + 'HashtableArray' = 'MSFT_KeyValuePair'; + 'PSCredentialArray' = 'MSFT_Credential'; } $NameRegex = "^[a-zA-Z][\w_]*$" $NameMaxLength = 255 #This number is hardcoded into the localization text as 255 <# -.SYNOPSIS +.SYNOPSIS Creates a DscResourceProperty to be used by New-cDscResource. .DESCRIPTION @@ -320,18 +320,18 @@ function New-cDscResourceProperty [parameter( Mandatory = $true, Position = 1)] - [ValidateSet('Uint8','Uint16','Uint32','Uint64', - 'Sint8','Sint16','Sint32','Sint64', - 'Real32','Real64','Char16','String', - 'Boolean','DateTime','Hashtable', - 'PSCredential', - 'Uint8[]','Uint16[]','Uint32[]','Uint64[]', - 'Sint8[]','Sint16[]','Sint32[]','Sint64[]', - 'Real32[]','Real64[]','Char16[]','String[]', - 'Boolean[]','DateTime[]','Hashtable[]', - 'PSCredential[]', - 'Microsoft.Management.Infrastructure.CimInstance', - 'Microsoft.Management.Infrastructure.CimInstance[]')] + [ValidateSet('Uint8','Uint16','Uint32','Uint64', + 'Sint8','Sint16','Sint32','Sint64', + 'Real32','Real64','Char16','String', + 'Boolean','DateTime','Hashtable', + 'PSCredential', + 'Uint8[]','Uint16[]','Uint32[]','Uint64[]', + 'Sint8[]','Sint16[]','Sint32[]','Sint64[]', + 'Real32[]','Real64[]','Char16[]','String[]', + 'Boolean[]','DateTime[]','Hashtable[]', + 'PSCredential[]', + 'Microsoft.Management.Infrastructure.CimInstance', + 'Microsoft.Management.Infrastructure.CimInstance[]')] [System.String] $Type, @@ -342,10 +342,10 @@ function New-cDscResourceProperty $Attribute, [System.String[]] - $ValueMap, - - [System.String[]] - $Values, + $ValueMap, + + [System.String[]] + $Values, [System.String] $Description, @@ -353,45 +353,45 @@ function New-cDscResourceProperty [bool] $ContainsEmbeddedInstance = $false ) - + if ((Test-TypeIsArray $Type) -and [DscResourcePropertyAttribute]::Key -eq $Attribute) { - $errorId = 'KeyArrayError' + $errorId = 'KeyArrayError' Write-Error $localizedData[$errorId] ` - -ErrorId $errorId - return + -ErrorId $errorId + return } - if (($Values -or $ValueMap) -and ((Test-TypeIsArray $Type) -or $EmbeddedInstances.ContainsKey($Type))) + if (($Values -or $ValueMap) -and ((Test-TypeIsArray $Type) -or $EmbeddedInstances.ContainsKey($Type))) { Write-Error ($localizedData.InvalidValidateSetUsageError) ` - -ErrorId 'InvalidValidateSetUsageError' - return + -ErrorId 'InvalidValidateSetUsageError' + return } - if ($ValueMap -and (-not $ValueMap.Length -le 0)) + if ($ValueMap -and (-not $ValueMap.Length -le 0)) { - $ValueMap | foreach { + $ValueMap | foreach { if (-not ([System.Management.Automation.LanguagePrimitives]::` TryConvertTo($_, $TypeMap[$Type], [ref]$null))) { Write-Error ($localizedData.ValidateSetTypeError -f $_,$Type) ` - -ErrorId 'ValidateSetTypeError' - return + -ErrorId 'ValidateSetTypeError' + return } } } - Test-Name $Name 'Property' + Test-Name $Name 'Property' - return [DscResourceProperty] @{ - Name = $Name - Type = $Type - Attribute = $Attribute - ValueMap = $ValueMap - Values = $Values - Description = $Description + return [DscResourceProperty] @{ + Name = $Name + Type = $Type + Attribute = $Attribute + ValueMap = $ValueMap + Values = $Values + Description = $Description ContainsEmbeddedInstance = $ContainsEmbeddedInstance } } @@ -411,14 +411,14 @@ function Test-Name [parameter( Mandatory = $true, Position = 2)] - [ValidateSet('Resource','Property')] + [ValidateSet('Resource','Property')] [System.String] $errorType ) if (-not ($Name -cmatch $NameRegex)) { - $errorId = 'Invalid' + $errorType + 'NameError' + $errorId = 'Invalid' + $errorType + 'NameError' Write-Error ($localizedData[$errorId] -f $Name) ` -ErrorId $errorId -ErrorAction Stop @@ -426,7 +426,7 @@ function Test-Name if ($Name.Length -gt $NameMaxLength) { - $errorId = $errorType + 'NameTooLongError' + $errorId = $errorType + 'NameTooLongError' Write-Error ($localizedData[$errorId] -f $Name) ` -ErrorId $errorId -ErrorAction Stop @@ -460,9 +460,9 @@ function Test-PropertiesForResource if (-not $key) { Write-Error ($localizedData.NoKeyError) ` - -ErrorId 'NoKeyError' -ErrorAction Stop + -ErrorId 'NoKeyError' -ErrorAction Stop } - Write-Verbose $localizedData['NewResourceKeyVerbose'] + Write-Verbose $localizedData['NewResourceKeyVerbose'] #Check to make sure all variables have unique names $unique = $true @@ -482,15 +482,15 @@ function Test-PropertiesForResource if (-not ($unique -eq $true)) { Write-Error ($localizedData.NonUniqueNameError -f $unique) ` - -ErrorId 'NonUniqueNameError' -ErrorAction Stop + -ErrorId 'NonUniqueNameError' -ErrorAction Stop } - Write-Verbose $localizedData['NewResourceUniqueVerbose'] - + Write-Verbose $localizedData['NewResourceUniqueVerbose'] + return $true } <# -.SYNOPSIS +.SYNOPSIS Creates a DscResource based on the given arguments. .DESCRIPTION @@ -540,8 +540,8 @@ function New-cDscResource Mandatory = $false, Position = 2)] [System.String] - $Path = '.', - + $Path = '.', + [Parameter( Mandatory = $false, Position = 3)] @@ -549,7 +549,7 @@ function New-cDscResource $ModuleName, [System.Version] - $ClassVersion = '1.0.0.0', + $ClassVersion = '1.0.0.0', [System.String] $FriendlyName = $Name, @@ -558,14 +558,14 @@ function New-cDscResource $Force ) - - Assert-AdminPrivilege - Test-Name $Name 'Resource' - Write-Verbose $localizedData['NewResourceNameVerbose'] - $null = Test-PropertiesForResource $Property - - # Check if the given path exists, if not create it. + Assert-AdminPrivilege + Test-Name $Name 'Resource' + Write-Verbose $localizedData['NewResourceNameVerbose'] + + $null = Test-PropertiesForResource $Property + + # Check if the given path exists, if not create it. if (-not (Test-Path $Path -PathType Container)) { New-Item $Path -type Directory -ErrorVariable ev -ErrorAction SilentlyContinue @@ -573,7 +573,7 @@ function New-cDscResource if ($ev) { Write-Error ($localizedData.PathIsInvalidError -f $Path) ` - -ErrorId 'PathIsInvalidError' -ErrorAction Stop + -ErrorId 'PathIsInvalidError' -ErrorAction Stop } } @@ -586,7 +586,7 @@ function New-cDscResource if($ev) { Write-Error ($localizedData.PathIsInvalidError -f $fullPath) ` - -ErrorId 'PathIsInvalidError' -ErrorAction Stop + -ErrorId 'PathIsInvalidError' -ErrorAction Stop } } $manifestPath = Join-Path $Path "$moduleName.psd1" @@ -595,15 +595,15 @@ function New-cDscResource New-ModuleManifest -Path $manifestPath -ErrorVariable ev -ErrorAction SilentlyContinue if($ev) { - Write-Error ($localizedData.PathIsInvalidError -f $fullPath) ` - -ErrorId 'PathIsInvalidError' -ErrorAction Stop - + Write-Error ($localizedData.PathIsInvalidError -f $manifestPath) ` + -ErrorId 'PathIsInvalidError' -ErrorAction Stop + } - Write-Verbose $localizedData['NewModuleManifestPathVerbose'] + Write-Verbose $localizedData['NewModuleManifestPathVerbose'] } } - $fullPath = Join-Path $Path 'DSCResources' + $fullPath = Join-Path $Path 'DSCResources' # Check if $Path/DSCResources exists, if not create it. if (-not (Test-Path $fullPath -PathType Container)) @@ -613,11 +613,11 @@ function New-cDscResource if ($ev) { Write-Error ($localizedData.PathIsInvalidError -f $fullPath) ` - -ErrorId 'PathIsInvalidError' -ErrorAction Stop + -ErrorId 'PathIsInvalidError' -ErrorAction Stop } } - Write-Verbose $localizedData['NewResourcePathVerbose'] + Write-Verbose $localizedData['NewResourcePathVerbose'] $fullPath = Join-Path $fullPath $Name # Check if $Path/DSCResources/$Name exists, if not create it. @@ -628,10 +628,10 @@ function New-cDscResource if ($ev) { Write-Error ($localizedData.PathIsInvalidError -f $fullPath) ` - -ErrorId 'PathIsInvalidError' -ErrorAction Stop + -ErrorId 'PathIsInvalidError' -ErrorAction Stop } } - + #New-DscManifest $Name $fullPath $ClassVersion -Force:$Force -ParentPSCmdlet $PSCmdlet -Confirm New-DscSchema $Name $fullPath $Property $ClassVersion -FriendlyName:$FriendlyName -Force:$Force -ParentPSCmdlet $PSCmdlet -Confirm @@ -645,13 +645,13 @@ function New-cDscResource if (-not (Test-cDscResource $fullPath)) { Write-Error ($localizedData.ResourceError) ` - -ErrorId 'ResourceError' -ErrorAction Stop + -ErrorId 'ResourceError' -ErrorAction Stop Remove-Item $schemaPath Remove-Item $modulePath #Remove-Item $manifestPath } - Write-Verbose $localizedData['NewResourceSuccessVerbose'] + Write-Verbose $localizedData['NewResourceSuccessVerbose'] } function New-DscManifest @@ -692,7 +692,7 @@ function New-DscManifest { New-ModuleManifest ` -Path $ManifestPath ` - -FunctionsToExport 'Get-TargetResource','Set-TargetResource','Test-TargetResource' ` + -FunctionsToExport 'Get-TargetResource','Set-TargetResource','Test-TargetResource' ` -ModuleVersion $ClassVersion ` -PowerShellVersion 3.0 ` -ClrVersion 4.0 ` @@ -728,7 +728,7 @@ function New-DscSchema Position = 3)] [DscResourceProperty[]] $Parameters, - + [parameter( Mandatory, Position = 4)] @@ -745,7 +745,7 @@ function New-DscSchema [System.Management.Automation.PSCmdlet] $ParentPSCmdlet = $PSCmdlet - ) + ) $Schema = New-Object -TypeName System.Text.StringBuilder @@ -753,14 +753,14 @@ function New-DscSchema Add-StringBuilderLine $Schema "[ClassVersion(`"$ClassVersion`"), FriendlyName(`"$FriendlyName`")]" Add-StringBuilderLine $Schema "class $Name : OMI_BaseResource" - Add-StringBuilderLine $Schema '{' + Add-StringBuilderLine $Schema '{' foreach ($parameter in $Parameters) { Add-StringBuilderLine $Schema (New-DscSchemaParameter $parameter) } - Add-StringBuilderLine $Schema '};' + Add-StringBuilderLine $Schema '};' $SchemaPath = Join-Path $Path "$name.schema.mof" $SchemaExists = Test-Path $SchemaPath -PathType Leaf @@ -773,7 +773,7 @@ function New-DscSchema { Write-Warning ($localizedData.SchemaNotOverWrittenWarning -f $SchemaPath) } - + } # Given a type string (Uint8,...,Uint8[]...,Uint8Array) return the version without the "[]" or "Array" characters @@ -791,11 +791,11 @@ function Get-TypeNameForSchema if ($EmbeddedInstances.ContainsKey($Type)) { - return 'String' + return 'String' } $null = $Type -cmatch "^([a-zA-Z][\w_]*?)(\[\]|Array)?$" - + return $Matches[1] } @@ -810,9 +810,9 @@ function Test-TypeIsArray $Type ) # Returns true if $Type ends with "[]" - if($Type -like 'hashtable') { - return $true; - } + if($Type -like 'hashtable') { + return $true; + } return ($Type -cmatch "^[a-zA-Z][\w_]*\[\]$") } @@ -831,7 +831,7 @@ function New-DscSchemaParameter Add-StringBuilderLine $SchemaEntry "`t[" -Append Add-StringBuilderLine $SchemaEntry $Parameter.Attribute -Append - + if ($EmbeddedInstances.ContainsKey($Parameter.Type)) { Add-StringBuilderLine $SchemaEntry ", EmbeddedInstance(`"" -Append @@ -847,41 +847,41 @@ function New-DscSchemaParameter } - if ($Parameter.ValueMap) + if ($Parameter.ValueMap) { - Add-StringBuilderLine $SchemaEntry ', ValueMap{' -Append + Add-StringBuilderLine $SchemaEntry ', ValueMap{' -Append - $CommaList = New-DelimitedList $Parameter.ValueMap -String:($Parameter.Type -eq 'String') + $CommaList = New-DelimitedList $Parameter.ValueMap -String:($Parameter.Type -eq 'String') Add-StringBuilderLine $SchemaEntry $CommaList -Append - Add-StringBuilderLine $SchemaEntry '}' -Append - } - - if ($Parameter.Values) - { - Add-StringBuilderLine $SchemaEntry ', Values{' -Append - - $CommaList = New-DelimitedList $Parameter.Values -String - + Add-StringBuilderLine $SchemaEntry '}' -Append + } + + if ($Parameter.Values) + { + Add-StringBuilderLine $SchemaEntry ', Values{' -Append + + $CommaList = New-DelimitedList $Parameter.Values -String + Add-StringBuilderLine $SchemaEntry $CommaList -Append - Add-StringBuilderLine $SchemaEntry '}' -Append + Add-StringBuilderLine $SchemaEntry '}' -Append } - - Add-StringBuilderLine $SchemaEntry '] ' -Append + + Add-StringBuilderLine $SchemaEntry '] ' -Append Add-StringBuilderLine $SchemaEntry (Get-TypeNameForSchema $Parameter.Type) -Append - Add-StringBuilderLine $SchemaEntry ' ' -Append + Add-StringBuilderLine $SchemaEntry ' ' -Append Add-StringBuilderLine $SchemaEntry ($Parameter.Name) -Append if (Test-TypeIsArray $Parameter.Type) { - Add-StringBuilderLine $SchemaEntry '[]' -Append + Add-StringBuilderLine $SchemaEntry '[]' -Append } - Add-StringBuilderLine $SchemaEntry ';' -Append + Add-StringBuilderLine $SchemaEntry ';' -Append return $SchemaEntry.ToString() @@ -898,7 +898,7 @@ function New-DelimitedList $String, [String] - $Separator = ',' + $Separator = ',' ) $CommaList = New-Object -TypeName System.Text.StringBuilder @@ -919,7 +919,7 @@ function New-DelimitedList { Add-StringBuilderLine $CommaList $curItem -Append } - + if($i -lt ($list.Count -1)) { @@ -940,7 +940,7 @@ function New-DscModule Position = 1)] [System.String] $Name, - + [parameter( Mandatory = $true, Position = 2)] @@ -952,32 +952,32 @@ function New-DscModule Position = 3)] [DscResourceProperty[]] $Parameters, - + [Switch] $Force, - + [System.Management.Automation.PSCmdlet] $ParentPSCmdlet = $PSCmdlet ) $Module = New-Object -TypeName System.Text.StringBuilder - + # Create a function Get-TargetResource # Add all parameters with the Key or Required tags Add-StringBuilderLine $Module (New-GetTargetResourceFunction $Parameters) - + # Create a function Set-TargetResource # Add all parametes without the Read tag Add-StringBuilderLine $Module (New-SetTargetResourceFunction $Parameters) - + # Create a function Test-TargetResource # Add all parametes without the Read tag Add-StringBuilderLine $Module (New-TestTargetResourceFunction $Parameters) - Add-StringBuilderLine $Module ('Export-ModuleMember -Function *-TargetResource') + Add-StringBuilderLine $Module ('Export-ModuleMember -Function *-TargetResource') + + $ModulePath = Join-Path $Path ($Name + '.psm1') - $ModulePath = Join-Path $Path ($Name + '.psm1') - $ModuleExists = Test-Path $ModulePath -PathType Leaf if (-not $ModuleExists -or $Force -or $ParentPSCmdlet.ShouldProcess($ModulePath, $localizedData.OverWriteModuleOperation)) @@ -1004,10 +1004,10 @@ function New-GetTargetResourceFunction $functionContent ) - return New-DscModuleFunction 'Get-TargetResource' ` + return New-DscModuleFunction 'Get-TargetResource' ` ($Parameters | Where-Object {([DscResourcePropertyAttribute]::Key -eq $_.Attribute) ` -or ([DscResourcePropertyAttribute]::Required -eq $_.Attribute)})` - 'System.Collections.Hashtable'` + 'System.Collections.Hashtable'` ($Parameters)` -FunctionContent $functionContent @@ -1027,7 +1027,7 @@ function New-SetTargetResourceFunction $functionContent ) - return New-DscModuleFunction 'Set-TargetResource' ` + return New-DscModuleFunction 'Set-TargetResource' ` ($Parameters | Where-Object {([DscResourcePropertyAttribute]::Read -ne $_.Attribute)})` -FunctionContent $functionContent } @@ -1046,13 +1046,13 @@ function New-TestTargetResourceFunction $functionContent ) - return New-DscModuleFunction 'Test-TargetResource' ` + return New-DscModuleFunction 'Test-TargetResource' ` ($Parameters | Where-Object {([DscResourcePropertyAttribute]::Read -ne $_.Attribute)})` - 'Boolean'` + 'Boolean'` -FunctionContent $functionContent } -# Given a function name and a set of parameters, +# Given a function name and a set of parameters, # returns a string representation of this function # If given the ReturnValues, returns a hashtable consiting of these values function New-DscModuleFunction @@ -1094,12 +1094,12 @@ function New-DscModuleFunction $Function = New-Object -TypeName System.Text.StringBuilder Add-StringBuilderLine $Function "function $Name" - Add-StringBuilderLine $Function '{' + Add-StringBuilderLine $Function '{' Add-StringBuilderLine $Function "`t[CmdletBinding()]" if ($ReturnType) { - Add-StringBuilderLine $Function ("`t[OutputType([" + $ReturnType.FullName +'])]') + Add-StringBuilderLine $Function ("`t[OutputType([" + $ReturnType.FullName +'])]') } Add-StringBuilderLine $Function "`tparam" @@ -1110,32 +1110,32 @@ function New-DscModuleFunction Add-StringBuilderLine $Function (New-DscModuleParameter $Parameters[$i]) } - #Because every function takes at least the key parameters, + #Because every function takes at least the key parameters, # $Parameters is at least size 1 Add-StringBuilderLine $Function (New-DscModuleParameter $Parameters[$i] -Last) Add-StringBuilderLine $Function "`t)" - + if ($FunctionContent) # If we are updating an already existing function { Add-StringBuilderLine $Function $FunctionContent } else # Add some useful comments { - Add-StringBuilderLine $Function + Add-StringBuilderLine $Function Add-StringBuilderLine $Function ("`t#Write-Verbose `"" + $localizedData.UsingWriteVerbose + "`"") Add-StringBuilderLine $Function Add-StringBuilderLine $Function ("`t#Write-Debug `"" + $localizedData.UsingWriteDebug + "`"") - - if ($Name.Contains('Set-TargetResource')) + + if ($Name.Contains('Set-TargetResource')) { Add-StringBuilderLine $Function Add-StringBuilderLine $Function ("`t#" + $localizedData.IfRebootRequired) Add-StringBuilderLine $Function "`t#`$global:DSCMachineStatus = 1" } - Add-StringBuilderLine $Function + Add-StringBuilderLine $Function Add-StringBuilderLine $Function if ($ReturnValues) @@ -1147,19 +1147,19 @@ function New-DscModuleFunction Add-StringBuilderLine $Function "`t<#" Add-StringBuilderLine $Function "`t`$result = [" -Append Add-StringBuilderLine $Function $ReturnType.FullName -Append - Add-StringBuilderLine $Function ']' + Add-StringBuilderLine $Function ']' Add-StringBuilderLine $Function "`t" Add-StringBuilderLine $Function "`t`$result" Add-StringBuilderLine $Function "`t#>" } } - Add-StringBuilderLine $Function '}' + Add-StringBuilderLine $Function '}' if (-not $FunctionContent) { - Add-StringBuilderLine $Function + Add-StringBuilderLine $Function } - + return $Function.ToString() } @@ -1179,7 +1179,7 @@ function New-DscModuleParameter [Switch] $Last ) - + $ParameterBuilder = New-Object -TypeName System.Text.StringBuilder if (([DscResourcePropertyAttribute]::Key -eq $Parameter.Attribute) ` @@ -1188,22 +1188,22 @@ function New-DscModuleParameter Add-StringBuilderLine $ParameterBuilder "`t`t[parameter(Mandatory = `$true)]" } - if ($Parameter.Values) + if ($Parameter.Values) { - $set = $Parameter.Values - if ($Parameter.ValueMap) - { - $set = $Parameter.ValueMap - } - + $set = $Parameter.Values + if ($Parameter.ValueMap) + { + $set = $Parameter.ValueMap + } + $ValidateSetProperty = New-Object -TypeName System.Text.StringBuilder - + Add-StringBuilderLine $ValidateSetProperty "`t`t[ValidateSet(" -Append Add-StringBuilderLine $ValidateSetProperty ` - (New-DelimitedList $set -String:($Parameter.Type -eq 'String')) -Append + (New-DelimitedList $set -String:($Parameter.Type -eq 'String')) -Append - Add-StringBuilderLine $ValidateSetProperty ')]' -Append + Add-StringBuilderLine $ValidateSetProperty ')]' -Append Add-StringBuilderLine $ParameterBuilder $ValidateSetProperty } @@ -1216,7 +1216,7 @@ function New-DscModuleParameter if (-not $Last) { - Add-StringBuilderLine $ParameterBuilder ',' + Add-StringBuilderLine $ParameterBuilder ',' } return $ParameterBuilder.ToString() @@ -1232,25 +1232,25 @@ function New-DscModuleReturn [DscResourceProperty[]] $Parameters ) - + $HashTable = New-Object -TypeName System.Text.StringBuilder Add-StringBuilderLine $HashTable "`t<#" Add-StringBuilderLine $HashTable "`t`$returnValue = @{" - + $Parameters | foreach { $HashTableEntry = New-Object -TypeName System.Text.StringBuilder Add-StringBuilderLine $HashTableEntry "`t`t" -Append Add-StringBuilderLine $HashTableEntry $_.Name -Append - Add-StringBuilderLine $HashTableEntry ' = [' -Append + Add-StringBuilderLine $HashTableEntry ' = [' -Append Add-StringBuilderLine $HashTableEntry $TypeMap[$_.Type].ToString() -Append - Add-StringBuilderLine $HashTableEntry ']' -Append + Add-StringBuilderLine $HashTableEntry ']' -Append Add-StringBuilderLine $HashTable $HashTableEntry.ToString() } - + Add-StringBuilderLine $HashTable "`t}" Add-StringBuilderLine $HashTable Add-StringBuilderLine $HashTable "`t`$returnValue" @@ -1260,7 +1260,7 @@ function New-DscModuleReturn } # Wrapper for StringBuilder.AppendLine that captures the returned StringBuilder object -function Add-StringBuilderLine +function Add-StringBuilderLine { param ( @@ -1280,13 +1280,13 @@ function Add-StringBuilderLine [Switch] $Append ) - + if ($Append) { $null = $Builder.Append($Line) - return + return } - + if ($Line) { @@ -1317,7 +1317,7 @@ function Get-FunctionParamLineNumbers ) $functionLineNumbers = @{} - + $contentString = [System.String]::Join([System.Environment]::NewLine, (Get-Content $modulePath)) $parserErrors = @() @@ -1330,37 +1330,37 @@ function Get-FunctionParamLineNumbers { # Because we used ParseInput, we need to add the file name to the error message ourselves. - $errorId = 'ModuleParsingError' + $errorId = 'ModuleParsingError' $errorMessage = $localizedData[$errorId] -f $modulePath for ($i = 0; $i -lt $parserErrors.Count - 1; $i++) { - Write-Error ($errorMessage + ' ' + $parserErrors[$i].ToString().Replace('At line:', 'at line:')) -ErrorId $errorId + Write-Error ($errorMessage + ' ' + $parserErrors[$i].ToString().Replace('At line:', 'at line:')) -ErrorId $errorId } - Write-Error ($errorMessage + ' ' + $parserErrors[$i].ToString().Replace('At line:', 'at line:')) -ErrorId $errorId -ErrorAction Stop + Write-Error ($errorMessage + ' ' + $parserErrors[$i].ToString().Replace('At line:', 'at line:')) -ErrorId $errorId -ErrorAction Stop } $AST.FindAll({$args[0].GetType().Equals([System.Management.Automation.Language.FunctionDefinitionAst])},$false) | foreach { - + if ($functionNames.Contains($_.Name)) { $name = $_.Name $functionLineNumbers.Add($name, @()) $functionLineNumbers[$name] += $_.Extent.StartLineNumber - + #Check for a ParamBlock if ($_.Body.ParamBlock.Extent.EndLineNumber) { $functionLineNumbers[$name] += $_.Body.ParamBlock.Extent.EndLineNumber } else - { #If there is no param block, + { #If there is no param block, # The function's content starts the line after the "{" $functionLineNumbers[$name] += $_.Body.Extent.StartLineNumber + 1 } - + $functionLineNumbers[$name] += $_.Extent.EndLineNumber } } @@ -1386,9 +1386,9 @@ function Get-ContentFromFunctions ) $functionContent = @{} - + $moduleLines = Get-Content $modulePath - + foreach ($function in $functionLineNumbers.Keys) { @@ -1427,12 +1427,12 @@ function Update-DscModule [Switch] $Force, - + [System.Management.Automation.PSCmdlet] $ParentPSCmdlet = $PSCmdlet ) - $functionNames = 'Get-TargetResource','Set-TargetResource','Test-TargetResource' + $functionNames = 'Get-TargetResource','Set-TargetResource','Test-TargetResource' $functionLineNumbers = Get-FunctionParamLineNumbers $ModulePath $functionNames @@ -1443,31 +1443,31 @@ function Update-DscModule # Create a function Get-TargetResource # Add all parameters with the Key or Required tags - $functionName = 'Get-TargetResource' + $functionName = 'Get-TargetResource' $updatedFunctions.Add($functionName, ` (New-GetTargetResourceFunction $Parameters -FunctionContent $functionContent[$functionName])) - - + + # Create a function Set-TargetResource # Add all parametes without the Read tag - $functionName = 'Set-TargetResource' + $functionName = 'Set-TargetResource' $updatedFunctions.Add($functionName, ` (New-SetTargetResourceFunction $Parameters -FunctionContent $functionContent[$functionName])) - + # Create a function Test-TargetResource # Add all parametes without the Read tag - $functionName = 'Test-TargetResource' + $functionName = 'Test-TargetResource' $updatedFunctions.Add($functionName, ` (New-TestTargetResourceFunction $Parameters -FunctionContent $functionContent[$functionName])) - + $sortedFunctionList = Get-SortedFunctionNames $functionLineNumbers $moduleLines = Get-Content $ModulePath $newModule = New-Object -TypeName System.Text.StringBuilder - + #Start at the first line of the file @@ -1516,7 +1516,7 @@ function Update-DscModule } <# -.SYNOPSIS +.SYNOPSIS Update an existing DscResource based on the given arguments. .DESCRIPTION @@ -1549,7 +1549,7 @@ function Update-cDscResource [parameter( Mandatory = $true, Position = 0)] - [Alias('Path')] + [Alias('Path')] [System.String] $Name, @@ -1561,7 +1561,7 @@ function Update-cDscResource $Property, [System.Version] - $ClassVersion = '1.0.0.0', + $ClassVersion = '1.0.0.0', [System.String] $NewName, @@ -1569,13 +1569,13 @@ function Update-cDscResource [Switch] $Force ) - - - Assert-AdminPrivilege + + + Assert-AdminPrivilege # Will hold path to the .schema.mof file - $Schema = '' + $Schema = '' # Will hold path to the .psm1 file - $Module = '' + $Module = '' #Ignore the schema because we will be generating a new one regardless if (-not (Test-ResourcePath $Name ([ref]$Schema) ([ref]$Module) -IgnoreSchema)) @@ -1583,8 +1583,8 @@ function Update-cDscResource return $false } - $null = Test-PropertiesForResource $Property - + $null = Test-PropertiesForResource $Property + $Name = [IO.Path]::GetFileNameWithoutExtension($Name) # The path to the folder containing the schema/module files @@ -1598,9 +1598,9 @@ function Update-cDscResource if (Test-cDscResource $fullPath) { - Write-Verbose $localizedData['NewResourceSuccessVerbose'] + Write-Verbose $localizedData['NewResourceSuccessVerbose'] } - + } #Line Numbers start at 1 @@ -1631,7 +1631,7 @@ function Get-SortedFunctionNames [System.Collections.Hashtable] $functionLineNumbers ) - + # Sort based on the starting line number of the function return ($functionLineNumbers.Keys | Sort-Object {$functionLineNumbers[$_][0]}) } @@ -1666,17 +1666,17 @@ function Test-ResourcePath $IgnoreSchema ) - $Schema = '' - $ResourceModule = '' + $Schema = '' + $ResourceModule = '' $error = $false if (Test-Path -PathType Container $ModuleName) - { + { $fileName = [IO.Path]::GetFileNameWithoutExtension($ModuleName) - $Schema = Join-Path $ModuleName ($fileName + '.schema.mof') - $ResourceModule = Join-Path $ModuleName ($fileName + '.psm1') + $Schema = Join-Path $ModuleName ($fileName + '.schema.mof') + $ResourceModule = Join-Path $ModuleName ($fileName + '.psm1') } else # We assume its the name of a module in $env:PSModulePath { @@ -1684,28 +1684,28 @@ function Test-ResourcePath if (-not $module) { - Write-Error ($localizedData['ModuleNameNotFoundError'] -f $ModuleName) ` - -ErrorId 'ModuleNotFoundError' -ErrorAction Stop + Write-Error ($localizedData['ModuleNameNotFoundError'] -f $ModuleName) ` + -ErrorId 'ModuleNotFoundError' -ErrorAction Stop } $moduleFolder = [IO.Path]::GetDirectoryName($module.Path) $leaf = Split-Path $moduleFolder -Leaf - $Schema = Join-Path $moduleFolder ($leaf + '.schema.mof') - $ResourceModule = Join-Path $moduleFolder ($leaf + '.psm1') + $Schema = Join-Path $moduleFolder ($leaf + '.schema.mof') + $ResourceModule = Join-Path $moduleFolder ($leaf + '.psm1') } if (-not $IgnoreSchema -and -not (Test-Path -PathType Leaf $Schema)) { - Write-Error ($localizedData['SchemaNotFoundInDirectoryError'] -f $Schema) ` - -ErrorId 'SchemaNotFoundInDirectoryError' -ErrorAction Continue + Write-Error ($localizedData['SchemaNotFoundInDirectoryError'] -f $Schema) ` + -ErrorId 'SchemaNotFoundInDirectoryError' -ErrorAction Continue $error = $true } - + if (-not (Test-Path -PathType Leaf $ResourceModule)) { - Write-Error ($localizedData['ModuleNotFoundInDirectoryError'] -f $ResourceModule) ` - -ErrorId 'ModuleNotFoundInDirectoryError' -ErrorAction Continue + Write-Error ($localizedData['ModuleNotFoundInDirectoryError'] -f $ResourceModule) ` + -ErrorId 'ModuleNotFoundInDirectoryError' -ErrorAction Continue $error = $true } @@ -1714,17 +1714,17 @@ function Test-ResourcePath { return $false } - + #Otherwise return the path to the files $SchemaRef.Value = $Schema $ResourceModuleRef.Value = $ResourceModule return $true - + } <# -.SYNOPSIS +.SYNOPSIS Determines if the given resource will work with the Dsc Engine. .DESCRIPTION @@ -1756,13 +1756,13 @@ function Test-cDscResource process { - Assert-AdminPrivilege + Assert-AdminPrivilege # Will hold path to the .schema.mof file - $Schema = '' + $Schema = '' # Will hold path to the .psm1 file - $ResourceModule = '' + $ResourceModule = '' + - if (-not (Test-ResourcePath $Name ([ref]$Schema) ([ref]$ResourceModule))) { return $false @@ -1780,42 +1780,42 @@ function Test-cDscResource $SetCommandInfo = 0 $TestCommandInfo = 0 - Write-Verbose $localizedData['TestResourceTestSchemaVerbose'] - $SchemaError = -not (Test-cDscSchemaInternal $Schema ([ref]$SchemaCimClass)) + Write-Verbose $localizedData['TestResourceTestSchemaVerbose'] + $SchemaError = -not (Test-cDscSchemaInternal $Schema ([ref]$SchemaCimClass)) - Write-Verbose $localizedData['TestResourceTestModuleVerbose'] - $ModuleError = -not (Test-DscResourceModule $ResourceModule ([ref]$GetCommandInfo) ([ref]$SetCommandInfo) ([ref]$TestCommandInfo)) + Write-Verbose $localizedData['TestResourceTestModuleVerbose'] + $ModuleError = -not (Test-DscResourceModule $ResourceModule ([ref]$GetCommandInfo) ([ref]$SetCommandInfo) ([ref]$TestCommandInfo)) if ($SchemaError -or $ModuleError) { return $false } - Write-Verbose $localizedData['TestResourceIndividualSuccessVerbose'] + Write-Verbose $localizedData['TestResourceIndividualSuccessVerbose'] # Check the dependencies between the files - $DscResourceProperties = Convert-SchemaToResourceProperty $SchemaCimClass + $DscResourceProperties = Convert-SchemaToResourceProperty $SchemaCimClass #Check get has all key and required and that they are mandatory - # NOTE: The LCM, at least as of version 4.0, treats Required properties as Key, and will not apply a configuration - # properly if any of these are missing from Get-TargetResource. Even though the Required properties are really - # supposed to be part of the output of Get-TargetResource rather than part of its input, we still have to make - # sure the resource matches the behavior that the LCM requires. - - $getMandatoryError = -not (Test-GetKeyRequiredMandatory $GetCommandInfo.Parameters ` - ($DscResourceProperties | Where-Object {([DscResourcePropertyAttribute]::Key -eq $_.Attribute) ` - -or ([DscResourcePropertyAttribute]::Required -eq $_.Attribute)})) - Write-Verbose ($localizedData['TestResourceGetMandatoryVerbose'] -f (-not $getMandatoryError)) + # NOTE: The LCM, at least as of version 4.0, treats Required properties as Key, and will not apply a configuration + # properly if any of these are missing from Get-TargetResource. Even though the Required properties are really + # supposed to be part of the output of Get-TargetResource rather than part of its input, we still have to make + # sure the resource matches the behavior that the LCM requires. + + $getMandatoryError = -not (Test-GetKeyRequiredMandatory $GetCommandInfo.Parameters ` + ($DscResourceProperties | Where-Object {([DscResourcePropertyAttribute]::Key -eq $_.Attribute) ` + -or ([DscResourcePropertyAttribute]::Required -eq $_.Attribute)})) + Write-Verbose ($localizedData['TestResourceGetMandatoryVerbose'] -f (-not $getMandatoryError)) #Check that set has all write - $setNoReadsError = -not (Test-SetHasExactlyAllNonReadProperties $SetCommandInfo ` + $setNoReadsError = -not (Test-SetHasExactlyAllNonReadProperties $SetCommandInfo ` ($DscResourceProperties | Where-Object {([DscResourcePropertyAttribute]::Read -ne $_.Attribute)})) - Write-Verbose ($localizedData['TestResourceSetNoReadsVerbose'] -f (-not $setNoReadsError)) + Write-Verbose ($localizedData['TestResourceSetNoReadsVerbose'] -f (-not $setNoReadsError)) $getNoReadsError = -not (Test-FunctionTakesNoReads $GetCommandInfo.Parameters ` ($DscResourceProperties | Where-Object {([DscResourcePropertyAttribute]::Read -eq $_.Attribute)}) ` -Get) - Write-Verbose ($localizedData['TestResourceGetNoReadsVerbose'] -f (-not $getNoReadsError)) + Write-Verbose ($localizedData['TestResourceGetNoReadsVerbose'] -f (-not $getNoReadsError)) #The Test-TargetResource case is handled by SetHasExactlyAllNonReadProperties @@ -1823,7 +1823,7 @@ function Test-cDscResource } } -function Test-GetKeyRequiredMandatory +function Test-GetKeyRequiredMandatory { param ( @@ -1837,7 +1837,7 @@ function Test-GetKeyRequiredMandatory Mandatory = $true, Position = 2)] [DscResourceProperty[]] - $KeyRequiredDscResourceProperties, + $KeyRequiredDscResourceProperties, [ref] $errorIdsRef @@ -1845,15 +1845,15 @@ function Test-GetKeyRequiredMandatory $errorIds = @() - foreach ($property in $KeyRequiredDscResourceProperties) + foreach ($property in $KeyRequiredDscResourceProperties) { if (-not $GetParameters[$property.Name] -or ` -not (Test-ParameterMetaDataIsDscResourceProperty $GetParameters[$property.Name] $property)) { - $errorId = 'GetMissingKeyOrRequiredError' + $errorId = 'GetMissingKeyOrRequiredError' Write-Error ($localizedData[$errorId] -f $property.Name) ` - -ErrorId $errorId -ErrorAction Continue + -ErrorId $errorId -ErrorAction Continue $errorIds += $errorId } @@ -1873,8 +1873,8 @@ function Test-SetHasExactlyAllNonReadProperties [parameter( Mandatory = $true, Position = 1)] - [System.Management.Automation.CommandInfo] - $Command, + [System.Management.Automation.CommandInfo] + $Command, [parameter( Mandatory = $true, @@ -1886,9 +1886,9 @@ function Test-SetHasExactlyAllNonReadProperties $errorIdsRef ) - $SetParameters = $Command.Parameters - $metadata = [System.Management.Automation.CommandMetadata]$Command - + $SetParameters = $Command.Parameters + $metadata = [System.Management.Automation.CommandMetadata]$Command + $propertiesHash = @{} $errorIds = @() @@ -1896,28 +1896,28 @@ function Test-SetHasExactlyAllNonReadProperties #Make sure each NonRead Property is represented in the function foreach ($property in $NonReadDscResourceProperties) { - + if (-not $SetParameters[$property.Name] -or ` -not (Test-ParameterMetaDataIsDscResourceProperty $SetParameters[$property.Name] $property)) { - $errorId = 'SetAndTestMissingParameterError' + $errorId = 'SetAndTestMissingParameterError' Write-Error ($localizedData[$errorId] -f $property.Name) ` - -ErrorId $errorId -ErrorAction Continue + -ErrorId $errorId -ErrorAction Continue $errorIds += $errorId } $propertiesHash.Add($property.Name,$true) } - + #Make sure there are no extra properties in the function foreach ($parameter in $SetParameters.Values) { - if (-not $propertiesHash[$parameter.Name] -and -not (IsCommonParameter -Name $parameter.Name -Metadata $metadata)) + if (-not $propertiesHash[$parameter.Name] -and -not (IsCommonParameter -Name $parameter.Name -Metadata $metadata)) { - $errorId = 'SetAndTestExtraParameterError' + $errorId = 'SetAndTestExtraParameterError' Write-Error ($localizedData[$errorId] -f $parameter.Name) ` - -ErrorId $errorId -ErrorAction Continue + -ErrorId $errorId -ErrorAction Continue $errorIds += $errorId } @@ -1959,20 +1959,20 @@ function Test-FunctionTakesNoReads { if ($FunctionParameters[$property.Name]) { - $errorId = '' + $errorId = '' if ($Get) { - $errorId = 'GetTakesReadError' + $errorId = 'GetTakesReadError' Write-Error ($localizedData[$errorId] -f $property.Name) ` - -ErrorId $errorId -ErrorAction Continue + -ErrorId $errorId -ErrorAction Continue } else { - $errorId = 'SetTestTakeReadError' + $errorId = 'SetTestTakeReadError' Write-Error ($localizedData[$errorId] -f $property.Name) ` - -ErrorId $errorId -ErrorAction Continue - } + -ErrorId $errorId -ErrorAction Continue + } $errorIds += $errorId } @@ -2012,11 +2012,11 @@ function Test-ParameterMetaDataIsDscResourceProperty return $false } - if ($property.Attribute -eq 'Read') + if ($property.Attribute -eq 'Read') { - $errorId = 'SchemaModuleReadError' + $errorId = 'SchemaModuleReadError' Write-Error ($localizedData[$errorId] -f $property.Name) ` - -ErrorId $errorId -ErrorAction Continue + -ErrorId $errorId -ErrorAction Continue if($errorIdRef) { $errorIdRef.Value = $errorId @@ -2024,11 +2024,11 @@ function Test-ParameterMetaDataIsDscResourceProperty return $false } - if (($property.Attribute -eq 'Key' -or $property.Attribute -eq 'Required') -xor (Test-ParameterIsMandatory $parameter)) + if (($property.Attribute -eq 'Key' -or $property.Attribute -eq 'Required') -xor (Test-ParameterIsMandatory $parameter)) { - $errorId = 'SchemaModuleAttributeError' + $errorId = 'SchemaModuleAttributeError' Write-Error ($localizedData[$errorId] -f $property.Name) ` - -ErrorId $errorId -ErrorAction Continue + -ErrorId $errorId -ErrorAction Continue if($errorIdRef) { $errorIdRef.Value = $errorId @@ -2036,18 +2036,18 @@ function Test-ParameterMetaDataIsDscResourceProperty return $false } - $typeToTest = $parameter.ParameterType - if ($typeToTest.IsEnum) - { - $typeToTest = $typeToTest.GetEnumUnderlyingType() - } - - if ($TypeMap[$property.Type].FullName -ne $typeToTest.FullName -and + $typeToTest = $parameter.ParameterType + if ($typeToTest.IsEnum) + { + $typeToTest = $typeToTest.GetEnumUnderlyingType() + } + + if ($TypeMap[$property.Type].FullName -ne $typeToTest.FullName -and -not $property.ContainsEmbeddedInstance) { - $errorId = 'SchemaModuleTypeError' + $errorId = 'SchemaModuleTypeError' Write-Error ($localizedData[$errorId] -f $property.Name) ` - -ErrorId $errorId -ErrorAction Continue + -ErrorId $errorId -ErrorAction Continue if($errorIdRef) { $errorIdRef.Value = $errorId @@ -2057,54 +2057,54 @@ function Test-ParameterMetaDataIsDscResourceProperty $parameterValidateSet = Get-ValidateSet $parameter - if ($parameter.ParameterType.IsEnum) - { - $enumValues = $parameter.ParameterType.GetEnumValues() - - if (-not $property.Values -or -not $property.ValueMap -or - $enumValues.Count -ne $property.Values.Count -or $enumValues.Count -ne $property.ValueMap.Count) - { - $errorId = 'SchemaModuleValidateSetCountError' - Write-Error ($localizedData[$errorId] -f $property.Name) ` - -ErrorId $errorId -ErrorAction Continue - if($errorIdRef) - { - $errorIdRef.Value = $errorId - } - return $false - } - - foreach ($item in $enumValues) - { - $index = [Array]::IndexOf($property.Values, $item.ToString()) - - if ($index -lt 0 -or $property.ValueMap[$index] -ne $item.value__) - { - $errorId = 'SchemaModuleValidateSetItemError' - Write-Error ($localizedData[$errorId] -f $property.Name,$item.ToString()) ` - -ErrorId $errorId -ErrorAction Continue - if($errorIdRef) - { - $errorIdRef.Value = $errorId - } - return $false - } - } - - return $true - } - elseif ($property.Values -xor $parameterValidateSet) - { - $errorId = 'SchemaModuleValidateSetDiscrepancyError' - Write-Error ($localizedData[$errorId] -f $property.Name) ` - -ErrorId $errorId -ErrorAction Continue - if ($errorIdRef) - { - $errorIdRef.Value = $errorId - } - return $false - } - elseif (-not $property.Values -and -not $parameterValidateSet) + if ($parameter.ParameterType.IsEnum) + { + $enumValues = $parameter.ParameterType.GetEnumValues() + + if (-not $property.Values -or -not $property.ValueMap -or + $enumValues.Count -ne $property.Values.Count -or $enumValues.Count -ne $property.ValueMap.Count) + { + $errorId = 'SchemaModuleValidateSetCountError' + Write-Error ($localizedData[$errorId] -f $property.Name) ` + -ErrorId $errorId -ErrorAction Continue + if($errorIdRef) + { + $errorIdRef.Value = $errorId + } + return $false + } + + foreach ($item in $enumValues) + { + $index = [Array]::IndexOf($property.Values, $item.ToString()) + + if ($index -lt 0 -or $property.ValueMap[$index] -ne $item.value__) + { + $errorId = 'SchemaModuleValidateSetItemError' + Write-Error ($localizedData[$errorId] -f $property.Name,$item.ToString()) ` + -ErrorId $errorId -ErrorAction Continue + if($errorIdRef) + { + $errorIdRef.Value = $errorId + } + return $false + } + } + + return $true + } + elseif ($property.Values -xor $parameterValidateSet) + { + $errorId = 'SchemaModuleValidateSetDiscrepancyError' + Write-Error ($localizedData[$errorId] -f $property.Name) ` + -ErrorId $errorId -ErrorAction Continue + if ($errorIdRef) + { + $errorIdRef.Value = $errorId + } + return $false + } + elseif (-not $property.Values -and -not $parameterValidateSet) { # both are null return $true @@ -2113,28 +2113,28 @@ function Test-ParameterMetaDataIsDscResourceProperty { #compare the two lists - $set = $property.Values - if ($property.ValueMap) { $set = $property.ValueMap } - - if ($set.Count -ne $parameterValidateSet.Count) + $set = $property.Values + if ($property.ValueMap) { $set = $property.ValueMap } + + if ($set.Count -ne $parameterValidateSet.Count) { - $errorId = 'SchemaModuleValidateSetCountError' + $errorId = 'SchemaModuleValidateSetCountError' Write-Error ($localizedData[$errorId] -f $property.Name) ` - -ErrorId $errorId -ErrorAction Continue + -ErrorId $errorId -ErrorAction Continue if($errorIdRef) { $errorIdRef.Value = $errorId } return $false } - - foreach ($item in $set) + + foreach ($item in $set) { if (-not $parameterValidateSet.Contains($item)) { - $errorId = 'SchemaModuleValidateSetItemError' + $errorId = 'SchemaModuleValidateSetItemError' Write-Error ($localizedData[$errorId] -f $property.Name,$item.ToString()) ` - -ErrorId $errorId -ErrorAction Continue + -ErrorId $errorId -ErrorAction Continue if($errorIdRef) { $errorIdRef.Value = $errorId @@ -2174,30 +2174,30 @@ function Test-SchemaProperty ) # Pass back that this property was marked as Key - if ($cimProperty.Qualifiers['Key']) + if ($cimProperty.Qualifiers['Key']) { $HasKeyRef.Value = $true } - if (-not ($cimProperty.Qualifiers['Key'] -or $CimProperty.Qualifiers['Required'] ` - -or $CimProperty.Qualifiers['Write'] -or $CimProperty.Qualifiers['Read'])) + if (-not ($cimProperty.Qualifiers['Key'] -or $CimProperty.Qualifiers['Required'] ` + -or $CimProperty.Qualifiers['Write'] -or $CimProperty.Qualifiers['Read'])) { - $errorId = 'MissingAttributeError' + $errorId = 'MissingAttributeError' Write-Error ($localizedData[$errorId] -f $CimProperty.Name) ` -ErrorId $errorId -ErrorAction Continue $ErrorIdsRef.Value += $errorId } - elseif ($CimProperty.Qualifiers['Read'] -and ($cimProperty.Qualifiers['Key'] -or $CimProperty.Qualifiers['Required'] ` - -or $CimProperty.Qualifiers['Write'])) + elseif ($CimProperty.Qualifiers['Read'] -and ($cimProperty.Qualifiers['Key'] -or $CimProperty.Qualifiers['Required'] ` + -or $CimProperty.Qualifiers['Write'])) { - $errorId = 'IllegalAttributeCombinationError' + $errorId = 'IllegalAttributeCombinationError' Write-Error ($localizedData[$errorId] -f $CimProperty.Name) ` -ErrorId $errorId -ErrorAction Continue $ErrorIdsRef.Value += $errorId } - elseif ($CimProperty.Qualifiers['Key'] -and $CimProperty.Qualifiers['EmbeddedInstance']) + elseif ($CimProperty.Qualifiers['Key'] -and $CimProperty.Qualifiers['EmbeddedInstance']) { - $errorId = 'IllegalAttributeCombinationError' + $errorId = 'IllegalAttributeCombinationError' Write-Error ($localizedData[$errorId] -f $CimProperty.Name) ` -ErrorId $errorId -ErrorAction Continue $ErrorIdsRef.Value += $errorId @@ -2212,27 +2212,27 @@ function Test-SchemaProperty if ($isArray) { - $simplifiedType = $Matches[1]+'[]' + $simplifiedType = $Matches[1]+'[]' } - $type = $null + $type = $null if (-not $TypeMap.ContainsKey($simplifiedType)) { - $errorId = 'UnsupportedMofTypeError' + $errorId = 'UnsupportedMofTypeError' Write-Error ($localizedData[$errorId] -f $CimProperty.Name,$CimProperty.CimType.ToString()) ` -ErrorId $errorId -ErrorAction Continue - $ErrorIdsRef.Value += $errorId + $ErrorIdsRef.Value += $errorId + } + else + { + $type = $TypeMap[$simplifiedType] } - else - { - $type = $TypeMap[$simplifiedType] - } - if ($CimProperty.Qualifiers['ValueMap'] -or $CimProperty.Qualifiers['Values']) + if ($CimProperty.Qualifiers['ValueMap'] -or $CimProperty.Qualifiers['Values']) { - $ValueMap = $CimProperty.Qualifiers['ValueMap'].Value - $Values = $CimProperty.Qualifiers['Values'].Value + $ValueMap = $CimProperty.Qualifiers['ValueMap'].Value + $Values = $CimProperty.Qualifiers['Values'].Value $error = $false @@ -2242,14 +2242,14 @@ function Test-SchemaProperty { $error = $true } - elseif ($simplifiedType -like 'String*') + elseif ($simplifiedType -like 'String*') { - # We only do this test for String properties. Enums that map string names to numeric values (and so don't have - # identical values / valuemap arrays) are acceptable. - - # TODO: Should we also allow for valuemaps that map strings to other strings? This is legal in WMI, though - # uncommon and perhaps not a use case that anyone cares about for DSC. - + # We only do this test for String properties. Enums that map string names to numeric values (and so don't have + # identical values / valuemap arrays) are acceptable. + + # TODO: Should we also allow for valuemaps that map strings to other strings? This is legal in WMI, though + # uncommon and perhaps not a use case that anyone cares about for DSC. + for ($i = 0; $i -lt $ValueMap.Count; $i++) { # Make sure the values contained in ValueMap and Values are identical @@ -2260,35 +2260,35 @@ function Test-SchemaProperty } } } - elseif ($null -ne $type) - { - foreach ($mappedValue in $ValueMap) - { - if ($null -eq ($mappedValue -as $type)) - { - $errorId = 'ValueMapTypeMismatch' - Write-Error ($localizedData[$errorId] -f $CimProperty.Name, $mappedValue, $simplifiedType) ` - -ErrorId $errorId -ErrorAction Continue - $ErrorIdsRef.Value += $errorId - } - } - } - + elseif ($null -ne $type) + { + foreach ($mappedValue in $ValueMap) + { + if ($null -eq ($mappedValue -as $type)) + { + $errorId = 'ValueMapTypeMismatch' + Write-Error ($localizedData[$errorId] -f $CimProperty.Name, $mappedValue, $simplifiedType) ` + -ErrorId $errorId -ErrorAction Continue + $ErrorIdsRef.Value += $errorId + } + } + } + if ($error) { - $errorId = 'ValueMapValuesPairError' + $errorId = 'ValueMapValuesPairError' Write-Error ($localizedData[$errorId] -f ($CimProperty.Name)) ` -ErrorId $errorId -ErrorAction Continue - $ErrorIdsRef.Value += $errorId + $ErrorIdsRef.Value += $errorId } } - if ($CimProperty.Qualifiers['EmbeddedInstance'] ` - -and (($CimProperty.Qualifiers['EmbeddedInstance'].Value -eq 'MSFT_Credential') ` - -or ($CimProperty.Qualifiers['EmbeddedInstance'].Value -eq 'MSFT_KeyValuePair')) ` - -and (($CimProperty.CimType -ne 'String') -and ($CimProperty.CimType -ne 'StringArray'))) + if ($CimProperty.Qualifiers['EmbeddedInstance'] ` + -and (($CimProperty.Qualifiers['EmbeddedInstance'].Value -eq 'MSFT_Credential') ` + -or ($CimProperty.Qualifiers['EmbeddedInstance'].Value -eq 'MSFT_KeyValuePair')) ` + -and (($CimProperty.CimType -ne 'String') -and ($CimProperty.CimType -ne 'StringArray'))) { - $errorId = 'EmbeddedInstanceCimTypeError' + $errorId = 'EmbeddedInstanceCimTypeError' Write-Error ($localizedData[$errorId] -f $CimProperty.Name) ` -ErrorId $errorId -ErrorAction Continue $ErrorIdsRef.Value += $errorId @@ -2318,141 +2318,141 @@ function Test-MockSchema $errorIdsRef ) - try - { - # Returns full path to a 0 byte .tmp file - $tempFilePath = [IO.Path]::GetTempFileName() - - $tempFolderPath = [IO.Path]::GetDirectoryName($tempFilePath) - - # Extracts the .tmp name - $newSchemaName = [IO.Path]::GetFileNameWithoutExtension($tempFilePath) - - # We can now use the temp file name to create a new unique file - Remove-Item $tempFilePath - - $newSchemaPath = "$tempFolderPath\$newSchemaName.schema.mof" - - $null = New-Item $newSchemaPath -ItemType File - - $null = [IO.Path]::GetFileNameWithoutExtension($Schema) -cmatch '(.+)\.schema' - $schemaName = $Matches[1] - - # Initialize this to correct; it will be overwritten if incorrect - $className = $schemaName - - $extendsOMI = $false - - Get-Content $Schema | % { - $newLine = $_ - - # Match to grab class name without grabbing ": OMI_BaseResource" - # \w - is the current regex for class names - if ($_ -cmatch '^class\s+([\w-&\(\)\[\]]+)\s*:?') - { - $className = $Matches[1] - } - - if ($_ -cmatch "^class\s+$className\s*:\s*OMI_BaseResource") - { - $extendsOMI = $true - $newLine = $_ -replace $Matches[0],"class $newSchemaName" - } - - Add-Content $newSchemaPath $newLine - } - - if (-not $extendsOMI -or ($schemaName -ne $className)) - { - $errorIds = @() - - if (-not $extendsOMI) - { - $errorId = 'MissingOMI_BaseResourceError' - $errorIds += $errorId - Write-Error ($localizedData[$errorId] -f $schemaName) ` - -ErrorId $errorId -ErrorAction Continue - } - - if ($schemaName -ne $className) - { - $errorId = 'ClassNameSchemaNameDifferentError' - $errorIds += $errorId - Write-Error ($localizedData[$errorId] -f $className,$schemaName) ` - -ErrorId $errorId -ErrorAction Continue - } - - if ($errorIdsRef) - { - $errorIdsRef.Value = $errorIds - } - return ($errorIds.Length -eq 0) - } - - $parseResult = mofcomp.exe -N:root\microsoft\windows\DesiredStateConfiguration -class:forceupdate $newSchemaPath - - # This shouldn't happen because mofcomp.exe -check is run previously - if ($LASTEXITCODE -ne 0) - { - $errorIds = @() - $errorId = 'SchemaParseError' - - - $parseText = New-Object -TypeName System.Text.StringBuilder - - $parseResult | % { - Add-StringBuilderLine $parseText $_ - } - - Write-Error ($parseText.ToString()) ` - -ErrorId $errorId -ErrorAction Continue - $errorIds += $errorId - - if ($errorIdsRef) - { - $errorIdsRef.Value = $errorIds - } - return ($errorIds.Length -eq 0) - } - - - $SchemaCimClass.Value = Get-CimClass -Namespace root\microsoft\windows\DesiredStateConfiguration -ClassName $newSchemaName -ErrorAction Continue -ErrorVariable ev - - if ($ev) - { - $errorIds = @() - $errorId = 'GetCimClass-Error' - - # Let Get-CimClass display its error, then report the error - - Write-Error ($localizedData[$errorId] -f $schemaName) ` - -ErrorId $errorId -ErrorAction Continue - $errorIds += $errorId - - if ($errorIdsRef) - { - $errorIdsRef.Value = $errorIds - } - return ($errorIds.Length -eq 0) - } - - $hasKey = $false + try + { + # Returns full path to a 0 byte .tmp file + $tempFilePath = [IO.Path]::GetTempFileName() + + $tempFolderPath = [IO.Path]::GetDirectoryName($tempFilePath) + + # Extracts the .tmp name + $newSchemaName = [IO.Path]::GetFileNameWithoutExtension($tempFilePath) + + # We can now use the temp file name to create a new unique file + Remove-Item $tempFilePath + + $newSchemaPath = "$tempFolderPath\$newSchemaName.schema.mof" + + $null = New-Item $newSchemaPath -ItemType File + + $null = [IO.Path]::GetFileNameWithoutExtension($Schema) -cmatch '(.+)\.schema' + $schemaName = $Matches[1] + + # Initialize this to correct; it will be overwritten if incorrect + $className = $schemaName + + $extendsOMI = $false + + Get-Content $Schema | % { + $newLine = $_ + + # Match to grab class name without grabbing ": OMI_BaseResource" + # \w - is the current regex for class names + if ($_ -cmatch '^class\s+([\w-&\(\)\[\]]+)\s*:?') + { + $className = $Matches[1] + } + + if ($_ -cmatch "^class\s+$className\s*:\s*OMI_BaseResource") + { + $extendsOMI = $true + $newLine = $_ -replace $Matches[0],"class $newSchemaName" + } + + Add-Content $newSchemaPath $newLine + } + + if (-not $extendsOMI -or ($schemaName -ne $className)) + { + $errorIds = @() + + if (-not $extendsOMI) + { + $errorId = 'MissingOMI_BaseResourceError' + $errorIds += $errorId + Write-Error ($localizedData[$errorId] -f $schemaName) ` + -ErrorId $errorId -ErrorAction Continue + } + + if ($schemaName -ne $className) + { + $errorId = 'ClassNameSchemaNameDifferentError' + $errorIds += $errorId + Write-Error ($localizedData[$errorId] -f $className,$schemaName) ` + -ErrorId $errorId -ErrorAction Continue + } + + if ($errorIdsRef) + { + $errorIdsRef.Value = $errorIds + } + return ($errorIds.Length -eq 0) + } + + $parseResult = mofcomp.exe -N:root\microsoft\windows\DesiredStateConfiguration -class:forceupdate $newSchemaPath + + # This shouldn't happen because mofcomp.exe -check is run previously + if ($LASTEXITCODE -ne 0) + { + $errorIds = @() + $errorId = 'SchemaParseError' + + + $parseText = New-Object -TypeName System.Text.StringBuilder + + $parseResult | % { + Add-StringBuilderLine $parseText $_ + } + + Write-Error ($parseText.ToString()) ` + -ErrorId $errorId -ErrorAction Continue + $errorIds += $errorId + + if ($errorIdsRef) + { + $errorIdsRef.Value = $errorIds + } + return ($errorIds.Length -eq 0) + } + + + $SchemaCimClass.Value = Get-CimClass -Namespace root\microsoft\windows\DesiredStateConfiguration -ClassName $newSchemaName -ErrorAction Continue -ErrorVariable ev + + if ($ev) + { + $errorIds = @() + $errorId = 'GetCimClass-Error' + + # Let Get-CimClass display its error, then report the error + + Write-Error ($localizedData[$errorId] -f $schemaName) ` + -ErrorId $errorId -ErrorAction Continue + $errorIds += $errorId + + if ($errorIdsRef) + { + $errorIdsRef.Value = $errorIds + } + return ($errorIds.Length -eq 0) + } + + $hasKey = $false $errorIds = @() - - $SchemaCimClass.Value.CimClassProperties | % { - - $null = Test-SchemaProperty $_ ([ref]$hasKey) ([ref]$errorIds) - - } - - if (-not $hasKey) - { - $errorId = 'NoKeyTestError' - Write-Error ($localizedData[$errorId]) ` - -ErrorId $errorId -ErrorAction Continue - $errorIds += $errorId - } + + $SchemaCimClass.Value.CimClassProperties | % { + + $null = Test-SchemaProperty $_ ([ref]$hasKey) ([ref]$errorIds) + + } + + if (-not $hasKey) + { + $errorId = 'NoKeyTestError' + Write-Error ($localizedData[$errorId]) ` + -ErrorId $errorId -ErrorAction Continue + $errorIds += $errorId + } if ($errorIdsRef) { @@ -2460,11 +2460,11 @@ function Test-MockSchema } return ($errorIds.Length -eq 0) } - finally + finally { Remove-WmiObject -Class $newSchemaName -Namespace root\microsoft\windows\DesiredStateConfiguration -ErrorAction SilentlyContinue Remove-Item $newSchemaPath -ErrorAction SilentlyContinue - } + } } # Given the path to a Schema.Mof file, check to see if has the BOM for UTF8 @@ -2472,7 +2472,7 @@ function Test-MockSchema # Otherwise, return true function Test-cDscSchemaEncoding { - [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] + [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] param ( [parameter( @@ -2492,17 +2492,17 @@ function Test-cDscSchemaEncoding -and ($schemaBytes[2] -eq 191)) { #Prompt the user to re-encode their schema as Unicode... - if ($pscmdlet.ShouldProcess($Schema, $localizedData['SchemaEncodingNotSupportedPrompt'])) + if ($pscmdlet.ShouldProcess($Schema, $localizedData['SchemaEncodingNotSupportedPrompt'])) { - Write-Verbose $localizedData['SchemaFileReEncodingVerbose'] + Write-Verbose $localizedData['SchemaFileReEncodingVerbose'] - $schemaContent = Get-Content $Schema + $schemaContent = Get-Content $Schema $schemaContent | Out-File -Encoding unicode $Schema -Force } #Otherwise fail else { - Write-Error $localizedData['SchemaEncodingNotSupportedError'] -ErrorAction Continue + Write-Error $localizedData['SchemaEncodingNotSupportedError'] -ErrorAction Continue return $false } } @@ -2566,19 +2566,19 @@ function Test-cDscSchemaInternal if ($ev -or -not $goodPath -or -not($Schema -cmatch ".*\.schema\.mof$")) { - $errorId = 'BadSchemaPath' + $errorId = 'BadSchemaPath' Write-Error ($localizedData[$errorId]) ` -ErrorId $errorId -ErrorAction Continue - + if ($errorIdsRef) { $errorIdsRef.Value = @() $errorIdsRef.Value += $errorId } - + return $false } - Write-Verbose ($localizedData['SchemaPathValidVerbose']) + Write-Verbose ($localizedData['SchemaPathValidVerbose']) if (-not (Test-cDscSchemaEncoding $Schema)) { @@ -2587,17 +2587,17 @@ function Test-cDscSchemaInternal $filename = [IO.Path]::GetFileName($Schema) $null = $filename -cmatch "^(.*)\.schema\.mof$" - $SchemaName = $Matches[1] + $SchemaName = $Matches[1] $parseResult = mofcomp.exe -Check $Schema - + if ($LASTEXITCODE -ne 0) { $errorIds = @() - $errorId = 'SchemaParseError' + $errorId = 'SchemaParseError' $parseText = New-Object -TypeName System.Text.StringBuilder - + $parseResult | % { Add-StringBuilderLine $parseText $_ } @@ -2614,8 +2614,8 @@ function Test-cDscSchemaInternal } return $false } - - Write-Verbose ($localizedData['SchemaMofCompCheckVerbose']) + + Write-Verbose ($localizedData['SchemaMofCompCheckVerbose']) # If used just to test the schema, they don't need the cimClass if (-not $SchemaCimClass) @@ -2624,7 +2624,7 @@ function Test-cDscSchemaInternal $SchemaCimClass = ([ref]$temp) } - Write-Verbose ($localizedData['SchemaDscContractsVerbose']) + Write-Verbose ($localizedData['SchemaDscContractsVerbose']) if ($errorIdsRef) { return (Test-MockSchema $Schema $SchemaCimClass -errorIdsRef $errorIdsRef) @@ -2669,170 +2669,170 @@ function Test-DscResourceModule $errorIdsRef ) - try - { - $ev = $null - $goodPath = Test-Path $Module -PathType Leaf -ErrorVariable ev -ErrorAction Continue - - if ($ev -or -not $goodPath -or ([IO.Path]::GetExtension($Module) -ne '.psm1' -and [IO.Path]::GetExtension($Module) -ne '.dll')) - { - $errorIds = @() - $errorId = 'BadResourceModulePath' - - Write-Error ($localizedData[$errorId]) ` - -ErrorId $errorId -ErrorAction Continue - $errorIds += $errorId - - if ($errorIdsRef) - { - $errorIdsRef.Value = $errorIds - } - return $false - } - - $ModuleName = [IO.Path]::GetFileNameWithoutExtension($Module) - - $Prefix = [IO.Path]::GetRandomFileName() - - $ev = $null - - Import-Module $Module -Prefix $Prefix -Force -NoClobber -ErrorVariable ev -ErrorAction Continue - - if ($ev) - { - $errorIds = @() - $errorId = 'ImportResourceModuleError' - Write-Error ($localizedData[$errorId]) ` - -ErrorId $errorId -ErrorAction Continue - $errorIds += $errorId - - if ($errorIdsRef) - { - $errorIdsRef.Value = $errorIds - } - return $false - } - - - - $undefinedFunctions = @() - - $ev = $null - - $GetCommandInfo.Value = Get-Command ('Get-' + $Prefix + 'TargetResource') -Module $ModuleName -ErrorAction SilentlyContinue -ErrorVariable ev - - if ($GetCommandInfo.Value -eq $null -or $ev) - { - $undefinedFunctions += 'Get-TargetResource' - } - - $ev = $null - - $SetCommandInfo.Value = Get-Command ('Set-' + $Prefix + 'TargetResource') -Module $ModuleName -ErrorAction SilentlyContinue -ErrorVariable ev - - if ($SetCommandInfo.Value -eq $null -or $ev) - { - $undefinedFunctions += 'Set-TargetResource' - } - - $ev = $null - - $TestCommandInfo.Value = Get-Command ('Test-' + $Prefix + 'TargetResource') -Module $ModuleName -ErrorAction SilentlyContinue -ErrorVariable ev - - if ($TestCommandInfo.Value -eq $null -or $ev) - { - $undefinedFunctions += 'Test-TargetResource' - } - - if ($undefinedFunctions.Length -gt 0) - { - $errorIds = @() - $errorId = 'KeyFunctionsNotDefined' - Write-Error ($localizedData[$errorId] -f (New-DelimitedList $undefinedFunctions -Separator ', ')) ` - -ErrorId $errorId -ErrorAction Continue - $errorIds += $errorId - - if ($errorIdsRef) - { - $errorIdsRef.Value = $errorIds - } - return $false - } + try + { + $ev = $null + $goodPath = Test-Path $Module -PathType Leaf -ErrorVariable ev -ErrorAction Continue + + if ($ev -or -not $goodPath -or ([IO.Path]::GetExtension($Module) -ne '.psm1' -and [IO.Path]::GetExtension($Module) -ne '.dll')) + { + $errorIds = @() + $errorId = 'BadResourceModulePath' + + Write-Error ($localizedData[$errorId]) ` + -ErrorId $errorId -ErrorAction Continue + $errorIds += $errorId + + if ($errorIdsRef) + { + $errorIdsRef.Value = $errorIds + } + return $false + } + + $ModuleName = [IO.Path]::GetFileNameWithoutExtension($Module) + + $Prefix = [IO.Path]::GetRandomFileName() + + $ev = $null + + Import-Module $Module -Prefix $Prefix -Force -NoClobber -ErrorVariable ev -ErrorAction Continue + + if ($ev) + { + $errorIds = @() + $errorId = 'ImportResourceModuleError' + Write-Error ($localizedData[$errorId]) ` + -ErrorId $errorId -ErrorAction Continue + $errorIds += $errorId + + if ($errorIdsRef) + { + $errorIdsRef.Value = $errorIds + } + return $false + } + + + + $undefinedFunctions = @() + + $ev = $null + + $GetCommandInfo.Value = Get-Command ('Get-' + $Prefix + 'TargetResource') -Module $ModuleName -ErrorAction SilentlyContinue -ErrorVariable ev + + if ($GetCommandInfo.Value -eq $null -or $ev) + { + $undefinedFunctions += 'Get-TargetResource' + } + + $ev = $null + + $SetCommandInfo.Value = Get-Command ('Set-' + $Prefix + 'TargetResource') -Module $ModuleName -ErrorAction SilentlyContinue -ErrorVariable ev + + if ($SetCommandInfo.Value -eq $null -or $ev) + { + $undefinedFunctions += 'Set-TargetResource' + } + + $ev = $null + + $TestCommandInfo.Value = Get-Command ('Test-' + $Prefix + 'TargetResource') -Module $ModuleName -ErrorAction SilentlyContinue -ErrorVariable ev + + if ($TestCommandInfo.Value -eq $null -or $ev) + { + $undefinedFunctions += 'Test-TargetResource' + } + + if ($undefinedFunctions.Length -gt 0) + { + $errorIds = @() + $errorId = 'KeyFunctionsNotDefined' + Write-Error ($localizedData[$errorId] -f (New-DelimitedList $undefinedFunctions -Separator ', ')) ` + -ErrorId $errorId -ErrorAction Continue + $errorIds += $errorId + + if ($errorIdsRef) + { + $errorIdsRef.Value = $errorIds + } + return $false + } $errorIds = @() - if (-not $GetCommandInfo.Value.OutputType) - { - Write-Warning $localizedData['GetTargetResourceOutWarning'] - } - - if ($GetCommandInfo.Value.OutputType -and $GetCommandInfo.Value.OutputType.Type -ne [Hashtable]) - { - $errorId = 'GetTargetResourceOutError' - Write-Error ($localizedData[$errorId]) ` - -ErrorId $errorId -ErrorAction Continue - $errorIds += $errorId - } - - #Set should not have an output type - if ($SetCommandInfo.Value.OutputType) - { - $errorId = 'SetTargetResourceOutError' - Write-Error ($localizedData[$errorId]) ` - -ErrorId $errorId -ErrorAction Continue - $errorIds += $errorId - } - - if (-not $TestCommandInfo.Value.OutputType) - { - Write-Warning $localizedData['TestTargetResourceOutWarning'] - } - if ($TestCommandInfo.Value.OutputType -and $TestCommandInfo.Value.OutputType.Type -ne [Boolean]) - { - $errorId = 'TestTargetResourceOutError' - Write-Error ($localizedData[$errorId]) ` - -ErrorId $errorId -ErrorAction Continue - $errorIds += $errorId - } - - #Make sure each has at least one mandatory property that isnt an array - # and that it only has parameters of valid types - - $getErrors = @() - $setErrors = @() - $testErrors = @() - - $null = Test-BasicDscFunction $GetCommandInfo.Value 'Get-TargetResource' -errorIdsRef ([ref]$getErrors) - $errorIds += $getErrors - $null = Test-BasicDscFunction $SetCommandInfo.Value 'Set-TargetResource' -errorIdsRef ([ref]$setErrors) - $errorIds += $setErrors - $null = Test-BasicDscFunction $TestCommandInfo.Value 'Test-TargetResource' -errorIdsRef ([ref]$testErrors) - $errorIds += $testErrors - - - # Set == Test - - $setTestErrors = @() - - $null = Test-SetTestIdentical $SetCommandInfo.Value $TestCommandInfo.Value -errorIdsRef ([ref]$setTestErrors) - $errorIds += $setTestErrors - - - # Get is subset of Set/Test - # Only check this if Test-SetTestIdentical succeeds, so we only need to compare against Set - if ($errorIds.Count -eq 0) - { - $getSubsetErrors = @() - $null = Test-GetSubsetSet $GetCommandInfo.Value $SetCommandInfo.Value -errorIdsRef ([ref]$getSubsetErrors) - $errorIds += $getSubsetErrors - } - - if ($errorIdsRef) - { - $errorIdsRef.Value = $errorIds - } - - return $errorIds.Count -eq 0 + if (-not $GetCommandInfo.Value.OutputType) + { + Write-Warning $localizedData['GetTargetResourceOutWarning'] + } + + if ($GetCommandInfo.Value.OutputType -and $GetCommandInfo.Value.OutputType.Type -ne [Hashtable]) + { + $errorId = 'GetTargetResourceOutError' + Write-Error ($localizedData[$errorId]) ` + -ErrorId $errorId -ErrorAction Continue + $errorIds += $errorId + } + + #Set should not have an output type + if ($SetCommandInfo.Value.OutputType) + { + $errorId = 'SetTargetResourceOutError' + Write-Error ($localizedData[$errorId]) ` + -ErrorId $errorId -ErrorAction Continue + $errorIds += $errorId + } + + if (-not $TestCommandInfo.Value.OutputType) + { + Write-Warning $localizedData['TestTargetResourceOutWarning'] + } + if ($TestCommandInfo.Value.OutputType -and $TestCommandInfo.Value.OutputType.Type -ne [Boolean]) + { + $errorId = 'TestTargetResourceOutError' + Write-Error ($localizedData[$errorId]) ` + -ErrorId $errorId -ErrorAction Continue + $errorIds += $errorId + } + + #Make sure each has at least one mandatory property that isnt an array + # and that it only has parameters of valid types + + $getErrors = @() + $setErrors = @() + $testErrors = @() + + $null = Test-BasicDscFunction $GetCommandInfo.Value 'Get-TargetResource' -errorIdsRef ([ref]$getErrors) + $errorIds += $getErrors + $null = Test-BasicDscFunction $SetCommandInfo.Value 'Set-TargetResource' -errorIdsRef ([ref]$setErrors) + $errorIds += $setErrors + $null = Test-BasicDscFunction $TestCommandInfo.Value 'Test-TargetResource' -errorIdsRef ([ref]$testErrors) + $errorIds += $testErrors + + + # Set == Test + + $setTestErrors = @() + + $null = Test-SetTestIdentical $SetCommandInfo.Value $TestCommandInfo.Value -errorIdsRef ([ref]$setTestErrors) + $errorIds += $setTestErrors + + + # Get is subset of Set/Test + # Only check this if Test-SetTestIdentical succeeds, so we only need to compare against Set + if ($errorIds.Count -eq 0) + { + $getSubsetErrors = @() + $null = Test-GetSubsetSet $GetCommandInfo.Value $SetCommandInfo.Value -errorIdsRef ([ref]$getSubsetErrors) + $errorIds += $getSubsetErrors + } + + if ($errorIdsRef) + { + $errorIdsRef.Value = $errorIds + } + + return $errorIds.Count -eq 0 } finally { @@ -2866,25 +2866,25 @@ function Test-GetSubsetSet $commonParameterError = $false - $getCommandMetadata = [System.Management.Automation.CommandMetadata]$getCommandInfo - + $getCommandMetadata = [System.Management.Automation.CommandMetadata]$getCommandInfo + foreach ($parameter in $getCommandInfo.Parameters.Values) { - + if (-not $setCommandInfo.Parameters.Keys.Contains($parameter.Name)) { - if (IsCommonParameter -Name $parameter.Name -Metadata $getCommandMetadata) + if (IsCommonParameter -Name $parameter.Name -Metadata $getCommandMetadata) { # Ignore Verbose,ErrorAction, etc # We can't report that Set doesnt contain $commonParameter X # because neither function actually "contains" it # It indicates an error elsewhere though - # so we'll make sure an error is reported. - $commonParameterError = $true + # so we'll make sure an error is reported. + $commonParameterError = $true } else { - $errorId = 'SetTestMissingGetParameterError' + $errorId = 'SetTestMissingGetParameterError' Write-Error ($localizedData[$errorId] -f $parameter.Name) ` -ErrorId $errorId -ErrorAction Continue $errorIds += $errorId @@ -2892,23 +2892,23 @@ function Test-GetSubsetSet continue; } - + $identicalParametersErrors = @() $null = Test-ParametersAreIdentical ` - $parameter 'Get-TargetResource' ` - $setCommandInfo.Parameters[$parameter.Name] 'Set-TargetResource' ` + $parameter 'Get-TargetResource' ` + $setCommandInfo.Parameters[$parameter.Name] 'Set-TargetResource' ` -errorIdsRef ([ref]$identicalParametersErrors) - + $errorIds += $identicalParametersErrors - + } #Report the top level rule about all Get Parameters # being represented in Set and Tests if ($errorIds.Count -ne 0) { - $errorId = 'GetParametersDifferentError' + $errorId = 'GetParametersDifferentError' Write-Error ($localizedData[$errorId]) ` -ErrorId $errorId -ErrorAction Continue $errorIds += $errorId @@ -2953,31 +2953,31 @@ function Test-ParametersAreIdentical [ref] $errorIdsRef ) - + $errorIds = @() - + if (-not (Test-ParametersValidateSet $parameterA $parameterB)) { - $errorId = 'ModuleValidateSetError' + $errorId = 'ModuleValidateSetError' Write-Error ($localizedData[$errorId] -f $parameterA.Name,$functionA,$functionB) ` -ErrorId $errorId -ErrorAction Continue $errorIds += $errorId } - - + + if ((Test-ParameterIsMandatory $parameterA) -xor (Test-ParameterIsMandatory $parameterB)) { - $errorId = 'ModuleMandatoryError' + $errorId = 'ModuleMandatoryError' Write-Error ($localizedData[$errorId] -f $parameterA.Name,$functionA,$functionB) ` -ErrorId $errorId -ErrorAction Continue $errorIds += $errorId } - + if ($parameterA.ParameterType -ne $parameterB.ParameterType) { - $errorId = 'ModuleTypeError' + $errorId = 'ModuleTypeError' Write-Error ($localizedData[$errorId] -f $parameterA.Name,$functionA,$functionB) ` -ErrorId $errorId -ErrorAction Continue $errorIds += $errorId @@ -3030,18 +3030,18 @@ function Test-ParametersValidateSet $parameter2 ) - + $a = Get-ValidateSet $parameter1 $b = Get-ValidateSet $parameter2 - + if ((-not $a) -and (-not $b)) { return $true } elseif ($a -and $b) { - + if ($a.Count -ne $b.Count) { @@ -3110,29 +3110,29 @@ function Test-BasicDscFunction $errorIds = @() - $metadata = [System.Management.Automation.CommandMetadata]$command - - # This would be a mandatory, non-array parameter + $metadata = [System.Management.Automation.CommandMetadata]$command + + # This would be a mandatory, non-array parameter $hasValidKey = $false foreach ($parameter in $command.Parameters.Values) { - if (IsCommonParameter -Name $parameter.Name -Metadata $metadata) + if (IsCommonParameter -Name $parameter.Name -Metadata $metadata) { continue; } - $typeToFind = $parameter.ParameterType - if ($typeToFind.IsEnum) - { - $typeToFind = $typeToFind.GetEnumUnderlyingType() - } - - if (-not $TypeMap.ContainsValue($typeToFind)) + $typeToFind = $parameter.ParameterType + if ($typeToFind.IsEnum) + { + $typeToFind = $typeToFind.GetEnumUnderlyingType() + } + + if (-not $TypeMap.ContainsValue($typeToFind)) { if ($parameter.ParameterType.tostring() -notmatch 'Microsoft\.Management\.Infrastructure\.CimInstance') { - $errorId = 'UnsupportedTypeError' + $errorId = 'UnsupportedTypeError' Write-Error ($localizedData[$errorId] -f ` $commandName,$parameter.ParameterType,$parameter.Name) ` -ErrorId $errorId -ErrorAction Continue @@ -3148,7 +3148,7 @@ function Test-BasicDscFunction if (-not $hasValidKey) { - $errorId = 'NoKeyPropertyError' + $errorId = 'NoKeyPropertyError' Write-Error ($localizedData[$errorId] -f $commandName) ` -ErrorId $errorId -ErrorAction Continue $errorIds += $errorId @@ -3186,32 +3186,32 @@ function Test-SetTestIdentical $errorIdsRef ) - $errorId = 'NoError' - - $setCommandMetadata = [System.Management.Automation.CommandMetadata]$setCommand - $testCommandMetadata = [System.Management.Automation.CommandMetadata]$testCommand - - $setParametersToTest = $setCommand.Parameters.Values.Where({ -not (IsCommonParameter -Name $_.Name -Metadata $setCommandMetadata) }) - $testParametersToTest = $testCommand.Parameters.Values.Where({ -not (IsCommonParameter -Name $_.Name -Metadata $testCommandMetadata) }) + $errorId = 'NoError' - if ($setParametersToTest -eq 0 -and $testParametersToTest -eq 0) + $setCommandMetadata = [System.Management.Automation.CommandMetadata]$setCommand + $testCommandMetadata = [System.Management.Automation.CommandMetadata]$testCommand + + $setParametersToTest = $setCommand.Parameters.Values.Where({ -not (IsCommonParameter -Name $_.Name -Metadata $setCommandMetadata) }) + $testParametersToTest = $testCommand.Parameters.Values.Where({ -not (IsCommonParameter -Name $_.Name -Metadata $testCommandMetadata) }) + + if ($setParametersToTest -eq 0 -and $testParametersToTest -eq 0) { #This will already have been reported by Test-BasicDscFunction - $errorId = 'NoKeyPropertyError' - + $errorId = 'NoKeyPropertyError' + if($errorIdsRef) { $errorIdsRef.Value = @() $errorIdsRef.Value += $errorId } - + return $false } - + # We can assume that if somebody took time to write a parameter # that is only in one function, - # than it is more likely that they forgot to add it to the other, + # than it is more likely that they forgot to add it to the other, # rather than that it was mistakenly included. # So check the function with more parameters first. @@ -3219,28 +3219,28 @@ function Test-SetTestIdentical $commandWithFewerParameters = $testCommand $commandWithMoreParameters = $setCommand - $moreParametersList = $setParametersToTest - $commandNameWithFewerParameters = 'Test-TargetResource' - $commandNameWithMoreParameters = 'Set-TargetResource' + $moreParametersList = $setParametersToTest + $commandNameWithFewerParameters = 'Test-TargetResource' + $commandNameWithMoreParameters = 'Set-TargetResource' - if ($setParametersToTest.Count -lt $testParametersToTest.Count) + if ($setParametersToTest.Count -lt $testParametersToTest.Count) { $commandWithFewerParameters = $setCommand $commandWithMoreParameters = $testCommand - $moreParametersList = $testParametersToTest - $commandNameWithFewerParameters = 'Set-TargetResource' - $commandNameWithMoreParameters = 'Test-TargetResource' + $moreParametersList = $testParametersToTest + $commandNameWithFewerParameters = 'Set-TargetResource' + $commandNameWithMoreParameters = 'Test-TargetResource' } $errorIds = @() $errorReported = $false # Loop over the longer list, if we find errors, report them then stop - foreach($parameter in $moreParametersList) + foreach($parameter in $moreParametersList) { if (-not $commandWithFewerParameters.Parameters[$parameter.Name]) { - $errorId = 'SetTestMissingParameterError' + $errorId = 'SetTestMissingParameterError' Write-Error ($localizedData[$errorId] -f $commandNameWithFewerParameters,$parameter.Name,$commandNameWithMoreParameters) ` -ErrorId $errorId -ErrorAction Continue $errorIds += $errorId @@ -3258,11 +3258,11 @@ function Test-SetTestIdentical } } - - if ($setParametersToTest.Count -ne $testParametersToTest.Count -and -not $errorReported) + + if ($setParametersToTest.Count -ne $testParametersToTest.Count -and -not $errorReported) { # if the counts are different but we didnt get an error, something is wrong... - $errorId = 'SetTestNotIdenticalError' + $errorId = 'SetTestNotIdenticalError' Write-Error ($localizedData[$errorId]) ` -ErrorId $errorId -ErrorAction Continue $errorIds += $errorId @@ -3270,13 +3270,13 @@ function Test-SetTestIdentical } elseif ($errorReported) # If there is an error, give the Set/Testerror as well { - $errorId = 'SetTestNotIdenticalError' + $errorId = 'SetTestNotIdenticalError' Write-Error ($localizedData[$errorId]) ` -ErrorId $errorId -ErrorAction Continue $errorIds += $errorId } - + if($errorIdsRef) { $errorIdsRef.Value = $errorIds @@ -3287,12 +3287,12 @@ function Test-SetTestIdentical # Throws an exception if New-DscResource or Test-DscResource are run without admin rights. -function Assert-AdminPrivilege +function Assert-AdminPrivilege { - if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole( - [Security.Principal.WindowsBuiltInRole] 'Administrator')) + if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole( + [Security.Principal.WindowsBuiltInRole] 'Administrator')) { - $errorId = 'AdminRightsError' + $errorId = 'AdminRightsError' Write-Error $localizedData[$errorId] ` -ErrorId $errorId -ErrorAction Stop } @@ -3319,9 +3319,9 @@ function Convert-SchemaToResourceProperty -Name $cimProperty.Name ` -Type (Convert-CimType $cimProperty) ` -Attribute (Convert-CimAttribute $cimProperty) ` - -ValueMap $cimProperty.Qualifiers['ValueMap'].Value ` - -Values $cimProperty.Qualifiers['Values'].Value ` - -Description $CimProperty.Qualifiers['Description'].Value ` + -ValueMap $cimProperty.Qualifiers['ValueMap'].Value ` + -Values $cimProperty.Qualifiers['Values'].Value ` + -Description $CimProperty.Qualifiers['Description'].Value ` -ContainsEmbeddedInstance ($null -ne $cimProperty.Qualifiers['EmbeddedInstance']) } @@ -3340,21 +3340,21 @@ function Convert-CimAttribute $CimProperty ) - if ($CimProperty.Qualifiers['Key']) + if ($CimProperty.Qualifiers['Key']) { - return 'Key' + return 'Key' } - elseif ($CimProperty.Qualifiers['Required']) + elseif ($CimProperty.Qualifiers['Required']) { - return 'Required' + return 'Required' } - elseif ($CimProperty.Qualifiers['Write']) + elseif ($CimProperty.Qualifiers['Write']) { - return 'Write' + return 'Write' } else { - return 'Read' + return 'Read' } } @@ -3370,12 +3370,12 @@ function Convert-CimType $CimProperty ) - if (-not $CimProperty.Qualifiers['EmbeddedInstance']) + if (-not $CimProperty.Qualifiers['EmbeddedInstance']) { if ($CimProperty.CimType.ToString() -cmatch "^(.+)Array$") { # If the Type ends with "Array", replace it with "[]" - return ($Matches[1] + '[]') + return ($Matches[1] + '[]') } else { @@ -3384,21 +3384,21 @@ function Convert-CimType } $reverseEmbeddedInstance = @{ - 'MSFT_KeyValuePair' = 'Hashtable'; - 'MSFT_Credential' = 'PSCredential' + 'MSFT_KeyValuePair' = 'Hashtable'; + 'MSFT_Credential' = 'PSCredential' } - $typeName = $reverseEmbeddedInstance[$CimProperty.Qualifiers['EmbeddedInstance'].Value] + $typeName = $reverseEmbeddedInstance[$CimProperty.Qualifiers['EmbeddedInstance'].Value] if (-not $typeName) { - $typeName = 'Microsoft.Management.Infrastructure.CimInstance' + $typeName = 'Microsoft.Management.Infrastructure.CimInstance' } - $arrayAddOn = '' + $arrayAddOn = '' - if ($CimProperty.CimType.ToString().EndsWith('Array')) + if ($CimProperty.CimType.ToString().EndsWith('Array')) { - $arrayAddOn = '[]' + $arrayAddOn = '[]' } return $typeName + $arrayAddOn @@ -3432,7 +3432,7 @@ function Import-cDscSchema return } - Write-Verbose ($localizedData['ImportTestSchemaVerbose']) + Write-Verbose ($localizedData['ImportTestSchemaVerbose']) #If the file passes Test-cDscSchema @@ -3441,46 +3441,46 @@ function Import-cDscSchema $fileName = [IO.Path]::GetFileName($Schema) $null = $fileName -cmatch "^(.*).schema.mof$" - Write-Verbose ($localizedData['ImportReadingPropertiesVerbose']) + Write-Verbose ($localizedData['ImportReadingPropertiesVerbose']) $resourceName = $Matches[1]; - $friendlyName = '' - if ($cimClass.CimClassQualifiers['FriendlyName']) + $friendlyName = '' + if ($cimClass.CimClassQualifiers['FriendlyName']) { - $friendlyName = $cimClass.CimClassQualifiers['FriendlyName'].Value.ToString(); + $friendlyName = $cimClass.CimClassQualifiers['FriendlyName'].Value.ToString(); } - $classVersion = '' - if ($cimClass.CimClassQualifiers['ClassVersion']) + $classVersion = '' + if ($cimClass.CimClassQualifiers['ClassVersion']) { - $classVersion = $cimClass.CimClassQualifiers['ClassVersion'].Value.ToString(); + $classVersion = $cimClass.CimClassQualifiers['ClassVersion'].Value.ToString(); } $properties = Convert-SchemaToResourceProperty $cimClass return @{ - 'ResourceName'=$resourceName; - 'FriendlyName'=$friendlyName; - 'ClassVersion'=$classVersion; - 'DscResourceProperties'=$properties; + 'ResourceName'=$resourceName; + 'FriendlyName'=$friendlyName; + 'ClassVersion'=$classVersion; + 'DscResourceProperties'=$properties; } } -function IsCommonParameter -{ - param ( - [string] $Name, - [System.Management.Automation.CommandMetadata] $Metadata - ) - - if ($null -ne $Metadata) - { - if ([System.Management.Automation.Internal.CommonParameters].GetProperty($Name)) { return $true } - if ($Metadata.SupportsShouldProcess -and [System.Management.Automation.Internal.ShouldProcessParameters].GetProperty($Name)) { return $true } - if ($Metadata.SupportsPaging -and [System.Management.Automation.PagingParameters].GetProperty($Name)) { return $true } - if ($Metadata.SupportsTransactions -and [System.Management.Automation.Internal.TransactionParameters].GetProperty($Name)) { return $true } - } - - return $false -} +function IsCommonParameter +{ + param ( + [string] $Name, + [System.Management.Automation.CommandMetadata] $Metadata + ) + + if ($null -ne $Metadata) + { + if ([System.Management.Automation.Internal.CommonParameters].GetProperty($Name)) { return $true } + if ($Metadata.SupportsShouldProcess -and [System.Management.Automation.Internal.ShouldProcessParameters].GetProperty($Name)) { return $true } + if ($Metadata.SupportsPaging -and [System.Management.Automation.PagingParameters].GetProperty($Name)) { return $true } + if ($Metadata.SupportsTransactions -and [System.Management.Automation.Internal.TransactionParameters].GetProperty($Name)) { return $true } + } + + return $false +}