summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Borean <jborean93@gmail.com>2019-03-06 06:49:37 +1000
committerGitHub <noreply@github.com>2019-03-06 06:49:37 +1000
commit6b294eab4d5b393aecd1946e1e17ea215db8b6d1 (patch)
tree1034902d4220eafa049c783bc176ab1a941b6e8e
parent853a65eead01544acb81dfcbe008f069e84c2752 (diff)
downloadansible-6b294eab4d5b393aecd1946e1e17ea215db8b6d1.tar.gz
win_dsc - Add argument validation and other fixes (#53093)
* win_dsc - Add argument validation and other fixes * Fix doc issues
-rw-r--r--changelogs/fragments/win_dsc-validation.yaml4
-rw-r--r--docs/docsite/rst/porting_guides/porting_guide_2.8.rst2
-rw-r--r--docs/docsite/rst/user_guide/windows_dsc.rst117
-rw-r--r--lib/ansible/modules/windows/win_dsc.ps1564
-rw-r--r--lib/ansible/modules/windows/win_dsc.py40
-rw-r--r--test/integration/targets/win_dsc/defaults/main.yml5
-rw-r--r--test/integration/targets/win_dsc/files/custom-result-normal.txt44
-rw-r--r--test/integration/targets/win_dsc/files/custom-result-versioned.txt44
-rw-r--r--test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xSetReboot/ANSIBLE_xSetReboot.psm141
-rw-r--r--test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xSetReboot/ANSIBLE_xSetReboot.schema.mof7
-rw-r--r--test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.psm1214
-rw-r--r--test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.schema.mof60
-rw-r--r--test/integration/targets/win_dsc/files/xTestDsc/1.0.0/xTestDsc.psd1 (renamed from test/integration/targets/win_dsc/templates/xTestDsc.psd1)7
-rw-r--r--test/integration/targets/win_dsc/files/xTestDsc/1.0.1/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.psm1214
-rw-r--r--test/integration/targets/win_dsc/files/xTestDsc/1.0.1/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.schema.mof63
-rw-r--r--test/integration/targets/win_dsc/files/xTestDsc/1.0.1/xTestDsc.psd113
-rw-r--r--test/integration/targets/win_dsc/filter_plugins/strip_newline.py16
-rw-r--r--test/integration/targets/win_dsc/library/test_win_dsc_iis_info.ps141
-rw-r--r--test/integration/targets/win_dsc/meta/main.yml2
-rw-r--r--test/integration/targets/win_dsc/tasks/destructive.yml135
-rw-r--r--test/integration/targets/win_dsc/tasks/main.yml51
-rw-r--r--test/integration/targets/win_dsc/tasks/smoke.yml8
-rw-r--r--test/integration/targets/win_dsc/tasks/tests.yml675
-rw-r--r--test/integration/targets/win_dsc/templates/ANSIBLE_xTestResource.psm1175
-rw-r--r--test/integration/targets/win_dsc/templates/ANSIBLE_xTestResource.schema.mof25
-rw-r--r--test/sanity/pslint/ignore.txt3
-rw-r--r--test/sanity/pslint/skip.txt5
27 files changed, 1585 insertions, 990 deletions
diff --git a/changelogs/fragments/win_dsc-validation.yaml b/changelogs/fragments/win_dsc-validation.yaml
new file mode 100644
index 0000000000..4664eb6ed1
--- /dev/null
+++ b/changelogs/fragments/win_dsc-validation.yaml
@@ -0,0 +1,4 @@
+minor_changes:
+- win_dsc - The win_dsc module will now fail if an invalid DSC property is set.
+- win_dsc - The module invocation and possible options will be displayed when running with ``-vvv``.
+- win_dsc - The Verbose logs will be returned when running with ``-vvv``.
diff --git a/docs/docsite/rst/porting_guides/porting_guide_2.8.rst b/docs/docsite/rst/porting_guides/porting_guide_2.8.rst
index 4689223d81..cda4ce0704 100644
--- a/docs/docsite/rst/porting_guides/porting_guide_2.8.rst
+++ b/docs/docsite/rst/porting_guides/porting_guide_2.8.rst
@@ -208,6 +208,8 @@ PowerShell module options and option choices are currently case insensitive to w
specification. This behaviour is deprecated and a warning displayed to the user if a case insensitive match was found.
A future release of Ansible will make these checks case sensitive.
+The ``win_dsc`` module will now validate the input options for a DSC resource. In previous versions invalid options would be ignored but are now not.
+
Modules removed
---------------
diff --git a/docs/docsite/rst/user_guide/windows_dsc.rst b/docs/docsite/rst/user_guide/windows_dsc.rst
index 1cacaf00ab..167256ae66 100644
--- a/docs/docsite/rst/user_guide/windows_dsc.rst
+++ b/docs/docsite/rst/user_guide/windows_dsc.rst
@@ -29,7 +29,7 @@ DSC and Ansible modules have a common goal which is to define and ensure the sta
resource. Because of
this, resources like the DSC `File resource <https://docs.microsoft.com/en-us/powershell/dsc/fileresource>`_
and Ansible ``win_file`` can be used to achieve the same result. Deciding which to use depends
-on the scenario.
+on the scenario.
Reasons for using an Ansible module over a DSC resource:
@@ -99,6 +99,67 @@ This is what the Ansible task version of the above DSC Registry resource would l
ValueName: TestValue
ValueData: TestData
+Starting in Ansible 2.8, the ``win_dsc`` module automatically validates the
+input options from Ansible with the DSC definition. This means Ansible will
+fail if the option name is incorrect, a mandatory option is not set, or the
+value is not a valid choice. When running Ansible with a verbosity level of 3
+or more (``-vvv``), the return value will contain the possible invocation
+options based on the ``resource_name`` specified. Here is an example of the
+invocation output for the above ``Registry`` task::
+
+ changed: [2016] => {
+ "changed": true,
+ "invocation": {
+ "module_args": {
+ "DependsOn": null,
+ "Ensure": "Present",
+ "Force": null,
+ "Hex": null,
+ "Key": "HKEY_LOCAL_MACHINE\\SOFTWARE\\ExampleKey",
+ "PsDscRunAsCredential_password": null,
+ "PsDscRunAsCredential_username": null,
+ "ValueData": [
+ "TestData"
+ ],
+ "ValueName": "TestValue",
+ "ValueType": null,
+ "module_version": "latest",
+ "resource_name": "Registry"
+ }
+ },
+ "module_version": "1.1",
+ "reboot_required": false,
+ "verbose_set": [
+ "Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = ResourceSet,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName' = root/Microsoft/Windows/DesiredStateConfiguration'.",
+ "An LCM method call arrived from computer SERVER2016 with user sid S-1-5-21-3088887838-4058132883-1884671576-1105.",
+ "[SERVER2016]: LCM: [ Start Set ] [[Registry]DirectResourceAccess]",
+ "[SERVER2016]: [[Registry]DirectResourceAccess] (SET) Create registry key 'HKLM:\\SOFTWARE\\ExampleKey'",
+ "[SERVER2016]: [[Registry]DirectResourceAccess] (SET) Set registry key value 'HKLM:\\SOFTWARE\\ExampleKey\\TestValue' to 'TestData' of type 'String'",
+ "[SERVER2016]: LCM: [ End Set ] [[Registry]DirectResourceAccess] in 0.1930 seconds.",
+ "[SERVER2016]: LCM: [ End Set ] in 0.2720 seconds.",
+ "Operation 'Invoke CimMethod' complete.",
+ "Time taken for configuration job to complete is 0.402 seconds"
+ ],
+ "verbose_test": [
+ "Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = ResourceTest,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName' = root/Microsoft/Windows/DesiredStateConfiguration'.",
+ "An LCM method call arrived from computer SERVER2016 with user sid S-1-5-21-3088887838-4058132883-1884671576-1105.",
+ "[SERVER2016]: LCM: [ Start Test ] [[Registry]DirectResourceAccess]",
+ "[SERVER2016]: [[Registry]DirectResourceAccess] Registry key 'HKLM:\\SOFTWARE\\ExampleKey' does not exist",
+ "[SERVER2016]: LCM: [ End Test ] [[Registry]DirectResourceAccess] False in 0.2510 seconds.",
+ "[SERVER2016]: LCM: [ End Set ] in 0.3310 seconds.",
+ "Operation 'Invoke CimMethod' complete.",
+ "Time taken for configuration job to complete is 0.475 seconds"
+ ]
+ }
+
+The ``invocation.module_args`` key shows the actual values that were set as
+well as other possible values that were not set. Unfortunately this will not
+show the default value for a DSC property, only what was set from the Ansible
+task. Any ``*_password`` option will be masked in the output for security
+reasons, if there are any other sensitive module options, set ``no_log: True``
+on the task to stop all task output from being logged.
+
+
Property Types
--------------
Each DSC resource property has a type that is associated with it. Ansible
@@ -110,9 +171,9 @@ require certain rules.
PSCredential
++++++++++++
A ``[PSCredential]`` object is used to store credentials in a secure way, but
-Ansible has no way to serialize this over JSON. To set a DSC PSCredential property,
-the definition of that parameter should have two entries that are suffixed with
-``_username`` and ``_password`` for the username and password respectively.
+Ansible has no way to serialize this over JSON. To set a DSC PSCredential property,
+the definition of that parameter should have two entries that are suffixed with
+``_username`` and ``_password`` for the username and password respectively.
For example:
.. code-block:: yaml+jinja
@@ -123,9 +184,12 @@ For example:
SourceCredential_username: AdminUser
SourceCredential_password: PasswordForAdminUser
-.. Note:: You should set ``no_log: yes`` on the task definition in
- Ansible to ensure any credentials used are not stored in any log file or
- console output.
+.. Note:: On versions of Ansible older than 2.8, you should set ``no_log: yes``
+ on the task definition in Ansible to ensure any credentials used are not
+ stored in any log file or console output.
+
+A ``[PSCredential]`` is defined with ``EmbeddedInstance("MSFT_Credential")`` in
+a DSC resource MOF definition.
CimInstance Type
++++++++++++++++
@@ -144,13 +208,20 @@ For example, to define a ``[CimInstance]`` value in Ansible:
Windows: yes
In the above example, the CIM instance is a representation of the class
-``MSFT_xWebAuthenticationInformation <https://github.com/PowerShell/xWebAdministration/blob/dev/DSCResources/MSFT_xWebsite/MSFT_xWebsite.schema.mof>``_.
+`MSFT_xWebAuthenticationInformation <https://github.com/PowerShell/xWebAdministration/blob/dev/DSCResources/MSFT_xWebsite/MSFT_xWebsite.schema.mof>`_.
This class accepts four boolean variables, ``Anonymous``, ``Basic``,
``Digest``, and ``Windows``. The keys to use in a ``[CimInstance]`` depend on
the class it represents. Please read through the documentation of the resource
to determine the keys that can be used and the types of each key value. The
class definition is typically located in the ``<resource name>.schema.mof``.
+HashTable Type
+++++++++++++++
+A ``[HashTable]`` object is also a dictionary but does not have a strict set of
+keys that can/need to be defined. Like a ``[CimInstance]``, define it like a
+normal dictionary value in YAML. A ``[HashTable]]`` is defined with
+``EmbeddedInstance("MSFT_KeyValuePair")`` in a DSC resource MOF definition.
+
Arrays
++++++
Simple type arrays like ``[string[]]`` or ``[UInt32[]]`` are defined as a list
@@ -192,17 +263,39 @@ like this example:
Port: 80
IPAddress: '*'
-The above example, is an array with two values of the class ``MSFT_xWebBindingInformation <https://github.com/PowerShell/xWebAdministration/blob/dev/DSCResources/MSFT_xWebsite/MSFT_xWebsite.schema.mof>``_.
+The above example, is an array with two values of the class `MSFT_xWebBindingInformation <https://github.com/PowerShell/xWebAdministration/blob/dev/DSCResources/MSFT_xWebsite/MSFT_xWebsite.schema.mof>`_.
When defining a ``[CimInstance[]]``, be sure to read the resource documentation
to find out what keys to use in the definition.
+DateTime
+++++++++
+A ``[DateTime]`` object is a DateTime string representing the date and time in
+the `ISO 8601 <https://www.w3.org/TR/NOTE-datetime>`_ date time format. The
+value for a ``[DateTime]`` field should be quoted in YAML to ensure the string
+is properly serialized to the Windows host. Here is an example of how to define
+a ``[DateTime]`` value in Ansible:
+
+.. code-block:: yaml+jinja
+
+ # As UTC-0 (No timezone)
+ DateTime: '2019-02-22T13:57:31.2311892+00:00'
+
+ # As UTC+4
+ DateTime: '2019-02-22T17:57:31.2311892+04:00'
+
+ # As UTC-4
+ DateTime: '2019-02-22T09:57:31.2311892-04:00'
+
+All the values above are equal to a UTC date time of February 22nd 2019 at
+1:57pm with 31 seconds and 2311892 milliseconds.
+
Run As Another User
-------------------
By default, DSC runs each resource as the SYSTEM account and not the account
that Ansible use to run the module. This means that resources that are dynamically
loaded based on a user profile, like the ``HKEY_CURRENT_USER`` registry hive,
-will be loaded under the ``SYSTEM`` profile. The parameter
-`PsDscRunAsCredential`` is a parameter that can be set for every DSC resource
+will be loaded under the ``SYSTEM`` profile. The parameter
+``PsDscRunAsCredential`` is a parameter that can be set for every DSC resource
force the DSC engine to run under a different account. As
``PsDscRunAsCredential`` has a type of ``PSCredential``, it is defined with the
``_username`` and ``_password`` suffix.
@@ -331,7 +424,7 @@ Interact with Azure
win_psmodule:
name: xAzure
state: present
-
+
- name: Create virtual machine in Azure
win_dsc:
resource_name: xAzureVM
diff --git a/lib/ansible/modules/windows/win_dsc.ps1 b/lib/ansible/modules/windows/win_dsc.ps1
index 007db9bef9..a753f7a01f 100644
--- a/lib/ansible/modules/windows/win_dsc.ps1
+++ b/lib/ansible/modules/windows/win_dsc.ps1
@@ -4,272 +4,400 @@
# Copyright: (c) 2017, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-#Requires -Module Ansible.ModuleUtils.Legacy
+#AnsibleRequires -CSharpUtil Ansible.Basic
#Requires -Version 5
-$ErrorActionPreference = "Stop"
+Function ConvertTo-ArgSpecType {
+ <#
+ .SYNOPSIS
+ Converts the DSC parameter type to the arg spec type required for Ansible.
+ #>
+ param(
+ [Parameter(Mandatory=$true)][String]$CimType
+ )
-$params = Parse-Args $args -supports_check_mode $true
-$result = @{
- changed = $false
+ $arg_type = switch($CimType) {
+ Boolean { "bool" }
+ Char16 { [Func[[Object], [Char]]]{ [System.Char]::Parse($args[0].ToString()) } }
+ DateTime { [Func[[Object], [DateTime]]]{
+ # o == ISO 8601 format
+ [System.DateTime]::ParseExact($args[0].ToString(), "o", [CultureInfo]::InvariantCulture,
+ [System.Globalization.DateTimeStyles]::None)
+ }}
+ Instance { "dict" }
+ Real32 { "float" }
+ Real64 { [Func[[Object], [Double]]]{ [System.Double]::Parse($args[0].ToString()) } }
+ Reference { "dict" }
+ SInt16 { [Func[[Object], [Int16]]]{ [System.Int16]::Parse($args[0].ToString()) } }
+ SInt32 { "int" }
+ SInt64 { [Func[[Object], [Int64]]]{ [System.Int64]::Parse($args[0].ToString()) } }
+ SInt8 { [Func[[Object], [SByte]]]{ [System.SByte]::Parse($args[0].ToString()) } }
+ String { "str" }
+ UInt16 { [Func[[Object], [UInt16]]]{ [System.UInt16]::Parse($args[0].ToString()) } }
+ UInt32 { [Func[[Object], [UInt32]]]{ [System.UInt32]::Parse($args[0].ToString()) } }
+ UInt64 { [Func[[Object], [UInt64]]]{ [System.UInt64]::Parse($args[0].ToString()) } }
+ UInt8 { [Func[[Object], [Byte]]]{ [System.Byte]::Parse($args[0].ToString()) } }
+ Unknown { "raw" }
+ default { "raw" }
+ }
+ return $arg_type
}
-Function Cast-ToCimInstance($name, $value, $className)
-{
- # this converts a hashtable to a CimInstance
+Function Get-DscCimClassProperties {
+ <#
+ .SYNOPSIS
+ Get's a list of CimProperties of a CIM Class. It filters out any magic or
+ read only properties that we don't need to know about.
+ #>
+ param([Parameter(Mandatory=$true)][String]$ClassName)
+
+ $resource = Get-CimClass -ClassName $ClassName -Namespace root\Microsoft\Windows\DesiredStateConfiguration
+
+ # Filter out any magic properties that are used internally on an OMI_BaseResource
+ # https://github.com/PowerShell/PowerShell/blob/master/src/System.Management.Automation/DscSupport/CimDSCParser.cs#L1203
+ $magic_properties = @("ResourceId", "SourceInfo", "ModuleName", "ModuleVersion", "ConfigurationName")
+ $properties = $resource.CimClassProperties | Where-Object {
- $valueType = $value.GetType()
- if ($valueType -ne [hashtable])
- {
- Fail-Json -obj $result -message "CimInstance value for property $name must be a hashtable, was $($valueType.FullName)"
+ ($resource.CimSuperClassName -ne "OMI_BaseResource" -or $_.Name -notin $magic_properties) -and
+ -not $_.Flags.HasFlag([Microsoft.Management.Infrastructure.CimFlags]::ReadOnly)
}
- try
- {
- $cim = New-CimInstance -ClassName $className -Property $value -ClientOnly
+ return ,$properties
+}
+
+Function Add-PropertyOption {
+ <#
+ .SYNOPSIS
+ Adds the spec for the property type to the existing module specification.
+ #>
+ param(
+ [Parameter(Mandatory=$true)][Hashtable]$Spec,
+ [Parameter(Mandatory=$true)]
+ [Microsoft.Management.Infrastructure.CimPropertyDeclaration]$Property
+ )
+
+ $option = @{
+ required = $false
}
- catch
- {
- Fail-Json -obj $result -message "Failed to convert hashtable to CimInstance of $($className): $($_.Exception.Message)"
+ $property_name = $Property.Name
+ $property_type = $Property.CimType.ToString()
+
+ if ($Property.Flags.HasFlag([Microsoft.Management.Infrastructure.CimFlags]::Key) -or
+ $Property.Flags.HasFlag([Microsoft.Management.Infrastructure.CimFlags]::Required)) {
+ $option.required = $true
}
- return ,$cim
-}
+ if ($null -ne $Property.Qualifiers['Values']) {
+ $option.choices = [System.Collections.Generic.List`1[Object]]$Property.Qualifiers['Values'].Value
+ }
-Function Cast-Value($value, $type, $typeString, $name)
-{
- if ($type -eq [CimInstance])
- {
- $newValue = Cast-ToCimInstance -name $name -value $value -className $typeString
+ if ($property_name -eq "Name") {
+ # For backwards compatibility we support specifying the Name DSC property as item_name
+ $option.aliases = @("item_name")
+ } elseif ($property_name -ceq "key") {
+ # There seems to be a bug in the CIM property parsing when the property name is 'Key'. The CIM instance will
+ # think the name is 'key' when the MOF actually defines it as 'Key'. We set the proper casing so the module arg
+ # validator won't fire a case sensitive warning
+ $property_name = "Key"
}
- ElseIf ($type -eq [CimInstance[]])
- {
- if ($value -isnot [array])
- {
- $value = @($value)
- }
- [CimInstance[]]$newValue = @()
- $baseTypeString = $typeString.Substring(0, $typeString.Length - 2)
- foreach ($cim in $value)
- {
- $newValue += Cast-ToCimInstance -name $name -value $cim -className $baseTypeString
+
+ if ($Property.ReferenceClassName -eq "MSFT_Credential") {
+ # Special handling for the MSFT_Credential type (PSCredential), we handle this with having 2 options that
+ # have the suffix _username and _password.
+ $option_spec_pass = @{
+ type = "str"
+ required = $option.required
+ no_log = $true
}
+ $Spec.options."$($property_name)_password" = $option_spec_pass
+ $Spec.required_together.Add(@("$($property_name)_username", "$($property_name)_password")) > $null
+
+ $property_name = "$($property_name)_username"
+ $option.type = "str"
+ } elseif ($Property.ReferenceClassName -eq "MSFT_KeyValuePair") {
+ $option.type = "dict"
+ } elseif ($property_type.EndsWith("Array")) {
+ $option.type = "list"
+ $option.elements = ConvertTo-ArgSpecType -CimType $property_type.Substring(0, $property_type.Length - 5)
+ } else {
+ $option.type = ConvertTo-ArgSpecType -CimType $property_type
}
- Else
- {
- $originalType = $value.GetType()
- if ($originalType -eq $type)
- {
- $newValue = $value
- }
- Else
- {
- $newValue = $value -as $type
- if ($newValue -eq $null)
- {
- Add-Warning -obj $result -message "failed to cast property $name from '$value' of type $($originalType.FullName) to type $($type.FullName), the DSC engine may ignore this property with an invalid cast"
- $newValue = $value
- }
- }
+
+ if (($option.type -eq "dict" -or ($option.type -eq "list" -and $option.elements -eq "dict")) -and
+ $Property.ReferenceClassName -ne "MSFT_KeyValuePair") {
+ # Get the sub spec if the type is a Instance (CimInstance/dict)
+ $sub_option_spec = Get-OptionSpec -ClassName $Property.ReferenceClassName
+ $option += $sub_option_spec
}
- return ,$newValue
+ $Spec.options.$property_name = $option
}
-Function Parse-DscProperty($name, $value, $resourceProp)
-{
- $propertyTypeString = $resourceProp.PropertyType
- if ($propertyTypeString.StartsWith("["))
- {
- $propertyTypeString = $propertyTypeString.Substring(1, $propertyTypeString.Length - 2)
+Function Get-OptionSpec {
+ <#
+ .SYNOPSIS
+ Generates the specifiec used in AnsibleModule for a CIM MOF resource name.
+
+ .NOTES
+ This won't be able to retrieve the default values for an option as that is not defined in the MOF for a resource.
+ Default values are still preserved in the DSC engine if we don't pass in the property at all, we just can't report
+ on what they are automatically.
+ #>
+ param(
+ [Parameter(Mandatory=$true)][String]$ClassName
+ )
+
+ $spec = @{
+ options = @{}
+ required_together = [System.Collections.ArrayList]@()
}
- $propertyType = $propertyTypeString -as [type]
-
- # CimInstance and CimInstance[] are reperesented as the actual Cim
- # ClassName and the above returns a $null. We need to manually set the
- # type in these cases
- if ($propertyType -eq $null)
- {
- if ($propertyTypeString.EndsWith("[]"))
- {
- $propertyType = [CimInstance[]]
- }
- Else
- {
- $propertyType = [CimInstance]
- }
+ $properties = Get-DscCimClassProperties -ClassName $ClassName
+ foreach ($property in $properties) {
+ Add-PropertyOption -Spec $spec -Property $property
}
- if ($propertyType.IsArray)
- {
- # convert the value to a list for later conversion
- if ($value -is [string])
- {
- $value = $value.Split(",").Trim()
- }
- ElseIf ($value -isnot [array])
- {
- $value = @($value)
+ return $spec
+}
+
+Function ConvertTo-CimInstance {
+ <#
+ .SYNOPSIS
+ Converts a dict to a CimInstance of the specified Class. Also provides a
+ better error message if this fails that contains the option name that failed.
+ #>
+ param(
+ [Parameter(Mandatory=$true)][String]$Name,
+ [Parameter(Mandatory=$true)][String]$ClassName,
+ [Parameter(Mandatory=$true)][System.Collections.IDictionary]$Value,
+ [Parameter(Mandatory=$true)][Ansible.Basic.AnsibleModule]$Module,
+ [Switch]$Recurse
+ )
+
+ $properties = @{}
+ foreach ($value_info in $Value.GetEnumerator()) {
+ # Need to remove all null values from existing dict so the conversion works
+ if ($null -eq $value_info.Value) {
+ continue
}
+ $properties.($value_info.Key) = $value_info.Value
}
- $newValue = Cast-Value -value $value -type $propertyType -typeString $propertyTypeString -name $name
- return ,$newValue
-}
+ if ($Recurse) {
+ # We want to validate and convert and values to what's required by DSC
+ $properties = ConvertTo-DscProperty -ClassName $ClassName -Params $properties -Module $Module
+ }
-$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false
-$resourcename = Get-AnsibleParam -obj $params -name "resource_name" -type "str" -failifempty $true
-$module_version = Get-AnsibleParam -obj $params -name "module_version" -type "str" -default "latest"
-
-#From Ansible 2.3 onwards, params is now a Hash Array
-$Attributes = @{}
-foreach ($param in $params.GetEnumerator())
-{
- if ($param.Name -notin @("resource_name", "module_version") -and $param.Name -notlike "_ansible_*")
- {
- $Attributes[$param.Name] = $param.Value
+ try {
+ return (New-CimInstance -ClassName $ClassName -Property $properties -ClientOnly)
+ } catch {
+ # New-CimInstance raises a poor error message, make sure we mention what option it is for
+ $Module.FailJson("Failed to cast dict value for option '$Name' to a CimInstance: $($_.Exception.Message)", $_)
}
}
-if ($Attributes.Count -eq 0)
-{
- Fail-Json -obj $result -message "No attributes specified"
-}
+Function ConvertTo-DscProperty {
+ <#
+ .SYNOPSIS
+ Converts the input module parameters that have been validated and casted
+ into the types expected by the DSC engine. This is mostly done to deal with
+ types like PSCredential and Dictionaries.
+ #>
+ param(
+ [Parameter(Mandatory=$true)][String]$ClassName,
+ [Parameter(Mandatory=$true)][System.Collections.IDictionary]$Params,
+ [Parameter(Mandatory=$true)][Ansible.Basic.AnsibleModule]$Module
+ )
+ $properties = Get-DscCimClassProperties -ClassName $ClassName
-#Always return some basic info
-$result["reboot_required"] = $false
+ $dsc_properties = @{}
+ foreach ($property in $properties) {
+ $property_name = $property.Name
+ $property_type = $property.CimType.ToString()
-$Config = @{
- Name = ($resourcename)
- Property = @{}
-}
+ if ($property.ReferenceClassName -eq "MSFT_Credential") {
+ $username = $Params."$($property_name)_username"
+ $password = $Params."$($property_name)_password"
-#Get the latest version of the module
-if ($module_version -eq "latest")
-{
- $Resource = Get-DscResource -Name $resourcename -ErrorAction SilentlyContinue | sort Version | select -Last 1
-}
-else
-{
- $Resource = Get-DscResource -Name $resourcename -ErrorAction SilentlyContinue | where {$_.Version -eq $module_version}
-}
+ # No user set == No option set in playbook, skip this property
+ if ($null -eq $username) {
+ continue
+ }
+ $sec_password = ConvertTo-SecureString -String $password -AsPlainText -Force
+ $value = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $sec_password
+ } else {
+ $value = $Params.$property_name
-if (!$Resource)
-{
- if ($module_version -eq "latest")
- {
- Fail-Json -obj $result -message "Resource $resourcename not found"
- }
- else
- {
- Fail-Json -obj $result -message "Resource $resourcename with version $module_version not found"
+ # The actual value wasn't set, skip adding this property
+ if ($null -eq $value) {
+ continue
+ }
+
+ if ($property.ReferenceClassName -eq "MSFT_KeyValuePair") {
+ $key_value_pairs = [System.Collections.Generic.List`1[CimInstance]]@()
+ foreach ($value_info in $value.GetEnumerator()) {
+ $kvp = @{Key = $value_info.Key; Value = $value_info.Value.ToString()}
+ $cim_instance = ConvertTo-CimInstance -Name $property_name -ClassName MSFT_KeyValuePair `
+ -Value $kvp -Module $Module
+ $key_value_pairs.Add($cim_instance) > $null
+ }
+ $value = $key_value_pairs.ToArray()
+ } elseif ($null -ne $property.ReferenceClassName) {
+ # Convert the dict to a CimInstance (or list of CimInstances)
+ $convert_args = @{
+ ClassName = $property.ReferenceClassName
+ Module = $Module
+ Name = $property_name
+ Recurse = $true
+ }
+ if ($property_type.EndsWith("Array")) {
+ $value = [System.Collections.Generic.List`1[CimInstance]]@()
+ foreach ($raw in $Params.$property_name.GetEnumerator()) {
+ $cim_instance = ConvertTo-CimInstance -Value $raw @convert_args
+ $value.Add($cim_instance) > $null
+ }
+ $value = $value.ToArray() # Need to make sure we are dealing with an Array not a List
+ } else {
+ $value = ConvertTo-CimInstance -Value $value @convert_args
+ }
+ }
+ }
+ $dsc_properties.$property_name = $value
}
-
-}
-#Get the Module that provides the resource. Will be used as
-#mandatory argument for Invoke-DscResource
-$Module = @{
- ModuleName = $Resource.ModuleName
- ModuleVersion = $Resource.Version
+ return $dsc_properties
}
-# Binary resources are not working very well with that approach - need to guesstimate module name/version
-if ( -not ($Module.ModuleName -or $Module.ModuleVersion)) {
- $Module = 'PSDesiredStateConfiguration'
-}
+Function Invoke-DscMethod {
+ <#
+ .SYNOPSIS
+ Invokes the DSC Resource Method specified in another PS pipeline. This is
+ done so we can retrieve the Verbose stream and return it back to the user
+ for futher debugging.
+ #>
+ param(
+ [Parameter(Mandatory=$true)][Ansible.Basic.AnsibleModule]$Module,
+ [Parameter(Mandatory=$true)][String]$Method,
+ [Parameter(Mandatory=$true)][Hashtable]$Arguments
+ )
-#grab the module version if we can
-try {
- if ($Resource.Module.Version)
- {
- $result["module_version"] = $Resource.Module.Version.ToString()
+ # Invoke the DSC resource in a separate runspace so we can capture the Verbose output
+ $ps = [PowerShell]::Create()
+ $ps.AddCommand("Invoke-DscResource").AddParameter("Method", $Method) > $null
+ $ps.AddParameters($Arguments) > $null
+
+ $result = $ps.Invoke()
+
+ # Pass the warnings through to the AnsibleModule return result
+ foreach ($warning in $ps.Streams.Warning) {
+ $Module.Warn($warning.Message)
}
-}
-catch {}
-
-#Convert params to correct datatype and inject
-foreach ($attribute in $Attributes.GetEnumerator())
-{
- $key = $attribute.Name.Replace("item_name", "name")
- $value = $attribute.Value
- $prop = $resource.Properties | Where-Object {$_.Name -eq $key}
- if (!$prop)
- {
- #If its a credential specified as "credential", Ansible will support credential_username and credential_password. Need to check for that
- $prop = $resource.Properties | Where-Object {$_.Name -eq $key.Replace("_username","")}
- if ($prop)
- {
- #We need to construct a cred object. At this point keyvalue is the username, so grab the password
- $PropUserNameValue = $value
- $PropPassword = $key.Replace("_username","_password")
- $PropPasswordValue = $Attributes.$PropPassword
-
- $KeyValue = New-Object System.Management.Automation.PSCredential ($PropUserNameValue, ($PropPasswordValue | ConvertTo-SecureString -AsPlainText -Force))
- $config.Property.Add($key.Replace("_username",""),$KeyValue)
- }
- ElseIf ($key.Contains("_password"))
- {
- #Do nothing. We suck in the password in the handler for _username, so we can just skip it.
- }
- Else
- {
- Fail-Json -obj $result -message "Property $key in resource $resourcename is not a valid property"
+
+ # If running at a high enough verbosity, add the verbose output to the AnsibleModule return result
+ if ($Module.Verbosity -ge 3) {
+ $verbose_logs = [System.Collections.Generic.List`1[String]]@()
+ foreach ($verbosity in $ps.Streams.Verbose) {
+ $verbose_logs.Add($verbosity.Message) > $null
}
+ $Module.Result."verbose_$($Method.ToLower())" = $verbose_logs
}
- Else
- {
- if ($value -eq $null)
- {
- $keyValue = $null
- }
- Else
- {
- $keyValue = Parse-DscProperty -name $key -value $value -resourceProp $prop
- }
-
- $config.Property.Add($key, $keyValue)
+
+ if ($ps.HadErrors) {
+ # Cannot pass in the ErrorRecord as it's a RemotingErrorRecord and doesn't contain the ScriptStackTrace
+ # or other info that would be useful
+ $Module.FailJson("Failed to invoke DSC $Method method: $($ps.Streams.Error[0].Exception.Message)")
}
+
+ return $result
}
-try
-{
- #Defined variables in strictmode
- $TestError, $TestError = $null
- $TestResult = Invoke-DscResource @Config -Method Test -ModuleName $Module -ErrorVariable TestError -ErrorAction SilentlyContinue -WarningVariable TestWarn
- foreach ($warning in $TestWarn) {
- Add-Warning -obj $result -message $warning.Message
+# win_dsc is unique in that is builds the arg spec based on DSC Resource input. To get this info
+# we need to read the resource_name and module_version value which is done outside of Ansible.Basic
+if ($args.Length -gt 0) {
+ $params = Get-Content -Path $args[0] | ConvertFrom-Json
+} else {
+ $params = $complex_args
+}
+if (-not $params.ContainsKey("resource_name")) {
+ $res = @{
+ msg = "missing required argument: resource_name"
+ failed = $true
}
+ Write-Output -InputObject (ConvertTo-Json -Compress -InputObject $res)
+ exit 1
+}
+$resource_name = $params.resource_name
+
+if ($params.ContainsKey("module_version")) {
+ $module_version = $params.module_version
+} else {
+ $module_version = "latest"
+}
+
+$module_versions = (Get-DscResource -Name $resource_name -ErrorAction SilentlyContinue | Sort-Object -Property Version)
+$resource = $null
+if ($module_version -eq "latest" -and $null -ne $module_versions) {
+ $resource = $module_versions[-1]
+} elseif ($module_version -ne "latest") {
+ $resource = $module_versions | Where-Object { $_.Version -eq $module_version }
+}
- if ($TestError)
- {
- throw ($TestError[0].Exception.Message)
+if (-not $resource) {
+ if ($module_version -eq "latest") {
+ $msg = "Resource '$resource_name' not found."
+ } else {
+ $msg = "Resource '$resource_name' with version '$module_version' not found."
+ $msg += " Versions installed: '$($module_versions.Version -join "', '")'."
}
- ElseIf (($TestResult.InDesiredState) -ne $true)
- {
- if ($check_mode -eq $False)
- {
- $SetResult = Invoke-DscResource -Method Set @Config -ModuleName $Module -ErrorVariable SetError -ErrorAction SilentlyContinue -WarningVariable SetWarn
- foreach ($warning in $SetWarn) {
- Add-Warning -obj $result -message $warning.Message
- }
- if ($SetError -and ($SetResult -eq $null))
- {
- #If SetError was filled, throw to exit out of the try/catch loop
- throw $SetError
- }
- $result["reboot_required"] = $SetResult.RebootRequired
- }
- $result["changed"] = $true
- if ($SetError)
- {
- throw ($SetError[0].Exception.Message)
- }
+
+ Write-Output -InputObject (ConvertTo-Json -Compress -InputObject @{ failed = $true; msg = $msg })
+ exit 1
+}
+
+# Build the base args for the DSC Invocation based on the resource selected
+$dsc_args = @{
+ Name = $resource.Name
+}
+
+# Binary resources are not working very well with that approach - need to guesstimate module name/version
+$module_version = $null
+if ($resource.Module) {
+ $dsc_args.ModuleName = @{
+ ModuleName = $resource.Module.Name
+ ModuleVersion = $resource.Module.Version
}
+ $module_version = $resource.Module.Version.ToString()
+} else {
+ $dsc_args.ModuleName = "PSDesiredStateConfiguration"
}
-Catch
-{
- Fail-Json -obj $result -message $_[0].Exception.Message
+
+# To ensure the class registered with CIM is the one based on our version, we want to run the Get method so the DSC
+# engine updates the metadata propery. We don't care about any errors here
+try {
+ Invoke-DscResource -Method Get -Property @{Fake="Fake"} @dsc_args > $null
+} catch {}
+
+# Dynamically build the option spec based on the resource_name specified and create the module object
+$spec = Get-OptionSpec -ClassName $resource.ResourceType
+$spec.supports_check_mode = $true
+$spec.options.module_version = @{ type = "str"; default = "latest" }
+$spec.options.resource_name = @{ type = "str"; required = $true }
+
+$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec)
+$module.Result.reboot_required = $false
+$module.Result.module_version = $module_version
+
+# Build the DSC invocation arguments and invoke the resource
+$dsc_args.Property = ConvertTo-DscProperty -ClassName $resource.ResourceType -Module $module -Params $Module.Params
+$dsc_args.Verbose = $true
+
+$test_result = Invoke-DscMethod -Module $module -Method Test -Arguments $dsc_args
+if ($test_result.InDesiredState -ne $true) {
+ if (-not $module.CheckMode) {
+ $result = Invoke-DscMethod -Module $module -Method Set -Arguments $dsc_args
+ $module.Result.reboot_required = $result.RebootRequired
+ }
+ $module.Result.changed = $true
}
-Exit-Json -obj $result
+$module.ExitJson()
+
diff --git a/lib/ansible/modules/windows/win_dsc.py b/lib/ansible/modules/windows/win_dsc.py
index 966d092840..ea5469096c 100644
--- a/lib/ansible/modules/windows/win_dsc.py
+++ b/lib/ansible/modules/windows/win_dsc.py
@@ -54,6 +54,11 @@ options:
provided but a comma separated string also work. Use a list where
possible as no escaping is required and it works with more complex types
list C(CimInstance[]).
+ - If the type of the DSC resource option is a C(DateTime), use a string in
+ the form of an ISO 8901 string.
+ - Since Ansible 2.8, Ansible will now validate the input fields against the
+ DSC resource definition automatically. Older versions will silently
+ ignore invalid fields.
type: str
required: true
notes:
@@ -65,6 +70,9 @@ notes:
- The DSC engine run's each task as the SYSTEM account, any resources that need
to be accessed with a different account need to have C(PsDscRunAsCredential)
set.
+- To see the valid options for a DSC resource, run the module with C(-vvv) to
+ show the possible module invocation. Default values are not shown in this
+ output but are applied within the DSC engine.
author:
- Trond Hindenes (@trondhindenes)
'''
@@ -103,6 +111,11 @@ EXAMPLES = r'''
Ensure: Present
Type: Directory
+- name: Call DSC resource with DateTime option
+ win_dsc:
+ resource_name: DateTimeResource
+ DateTimeOption: '2019-02-22T13:57:31.2311892+00:00'
+
# more complex example using custom DSC resource and dict values
- name: Setup the xWebAdministration module
win_psmodule:
@@ -137,7 +150,7 @@ EXAMPLES = r'''
RETURN = r'''
module_version:
description: The version of the dsc resource/module used.
- returned: success
+ returned: always
type: str
sample: "1.0.1"
reboot_required:
@@ -146,9 +159,24 @@ reboot_required:
returned: always
type: bool
sample: true
-message:
- description: Any error message from invoking the DSC resource.
- returned: error
- type: str
- sample: Multiple DSC modules found with resource name xyz
+verbose_test:
+ description: The verbose output as a list from executing the DSC test
+ method.
+ returned: Ansible verbosity is -vvv or greater
+ type: list
+ sample: [
+ "Perform operation 'Invoke CimMethod' with the following parameters, ",
+ "[SERVER]: LCM: [Start Test ] [[File]DirectResourceAccess]",
+ "Operation 'Invoke CimMethod' complete."
+ ]
+verbose_set:
+ description: The verbose output as a list from executing the DSC Set
+ method.
+ returned: Ansible verbosity is -vvv or greater and a change occurred
+ type: list
+ sample: [
+ "Perform operation 'Invoke CimMethod' with the following parameters, ",
+ "[SERVER]: LCM: [Start Set ] [[File]DirectResourceAccess]",
+ "Operation 'Invoke CimMethod' complete."
+ ]
'''
diff --git a/test/integration/targets/win_dsc/defaults/main.yml b/test/integration/targets/win_dsc/defaults/main.yml
deleted file mode 100644
index 90aaec6656..0000000000
--- a/test/integration/targets/win_dsc/defaults/main.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-# Feature not normally installed by default.
-test_win_dsc_feature_name: Telnet-Client
-test_win_dsc_folder: C:\ansible test
-test_win_dsc_run_desctructive: no
diff --git a/test/integration/targets/win_dsc/files/custom-result-normal.txt b/test/integration/targets/win_dsc/files/custom-result-normal.txt
deleted file mode 100644
index 8220d589f8..0000000000
--- a/test/integration/targets/win_dsc/files/custom-result-normal.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-xTestResource Version: 2.0.0
-
-Ensure:
- Type: System.String
- Value: Present
-
-StringParam:
- Type: System.String
- Value: string param
-
-UInt32Param:
- Type: System.UInt32
- Value: 1000
-
-UInt64Param:
- Type: System.UInt64
- Value: 1000000
-
-StringArrayParam:
- Type: System.String[]
- Value: [ "string 1", "string 2" ]
-
-UInt32ArrayParam:
- Type: System.UInt32[]
- Value: [ 1000, 2000 ]
-
-UInt64ArrayParam:
- Type: System.UInt64[]
- Value: [ 1000000, 2000000 ]
-
-BooleanParam:
- Type: System.Boolean
- Value: True
-
-PSCredentialParam:
- Type: System.Management.Automation.PSCredential
- Username: username
- Password: password
-
-CimInstanceParam:
- Type: Microsoft.Management.Infrastructure.CimInstance
-
-CimInstanceArrayParam:
- Type: Microsoft.Management.Infrastructure.CimInstance[]
diff --git a/test/integration/targets/win_dsc/files/custom-result-versioned.txt b/test/integration/targets/win_dsc/files/custom-result-versioned.txt
deleted file mode 100644
index fe5a6e2dff..0000000000
--- a/test/integration/targets/win_dsc/files/custom-result-versioned.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-xTestResource Version: 1.0.0
-
-Ensure:
- Type: System.String
- Value: Present
-
-StringParam:
- Type: System.String
- Value: string param
-
-UInt32Param:
- Type: System.UInt32
- Value: 1000
-
-UInt64Param:
- Type: System.UInt64
- Value: 1000000
-
-StringArrayParam:
- Type: System.String[]
- Value: [ "string 1", "string 2" ]
-
-UInt32ArrayParam:
- Type: System.UInt32[]
- Value: [ 1000, 2000 ]
-
-UInt64ArrayParam:
- Type: System.UInt64[]
- Value: [ 1000000, 2000000 ]
-
-BooleanParam:
- Type: System.Boolean
- Value: True
-
-PSCredentialParam:
- Type: System.Management.Automation.PSCredential
- Username: username
- Password: password
-
-CimInstanceParam:
- Type: Microsoft.Management.Infrastructure.CimInstance
-
-CimInstanceArrayParam:
- Type: Microsoft.Management.Infrastructure.CimInstance[]
diff --git a/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xSetReboot/ANSIBLE_xSetReboot.psm1 b/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xSetReboot/ANSIBLE_xSetReboot.psm1
new file mode 100644
index 0000000000..dbf1ecf3ee
--- /dev/null
+++ b/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xSetReboot/ANSIBLE_xSetReboot.psm1
@@ -0,0 +1,41 @@
+#Requires -Version 5.0 -Modules CimCmdlets
+
+Function Get-TargetResource
+{
+ [CmdletBinding()]
+ [OutputType([Hashtable])]
+ param(
+ [Parameter(Mandatory=$true)]
+ [ValidateNotNullOrEmpty()]
+ [String]$KeyParam
+ )
+ return @{Value = [bool]$global:DSCMachineStatus}
+}
+
+Function Set-TargetResource
+{
+ [CmdletBinding()]
+ param (
+ [Parameter(Mandatory=$true)]
+ [ValidateNotNullOrEmpty()]
+ [String]$KeyParam,
+ [Bool]$Value = $true
+ )
+ $global:DSCMachineStatus = [int]$Value
+}
+
+Function Test-TargetResource
+{
+ [CmdletBinding()]
+ [OutputType([Boolean])]
+ param (
+ [Parameter(Mandatory=$true)]
+ [ValidateNotNullOrEmpty()]
+ [String]$KeyParam,
+ [Bool]$Value = $true
+ )
+ $false
+}
+
+Export-ModuleMember -Function *-TargetResource
+
diff --git a/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xSetReboot/ANSIBLE_xSetReboot.schema.mof b/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xSetReboot/ANSIBLE_xSetReboot.schema.mof
new file mode 100644
index 0000000000..288b887722
--- /dev/null
+++ b/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xSetReboot/ANSIBLE_xSetReboot.schema.mof
@@ -0,0 +1,7 @@
+[ClassVersion("1.0.0"), FriendlyName("xSetReboot")]
+class ANSIBLE_xSetReboot : OMI_BaseResource
+{
+ [Key] String KeyParam;
+ [Write] Boolean Value;
+};
+
diff --git a/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.psm1 b/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.psm1
new file mode 100644
index 0000000000..79f6496962
--- /dev/null
+++ b/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.psm1
@@ -0,0 +1,214 @@
+#Requires -Version 5.0 -Modules CimCmdlets
+
+Function ConvertFrom-CimInstance {
+ param(
+ [Parameter(Mandatory=$true)][CimInstance]$Instance
+ )
+ $hashtable = @{
+ _cim_instance = $Instance.CimSystemProperties.ClassName
+ }
+ foreach ($prop in $Instance.CimInstanceProperties) {
+ $hashtable."$($prop.Name)" = ConvertTo-OutputValue -Value $prop.Value
+ }
+ return $hashtable
+}
+
+Function ConvertTo-OutputValue {
+ param($Value)
+
+ if ($Value -is [DateTime[]]) {
+ $Value = $Value | ForEach-Object { $_.ToString("o") }
+ } elseif ($Value -is [DateTime]) {
+ $Value = $Value.ToString("o")
+ } elseif ($Value -is [Double]) {
+ $Value = $Value.ToString() # To avoid Python 2 double parsing issues on test validation
+ } elseif ($Value -is [Double[]]) {
+ $Value = $Value | ForEach-Object { $_.ToString() }
+ } elseif ($Value -is [PSCredential]) {
+ $password = $null
+ $password_ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUnicode($Value.Password)
+ try {
+ $password = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($password_ptr)
+ } finally {
+ [System.Runtime.InteropServices.Marshal]::ZeroFreeGlobalAllocUnicode($password_ptr)
+ }
+ $Value = @{
+ username = $Value.Username
+ password = $password
+ }
+ } elseif ($Value -is [CimInstance[]]) {
+ $value_list = [System.Collections.Generic.List`1[Hashtable]]@()
+ foreach ($cim_instance in $Value) {
+ $value_list.Add((ConvertFrom-CimInstance -Instance $cim_instance))
+ }
+ $Value = $value_list.ToArray()
+ } elseif ($Value -is [CimInstance]) {
+ $Value = ConvertFrom-CimInstance -Instance $Value
+ }
+
+ return ,$Value
+}
+
+Function Get-TargetResource
+{
+ [CmdletBinding()]
+ [OutputType([Hashtable])]
+ param(
+ [Parameter(Mandatory = $true)]
+ [ValidateSet("Present", "Absent")]
+ [String] $Ensure = "Present",
+
+ [Parameter(Mandatory = $true)]
+ [ValidateNotNullOrEmpty()]
+ [String] $Path
+ )
+ return @{
+ Ensure = $Ensure
+ Path = $Path
+ }
+}
+
+Function Set-TargetResource
+{
+ [CmdletBinding()]
+ param
+ (
+ [Parameter(Mandatory = $true)]
+ [ValidateSet("Present", "Absent")]
+ [String] $Ensure = "Present",
+
+ [Parameter(Mandatory = $true)]
+ [ValidateNotNullOrEmpty()]
+ [String] $Path,
+
+ [String] $DefaultParam = "Default",
+ [String] $StringParam,
+ [String[]] $StringArrayParam,
+ [SByte] $Int8Param,
+ [SByte[]] $Int8ArrayParam,
+ [Byte] $UInt8Param,
+ [Byte[]] $UInt8ArrayParam,
+ [Int16] $Int16Param,
+ [Int16[]] $Int16ArrayParam,
+ [UInt16] $UInt16Param,
+ [UInt16[]] $UInt16ArrayParam,
+ [Int32] $Int32Param,
+ [Int32[]] $Int32ArrayParam,
+ [UInt32] $UInt32Param,
+ [UInt32[]] $UInt32ArrayParam,
+ [Int64] $Int64Param,
+ [Int64[]] $Int64ArrayParam,
+ [UInt64] $UInt64Param,
+ [UInt64[]] $UInt64ArrayParam,
+ [Bool] $BooleanParam,
+ [Bool[]] $BooleanArrayParam,
+ [Char] $CharParam,
+ [Char[]] $CharArrayParam,
+ [Single] $SingleParam,
+ [Single[]] $SingleArrayParam,
+ [Double] $DoubleParam,
+ [Double[]] $DoubleArrayParam,
+ [DateTime] $DateTimeParam,
+ [DateTime[]] $DateTimeArrayParam,
+ [PSCredential] $PSCredentialParam,
+ [CimInstance[]] $HashtableParam,
+ [CimInstance] $CimInstanceParam,
+ [CimInstance[]] $CimInstanceArrayParam,
+ [CimInstance] $NestedCimInstanceParam,
+ [CimInstance[]] $NestedCimInstanceArrayParam
+ )
+
+ $info = @{
+ Version = "1.0.0"
+ Ensure = @{
+ Type = $Ensure.GetType().FullName
+ Value = $Ensure
+ }
+ Path = @{
+ Type = $Path.GetType().FullName
+ Value = $Path
+ }
+ DefaultParam = @{
+ Type = $DefaultParam.GetType().FullName
+ Value = $DefaultParam
+ }
+ }
+
+ foreach ($kvp in $PSCmdlet.MyInvocation.BoundParameters.GetEnumerator()) {
+ $info."$($kvp.Key)" = @{
+ Type = $kvp.Value.GetType().FullName
+ Value = (ConvertTo-OutputValue -Value $kvp.Value)
+ }
+ }
+
+ if (Test-Path -Path $Path) {
+ Remove-Item -Path $Path -Force > $null
+ }
+ New-Item -Path $Path -ItemType File > $null
+ Set-Content -Path $Path -Value (ConvertTo-Json -InputObject $info -Depth 10) > $null
+ Write-Verbose -Message "set verbose"
+ Write-Warning -Message "set warning"
+}
+
+Function Test-TargetResource
+{
+ [CmdletBinding()]
+ [OutputType([Boolean])]
+ param
+ (
+ [Parameter(Mandatory = $true)]
+ [ValidateSet("Present", "Absent")]
+ [String] $Ensure = "Present",
+
+ [Parameter(Mandatory = $true)]
+ [ValidateNotNullOrEmpty()]
+ [String] $Path,
+
+ [String] $DefaultParam = "Default",
+ [String] $StringParam,
+ [String[]] $StringArrayParam,
+ [SByte] $Int8Param,
+ [SByte[]] $Int8ArrayParam,
+ [Byte] $UInt8Param,
+ [Byte[]] $UInt8ArrayParam,
+ [Int16] $Int16Param,
+ [Int16[]] $Int16ArrayParam,
+ [UInt16] $UInt16Param,
+ [UInt16[]] $UInt16ArrayParam,
+ [Int32] $Int32Param,
+ [Int32[]] $Int32ArrayParam,
+ [UInt32] $UInt32Param,
+ [UInt32[]] $UInt32ArrayParam,
+ [Int64] $Int64Param,
+ [Int64[]] $Int64ArrayParam,
+ [UInt64] $UInt64Param,
+ [UInt64[]] $UInt64ArrayParam,
+ [Bool] $BooleanParam,
+ [Bool[]] $BooleanArrayParam,
+ [Char] $CharParam,
+ [Char[]] $CharArrayParam,
+ [Single] $SingleParam,
+ [Single[]] $SingleArrayParam,
+ [Double] $DoubleParam,
+ [Double[]] $DoubleArrayParam,
+ [DateTime] $DateTimeParam,
+ [DateTime[]] $DateTimeArrayParam,
+ [PSCredential] $PSCredentialParam,
+ [CimInstance[]] $HashtableParam,
+ [CimInstance] $CimInstanceParam,
+ [CimInstance[]] $CimInstanceArrayParam,
+ [CimInstance] $NestedCimInstanceParam,
+ [CimInstance[]] $NestedCimInstanceArrayParam
+ )
+ Write-Verbose -Message "test verbose"
+ Write-Warning -Message "test warning"
+ $exists = Test-Path -LiteralPath $Path -PathType Leaf
+ if ($Ensure -eq "Present") {
+ $exists
+ } else {
+ -not $exists
+ }
+}
+
+Export-ModuleMember -Function *-TargetResource
+
diff --git a/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.schema.mof b/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.schema.mof
new file mode 100644
index 0000000000..c61b2b1e6a
--- /dev/null
+++ b/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.schema.mof
@@ -0,0 +1,60 @@
+[ClassVersion("1.0.0")]
+class ANSIBLE_xTestClass
+{
+ [Key] String Key;
+ [Write] String StringValue;
+ [Write] SInt32 IntValue;
+ [Write] String StringArrayValue[];
+};
+
+[ClassVersion("1.0.0")]
+class ANSIBLE_xNestedClass
+{
+ [Key] String KeyValue;
+ [Write, EmbeddedInstance("ANSIBLE_xTestClass")] String CimValue;
+ [Write, EmbeddedInstance("MSFT_KeyValuePair")] String HashValue[];
+ [Write] SInt16 IntValue;
+};
+
+[ClassVersion("1.0.0"), FriendlyName("xTestResource")]
+class ANSIBLE_xTestResource : OMI_BaseResource
+{
+ [Key] String Path;
+ [Required, ValueMap{"Present", "Absent"}, Values{"Present", "Absent"}] String Ensure;
+ [Read] String ReadParam;
+ [Write] String DefaultParam;
+ [Write] String StringParam;
+ [Write] String StringArrayParam[];
+ [Write] SInt8 Int8Param;
+ [Write] SInt8 Int8ArrayParam[];
+ [Write] UInt8 UInt8Param;
+ [Write] UInt8 UInt8ArrayParam[];
+ [Write] SInt16 Int16Param;
+ [Write] SInt16 Int16ArrayParam[];
+ [Write] UInt16 UInt16Param;
+ [Write] UInt16 UInt16ArrayParam[];
+ [Write] SInt32 Int32Param;
+ [Write] SInt32 Int32ArrayParam[];
+ [Write] UInt32 UInt32Param;
+ [Write] UInt32 UInt32ArrayParam[];
+ [Write] SInt64 Int64Param;
+ [Write] SInt64 Int64ArrayParam[];
+ [Write] UInt64 UInt64Param;
+ [Write] UInt64 UInt64ArrayParam[];
+ [Write] Boolean BooleanParam;
+ [Write] Boolean BooleanArrayParam[];
+ [Write] Char16 CharParam;
+ [Write] Char16 CharArrayParam[];
+ [Write] Real32 SingleParam;
+ [Write] Real32 SingleArrayParam[];
+ [Write] Real64 DoubleParam;
+ [Write] Real64 DoubleArrayParam[];
+ [Write] DateTime DateTimeParam;
+ [Write] DateTime DateTimeArrayParam[];
+ [Write, EmbeddedInstance("MSFT_Credential")] String PSCredentialParam;
+ [Write, EmbeddedInstance("MSFT_KeyValuePair")] String HashtableParam[];
+ [Write, EmbeddedInstance("ANSIBLE_xTestClass")] String CimInstanceArrayParam[];
+ [Write, EmbeddedInstance("ANSIBLE_xNestedClass")] String NestedCimInstanceParam;
+ [Write, EmbeddedInstance("ANSIBLE_xNestedClass")] String NestedCimInstanceArrayParam[];
+};
+
diff --git a/test/integration/targets/win_dsc/templates/xTestDsc.psd1 b/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/xTestDsc.psd1
index b3cdc08d57..3d61611d70 100644
--- a/test/integration/targets/win_dsc/templates/xTestDsc.psd1
+++ b/test/integration/targets/win_dsc/files/xTestDsc/1.0.0/xTestDsc.psd1
@@ -1,12 +1,13 @@
@{
- ModuleVersion = '{{item.version}}'
- GUID = '{{item.version|to_uuid}}'
+ ModuleVersion = '1.0.0'
+ GUID = '80c895c4-de3f-4d6d-8fa4-c504c96b6f22'
Author = 'Ansible'
CompanyName = 'Ansible'
- Copyright = '(c) 2017'
+ Copyright = '(c) 2019'
Description = 'Test DSC Resource for Ansible integration tests'
PowerShellVersion = '5.0'
CLRVersion = '4.0'
FunctionsToExport = '*'
CmdletsToExport = '*'
}
+
diff --git a/test/integration/targets/win_dsc/files/xTestDsc/1.0.1/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.psm1 b/test/integration/targets/win_dsc/files/xTestDsc/1.0.1/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.psm1
new file mode 100644
index 0000000000..d75256e1d9
--- /dev/null
+++ b/test/integration/targets/win_dsc/files/xTestDsc/1.0.1/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.psm1
@@ -0,0 +1,214 @@
+#Requires -Version 5.0 -Modules CimCmdlets
+
+Function ConvertFrom-CimInstance {
+ param(
+ [Parameter(Mandatory=$true)][CimInstance]$Instance
+ )
+ $hashtable = @{
+ _cim_instance = $Instance.CimSystemProperties.ClassName
+ }
+ foreach ($prop in $Instance.CimInstanceProperties) {
+ $hashtable."$($prop.Name)" = ConvertTo-OutputValue -Value $prop.Value
+ }
+ return $hashtable
+}
+
+Function ConvertTo-OutputValue {
+ param($Value)
+
+ if ($Value -is [DateTime[]]) {
+ $Value = $Value | ForEach-Object { $_.ToString("o") }
+ } elseif ($Value -is [DateTime]) {
+ $Value = $Value.ToString("o")
+ } elseif ($Value -is [Double]) {
+ $Value = $Value.ToString() # To avoid Python 2 double parsing issues on test validation
+ } elseif ($Value -is [Double[]]) {
+ $Value = $Value | ForEach-Object { $_.ToString() }
+ } elseif ($Value -is [PSCredential]) {
+ $password = $null
+ $password_ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUnicode($Value.Password)
+ try {
+ $password = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($password_ptr)
+ } finally {
+ [System.Runtime.InteropServices.Marshal]::ZeroFreeGlobalAllocUnicode($password_ptr)
+ }
+ $Value = @{
+ username = $Value.Username
+ password = $password
+ }
+ } elseif ($Value -is [CimInstance[]]) {
+ $value_list = [System.Collections.Generic.List`1[Hashtable]]@()
+ foreach ($cim_instance in $Value) {
+ $value_list.Add((ConvertFrom-CimInstance -Instance $cim_instance))
+ }
+ $Value = $value_list.ToArray()
+ } elseif ($Value -is [CimInstance]) {
+ $Value = ConvertFrom-CimInstance -Instance $Value
+ }
+
+ return ,$Value
+}
+
+Function Get-TargetResource
+{
+ [CmdletBinding()]
+ [OutputType([Hashtable])]
+ param(
+ [Parameter(Mandatory = $true)]
+ [ValidateSet("Present", "Absent")]
+ [String] $Ensure = "Present",
+
+ [Parameter(Mandatory = $true)]
+ [ValidateNotNullOrEmpty()]
+ [String] $Path
+ )
+ return @{
+ Ensure = $Ensure
+ Path = $Path
+ }
+}
+
+Function Set-TargetResource
+{
+ [CmdletBinding()]
+ param
+ (
+ [Parameter(Mandatory = $true)]
+ [ValidateSet("Present", "Absent")]
+ [String] $Ensure = "Present",
+
+ [Parameter(Mandatory = $true)]
+ [ValidateNotNullOrEmpty()]
+ [String] $Path,
+
+ [String] $DefaultParam = "Default",
+ [String] $StringParam,
+ [String[]] $StringArrayParam,
+ [SByte] $Int8Param,
+ [SByte[]] $Int8ArrayParam,
+ [Byte] $UInt8Param,
+ [Byte[]] $UInt8ArrayParam,
+ [Int16] $Int16Param,
+ [Int16[]] $Int16ArrayParam,
+ [UInt16] $UInt16Param,
+ [UInt16[]] $UInt16ArrayParam,
+ [Int32] $Int32Param,
+ [Int32[]] $Int32ArrayParam,
+ [UInt32] $UInt32Param,
+ [UInt32[]] $UInt32ArrayParam,
+ [Int64] $Int64Param,
+ [Int64[]] $Int64ArrayParam,
+ [UInt64] $UInt64Param,
+ [UInt64[]] $UInt64ArrayParam,
+ [Bool] $BooleanParam,
+ [Bool[]] $BooleanArrayParam,
+ [Char] $CharParam,
+ [Char[]] $CharArrayParam,
+ [Single] $SingleParam,
+ [Single[]] $SingleArrayParam,
+ [Double] $DoubleParam,
+ [Double[]] $DoubleArrayParam,
+ [DateTime] $DateTimeParam,
+ [DateTime[]] $DateTimeArrayParam,
+ [PSCredential] $PSCredentialParam,
+ [CimInstance[]] $HashtableParam,
+ [CimInstance] $CimInstanceParam,
+ [CimInstance[]] $CimInstanceArrayParam,
+ [CimInstance] $NestedCimInstanceParam,
+ [CimInstance[]] $NestedCimInstanceArrayParam
+ )
+
+ $info = @{
+ Version = "1.0.1"
+ Ensure = @{
+ Type = $Ensure.GetType().FullName
+ Value = $Ensure
+ }
+ Path = @{
+ Type = $Path.GetType().FullName
+ Value = $Path
+ }
+ DefaultParam = @{
+ Type = $DefaultParam.GetType().FullName
+ Value = $DefaultParam
+ }
+ }
+
+ foreach ($kvp in $PSCmdlet.MyInvocation.BoundParameters.GetEnumerator()) {
+ $info."$($kvp.Key)" = @{
+ Type = $kvp.Value.GetType().FullName
+ Value = (ConvertTo-OutputValue -Value $kvp.Value)
+ }
+ }
+
+ if (Test-Path -Path $Path) {
+ Remove-Item -Path $Path -Force > $null
+ }
+ New-Item -Path $Path -ItemType File > $null
+ Set-Content -Path $Path -Value (ConvertTo-Json -InputObject $info -Depth 10) > $null
+ Write-Verbose -Message "set verbose"
+ Write-Warning -Message "set warning"
+}
+
+Function Test-TargetResource
+{
+ [CmdletBinding()]
+ [OutputType([Boolean])]
+ param
+ (
+ [Parameter(Mandatory = $true)]
+ [ValidateSet("Present", "Absent")]
+ [String] $Ensure = "Present",
+
+ [Parameter(Mandatory = $true)]
+ [ValidateNotNullOrEmpty()]
+ [String] $Path,
+
+ [String] $DefaultParam = "Default",
+ [String] $StringParam,
+ [String[]] $StringArrayParam,
+ [SByte] $Int8Param,
+ [SByte[]] $Int8ArrayParam,
+ [Byte] $UInt8Param,
+ [Byte[]] $UInt8ArrayParam,
+ [Int16] $Int16Param,
+ [Int16[]] $Int16ArrayParam,
+ [UInt16] $UInt16Param,
+ [UInt16[]] $UInt16ArrayParam,
+ [Int32] $Int32Param,
+ [Int32[]] $Int32ArrayParam,
+ [UInt32] $UInt32Param,
+ [UInt32[]] $UInt32ArrayParam,
+ [Int64] $Int64Param,
+ [Int64[]] $Int64ArrayParam,
+ [UInt64] $UInt64Param,
+ [UInt64[]] $UInt64ArrayParam,
+ [Bool] $BooleanParam,
+ [Bool[]] $BooleanArrayParam,
+ [Char] $CharParam,
+ [Char[]] $CharArrayParam,
+ [Single] $SingleParam,
+ [Single[]] $SingleArrayParam,
+ [Double] $DoubleParam,
+ [Double[]] $DoubleArrayParam,
+ [DateTime] $DateTimeParam,
+ [DateTime[]] $DateTimeArrayParam,
+ [PSCredential] $PSCredentialParam,
+ [CimInstance[]] $HashtableParam,
+ [CimInstance] $CimInstanceParam,
+ [CimInstance[]] $CimInstanceArrayParam,
+ [CimInstance] $NestedCimInstanceParam,
+ [CimInstance[]] $NestedCimInstanceArrayParam
+ )
+ Write-Verbose -Message "test verbose"
+ Write-Warning -Message "test warning"
+ $exists = Test-Path -LiteralPath $Path -PathType Leaf
+ if ($Ensure -eq "Present") {
+ $exists
+ } else {
+ -not $exists
+ }
+}
+
+Export-ModuleMember -Function *-TargetResource
+
diff --git a/test/integration/targets/win_dsc/files/xTestDsc/1.0.1/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.schema.mof b/test/integration/targets/win_dsc/files/xTestDsc/1.0.1/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.schema.mof
new file mode 100644
index 0000000000..9301664b3c
--- /dev/null
+++ b/test/integration/targets/win_dsc/files/xTestDsc/1.0.1/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.schema.mof
@@ -0,0 +1,63 @@
+[ClassVersion("1.0.1")]
+class ANSIBLE_xTestClass
+{
+ [Key] String KeyValue;
+ [Write, ValueMap{"Choice1", "Choice2"}, Values{"Choice1", "Choice2"}] String Choice;
+ [Write] String StringValue;
+ [Write] SInt32 IntValue;
+ [Write] String StringArrayValue[];
+};
+
+[ClassVersion("1.0.1")]
+class ANSIBLE_xNestedClass
+{
+ [Key] String KeyValue;
+ [Write, EmbeddedInstance("ANSIBLE_xTestClass")] String CimValue;
+ [Write, EmbeddedInstance("ANSIBLE_xTestClass")] String CimArrayValue[];
+ [Write, EmbeddedInstance("MSFT_KeyValuePair")] String HashValue[];
+ [Write] SInt16 IntValue;
+};
+
+[ClassVersion("1.0.1"), FriendlyName("xTestResource")]
+class ANSIBLE_xTestResource : OMI_BaseResource
+{
+ [Key] String Path;
+ [Required, ValueMap{"Present", "Absent"}, Values{"Present", "Absent"}] String Ensure;
+ [Read] String ReadParam;
+ [Write] String DefaultParam;
+ [Write] String StringParam;
+ [Write] String StringArrayParam[];
+ [Write] SInt8 Int8Param;
+ [Write] SInt8 Int8ArrayParam[];
+ [Write] UInt8 UInt8Param;
+ [Write] UInt8 UInt8ArrayParam[];
+ [Write] SInt16 Int16Param;
+ [Write] SInt16 Int16ArrayParam[];
+ [Write] UInt16 UInt16Param;
+ [Write] UInt16 UInt16ArrayParam[];
+ [Write] SInt32 Int32Param;
+ [Write] SInt32 Int32ArrayParam[];
+ [Write] UInt32 UInt32Param;
+ [Write] UInt32 UInt32ArrayParam[];
+ [Write] SInt64 Int64Param;
+ [Write] SInt64 Int64ArrayParam[];
+ [Write] UInt64 UInt64Param;
+ [Write] UInt64 UInt64ArrayParam[];
+ [Write] Boolean BooleanParam;
+ [Write] Boolean BooleanArrayParam[];
+ [Write] Char16 CharParam;
+ [Write] Char16 CharArrayParam[];
+ [Write] Real32 SingleParam;
+ [Write] Real32 SingleArrayParam[];
+ [Write] Real64 DoubleParam;
+ [Write] Real64 DoubleArrayParam[];
+ [Write] DateTime DateTimeParam;
+ [Write] DateTime DateTimeArrayParam[];
+ [Write, EmbeddedInstance("MSFT_Credential")] String PSCredentialParam;
+ [Write, EmbeddedInstance("MSFT_KeyValuePair")] String HashtableParam[];
+ [Write, EmbeddedInstance("ANSIBLE_xTestClass")] String CimInstanceParam;
+ [Write, EmbeddedInstance("ANSIBLE_xTestClass")] String CimInstanceArrayParam[];
+ [Write, EmbeddedInstance("ANSIBLE_xNestedClass")] String NestedCimInstanceParam;
+ [Write, EmbeddedInstance("ANSIBLE_xNestedClass")] String NestedCimInstanceArrayParam[];
+};
+
diff --git a/test/integration/targets/win_dsc/files/xTestDsc/1.0.1/xTestDsc.psd1 b/test/integration/targets/win_dsc/files/xTestDsc/1.0.1/xTestDsc.psd1
new file mode 100644
index 0000000000..0c43b85238
--- /dev/null
+++ b/test/integration/targets/win_dsc/files/xTestDsc/1.0.1/xTestDsc.psd1
@@ -0,0 +1,13 @@
+@{
+ ModuleVersion = '1.0.1'
+ GUID = '80c895c4-de3f-4d6d-8fa4-c504c96b6f22'
+ Author = 'Ansible'
+ CompanyName = 'Ansible'
+ Copyright = '(c) 2019'
+ Description = 'Test DSC Resource for Ansible integration tests'
+ PowerShellVersion = '5.0'
+ CLRVersion = '4.0'
+ FunctionsToExport = '*'
+ CmdletsToExport = '*'
+}
+
diff --git a/test/integration/targets/win_dsc/filter_plugins/strip_newline.py b/test/integration/targets/win_dsc/filter_plugins/strip_newline.py
deleted file mode 100644
index bfa642de49..0000000000
--- a/test/integration/targets/win_dsc/filter_plugins/strip_newline.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# (c) 2017 Red Hat, Inc.
-#
-# This file is part of Ansible
-
-
-class FilterModule(object):
- def filters(self):
- return {
- 'strip_newline': self.strip_newline
- }
-
- def strip_newline(self, value):
- # will convert \r\n and \n to just \n
- split_lines = value.splitlines()
-
- return "\n".join(split_lines)
diff --git a/test/integration/targets/win_dsc/library/test_win_dsc_iis_info.ps1 b/test/integration/targets/win_dsc/library/test_win_dsc_iis_info.ps1
deleted file mode 100644
index 3c353d01cc..0000000000
--- a/test/integration/targets/win_dsc/library/test_win_dsc_iis_info.ps1
+++ /dev/null
@@ -1,41 +0,0 @@
-#!powershell
-# This file is part of Ansible
-
-# Copyright (c) 2017 Ansible Project
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-#Requires -Module Ansible.ModuleUtils.Legacy
-
-Import-Module -Name WebAdministration
-$params = Parse-Args $args -supports_check_mode $true
-$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true
-
-$site = Get-Website -Name $name
-
-$result = @{}
-if ($site -eq $null) {
- $result.exists = $false
-} else {
- $result.exists = $true
- $site_config = Get-WebConfiguration -Filter "System.WebServer/Security/Authentication/*" -PSPath "IIS:\Sites\$name"
- $http_bindings = $site.bindings.Collection | Where-Object { $_.protocol -eq "http" }
- $https_bindings = $site.bindings.Collection | Where-Object { $_.protocol -eq "https" }
-
- $result.http = @{
- binding = $http_bindings.bindingInformation
- }
- $result.https = @{
- binding = $https_bindings.bindingInformation
- sslFlags = $https_bindings.sslFlags
- store = ($https_bindings.Attributes | Where-Object { $_.Name -eq "certificateStoreName" }).Value
- hash = ($https_bindings.Attributes | Where-Object { $_.Name -eq "certificateHash" }).Value
- }
- $result.auth = @{
- anonymous = ($site_config | Where-Object { $_.ElementTagName -like "*anonymous*" }).enabled
- basic = ($site_config | Where-Object { $_.ElementTagName -like "*basic*" }).enabled
- digest = ($site_config | Where-Object { $_.ElementTagName -like "*digest*" }).enabled
- windows = ($site_config | Where-Object { $_.ElementTagName -like "*windows*" }).enabled
- }
-}
-
-Exit-Json -obj $result
diff --git a/test/integration/targets/win_dsc/meta/main.yml b/test/integration/targets/win_dsc/meta/main.yml
new file mode 100644
index 0000000000..9f37e96cd9
--- /dev/null
+++ b/test/integration/targets/win_dsc/meta/main.yml
@@ -0,0 +1,2 @@
+dependencies:
+- setup_remote_tmp_dir
diff --git a/test/integration/targets/win_dsc/tasks/destructive.yml b/test/integration/targets/win_dsc/tasks/destructive.yml
deleted file mode 100644
index 86051fe394..0000000000
--- a/test/integration/targets/win_dsc/tasks/destructive.yml
+++ /dev/null
@@ -1,135 +0,0 @@
-# these tests are destructive and can be run manually on a throwaway host
-# set test_win_dsc_run_desctructive: yes in default/main.yml
----
-- name: ensure IIS features are installed
- win_feature:
- name: Web-Server
- include_sub_features: yes
- include_management_tools: no
- state: present
-
-- name: install xWebAdministration module
- win_psmodule:
- name: xWebAdministration
- state: present
-
-- name: ensure IIS website does not exist
- win_iis_website:
- name: Ansible DSC Test
- state: absent
-
-- name: get certificate hash for IIS test
- win_shell: (Get-ChildItem -Path Cert:\LocalMachine\My)[0].Thumbprint
- register: win_dsc_cert_thumbprint
-
-- name: create an IIS website with auth and binding info (check mode)
- win_dsc:
- resource_name: xWebSite
- Ensure: Present
- Name: Ansible DSC Test
- State: Started
- PhysicalPath: C:\inetpub\wwwroot
- BindingInfo:
- - Protocol: https
- Port: 8443
- CertificateStoreName: MY
- CertificateThumbprint: '{{win_dsc_cert_thumbprint.stdout_lines[0]}}'
- HostName: DSCTest
- IPAddress: '*'
- SSLFlags: '1'
- - Protocol: http
- Port: 8888
- IPAddress: '*'
- AuthenticationInfo:
- Anonymous: yes
- Basic: no
- Digest: no
- Windows: yes
- register: win_dsc_iis_check
- check_mode: yes
-
-- name: get result of create an IIS website (check mode)
- test_win_dsc_iis_info:
- name: Ansible DSC Test
- register: win_dsc_iis_check_result
-
-- name: assert results of create an IIS website (check mode)
- assert:
- that:
- - win_dsc_iis_check is changed
- - win_dsc_iis_check_result.exists == False
-
-- name: create an IIS website with auth and binding info
- win_dsc:
- resource_name: xWebSite
- Ensure: Present
- Name: Ansible DSC Test
- State: Started
- PhysicalPath: C:\inetpub\wwwroot
- BindingInfo:
- - Protocol: https
- Port: 8443
- CertificateStoreName: MY
- CertificateThumbprint: '{{win_dsc_cert_thumbprint.stdout_lines[0]}}'
- HostName: Test
- IPAddress: '*'
- SSLFlags: '1'
- - Protocol: http
- Port: 8888
- IPAddress: '*'
- AuthenticationInfo:
- Anonymous: yes
- Basic: no
- Digest: no
- Windows: yes
- register: win_dsc_iis
-
-- name: get result of create an IIS website
- test_win_dsc_iis_info:
- name: Ansible DSC Test
- register: win_dsc_iis_result
-
-- name: assert results of create an IIS website
- assert:
- that:
- - win_dsc_iis is changed
- - win_dsc_iis_result.exists == True
- - win_dsc_iis_result.auth.anonymous == True
- - win_dsc_iis_result.auth.basic == False
- - win_dsc_iis_result.auth.digest == False
- - win_dsc_iis_result.auth.windows == True
- - win_dsc_iis_result.http.binding == "*:8888:"
- - win_dsc_iis_result.https.binding == "*:8443:Test"
- - win_dsc_iis_result.https.hash == '{{win_dsc_cert_thumbprint.stdout_lines[0]}}'
- - win_dsc_iis_result.https.sslFlags == 1
- - win_dsc_iis_result.https.store == "MY"
-
-- name: create an IIS website with auth and binding info (idempotent)
- win_dsc:
- resource_name: xWebSite
- Ensure: Present
- Name: Ansible DSC Test
- State: Started
- PhysicalPath: C:\inetpub\wwwroot
- BindingInfo:
- - Protocol: https
- Port: 8443
- CertificateStoreName: MY
- CertificateThumbprint: '{{win_dsc_cert_thumbprint.stdout_lines[0]}}'
- HostName: Test
- IPAddress: '*'
- SSLFlags: '1'
- - Protocol: http
- Port: 8888
- IPAddress: '*'
- AuthenticationInfo:
- Anonymous: yes
- Basic: no
- Digest: no
- Windows: yes
- register: win_dsc_iis_again
-
-- name: assert results of create an IIS website (idempotent)
- assert:
- that:
- - win_dsc_iis_again is not changed
diff --git a/test/integration/targets/win_dsc/tasks/main.yml b/test/integration/targets/win_dsc/tasks/main.yml
index 1c241e7217..f37295ab71 100644
--- a/test/integration/targets/win_dsc/tasks/main.yml
+++ b/test/integration/targets/win_dsc/tasks/main.yml
@@ -3,32 +3,37 @@
win_shell: $PSVersionTable.PSVersion.Major
register: powershell_version
-- name: run smoke tests when we can't run the full suite
- include_tasks: smoke.yml
+- name: expect failure when running on old PS hosts
+ win_dsc:
+ resource_name: File
+ register: fail_dsc_old
+ failed_when: '"This module cannot run as it requires a minimum PowerShell version of 5.0" not in fail_dsc_old.msg'
when: powershell_version.stdout_lines[0]|int < 5
-- block:
- - name: run non-destructive tests
+- name: run tests when PSv5+
+ when: powershell_version.stdout_lines[0]|int >= 5
+ block:
+ - name: add remote temp dir to PSModulePath
+ win_path:
+ name: PSModulePath
+ state: present
+ scope: machine
+ elements:
+ - '{{ remote_tmp_dir }}'
+
+ - name: copy custom DSC resources to remote temp dir
+ win_copy:
+ src: xTestDsc
+ dest: '{{ remote_tmp_dir }}'
+
+ - name: run tests
include_tasks: tests.yml
-
- - name: run destructive tests if flag is set
- include_tasks: destructive.yml
- when: test_win_dsc_run_desctructive == True
always:
- - name: remove test feature
- win_feature:
- name: '{{test_win_dsc_feature_name}}'
- state: absent
-
- - name: remove test folder
- win_file:
- path: '{{test_win_dsc_folder}}'
+ - name: remove remote tmp dir from PSModulePath
+ win_path:
+ name: PSModulePath
state: absent
-
- - name: remove custom DSC resource folder
- win_file:
- path: C:\Program Files\WindowsPowerShell\Modules\xTestDsc
- state: absent
-
- when: powershell_version.stdout_lines[0]|int >= 5
+ scope: machine
+ elements:
+ - '{{ remote_tmp_dir }}'
diff --git a/test/integration/targets/win_dsc/tasks/smoke.yml b/test/integration/targets/win_dsc/tasks/smoke.yml
deleted file mode 100644
index 5489cf4dfa..0000000000
--- a/test/integration/targets/win_dsc/tasks/smoke.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-# basic smoke tests run on hosts that cannot run DSC, verifies the code is at
-# least runnable
----
-- name: expect failure when running on old PS hosts
- win_dsc:
- resource_name: File
- register: fail_dsc_old
- failed_when: '"This module cannot run as it requires a minimum PowerShell version of 5.0, actual was " not in fail_dsc_old.msg'
diff --git a/test/integration/targets/win_dsc/tasks/tests.yml b/test/integration/targets/win_dsc/tasks/tests.yml
index b855e2fff2..d2a6802fdf 100644
--- a/test/integration/targets/win_dsc/tasks/tests.yml
+++ b/test/integration/targets/win_dsc/tasks/tests.yml
@@ -1,333 +1,544 @@
-# slightly non-destructive tests that will run if WMF 5.0 is installed
---
-- name: start with feature absent
- win_feature:
- name: '{{test_win_dsc_feature_name}}'
- state: absent
-
- name: fail with incorrect DSC resource name
win_dsc:
resource_name: FakeResource
- Name: fake
register: fail_invalid_resource
- failed_when: fail_invalid_resource.msg != "Resource FakeResource not found"
+ failed_when: fail_invalid_resource.msg != "Resource 'FakeResource' not found."
-- name: fail by not setting mandatory option
+- name: fail with invalid DSC version
win_dsc:
- resource_name: WindowsFeature
- Ensure: Present
- register: fail_missing_mandatory
- failed_when: fail_missing_mandatory.msg != "Could not find mandatory property Name. Add this property and try again."
+ resource_name: xTestResource
+ module_version: 0.0.1
+ register: fail_invalid_version
+ failed_when: 'fail_invalid_version.msg != "Resource ''xTestResource'' with version ''0.0.1'' not found. Versions installed: ''1.0.0'', ''1.0.1''."'
-- name: fail to add a non-existant feature
+- name: fail with mandatory option not set
win_dsc:
- resource_name: WindowsFeature
- Name: InvalidFeature
- Ensure: Present
- register: fail_invalid_feature
- failed_when: '"The requested feature InvalidFeature is not found on the target machine" not in fail_invalid_feature.msg'
+ resource_name: xSetReboot
+ Value: yes
+ register: fail_man_key
+ failed_when: 'fail_man_key.msg != "missing required arguments: KeyParam"'
-- name: add Windows feature (check mode)
+- name: fail with mandatory option not set in sub dict
win_dsc:
- resource_name: WindowsFeature
- Name: '{{test_win_dsc_feature_name}}'
+ resource_name: xTestResource
+ Path: C:\path
Ensure: Present
- register: win_dsc_add_feature_check
- check_mode: yes
-
-- name: get result of add Windows feature (check mode)
- win_shell: (Get-WindowsFeature -Name {{test_win_dsc_feature_name}}).Installed
- register: win_dsc_add_feature_result_check
+ CimInstanceParam: # Missing KeyValue in dict
+ Choice: Choice1
+ register: fail_man_key_sub_dict
+ failed_when: 'fail_man_key_sub_dict.msg != "missing required arguments: KeyValue found in CimInstanceParam"'
-- name: assert result of add Windows feature (check mode)
- assert:
- that:
- - win_dsc_add_feature_check is changed
- - win_dsc_add_feature_result_check.stdout == "False\r\n"
+- name: fail invalid option
+ win_dsc:
+ resource_name: xSetReboot
+ KeyParam: key
+ OtherParam: invalid
+ register: fail_invalid_option
+ failed_when: 'fail_invalid_option.msg != "Unsupported parameters for (win_dsc) module: OtherParam. Supported parameters include: KeyParam, PsDscRunAsCredential_username, module_version, Value, PsDscRunAsCredential_password, resource_name, DependsOn"'
-- name: add Windows feature
+- name: fail invalid option in sub dict
win_dsc:
- resource_name: WindowsFeature
- Name: '{{test_win_dsc_feature_name}}'
+ resource_name: xTestResource
+ Path: C:\path
Ensure: Present
- register: win_dsc_add_feature
-
-- name: get result of add Windows feature
- win_shell: (Get-WindowsFeature -Name {{test_win_dsc_feature_name}}).Installed
- register: win_dsc_add_feature_result
-
-- name: assert result of add Windows feature
- assert:
- that:
- - win_dsc_add_feature is changed
- - win_dsc_add_feature_result.stdout == "True\r\n"
-
-- name: add Windows feature (idempotent)
+ NestedCimInstanceParam:
+ KeyValue: key
+ CimValue:
+ KeyValue: other key
+ InvalidKey: invalid
+ register: fail_invalid_option_sub_dict
+ failed_when: 'fail_invalid_option_sub_dict.msg != "Unsupported parameters for (win_dsc) module: InvalidKey found in NestedCimInstanceParam -> CimValue. Supported parameters include: IntValue, KeyValue, StringArrayValue, Choice, StringValue"'
+
+- name: fail invalid read only option
win_dsc:
- resource_name: WindowsFeature
- Name: '{{test_win_dsc_feature_name}}'
+ resource_name: xTestResource
+ Path: C:\path
Ensure: Present
- register: win_dsc_add_feature_again
-
-- name: assert result of add Windows feature (idempotent)
- assert:
- that:
- - win_dsc_add_feature_again is not changed
+ ReadParam: abc
+ register: fail_invalid_option_read_only
+ failed_when: '"Unsupported parameters for (win_dsc) module: ReadParam" not in fail_invalid_option_read_only.msg'
-- name: remove Windows feature (check mode)
+- name: fail invalid choice
win_dsc:
- resource_name: WindowsFeature
- Name: '{{test_win_dsc_feature_name}}'
- Ensure: Absent
- register: win_dsc_remove_feature_check
- check_mode: yes
-
-- name: get result of remove Windows feature (check mode)
- win_shell: (Get-WindowsFeature -Name {{test_win_dsc_feature_name}}).Installed
- register: win_dsc_remove_feature_result_check
-
-- name: assert result of remove Windows feature (check mode)
- assert:
- that:
- - win_dsc_remove_feature_check is changed
- - win_dsc_remove_feature_result_check.stdout == "True\r\n"
+ resource_name: xTestResource
+ Path: C:\path
+ Ensure: invalid
+ register: fail_invalid_choice
+ failed_when: 'fail_invalid_choice.msg != "value of Ensure must be one of: Present, Absent. Got no match for: invalid"'
-- name: remove Windows feature
+- name: fail invalid choice in sub dict
win_dsc:
- resource_name: WindowsFeature
- Name: '{{test_win_dsc_feature_name}}'
- Ensure: Absent
- register: win_dsc_remove_feature
-
-- name: get result of remove Windows feature
- win_shell: (Get-WindowsFeature -Name {{test_win_dsc_feature_name}}).Installed
- register: win_dsc_remove_feature_result
-
-- name: assert result of remove Windows feature
- assert:
- that:
- - win_dsc_remove_feature is changed
- - win_dsc_remove_feature_result.stdout == "False\r\n"
+ resource_name: xTestResource
+ Path: C:\path
+ Ensure: Present
+ CimInstanceArrayParam:
+ - KeyValue: key
+ - KeyValue: key2
+ Choice: Choice3
+ register: fail_invalid_choice_sub_dict
+ failed_when: 'fail_invalid_choice_sub_dict.msg != "value of Choice must be one of: Choice1, Choice2. Got no match for: Choice3 found in CimInstanceArrayParam"'
-- name: remove Windows feature (idempotent)
+- name: fail old version missing new option
win_dsc:
- resource_name: WindowsFeature
- Name: '{{test_win_dsc_feature_name}}'
- Ensure: Absent
- register: win_dsc_remove_feature_again
-
-- name: assert result of remove Windows feature (idempotent)
- assert:
- that:
- - win_dsc_remove_feature_again is not changed
+ resource_name: xTestResource
+ module_version: 1.0.0
+ Path: C:\path
+ Ensure: Present
+ CimInstanceParam: # CimInstanceParam does not exist in the 1.0.0 version
+ Key: key
+ register: fail_invalid_option_old
+ failed_when: '"Unsupported parameters for (win_dsc) module: CimInstanceParam" not in fail_invalid_option_old.msg'
-- name: ensure test folder doesn't exist before test
- win_file:
- path: '{{test_win_dsc_folder}}'
- state: absent
+- name: fail old version missing new option sub dict
+ win_dsc:
+ resource_name: xTestResource
+ module_version: 1.0.0
+ Path: C:\path
+ Ensure: Present
+ CimInstanceArrayParam:
+ - Key: key
+ Choice: Choice1
+ register: fail_invalid_option_old_sub_dict
+ failed_when: 'fail_invalid_option_old_sub_dict.msg != "Unsupported parameters for (win_dsc) module: Choice found in CimInstanceArrayParam. Supported parameters include: Key, IntValue, StringArrayValue, StringValue"'
- name: create test file (check mode)
win_dsc:
resource_name: File
- DestinationPath: '{{test_win_dsc_folder}}\dsc-file'
+ DestinationPath: '{{ remote_tmp_dir }}\dsc-file'
Contents: file contents
Attributes:
- Hidden
- ReadOnly
Ensure: Present
Type: File
- register: win_dsc_create_file_check
+ register: create_file_check
check_mode: yes
- name: get result of create test file (check mode)
win_stat:
- path: '{{test_win_dsc_folder}}\dsc-file'
- register: win_dsc_create_file_result_check
+ path: '{{ remote_tmp_dir }}\dsc-file'
+ register: create_file_actual_check
+
+- name: assert create test file (check mode)
+ assert:
+ that:
+ - create_file_check is changed
+ - create_file_check.module_version == None # Some built in modules don't have a version set
+ - not create_file_check.reboot_required
+ - not create_file_actual_check.stat.exists
-- name: assert results of create test file (check mode)
+- name: assert create test file verbosity (check mode)
assert:
that:
- - win_dsc_create_file_check is changed
- - win_dsc_create_file_result_check.stat.exists == False
+ - create_file_check.verbose_test is defined
+ - not create_file_check.verbose_set is defined
+ when: ansible_verbosity >= 3
- name: create test file
win_dsc:
resource_name: File
- DestinationPath: '{{test_win_dsc_folder}}\dsc-file'
+ DestinationPath: '{{ remote_tmp_dir }}\dsc-file'
Contents: file contents
Attributes:
- Hidden
- ReadOnly
Ensure: Present
Type: File
- register: win_dsc_create_file
+ register: create_file
- name: get result of create test file
win_stat:
- path: '{{test_win_dsc_folder}}\dsc-file'
- register: win_dsc_create_file_result
+ path: '{{ remote_tmp_dir }}\dsc-file'
+ register: create_file_actual
-- name: assert results of create test file
+- name: assert create test file verbosity
assert:
that:
- - win_dsc_create_file is changed
- - win_dsc_create_file_result.stat.exists == True
- - win_dsc_create_file_result.stat.isdir == False
- - win_dsc_create_file_result.stat.ishidden == True
- - win_dsc_create_file_result.stat.isreadonly == True
+ - create_file.verbose_test is defined
+ - create_file.verbose_set is defined
+ when: ansible_verbosity >= 3
+
+- name: assert create test file
+ assert:
+ that:
+ - create_file is changed
+ - create_file.module_version == None
+ - not create_file.reboot_required
+ - create_file_actual.stat.exists
+ - create_file_actual.stat.attributes == "ReadOnly, Hidden, Archive"
+ - create_file_actual.stat.checksum == 'd48daab51112b49ecabd917adc345b8ba257055e'
- name: create test file (idempotent)
win_dsc:
resource_name: File
- DestinationPath: '{{test_win_dsc_folder}}\dsc-file'
+ DestinationPath: '{{ remote_tmp_dir }}\dsc-file'
Contents: file contents
- Attributes: Hidden, ReadOnly
+ Attributes:
+ - Hidden
+ - ReadOnly
Ensure: Present
Type: File
- register: win_dsc_create_file_again
+ register: create_file_again
-- name: assert results of create test file (idempotent)
+- name: assert create test file (idempotent)
assert:
that:
- - win_dsc_create_file_again is not changed
+ - not create_file_again is changed
+ - create_file.module_version == None
+ - not create_file.reboot_required
-- name: get SID of current ansible user
- win_shell: (New-Object System.Security.Principal.NTAccount("{{ansible_user}}")).Translate([System.Security.Principal.SecurityIdentifier]).ToString()
- register: win_dsc_actual_sid
+- name: get SID of the current Ansible user
+ win_shell: |
+ Add-Type -AssemblyName System.DirectoryServices.AccountManagement
+ [System.DirectoryServices.AccountManagement.UserPrincipal]::Current.Sid.Value
+ register: actual_sid
- name: run DSC process as another user
win_dsc:
resource_name: Script
- GetScript: '@{ Result = "" }'
+ GetScript: '@{ Result= "" }'
SetScript: |
- $output = &whoami.exe
- $sid = (New-Object System.Security.Principal.NTAccount($output)).Translate([System.Security.Principal.SecurityIdentifier]).ToString()
- Set-Content -Path "{{test_win_dsc_folder}}\file" -Value $sid
- TestScript: Test-Path -Path "{{test_win_dsc_folder}}\file"
- PsDscRunAsCredential_username: '{{ansible_user}}'
- PsDscRunAsCredential_password: '{{ansible_password}}'
- register: win_dsc_runas
-
-- name: get content of script output file
+ Add-Type -AssemblyName System.DirectoryServices.AccountManagement
+ $sid = [System.DirectoryServices.AccountManagement.UserPrincipal]::Current.Sid.Value
+ Set-Content -Path "{{ remote_tmp_dir }}\runas.txt" -Value $sid
+ TestScript: $false
+ PsDscRunAsCredential_username: '{{ ansible_user }}'
+ PsDscRunAsCredential_password: '{{ ansible_password }}'
+ register: runas_user
+
+- name: get result of run DSC process as another user
slurp:
- path: '{{test_win_dsc_folder}}\file'
- register: win_dsc_runas_result
+ path: '{{ remote_tmp_dir }}\runas.txt'
+ register: runas_user_result
+
+- name: assert run DSC process as another user
+ assert:
+ that:
+ - runas_user is changed
+ - runas_user.module_version != None # Can't reliably set the version but we can test it is set
+ - not runas_user.reboot_required
+ - runas_user_result.content|b64decode == actual_sid.stdout
-- name: assert results of run DSC process as another user
+- name: run DSC that sets reboot_required with defaults
+ win_dsc:
+ resource_name: xSetReboot
+ KeyParam: value # Just to satisfy the Resource with key validation
+ register: set_reboot_defaults
+
+- name: assert run DSC that sets reboot_required with defaults
+ assert:
+ that:
+ - set_reboot_defaults.reboot_required
+
+- name: run DSC that sets reboot_required with False
+ win_dsc:
+ resource_name: xSetReboot
+ KeyParam: value
+ Value: no
+ register: set_reboot_false
+
+- name: assert run DSC that sets reboot_required with False
assert:
that:
- - win_dsc_runas is changed
- - win_dsc_runas_result.content|b64decode == win_dsc_actual_sid.stdout
-
-- name: create custom DSC resource folder
- win_file:
- path: C:\Program Files\WindowsPowerShell\Modules\xTestDsc\{{item}}\DSCResources\ANSIBLE_xTestResource
- state: directory
- with_items:
- - "1.0.0"
- - "2.0.0"
-
-- name: template custom DSC resource files
- win_template:
- src: '{{item.src}}'
- dest: C:\Program Files\WindowsPowerShell\Modules\xTestDsc\{{item.version}}\{{item.dest}}
- with_items:
- - src: ANSIBLE_xTestResource.schema.mof
- dest: DSCResources\ANSIBLE_xTestResource\ANSIBLE_xTestResource.schema.mof
- version: "1.0.0"
- - src: ANSIBLE_xTestResource.psm1
- dest: DSCResources\ANSIBLE_xTestResource\ANSIBLE_xTestResource.psm1
- version: "1.0.0"
- - src: xTestDsc.psd1
- dest: xTestDsc.psd1
- version: "1.0.0"
- - src: ANSIBLE_xTestResource.schema.mof
- dest: DSCResources\ANSIBLE_xTestResource\ANSIBLE_xTestResource.schema.mof
- version: "2.0.0"
- - src: ANSIBLE_xTestResource.psm1
- dest: DSCResources\ANSIBLE_xTestResource\ANSIBLE_xTestResource.psm1
- version: "2.0.0"
- - src: xTestDsc.psd1
- dest: xTestDsc.psd1
- version: "2.0.0"
-
-- name: run custom DSC resource
- win_dsc: &dsc_params
+ - not set_reboot_false.reboot_required
+
+- name: run DSC that sets reboot_required with True
+ win_dsc:
+ resource_name: xSetReboot
+ KeyParam: value
+ Value: yes
+ register: set_reboot_true
+
+- name: assert run DSC that sets reboot_required with True
+ assert:
+ that:
+ - set_reboot_true.reboot_required
+
+- name: test DSC with all types
+ win_dsc:
resource_name: xTestResource
- Path: '{{test_win_dsc_folder}}\custom-output.txt'
+ Path: '{{ remote_tmp_dir }}\test-types.json'
Ensure: Present
StringParam: string param
- UInt32Param: 1000
- UInt64Param: 1000000
StringArrayParam:
- string 1
- string 2
+ Int8Param: 127 # [SByte]::MaxValue
+ Int8ArrayParam:
+ - 127
+ - '127'
+ UInt8Param: 255 # [Byte]::MaxValue
+ UInt8ArrayParam:
+ - 255
+ - '255'
+ Int16Param: 32767 # [Int16]::MaxValue
+ Int16ArrayParam: 32767, 32767
+ UInt16Param: '65535' # [UInt16]::MaxValue
+ UInt16ArrayParam: 65535
+ Int32Param: 2147483647 # [Int32]::MaxValue
+ Int32ArrayParam: '2147483647'
+ UInt32Param: '4294967295' # [UInt32]::MaxValue
UInt32ArrayParam:
- - 1000
- - 2000
+ - '4294967295'
+ - 4294967295
+ Int64Param: 9223372036854775807 # [Int64]::MaxValue
+ Int64ArrayParam:
+ - -9223372036854775808 # [Int64]::MinValue
+ - 9223372036854775807
+ UInt64Param: 18446744073709551615 # [UInt64]::MaxValue
UInt64ArrayParam:
- - 1000000
- - 2000000
- BooleanParam: yes
- PSCredentialParam_username: username
- PSCredentialParam_password: password
+ - 0 # [UInt64]::MinValue
+ - 18446744073709551615
+ BooleanParam: True
+ BooleanArrayParam:
+ - True
+ - 'True'
+ - 'true'
+ - 'y'
+ - 'yes'
+ - 1
+ - False
+ - 'False'
+ - 'false'
+ - 'n'
+ - 'no'
+ - 0
+ CharParam: c
+ CharArrayParam:
+ - c
+ - h
+ - a
+ - r
+ SingleParam: 3.402823E+38
+ SingleArrayParam:
+ - '3.402823E+38'
+ - 1.2393494
+ DoubleParam: 1.79769313486232E+300
+ DoubleArrayParam:
+ - '1.79769313486232E+300'
+ - 3.56821831681516
+ DateTimeParam: '2019-02-22T13:57:31.2311892-04:00'
+ DateTimeArrayParam:
+ - '2019-02-22T13:57:31.2311892+00:00'
+ - '2019-02-22T13:57:31.2311892+04:00'
+ PSCredentialParam_username: username1
+ PSCredentialParam_password: password1
+ HashtableParam:
+ key1: string 1
+ key2: ''
+ key3: 1
CimInstanceParam:
- StringKey: a
- BooleanKey: yes
- UInt32Key: 1
- StringArrayKey:
- - string 1
- - string 2
+ KeyValue: a
CimInstanceArrayParam:
- - StringKey: b
- BooleanKey: no
- UInt32Key: 2
- StringArrayKey:
- - string 3
- - string 4
- - StringKey: c
- BooleanKey: no
- UInt32Key: 3
- StringArrayKey:
- - string 5
- - string 6
- register: test_dsc_custom
-
-- name: get output of custom DSC resource
+ - KeyValue: b
+ Choice: Choice1
+ StringValue: string 1
+ IntValue: 1
+ StringArrayValue:
+ - abc
+ - def
+ - KeyValue: c
+ Choice: Choice2
+ StringValue: string 2
+ IntValue: '2'
+ StringArrayValue:
+ - ghi
+ - jkl
+ NestedCimInstanceParam:
+ KeyValue: key value
+ CimValue:
+ KeyValue: d
+ CimArrayValue:
+ - KeyValue: e
+ Choice: Choice2
+ HashValue:
+ a: a
+ IntValue: '300'
+ register: dsc_types
+
+- name: get result of test DSC with all types
slurp:
- path: '{{test_win_dsc_folder}}\custom-output.txt'
- register: test_dsc_custom_output
+ path: '{{ remote_tmp_dir }}\test-types.json'
+ register: dsc_types_raw
-- name: get expected output of custom DSC resource
+- name: convert result of test DSC with all types to dict
set_fact:
- test_dsc_custom_expected: '{{lookup("file", "custom-result-normal.txt")}}'
+ dsc_types_actual: '{{ dsc_types_raw.content | b64decode | from_json }}'
-- name: assert result of custom DSC resource
+- name: assert test DSC with all types
assert:
that:
- - test_dsc_custom is changed
- - test_dsc_custom_output.content|b64decode|strip_newline == test_dsc_custom_expected|strip_newline
- - test_dsc_custom.warnings | length == 2
- - "'[[xTestResource]DirectResourceAccess] test warning' in test_dsc_custom.warnings[0]"
- - "'[[xTestResource]DirectResourceAccess] set warning' in test_dsc_custom.warnings[1]"
-
-- name: run custom DSC resource with version
+ - dsc_types is changed
+ - dsc_types.module_version == '1.0.1'
+ - not dsc_types.reboot_required
+ - dsc_types_actual.Version == '1.0.1'
+ - dsc_types_actual.Verbose.Value.IsPresent
+ - dsc_types_actual.DefaultParam.Value == 'Default' # ensures that the default is set in the engine if we don't set it outselves
+ - dsc_types_actual.Ensure.Value == 'Present'
+ - dsc_types_actual.Path.Value == remote_tmp_dir + "\\test-types.json"
+ - dsc_types_actual.StringParam.Type == 'System.String'
+ - dsc_types_actual.StringParam.Value == 'string param'
+ - dsc_types_actual.StringArrayParam.Type == 'System.String[]'
+ - dsc_types_actual.StringArrayParam.Value == ['string 1', 'string 2']
+ - dsc_types_actual.Int8Param.Type == 'System.SByte'
+ - dsc_types_actual.Int8Param.Value == 127
+ - dsc_types_actual.Int8ArrayParam.Type == 'System.SByte[]'
+ - dsc_types_actual.Int8ArrayParam.Value == [127, 127]
+ - dsc_types_actual.UInt8Param.Type == 'System.Byte'
+ - dsc_types_actual.UInt8Param.Value == 255
+ - dsc_types_actual.UInt8ArrayParam.Type == 'System.Byte[]'
+ - dsc_types_actual.UInt8ArrayParam.Value == [255, 255]
+ - dsc_types_actual.Int16Param.Type == 'System.Int16'
+ - dsc_types_actual.Int16Param.Value == 32767
+ - dsc_types_actual.Int16ArrayParam.Type == 'System.Int16[]'
+ - dsc_types_actual.Int16ArrayParam.Value == [32767, 32767]
+ - dsc_types_actual.UInt16Param.Type == 'System.UInt16'
+ - dsc_types_actual.UInt16Param.Value == 65535
+ - dsc_types_actual.UInt16ArrayParam.Type == 'System.UInt16[]'
+ - dsc_types_actual.UInt16ArrayParam.Value == [65535]
+ - dsc_types_actual.Int32Param.Type == 'System.Int32'
+ - dsc_types_actual.Int32Param.Value == 2147483647
+ - dsc_types_actual.Int32ArrayParam.Type == 'System.Int32[]'
+ - dsc_types_actual.Int32ArrayParam.Value == [2147483647]
+ - dsc_types_actual.UInt32Param.Type == 'System.UInt32'
+ - dsc_types_actual.UInt32Param.Value == 4294967295
+ - dsc_types_actual.UInt32ArrayParam.Type == 'System.UInt32[]'
+ - dsc_types_actual.UInt32ArrayParam.Value == [4294967295, 4294967295]
+ - dsc_types_actual.Int64Param.Type == 'System.Int64'
+ - dsc_types_actual.Int64Param.Value == 9223372036854775807
+ - dsc_types_actual.Int64ArrayParam.Type == 'System.Int64[]'
+ - dsc_types_actual.Int64ArrayParam.Value == [-9223372036854775808, 9223372036854775807]
+ - dsc_types_actual.UInt64Param.Type == 'System.UInt64'
+ - dsc_types_actual.UInt64Param.Value == 18446744073709551615
+ - dsc_types_actual.UInt64ArrayParam.Type == 'System.UInt64[]'
+ - dsc_types_actual.UInt64ArrayParam.Value == [0, 18446744073709551615]
+ - dsc_types_actual.BooleanParam.Type == 'System.Boolean'
+ - dsc_types_actual.BooleanParam.Value == True
+ - dsc_types_actual.BooleanArrayParam.Type == 'System.Boolean[]'
+ - dsc_types_actual.BooleanArrayParam.Value == [True, True, True, True, True, True, False, False, False, False, False, False]
+ - dsc_types_actual.CharParam.Type == 'System.Char'
+ - dsc_types_actual.CharParam.Value == 'c'
+ - dsc_types_actual.CharArrayParam.Type == 'System.Char[]'
+ - dsc_types_actual.CharArrayParam.Value == ['c', 'h', 'a', 'r']
+ - dsc_types_actual.SingleParam.Type == 'System.Single'
+ - dsc_types_actual.SingleParam.Value|string == '3.402823e+38'
+ - dsc_types_actual.SingleArrayParam.Type == 'System.Single[]'
+ - dsc_types_actual.SingleArrayParam.Value|length == 2
+ - dsc_types_actual.SingleArrayParam.Value[0]|string == '3.402823e+38'
+ - dsc_types_actual.SingleArrayParam.Value[1]|string == '1.23934937'
+ - dsc_types_actual.DoubleParam.Type == 'System.Double'
+ - dsc_types_actual.DoubleParam.Value == '1.79769313486232E+300'
+ - dsc_types_actual.DoubleArrayParam.Type == 'System.Double[]'
+ - dsc_types_actual.DoubleArrayParam.Value|length == 2
+ - dsc_types_actual.DoubleArrayParam.Value[0] == '1.79769313486232E+300'
+ - dsc_types_actual.DoubleArrayParam.Value[1] == '3.56821831681516'
+ - dsc_types_actual.DateTimeParam.Type == 'System.DateTime'
+ - dsc_types_actual.DateTimeParam.Value == '2019-02-22T17:57:31.2311890+00:00'
+ - dsc_types_actual.DateTimeArrayParam.Type == 'System.DateTime[]'
+ - dsc_types_actual.DateTimeArrayParam.Value == ['2019-02-22T13:57:31.2311890+00:00', '2019-02-22T09:57:31.2311890+00:00']
+ - dsc_types_actual.PSCredentialParam.Type == 'System.Management.Automation.PSCredential'
+ - dsc_types_actual.PSCredentialParam.Value.username == 'username1'
+ - dsc_types_actual.PSCredentialParam.Value.password == 'password1'
+ # Hashtable is actually a CimInstance[] of MSFT_KeyValuePairs
+ - dsc_types_actual.HashtableParam.Type == 'Microsoft.Management.Infrastructure.CimInstance[]'
+ - dsc_types_actual.HashtableParam.Value|length == 3
+ # Can't guarantee the order of the keys so just check they are the values they could be
+ - dsc_types_actual.HashtableParam.Value[0].Key in ["key1", "key2", "key3"]
+ - dsc_types_actual.HashtableParam.Value[0].Value in ["string 1", "1", ""]
+ - dsc_types_actual.HashtableParam.Value[0]._cim_instance == 'MSFT_KeyValuePair'
+ - dsc_types_actual.HashtableParam.Value[1].Key in ["key1", "key2", "key3"]
+ - dsc_types_actual.HashtableParam.Value[1].Value in ["string 1", "1", ""]
+ - dsc_types_actual.HashtableParam.Value[1]._cim_instance == 'MSFT_KeyValuePair'
+ - dsc_types_actual.HashtableParam.Value[2].Key in ["key1", "key2", "key3"]
+ - dsc_types_actual.HashtableParam.Value[2].Value in ["string 1", "1", ""]
+ - dsc_types_actual.HashtableParam.Value[2]._cim_instance == 'MSFT_KeyValuePair'
+ - dsc_types_actual.CimInstanceParam.Type == 'Microsoft.Management.Infrastructure.CimInstance'
+ - dsc_types_actual.CimInstanceParam.Value.Choice == None
+ - dsc_types_actual.CimInstanceParam.Value.IntValue == None
+ - dsc_types_actual.CimInstanceParam.Value.KeyValue == 'a'
+ - dsc_types_actual.CimInstanceParam.Value.StringArrayValue == None
+ - dsc_types_actual.CimInstanceParam.Value.StringValue == None
+ - dsc_types_actual.CimInstanceParam.Value._cim_instance == "ANSIBLE_xTestClass"
+ - dsc_types_actual.CimInstanceArrayParam.Type == 'Microsoft.Management.Infrastructure.CimInstance[]'
+ - dsc_types_actual.CimInstanceArrayParam.Value|length == 2
+ - dsc_types_actual.CimInstanceArrayParam.Value[0].Choice == 'Choice1'
+ - dsc_types_actual.CimInstanceArrayParam.Value[0].IntValue == 1
+ - dsc_types_actual.CimInstanceArrayParam.Value[0].KeyValue == 'b'
+ - dsc_types_actual.CimInstanceArrayParam.Value[0].StringArrayValue == ['abc', 'def']
+ - dsc_types_actual.CimInstanceArrayParam.Value[0].StringValue == 'string 1'
+ - dsc_types_actual.CimInstanceArrayParam.Value[0]._cim_instance == 'ANSIBLE_xTestClass'
+ - dsc_types_actual.CimInstanceArrayParam.Value[1].Choice == 'Choice2'
+ - dsc_types_actual.CimInstanceArrayParam.Value[1].IntValue == 2
+ - dsc_types_actual.CimInstanceArrayParam.Value[1].KeyValue == 'c'
+ - dsc_types_actual.CimInstanceArrayParam.Value[1].StringArrayValue == ['ghi', 'jkl']
+ - dsc_types_actual.CimInstanceArrayParam.Value[1].StringValue == 'string 2'
+ - dsc_types_actual.CimInstanceArrayParam.Value[1]._cim_instance == 'ANSIBLE_xTestClass'
+ - dsc_types_actual.NestedCimInstanceParam.Type == 'Microsoft.Management.Infrastructure.CimInstance'
+ - dsc_types_actual.NestedCimInstanceParam.Value.CimArrayValue|length == 1
+ - dsc_types_actual.NestedCimInstanceParam.Value.CimArrayValue[0].Choice == 'Choice2'
+ - dsc_types_actual.NestedCimInstanceParam.Value.CimArrayValue[0].IntValue == None
+ - dsc_types_actual.NestedCimInstanceParam.Value.CimArrayValue[0].KeyValue == 'e'
+ - dsc_types_actual.NestedCimInstanceParam.Value.CimArrayValue[0].StringArrayValue == None
+ - dsc_types_actual.NestedCimInstanceParam.Value.CimArrayValue[0].StringValue == None
+ - dsc_types_actual.NestedCimInstanceParam.Value.CimArrayValue[0]._cim_instance == 'ANSIBLE_xTestClass'
+ - dsc_types_actual.NestedCimInstanceParam.Value.CimValue.Choice == None
+ - dsc_types_actual.NestedCimInstanceParam.Value.CimValue.IntValue == None
+ - dsc_types_actual.NestedCimInstanceParam.Value.CimValue.KeyValue == 'd'
+ - dsc_types_actual.NestedCimInstanceParam.Value.CimValue.StringArrayValue == None
+ - dsc_types_actual.NestedCimInstanceParam.Value.CimValue.StringValue == None
+ - dsc_types_actual.NestedCimInstanceParam.Value.CimValue._cim_instance == 'ANSIBLE_xTestClass'
+ - dsc_types_actual.NestedCimInstanceParam.Value.HashValue|length == 1
+ - dsc_types_actual.NestedCimInstanceParam.Value.HashValue[0].Key == 'a'
+ - dsc_types_actual.NestedCimInstanceParam.Value.HashValue[0].Value == 'a'
+ - dsc_types_actual.NestedCimInstanceParam.Value.HashValue[0]._cim_instance == 'MSFT_KeyValuePair'
+ - dsc_types_actual.NestedCimInstanceParam.Value.IntValue == 300
+ - dsc_types_actual.NestedCimInstanceParam.Value.KeyValue == 'key value'
+ - dsc_types_actual.NestedCimInstanceParam.Value._cim_instance == 'ANSIBLE_xNestedClass'
+
+- name: test DSC with all types older version
win_dsc:
- <<: *dsc_params
- module_version: '1.0.0'
- register: test_dsc_custom_version
-
-- name: get output of custom DSC resource with version
+ resource_name: xTestResource
+ module_version: 1.0.0
+ Path: '{{ remote_tmp_dir }}\test-types.json'
+ Ensure: Absent
+ StringParam: string param old
+ CimInstanceArrayParam:
+ - Key: old key
+ StringValue: string old 1
+ IntValue: 0
+ StringArrayValue:
+ - zyx
+ - wvu
+ register: dsc_types_old
+
+- name: get result of test DSC with all types older version
slurp:
- path: '{{test_win_dsc_folder}}\custom-output.txt'
- register: test_dsc_custom_output_version
+ path: '{{ remote_tmp_dir }}\test-types.json'
+ register: dsc_types_old_raw
-- name: get expected output of custom DSC resource with version
+- name: convert result of test DSC with all types to dict
set_fact:
- test_dsc_custom_expected_version: '{{lookup("file", "custom-result-versioned.txt")}}'
+ dsc_types_old_actual: '{{ dsc_types_old_raw.content | b64decode | from_json }}'
-- name: assert result of custom DSC resource with version
+- name: assert test DSC with all types older version
assert:
that:
- - test_dsc_custom is changed
- - test_dsc_custom_output_version.content|b64decode|strip_newline == test_dsc_custom_expected_version|strip_newline
+ - dsc_types_old is changed
+ - dsc_types_old.module_version == '1.0.0'
+ - not dsc_types_old.reboot_required
+ - dsc_types_old_actual.Version == '1.0.0'
+ - dsc_types_old_actual.Verbose.Value.IsPresent
+ - dsc_types_old_actual.DefaultParam.Value == 'Default'
+ - dsc_types_old_actual.Ensure.Value == 'Absent'
+ - dsc_types_old_actual.Path.Value == remote_tmp_dir + "\\test-types.json"
+ - dsc_types_old_actual.StringParam.Type == 'System.String'
+ - dsc_types_old_actual.StringParam.Value == 'string param old'
+ - dsc_types_old_actual.CimInstanceArrayParam.Type == 'Microsoft.Management.Infrastructure.CimInstance[]'
+ - dsc_types_old_actual.CimInstanceArrayParam.Value|length == 1
+ - not dsc_types_old_actual.CimInstanceArrayParam.Value[0].Choice is defined # 1.0.0 does not have a Choice option
+ - dsc_types_old_actual.CimInstanceArrayParam.Value[0].IntValue == 0
+ - dsc_types_old_actual.CimInstanceArrayParam.Value[0].Key == 'old key'
+ - dsc_types_old_actual.CimInstanceArrayParam.Value[0].StringArrayValue == ['zyx', 'wvu']
+ - dsc_types_old_actual.CimInstanceArrayParam.Value[0].StringValue == 'string old 1'
+ - dsc_types_old_actual.CimInstanceArrayParam.Value[0]._cim_instance == 'ANSIBLE_xTestClass'
diff --git a/test/integration/targets/win_dsc/templates/ANSIBLE_xTestResource.psm1 b/test/integration/targets/win_dsc/templates/ANSIBLE_xTestResource.psm1
deleted file mode 100644
index a7cd3bad1c..0000000000
--- a/test/integration/targets/win_dsc/templates/ANSIBLE_xTestResource.psm1
+++ /dev/null
@@ -1,175 +0,0 @@
-#Requires -Version 5.0 -Modules CimCmdlets
-
-Function Get-TargetResource
-{
- [CmdletBinding()]
- [OutputType([Hashtable])]
- param(
- [Parameter(Mandatory = $true)]
- [ValidateSet("Present", "Absent")]
- [String]
- $Ensure = "Present",
-
- [Parameter(Mandatory = $true)]
- [ValidateNotNullOrEmpty()]
- [String]
- $Path
- )
- return @{
- Ensure = $Ensure
- Path = $Path
- }
-}
-
-Function Set-TargetResource
-{
- [CmdletBinding()]
- param
- (
- [Parameter(Mandatory = $true)]
- [ValidateSet("Present", "Absent")]
- [String]
- $Ensure = "Present",
-
- [Parameter(Mandatory = $true)]
- [ValidateNotNullOrEmpty()]
- [String]
- $Path,
-
- [String]
- $StringParam,
-
- [UInt32]
- $UInt32Param,
-
- [UInt64]
- $UInt64Param,
-
- [String[]]
- $StringArrayParam,
-
- [UInt32[]]
- $UInt32ArrayParam,
-
- [UInt64[]]
- $UInt64ArrayParam,
-
- [Boolean]
- $BooleanParam,
-
- [PSCredential]
- $PSCredentialParam,
-
- [Microsoft.Management.Infrastructure.CimInstance]
- $CimInstanceParam,
-
- [Microsoft.Management.Infrastructure.CimInstance[]]
- $CimInstanceArrayParam
- )
-
- $file_contents = @"
-xTestResource Version: {{item.version}}
-
-Ensure:
- Type: $($Ensure.GetType().FullName)
- Value: $($Ensure.ToString())
-
-StringParam:
- Type: $($StringParam.GetType().FullName)
- Value: $($StringParam)
-
-UInt32Param:
- Type: $($UInt32Param.GetType().FullName)
- Value: $($UInt32Param.ToString())
-
-UInt64Param:
- Type: $($UInt64Param.GetType().FullName)
- Value: $($UInt64Param.ToString())
-
-StringArrayParam:
- Type: $($StringArrayParam.GetType().FullName)
- Value: [ "$($StringArrayParam -join '", "')" ]
-
-UInt32ArrayParam:
- Type: $($UInt32ArrayParam.GetType().FullName)
- Value: [ $($UInt32ArrayParam -join ', ') ]
-
-UInt64ArrayParam:
- Type: $($UInt64ArrayParam.GetType().FullName)
- Value: [ $($UInt64ArrayParam -join ', ') ]
-
-BooleanParam:
- Type: $($BooleanParam.GetType().FullName)
- Value: $($BooleanParam.ToString())
-
-PSCredentialParam:
- Type: $($PSCredentialParam.GetType().FullName)
- Username: $($PSCredentialParam.GetNetworkCredential().Username)
- Password: $($PSCredentialParam.GetNetworkCredential().Password)
-
-CimInstanceParam:
- Type: $($CimInstanceParam.GetType().FullName)
-
-CimInstanceArrayParam:
- Type: $($CimInstanceArrayParam.GetType().FullName)
-"@
- if (Test-Path -Path $Path)
- {
- Remove-Item -Path $Path -Force > $null
- }
- New-Item -Path $Path -ItemType File > $null
- Set-Content -Path $Path -Value $file_contents > $null
- Write-Warning -Message "set warning"
-}
-
-Function Test-TargetResource
-{
- [CmdletBinding()]
- [OutputType([Boolean])]
- param
- (
- [Parameter(Mandatory = $true)]
- [ValidateSet("Present", "Absent")]
- [String]
- $Ensure = "Present",
-
- [Parameter(Mandatory = $true)]
- [ValidateNotNullOrEmpty()]
- [String]
- $Path,
-
- [String]
- $StringParam,
-
- [UInt32]
- $UInt32Param,
-
- [UInt64]
- $UInt64Param,
-
- [String[]]
- $StringArrayParam,
-
- [UInt32[]]
- $UInt32ArrayParam,
-
- [UInt64[]]
- $UInt64ArrayParam,
-
- [Boolean]
- $BooleanParam,
-
- [PSCredential]
- $PSCredentialParam,
-
- [Microsoft.Management.Infrastructure.CimInstance]
- $CimInstanceParam,
-
- [Microsoft.Management.Infrastructure.CimInstance[]]
- $CimInstanceArrayParam
- )
- Write-Warning -Message "test warning"
- return $false
-}
-
-Export-ModuleMember -Function *-TargetResource
diff --git a/test/integration/targets/win_dsc/templates/ANSIBLE_xTestResource.schema.mof b/test/integration/targets/win_dsc/templates/ANSIBLE_xTestResource.schema.mof
deleted file mode 100644
index 00632f3f55..0000000000
--- a/test/integration/targets/win_dsc/templates/ANSIBLE_xTestResource.schema.mof
+++ /dev/null
@@ -1,25 +0,0 @@
-[ClassVersion("{{item.version}}")]
-class ANSIBLE_xTestClass
-{
- [Write] String StringKey;
- [Write] Boolean BooleanKey;
- [Write] UInt32 UInt32Key;
- [Write] String StringArrayKey[];
-};
-
-[ClassVersion("{{item.version}}"), FriendlyName("xTestResource")]
-class ANSIBLE_xTestResource : OMI_BaseResource
-{
- [Key] String Path;
- [Required, ValueMap{"Present", "Absent"}, Values{"Present", "Absent"}] String Ensure;
- [Write] String StringParam;
- [Write] UInt32 UInt32Param;
- [Write] UInt64 UInt64Param;
- [Write] String StringArrayParam[];
- [Write] UInt32 UInt32ArrayParam[];
- [Write] UInt64 UInt64ArrayParam[];
- [Write] Boolean BooleanParam;
- [Write, EmbeddedInstance("MSFT_Credential")] String PSCredentialParam;
- [Write, EmbeddedInstance("ANSIBLE_xTestClass")] String CimInstanceParam;
- [Write, EmbeddedInstance("ANSIBLE_xTestClass")] String CimInstanceArrayParam[];
-};
diff --git a/test/sanity/pslint/ignore.txt b/test/sanity/pslint/ignore.txt
index 51ef60bb5c..dc8a96d75c 100644
--- a/test/sanity/pslint/ignore.txt
+++ b/test/sanity/pslint/ignore.txt
@@ -30,9 +30,7 @@ lib/ansible/modules/windows/win_domain_membership.ps1 PSAvoidGlobalVars
lib/ansible/modules/windows/win_domain_membership.ps1 PSAvoidUsingWMICmdlet
lib/ansible/modules/windows/win_domain_membership.ps1 PSUseApprovedVerbs
lib/ansible/modules/windows/win_domain_membership.ps1 PSUseDeclaredVarsMoreThanAssignments
-lib/ansible/modules/windows/win_dsc.ps1 PSAvoidUsingCmdletAliases
lib/ansible/modules/windows/win_dsc.ps1 PSAvoidUsingEmptyCatchBlock
-lib/ansible/modules/windows/win_dsc.ps1 PSUseApprovedVerbs
lib/ansible/modules/windows/win_eventlog.ps1 PSUseDeclaredVarsMoreThanAssignments
lib/ansible/modules/windows/win_find.ps1 PSAvoidUsingEmptyCatchBlock
lib/ansible/modules/windows/win_find.ps1 PSAvoidUsingWMICmdlet
@@ -72,7 +70,6 @@ lib/ansible/modules/windows/win_user.ps1 PSAvoidUsingCmdletAliases
lib/ansible/modules/windows/win_wait_for.ps1 PSAvoidUsingEmptyCatchBlock
lib/ansible/modules/windows/win_webpicmd.ps1 PSAvoidUsingInvokeExpression
test/integration/targets/win_audit_rule/library/test_get_audit_rule.ps1 PSAvoidUsingCmdletAliases
-test/integration/targets/win_dsc/templates/ANSIBLE_xTestResource.psm1 PSAvoidDefaultValueForMandatoryParameter
test/integration/targets/win_iis_webbinding/library/test_get_webbindings.ps1 PSUseApprovedVerbs
test/integration/targets/win_module_utils/library/argv_parser_test.ps1 PSUseApprovedVerbs
test/integration/targets/win_module_utils/library/camel_conversion_test.ps1 PSUseDeclaredVarsMoreThanAssignments
diff --git a/test/sanity/pslint/skip.txt b/test/sanity/pslint/skip.txt
index 12e84739a8..83a8f32da6 100644
--- a/test/sanity/pslint/skip.txt
+++ b/test/sanity/pslint/skip.txt
@@ -1 +1,6 @@
test/integration/targets/win_ping/library/win_ping_syntax_error.ps1
+test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xSetReboot/ANSIBLE_xSetReboot.psm1
+test/integration/targets/win_dsc/files/xTestDsc/1.0.0/xTestDsc.psd1
+test/integration/targets/win_dsc/files/xTestDsc/1.0.0/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.psm1
+test/integration/targets/win_dsc/files/xTestDsc/1.0.1/xTestDsc.psd1
+test/integration/targets/win_dsc/files/xTestDsc/1.0.1/DSCResources/ANSIBLE_xTestResource/ANSIBLE_xTestResource.psm1