diff --git a/wmi-adapter/Tests/wmi.tests.ps1 b/wmi-adapter/Tests/wmi.tests.ps1
index e5d2115c0..7c479560a 100644
--- a/wmi-adapter/Tests/wmi.tests.ps1
+++ b/wmi-adapter/Tests/wmi.tests.ps1
@@ -6,7 +6,7 @@ Describe 'WMI adapter resource tests' {
     BeforeAll {
         if ($IsWindows)
         {
-            $OldPSModulePath  = $env:PSModulePath
+            $OldPSModulePath = $env:PSModulePath
             $env:PSModulePath += ";" + $PSScriptRoot
 
             $configPath = Join-path $PSScriptRoot "test_wmi_config.dsc.yaml"
@@ -19,39 +19,92 @@ Describe 'WMI adapter resource tests' {
         }
     }
 
-    It 'List shows WMI resources' -Skip:(!$IsWindows){
+    Context 'List WMI resources' {
+        It 'List shows WMI resources' -Skip:(!$IsWindows) {
 
-        $r = dsc resource list *OperatingSystem* -a Microsoft.Windows/WMI
-        $LASTEXITCODE | Should -Be 0
-        $res = $r | ConvertFrom-Json
-        $res.Count | Should -BeGreaterOrEqual 1
+            $r = dsc resource list *OperatingSystem* -a Microsoft.Windows/WMI
+            $LASTEXITCODE | Should -Be 0
+            $res = $r | ConvertFrom-Json
+            $res.Count | Should -BeGreaterOrEqual 1
+        }   
     }
 
-    It 'Get works on an individual WMI resource' -Skip:(!$IsWindows){
+    Context 'Get WMI resources' {
+        It 'Get works on an individual WMI resource' -Skip:(!$IsWindows) {
 
-        $r = dsc resource get -r root.cimv2/Win32_OperatingSystem
-        $LASTEXITCODE | Should -Be 0
-        $res = $r | ConvertFrom-Json
-        $res.actualState.CreationClassName | Should -Be "Win32_OperatingSystem"
+            $r = dsc resource get -r root.cimv2/Win32_OperatingSystem
+            $LASTEXITCODE | Should -Be 0
+            $res = $r | ConvertFrom-Json
+            $res.actualState.result.type | Should -BeLike "*Win32_OperatingSystem"
+        }
+    
+        It 'Get works on a config with WMI resources' -Skip:(!$IsWindows) {
+    
+            $r = Get-Content -Raw $configPath | dsc config get
+            $LASTEXITCODE | Should -Be 0
+            $res = $r | ConvertFrom-Json
+            $res.results.result.actualstate.result[0].properties.LastBootUpTime | Should -Not -BeNull
+            $res.results.result.actualstate.result[0].properties.Caption | Should -Not -BeNull
+            $res.results.result.actualstate.result[0].properties.NumberOfProcesses | Should -Not -BeNull
+        }
+    
+        It 'Example config works' -Skip:(!$IsWindows) {
+            $configPath = Join-Path $PSScriptRoot '..\..\dsc\examples\wmi.dsc.yaml'
+            $r = dsc config get -p $configPath
+            $LASTEXITCODE | Should -Be 0
+            $r | Should -Not -BeNullOrEmpty
+            $res = $r | ConvertFrom-Json
+            $res.results.result.actualstate.result[0].properties.Model | Should -Not -BeNullOrEmpty
+            $res.results.result.actualstate.result[0].properties.Description | Should -Not -BeNullOrEmpty
+        }
     }
 
-    It 'Get works on a config with WMI resources' -Skip:(!$IsWindows){
+    # TODO: work on set test configs
+    Context "Set WMI resources" {
+        It 'Set a resource' -Skip:(!$IsWindows) {
+            $inputs = @{
+                adapted_dsc_type = "root.cimv2/Win32_Process"
+                properties       = @{
+                    MethodName  = 'Create'
+                    CommandLine = 'powershell.exe'
+                }
+            }
+            # get the start of processes
+            $ref = Get-Process 
+
+            # run the creation of process
+            $r = ($inputs | ConvertTo-Json -Compress) | dsc resource set -r root.cimv2/Win32_Process
 
-        $r = Get-Content -Raw $configPath | dsc config get
-        $LASTEXITCODE | Should -Be 0
-        $res = $r | ConvertFrom-Json
-        $res.results[0].result.actualState[0].LastBootUpTime | Should -Not -BeNull
-        $res.results[0].result.actualState[1].BiosCharacteristics | Should -Not -BeNull
-        $res.results[0].result.actualState[2].NumberOfLogicalProcessors | Should -Not -BeNull
+            # handle the output as we do not have a filter yet on the get method
+            $diff = Get-Process
+
+            $comparison = (Compare-Object -ReferenceObject $ref -DifferenceObject $diff | Where-Object { $_.SideIndicator -eq '=>' })
+            $process = foreach ($c in $comparison)
+            {
+                if ($c.InputObject.Path -like "*$($inputs.properties.CommandLine)*")
+                {
+                    $c.InputObject
+                }
+            }
+            $res = $r | ConvertFrom-Json
+            $res.afterState.result | Should -Not -BeNull
+            $LASTEXITCODE | Should -Be 0
+            $process | Should -Not -BeNullOrEmpty
+            $process.Path | Should -BeLike "*powershell.exe*"
+        }
+        AfterAll {
+            $process = Get-Process -Name "powershell" -ErrorAction SilentlyContinue | Sort-Object StartTime -Descending -Top 1
+            Stop-Process $process
+        }
     }
 
-    It 'Example config works' -Skip:(!$IsWindows) {
-        $configPath = Join-Path $PSScriptRoot '..\..\dsc\examples\wmi.dsc.yaml'
-        $r = dsc config get -p $configPath
-        $LASTEXITCODE | Should -Be 0
-        $r | Should -Not -BeNullOrEmpty
-        $res = $r | ConvertFrom-Json
-        $res.results[0].result.actualState[0].Model | Should -Not -BeNullOrEmpty
-        $res.results[0].result.actualState[1].Description | Should -Not -BeNullOrEmpty
+    Context "Export WMI resources" {
+        It 'Exports all resources' -Skip:(!$IsWindows) {
+            $r = dsc resource export -r root.cimv2/Win32_Process
+            $LASTEXITCODE | Should -Be 0
+            $res = $r | ConvertFrom-Json
+            $res.resources.properties.result.properties.value.count | Should -BeGreaterThan 1
+            $res.resources.properties.result.properties.value[0].CreationClassName | Should -Be 'Win32_Process'
+        }
     }
 }
diff --git a/wmi-adapter/copy_files.txt b/wmi-adapter/copy_files.txt
index a6bfcb395..a96936ddd 100644
--- a/wmi-adapter/copy_files.txt
+++ b/wmi-adapter/copy_files.txt
@@ -1,2 +1,4 @@
 wmi.resource.ps1
-wmi.dsc.resource.json
\ No newline at end of file
+wmi.dsc.resource.json
+wmiAdapter.psd1
+wmiAdapter.psm1
\ No newline at end of file
diff --git a/wmi-adapter/wmi.dsc.resource.json b/wmi-adapter/wmi.dsc.resource.json
index 5b63c7d37..0d1bb66ac 100644
--- a/wmi-adapter/wmi.dsc.resource.json
+++ b/wmi-adapter/wmi.dsc.resource.json
@@ -1,48 +1,68 @@
 {
-    "$schema": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.json",
-    "type": "Microsoft.Windows/WMI",
-    "version": "0.1.0",
-    "kind": "Adapter",
-    "description": "Resource adapter to WMI resources.",
-    "tags": [
-      "PowerShell"
-    ],
-    "adapter": {
-      "list": {
-        "executable": "powershell",
-        "args": [
-          "-NoLogo",
-          "-NonInteractive",
-          "-NoProfile",
-          "-Command",
-          "./wmi.resource.ps1 List"
-        ]
-        },
-      "config": "full"
-    },
-    "get": {
+  "$schema": "https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.json",
+  "type": "Microsoft.Windows/WMI",
+  "version": "0.1.0",
+  "kind": "Adapter",
+  "description": "Resource adapter to WMI resources.",
+  "tags": ["PowerShell"],
+  "adapter": {
+    "list": {
       "executable": "powershell",
       "args": [
         "-NoLogo",
         "-NonInteractive",
         "-NoProfile",
         "-Command",
-        "$Input | ./wmi.resource.ps1 Get"
-      ],
-      "input": "stdin"
+        "./wmi.resource.ps1 List"
+      ]
     },
-    "validate": {
-        "executable": "powershell",
-        "args": [
-          "-NoLogo",
-          "-NonInteractive",
-          "-NoProfile",
-          "-Command",
-          "$Input | ./wmi.resource.ps1 Validate"
-          ]
-      },
-    "exitCodes": {
-      "0": "Success",
-      "1": "Error"
-    }
+    "config": "full"
+  },
+  "get": {
+    "executable": "powershell",
+    "args": [
+      "-NoLogo",
+      "-NonInteractive",
+      "-NoProfile",
+      "-Command",
+      "$Input | ./wmi.resource.ps1 Get"
+    ],
+    "input": "stdin"
+  },
+  "set": {
+    "executable": "powershell",
+    "args": [
+      "-NoLogo",
+      "-NonInteractive",
+      "-NoProfile",
+      "-Command",
+      "$Input | ./wmi.resource.ps1 Set"
+    ],
+    "input": "stdin"
+  },
+  "export": {
+    "executable": "powershell",
+    "args": [
+      "-NoLogo",
+      "-NonInteractive",
+      "-NoProfile",
+      "-Command",
+      "$Input | ./wmi.resource.ps1 Export"
+    ],
+    "input": "stdin"
+  },
+  "validate": {
+    "executable": "powershell",
+    "args": [
+      "-NoLogo",
+      "-NonInteractive",
+      "-NoProfile",
+      "-Command",
+      "$Input | ./wmi.resource.ps1 Validate"
+    ]
+  },
+  "exitCodes": {
+    "0": "Success",
+    "1": "Error"
   }
+}
diff --git a/wmi-adapter/wmi.resource.ps1 b/wmi-adapter/wmi.resource.ps1
index 6eb2f88d9..504b6277c 100644
--- a/wmi-adapter/wmi.resource.ps1
+++ b/wmi-adapter/wmi.resource.ps1
@@ -3,142 +3,147 @@
 
 [CmdletBinding()]
 param(
-    [ValidateSet('List','Get','Set','Test','Validate')]
-    $Operation = 'List',
-    [Parameter(ValueFromPipeline)]
-    $stdinput
+    [Parameter(Mandatory = $true, Position = 0, HelpMessage = 'Operation to perform. Choose from List, Get, Set, Test, Export, Validate.')]
+    [ValidateSet('List', 'Get', 'Set', 'Test', 'Export', 'Validate')]
+    [string]$Operation,
+    [Parameter(Mandatory = $false, Position = 1, ValueFromPipeline = $true, HelpMessage = 'Configuration or resource input in JSON format.')]
+    [string]$jsonInput = '@{}'
 )
 
-$ProgressPreference = 'Ignore'
-$WarningPreference = 'Ignore'
-$VerbosePreference = 'Ignore'
+function Write-DscTrace
+{
+    param
+    (
+        [Parameter(Mandatory = $false)]
+        [ValidateSet('Error', 'Warn', 'Info', 'Debug', 'Trace')]
+        [string]$Operation = 'Debug',
+
+        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
+        [string]$Message
+    )
+
+    $trace = @{$Operation = $Message } | ConvertTo-Json -Compress
+    $host.ui.WriteErrorLine($trace)
+}
 
-function IsConfiguration($obj) {
-    if ($null -ne $obj.metadata -and $null -ne $obj.metadata.'Microsoft.DSC' -and $obj.metadata.'Microsoft.DSC'.context -eq 'Configuration') {
-        return $true
-    }
+# Adding some debug info to STDERR
+'PSVersion=' + $PSVersionTable.PSVersion.ToString() | Write-DscTrace
+'PSPath=' + $PSHome | Write-DscTrace
+'PSModulePath=' + $env:PSModulePath | Write-DscTrace
 
-    return $false
+if ('Validate' -ne $Operation)
+{
+    # write $jsonInput to STDERR for debugging
+    $trace = @{'Debug' = 'jsonInput=' + $jsonInput } | ConvertTo-Json -Compress
+    $host.ui.WriteErrorLine($trace)
+    $wmiAdapter = Import-Module "$PSScriptRoot/wmiAdapter.psd1" -Force -PassThru
+    
+    # initialize OUTPUT as array
+    $result = [System.Collections.Generic.List[Object]]::new()
 }
 
-if ($Operation -eq 'List')
+switch ($Operation)
 {
-    $clases = Get-CimClass
-
-    foreach ($r in $clases)
+    'List'
     {
-        $version_string = "";
-        $author_string = "";
-        $moduleName = "";
+        $clases = Get-CimClass
 
-        $propertyList = @()
-        foreach ($p in $r.CimClassProperties)
+        foreach ($r in $clases)
         {
-            if ($p.Name)
+            $version_string = "";
+            $author_string = "";
+            $moduleName = "";
+    
+            $propertyList = @()
+            foreach ($p in $r.CimClassProperties)
             {
-                $propertyList += $p.Name
+                if ($p.Name)
+                {
+                    $propertyList += $p.Name
+                }
             }
-        }
-
-        $namespace = $r.CimSystemProperties.Namespace.ToLower().Replace('/','.')
-        $classname = $r.CimSystemProperties.ClassName
-        $fullResourceTypeName = "$namespace/$classname"
-        $requiresString = "Microsoft.Windows/WMI"
-
-        $z = [pscustomobject]@{
-            type = $fullResourceTypeName;
-            kind = 'Resource';
-            version = $version_string;
-            capabilities = @('Get');
-            path = "";
-            directory = "";
-            implementedAs = "";
-            author = $author_string;
-            properties = $propertyList;
-            requireAdapter = $requiresString
-        }
-
-        $z | ConvertTo-Json -Compress
-    }
-}
-elseif ($Operation -eq 'Get')
-{
-    $inputobj_pscustomobj = $null
-    if ($stdinput)
-    {
-        $inputobj_pscustomobj = $stdinput | ConvertFrom-Json
-    }
-
-    $result = @()
-
-    if (IsConfiguration $inputobj_pscustomobj) # we are processing a config batch
-    {
-        foreach($r in $inputobj_pscustomobj.resources)
-        {
-            $type_fields = $r.type -split "/"
-            $wmi_namespace = $type_fields[0].Replace('.','\')
-            $wmi_classname = $type_fields[1]
-
-            #TODO: add filtering based on supplied properties of $r
-            $wmi_instances = Get-CimInstance -Namespace $wmi_namespace -ClassName $wmi_classname
-
-            if ($wmi_instances)
+    
+            # TODO: create class
+            $methodList = [System.Collections.Generic.List[PSObject]]@()
+            foreach ($m in $r.CimClassMethods)
             {
-                $instance_result = @{}
-                $wmi_instance = $wmi_instances[0] # for 'Get' we return just first matching instance; for 'export' we return all instances
-                $wmi_instance.psobject.properties | %{
-                    if (($_.Name -ne "type") -and (-not $_.Name.StartsWith("Cim")))
-                    {
-                        $instance_result[$_.Name] = $_.Value
-                    }
+                $inputObject = [PSCustomObject]@{
+                    methodName = $m.Name
+                    parameters = @()
                 }
-
-                $result += @($instance_result)
+                
+                if ($m.Parameters)
+                {
+                    $inputObject.parameters = $m.Parameters.Name
+                }
+                $methodList += $inputObject
             }
-            else
-            {
-                $errmsg = "Can not find type " + $r.type + "; please ensure that Get-CimInstance returns this resource type"
-                Write-Error $errmsg
-                exit 1
+    
+            $namespace = $r.CimSystemProperties.Namespace.ToLower().Replace('/', '.')
+            $classname = $r.CimSystemProperties.ClassName
+            $fullResourceTypeName = "$namespace/$classname"
+            $requiresString = "Microsoft.Windows/WMI"
+    
+            $z = [pscustomobject]@{
+                type           = $fullResourceTypeName;
+                kind           = 'Resource';
+                version        = $version_string;
+                capabilities   = @('Get', 'Set', 'Test', 'Export');
+                # capabilities   = $methodList
+                path           = "";
+                directory      = "";
+                implementedAs  = "";
+                author         = $author_string;
+                properties     = $propertyList;
+                # TODO: Could not use methodsDetails because expected one of `type`, `kind`, `version`, `capabilities`, `path`, `description`, `directory`, `implementedAs`, `author`, `properties`, `requireAdapter`, `manifest`
+                # Where is this coming from?
+                # methodsDetails = $methodList
+                requireAdapter = $requiresString
             }
+    
+            $z | ConvertTo-Json -Compress -Depth 10
         }
     }
-    else # we are processing an individual resource call
+    { @('Get', 'Set', 'Test', 'Export') -contains $_ }
     {
-        $type_fields = $inputobj_pscustomobj.adapted_dsc_type -split "/"
-        $wmi_namespace = $type_fields[0].Replace('.','\')
-        $wmi_classname = $type_fields[1]
-
-        #TODO: add filtering based on supplied properties of $inputobj_pscustomobj
-        $wmi_instances = Get-CimInstance -Namespace $wmi_namespace -ClassName $wmi_classname
-
-        if ($wmi_instances)
+        
+        $desiredState = $wmiAdapter.invoke(   { param($jsonInput) Get-DscResourceObject -jsonInput $jsonInput }, $jsonInput )
+        if ($null -eq $desiredState)
         {
-            $wmi_instance = $wmi_instances[0] # for 'Get' we return just first matching instance; for 'export' we return all instances
-            $result = @{}
-            $wmi_instance.psobject.properties | %{
-                if (($_.Name -ne "type") -and (-not $_.Name.StartsWith("Cim")))
-                {
-                    $result[$_.Name] = $_.Value
-                }
-            }
+            $trace = @{'Debug' = 'ERROR: Failed to create configuration object from provided input JSON.' } | ConvertTo-Json -Compress
+            $host.ui.WriteErrorLine($trace)
+            exit 1
         }
-        else
+
+        foreach ($ds in $desiredState)
         {
-            $errmsg = "Can not find type " + $inputobj_pscustomobj.type + "; please ensure that Get-CimInstance returns this resource type"
-            Write-Error $errmsg
-            exit 1
+            # process the INPUT (desiredState) for each resource as dscresourceInfo and return the OUTPUT as actualState
+            $actualstate = $wmiAdapter.Invoke( { param($op, $ds) Invoke-DscWmi -Operation $op -DesiredState $ds }, $Operation, $ds)
+            if ($null -eq $actualState)
+            {
+                $trace = @{'Debug' = 'ERROR: Incomplete GET for resource ' + $ds.type } | ConvertTo-Json -Compress
+                $host.ui.WriteErrorLine($trace)
+                exit 1
+            }
+
+            $result += $actualstate
         }
-    }
 
-    $result | ConvertTo-Json -Compress
-}
-elseif ($Operation -eq 'Validate')
-{
-    # TODO: this is placeholder
-    @{ valid = $true } | ConvertTo-Json
-}
-else
-{
-    Write-Error "ERROR: Unsupported operation requested from wmigroup.resource.ps1"
+        # OUTPUT json to stderr for debug, and to stdout
+        $result = @{ result = $result } | ConvertTo-Json -Depth 10 -Compress
+        $trace = @{'Debug' = 'jsonOutput=' + $result } | ConvertTo-Json -Compress
+        $host.ui.WriteErrorLine($trace)
+        return $result
+    }
+    'Validate'
+    {
+        # VALIDATE not implemented
+        
+        # OUTPUT
+        @{ valid = $true } | ConvertTo-Json
+    }
+    Default
+    {
+        Write-Error 'Unsupported operation. Please use one of the following: List, Get, Set, Test, Export, Validate'
+    }
 }
\ No newline at end of file
diff --git a/wmi-adapter/wmiAdapter.psd1 b/wmi-adapter/wmiAdapter.psd1
new file mode 100644
index 000000000..4dd03d3db
--- /dev/null
+++ b/wmi-adapter/wmiAdapter.psd1
@@ -0,0 +1,47 @@
+# Copyright (c) Microsoft Corporation.
+# Licensed under the MIT License.
+
+@{
+
+    # Script module or binary module file associated with this manifest.
+    RootModule        = 'wmiAdapter.psm1'
+    
+    # Version number of this module.
+    moduleVersion     = '0.0.1'
+    
+    # ID used to uniquely identify this module
+    GUID              = '420c66dc-d243-4bf8-8de0-66467328f4b7'
+    
+    # Author of this module
+    Author            = 'Microsoft Corporation'
+    
+    # Company or vendor of this module
+    CompanyName       = 'Microsoft Corporation'
+    
+    # Copyright statement for this module
+    Copyright         = '(c) Microsoft Corporation. All rights reserved.'
+    
+    # Description of the functionality provided by this module
+    Description       = 'PowerShell Desired State Configuration Module for DSC WMI Adapter'
+    
+    # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
+    FunctionsToExport = @(
+        'Invoke-DscWmi'
+    )
+    
+    # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
+    CmdletsToExport   = @()
+    
+    # Variables to export from this module
+    VariablesToExport = @()
+    
+    # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
+    AliasesToExport   = @()
+    
+    PrivateData       = @{
+        PSData = @{
+            ProjectUri = 'https://github.com/PowerShell/dsc'
+        }
+    }
+}
+    
\ No newline at end of file
diff --git a/wmi-adapter/wmiAdapter.psm1 b/wmi-adapter/wmiAdapter.psm1
new file mode 100644
index 000000000..2498b01a4
--- /dev/null
+++ b/wmi-adapter/wmiAdapter.psm1
@@ -0,0 +1,391 @@
+function Write-DscTrace
+{
+    param(
+        [Parameter(Mandatory = $false)]
+        [ValidateSet('Error', 'Warn', 'Info', 'Debug', 'Trace')]
+        [string]$Operation = 'Debug',
+
+        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
+        [string]$Message
+    )
+
+    $trace = @{$Operation = $Message } | ConvertTo-Json -Compress
+    $host.ui.WriteErrorLine($trace)
+}
+
+function Get-DscResourceObject
+{
+    param(
+        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
+        $jsonInput
+    )
+    # normalize the INPUT object to an array of dscResourceObject objects
+    $inputObj = $jsonInput | ConvertFrom-Json -ErrorAction SilentlyContinue
+    $desiredState = [System.Collections.Generic.List[Object]]::new()
+
+    # catch potential for improperly formatted configuration input
+    if ($inputObj.resources -and -not $inputObj.metadata.'Microsoft.DSC'.context -eq 'configuration')
+    {
+        $msg = 'The input has a top level property named "resources" but is not a configuration. If the input should be a configuration, include the property: "metadata": {"Microsoft.DSC": {"context": "Configuration"}}' 
+        $msg | Write-DscTrace -Operation Warn
+    }
+
+    $adapterName = 'Microsoft.Windows/WMI'
+
+    if ($null -ne $inputObj.metadata -and $null -ne $inputObj.metadata.'Microsoft.DSC' -and $inputObj.metadata.'Microsoft.DSC'.context -eq 'configuration')
+    {
+        # change the type from pscustomobject to dscResourceObject
+        $inputObj.resources | ForEach-Object -Process {
+            $desiredState += [dscResourceObject]@{
+                name       = $_.name
+                type       = $_.type
+                properties = $_.properties
+            }
+        }
+    }
+    else
+    {
+        # mimic a config object with a single resource
+        $type = $inputObj.adapted_dsc_type
+        if (-not $type)
+        {
+            $errmsg = "Can not find " + $jsonInput + ". Please make sure the payload contains the 'adapted_dsc_type' key property."
+            $errmsg | Write-DscTrace -Operation Error
+            exit 1
+        }
+
+        $inputObj.psobject.properties.Remove('adapted_dsc_type')
+        $desiredState += [dscResourceObject]@{
+            name       = $adapterName
+            type       = $type
+            properties = $inputObj.properties
+        }
+    }
+    return $desiredState
+}
+
+function GetCimSpace 
+{
+    [CmdletBinding()]
+    param 
+    (
+        [Parameter(Mandatory)]
+        [ValidateSet('Get', 'Set', 'Test', 'Export')]
+        [System.String]
+        $Operation,
+
+        [Parameter(Mandatory, ValueFromPipeline = $true)]
+        [psobject]
+        $DesiredState
+    )
+
+    $addToActualState = [dscResourceObject]@{}
+    $DesiredState.psobject.properties | ForEach-Object -Process {
+        if ($_.TypeNameOfValue -EQ 'System.String') { $addToActualState.$($_.Name) = $DesiredState.($_.Name) }
+    }
+
+    foreach ($r in $DesiredState)
+    {
+        $type_fields = $r.type -split "/"
+        $wmi_namespace = $type_fields[0].Replace('.', '\')
+        $wmi_classname = $type_fields[1]
+
+        #TODO: add filtering based on supplied properties of $r
+        $wmi_instances = Get-CimInstance -Namespace $wmi_namespace -ClassName $wmi_classname
+
+        if ($wmi_instances)
+        {
+            $instance_result = @{}
+            switch ($Operation)
+            {
+                'Get'
+                {
+                    $instance_result = @{}
+                    $wmi_instance = $wmi_instances[0] # for 'Get' we return just first matching instance; for 'export' we return all instances
+                    $wmi_instance.psobject.properties | ForEach-Object {
+                        if (($_.Name -ne "type") -and (-not $_.Name.StartsWith("Cim")))
+                        {
+                            $instance_result[$_.Name] = $_.Value
+                        }
+                    }
+
+                    $addToActualState.properties = $instance_result
+
+                    # TODO: validate if we can set it to null
+                    $addToActualState.CimInstance = $null
+                }
+                'Set'
+                {
+                    # TODO: with the wmi_instances now added on top, it becomes easier to apply some logic on the parameters available to Get-CimInstance
+                    $wmi_instance = $wmi_instances[0]
+
+                    # add the properties from INPUT
+                    $addToActualState.properties = $r.properties
+
+                    # return the Microsoft.Management.Infrastructure.CimInstance class
+                    $addToActualState.CimInstance = $wmi_instance
+                    
+                }
+                'Test'
+                {
+                    # TODO: implement test
+                }
+                'Export'
+                {
+                    foreach ($wmi_instance in $wmi_instances) 
+                    {
+                        $wmi_instance.psobject.properties | ForEach-Object {
+                            if (($_.Name -ne "type") -and (-not $_.Name.StartsWith("Cim")))
+                            {
+                                $instance_result[$_.Name] = $_.Value
+                            }
+                        }
+
+                        $addToActualState.properties += @($instance_result)
+                    }
+                }
+            }
+
+            return $addToActualState
+        }
+        else
+        {
+            $errmsg = "Can not find type " + $addToActualState.type + "; please ensure that Get-CimInstance returns this resource type"
+            $errmsg | Write-DscTrace -Operation Error
+            exit 1
+        }
+    }
+}
+
+function ValidateCimMethodAndArguments
+{
+    # TODO: whenever dsc exit codes come in add them, see: https://github.com/PowerShell/DSC/issues/421
+    [CmdletBinding()]
+    param 
+    (
+        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
+        [dscResourceObject[]]
+        $DesiredState
+
+    )
+
+    $inputObject = [System.Collections.Generic.List[hashtable]]@{}
+
+    foreach ($r in $DesiredState)
+    {
+        $methodName = $r.properties.MethodName
+        if (-not $methodName)
+        {
+            $errmsg = 'Can not find method name when calling ' + $DesiredState.type + '; Please add "MethodName" in input.' 
+            'ERROR: ' + $errmsg | Write-DscTrace
+            exit 1
+        }
+
+        $className = $r.type.Split("/")[-1]
+        $namespace = $r.type.Split("/")[0].Replace(".", "/")
+        $class = Get-CimClass -ClassName $className -Namespace $namespace
+
+        $classMethods = $class.CimClassMethods.Name
+        if ($classMethods -notcontains $methodName)
+        {
+            $errmsg = 'Method ' + ('"{0}"' -f $r.properties.MethodName) + ' was not found on ' + $r.type + "; Please ensure you call the correct method" 
+            # $debugmsg = 'Available method(s) ' + ('{0}' -f ($class.CimClassMethods.Name | ConvertTo-Json -Compress))
+            'ERROR: ' + $errmsg | Write-DscTrace
+            #'DEBUG: ' + $debugmsg | Write-DscTrace
+            exit 1 
+        }
+
+        $parameters = $class.CimClassMethods.parameters.Name
+        $props = $r.properties | Get-Member | Where-Object { $_.MemberType -eq 'NoteProperty' } | Select-Object -ExpandProperty Name
+
+        # TODO: can also validate if empty values are provided and which might be mandatory
+        $arguments = @{}
+        if (-not ($null -eq $props))
+        {
+            $props | ForEach-Object {
+                $propertyName = $_
+                if ($propertyName -notin $parameters)
+                {
+                    $msg = 'Parameter ' + $propertyName + " not found on $className." 
+                    'WARNING: ' + $msg | Write-DscTrace
+                }
+                else 
+                {
+                    $arguments += @{$propertyName = $r.Properties.$propertyName }
+                }
+            }
+        }
+        
+        # return hash table of parameters for InvokeCimMethod
+        $inputObject += @{
+            CimInstance = $r.CimInstance
+            MethodName  = $methodName
+            Arguments   = $arguments
+        }
+    }
+
+    return $inputObject
+}
+
+function Invoke-DscWmi 
+{
+    [CmdletBinding()]
+    param 
+    (
+        [Parameter(Mandatory)]
+        [ValidateSet('Get', 'Set', 'Test', 'Export')]
+        [System.String]
+        $Operation,
+
+        [Parameter(Mandatory, ValueFromPipeline = $true)]
+        [dscResourceObject]
+        $DesiredState
+    )
+
+    $osVersion = [System.Environment]::OSVersion.VersionString
+    'OS version: ' + $osVersion | Write-DscTrace
+
+    $psVersion = $PSVersionTable.PSVersion.ToString()
+    'PowerShell version: ' + $psVersion | Write-DscTrace
+
+    switch ($Operation)
+    {
+        'Get'
+        {
+            $addToActualState = GetCimSpace -Operation $Operation -DesiredState $DesiredState
+        }
+        'Set'
+        {
+            $addToActualState = GetCimSpace -Operation $Operation -DesiredState $DesiredState
+
+            $wmiResources = ValidateCimMethodAndArguments -DesiredState $addToActualState
+            foreach ($resource in $wmiResources)
+            {
+                $null = InvokeCimMethod @resource
+            }
+
+            # reset the value to be empty
+            $addToActualState = [PSCustomObject]@{
+                name       = $addToActualState.name 
+                type       = $addToActualState.type
+                properties = $null
+            }
+        }
+        'Test'
+        {
+
+        }
+        'Export'
+        {
+            $addToActualState = GetCimSpace -Operation $Operation -DesiredState $DesiredState
+        }
+    }
+
+    return $addToActualState
+}
+
+
+function InvokeCimMethod
+{
+    [CmdletBinding()]
+    [OutputType([Microsoft.Management.Infrastructure.CimMethodResult])]
+    param
+    (
+
+        [Parameter(Mandatory = $true)]
+        [Microsoft.Management.Infrastructure.CimInstance]
+        $CimInstance,
+
+        [Parameter(Mandatory = $true)]
+        [System.String]
+        $MethodName,
+
+        [Parameter()]
+        [System.Collections.Hashtable]
+        $Arguments
+    )
+
+    $invokeCimMethodParameters = @{
+        MethodName  = $MethodName
+        ErrorAction = 'Stop'
+    }
+
+    if ($PSBoundParameters.ContainsKey('Arguments'))
+    {
+        $invokeCimMethodParameters['Arguments'] = $Arguments
+    }
+    
+    try
+    {
+        $invokeCimMethodResult = $CimInstance | Invoke-CimMethod @invokeCimMethodParameters
+    }
+    catch [Microsoft.Management.Infrastructure.CimException]
+    {
+        $errMsg = $_.Exception.Message.Trim("")
+        if ($errMsg -eq 'Invalid method')
+        {
+            "Retrying without instance" | Write-DscTrace -Operation Trace
+            $invokeCimMethodResult = Invoke-CimMethod @invokeCimMethodParameters -ClassName $CimInstance[0].CimClass.CimClassName
+        }
+    }
+    catch 
+    {
+        $errmsg = "Could not execute 'Invoke-CimMethod' with error message: " + $_.Exception.Message
+        'ERROR: ' + $errmsg | Write-DscTrace
+        exit 1
+    }
+    
+    <#
+        Successfully calling the method returns $invokeCimMethodResult.HRESULT -eq 0.
+        If an general error occur in the Invoke-CimMethod, like calling a method
+        that does not exist, returns $null in $invokeCimMethodResult.
+    #>
+    if ($invokeCimMethodResult.HRESULT)
+    {
+        $res = $invokeCimMethodResult.HRESULT
+    }
+    else 
+    {
+        $res = $invokeCimMethodResult.ReturnValue
+    }
+    if ($invokeCimMethodResult -and $res -ne 0)
+    {
+        if ($invokeCimMethodResult | Get-Member -Name 'ExtendedErrors')
+        {
+            <#
+                The returned object property ExtendedErrors is an array
+                so that needs to be concatenated.
+            #>
+            $errorMessage = $invokeCimMethodResult.ExtendedErrors -join ';'
+        }
+        else
+        {
+            $errorMessage = $invokeCimMethodResult.Error
+        }
+
+        $hResult = $invokeCimMethodResult.ReturnValue
+
+        if ($invokeCimMethodResult.HRESULT)
+        {
+            $hResult = $invokeCimMethodResult.HRESULT
+        }
+
+        $errmsg = 'Method {0}() failed with an error. Error: {1} (HRESULT:{2})' -f @(
+            $MethodName
+            $errorMessage
+            $hResult
+        )
+        'ERROR: ' + $errmsg | Write-DscTrace
+        exit 1
+    }
+
+    return $invokeCimMethodResult
+}
+
+class dscResourceObject
+{
+    [string] $name
+    [string] $type
+    [PSCustomObject] $properties
+    [Microsoft.Management.Infrastructure.CimInstance] $CimInstance
+}
\ No newline at end of file