Skip to content

Commit 652aa44

Browse files
committed
Create query for both scenarios
1 parent 0a41e82 commit 652aa44

File tree

2 files changed

+81
-37
lines changed

2 files changed

+81
-37
lines changed

wmi-adapter/Tests/wmi.tests.ps1

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,16 @@ Describe 'WMI adapter resource tests' {
5353
$r | Should -Not -BeNullOrEmpty
5454
$res = $r | ConvertFrom-Json
5555

56-
Write-Verbose ($res.results[1].result.actualState.result[4] | ConvertTo-Json -Depth 10) -Verbose
5756
$res.results[1].result.actualState.result[0].properties.Name | Should -Not -BeNullOrEmpty
5857
$res.results[1].result.actualState.result[0].properties.BootupState | Should -BeNullOrEmpty
5958
$res.results[1].result.actualState.result[1].properties.Caption | Should -Not -BeNullOrEmpty
6059
$res.results[1].result.actualState.result[1].properties.BuildNumber | Should -BeNullOrEmpty
61-
$res.results[1].result.actualState.result[4].properties.AdapterType | Should -BeLike "Ethernet*"
60+
$res.results[1].result.actualState.result[4].properties.Name | Should -Not -BeNullOrEmpty
6261
}
6362

6463
It 'Set does not work without input for resource' -Skip:(!$IsWindows) {
65-
$s = dsc resource set --resource root.cimv2/Win32_Environment --input '{}' 2>&1
66-
$s | Should -BeLike "*No valid properties found in the CIM class 'Win32_Environment' for the provided properties.*"
64+
$out = dsc resource set --resource root.cimv2/Win32_Environment --input '{}' 2>&1
65+
$out[0] | Should -BeLike "*No valid properties found in the CIM class 'Win32_Environment' for the provided properties.*"
6766
}
6867

6968
It 'Set does not work without a key property' -Skip:(!$IsWindows) {
@@ -72,8 +71,8 @@ Describe 'WMI adapter resource tests' {
7271
UserName = ("{0}\{1}" -f $env:USERDOMAIN, $env:USERNAME) # Read-only property is key, but we require a key property to be set
7372
} | ConvertTo-Json
7473

75-
$s = dsc resource set -r root.cimv2/Win32_Environment -i $i 2>&1
76-
$s | Should -BeLike "*All key properties in the CIM class 'Win32_Environment' are read-only, which is not supported.*"
74+
$out = dsc resource set -r root.cimv2/Win32_Environment -i $i 2>&1
75+
$out[0] | Should -BeLike "*All key properties in the CIM class 'Win32_Environment' are read-only, which is not supported.*"
7776
}
7877

7978
It 'Set works on a WMI resource' -Skip:(!$IsWindows) {
@@ -86,10 +85,10 @@ Describe 'WMI adapter resource tests' {
8685
$r = dsc resource set -r root.cimv2/Win32_Environment -i $i
8786
$LASTEXITCODE | Should -Be 0
8887

89-
$out = $r | ConvertFrom-Json
90-
$out.afterState.Name | Should -Be 'test'
91-
$out.afterState.VariableValue | Should -Be 'test'
92-
$out.afterState.UserName | Should -Be ("{0}\{1}" -f $env:USERDOMAIN, $env:USERNAME)
88+
$res = $r | ConvertFrom-Json
89+
$res.afterState.Name | Should -Be 'test'
90+
$res.afterState.VariableValue | Should -Be 'test'
91+
$res.afterState.UserName | Should -Be ("{0}\{1}" -f $env:USERDOMAIN, $env:USERNAME)
9392
}
9493

9594
It 'Update works on a WMI resource' -Skip:(!$IsWindows) {
@@ -102,9 +101,9 @@ Describe 'WMI adapter resource tests' {
102101
$r = dsc resource set -r root.cimv2/Win32_Environment -i $i
103102
$LASTEXITCODE | Should -Be 0
104103

105-
$out = $r | ConvertFrom-Json
106-
$out.afterState.Name | Should -Be 'test'
107-
$out.afterState.VariableValue | Should -Be 'update'
108-
$out.afterState.UserName | Should -Be ("{0}\{1}" -f $env:USERDOMAIN, $env:USERNAME)
104+
$res = $r | ConvertFrom-Json
105+
$res.afterState.Name | Should -Be 'test'
106+
$res.afterState.VariableValue | Should -Be 'update'
107+
$res.afterState.UserName | Should -Be ("{0}\{1}" -f $env:USERDOMAIN, $env:USERNAME)
109108
}
110109
}

wmi-adapter/wmiAdapter.psm1

Lines changed: 68 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,61 @@ function GetValidCimProperties {
117117
return $validatedProperties
118118
}
119119

120+
function BuildWmiQuery {
121+
[CmdletBinding()]
122+
param(
123+
[Parameter(Mandatory = $true)]
124+
[string]$ClassName,
125+
126+
[Parameter(Mandatory = $true)]
127+
[array]$Properties,
128+
129+
[Parameter(Mandatory = $true)]
130+
[psobject]$DesiredStateProperties,
131+
132+
[Parameter()]
133+
[switch]$KeyPropertiesOnly
134+
)
135+
136+
$targetProperties = if ($KeyPropertiesOnly.IsPresent) {
137+
$Properties | Where-Object { $_.Flags.ToString() -like "*Key*" }
138+
} else {
139+
$Properties
140+
}
141+
142+
if ($targetProperties.Count -eq 0) {
143+
return $null
144+
}
145+
146+
$query = "SELECT $($targetProperties.Name -join ',') FROM $ClassName"
147+
$whereClause = " WHERE "
148+
$useWhere = $false
149+
$isFirst = $true
150+
151+
foreach ($property in $targetProperties) {
152+
if ($null -ne $DesiredStateProperties.$($property.Name)) {
153+
$useWhere = $true
154+
if ($isFirst) {
155+
$isFirst = $false
156+
} else {
157+
$whereClause += " AND "
158+
}
159+
160+
if ($property.CimType -eq "String") {
161+
$whereClause += "$($property.Name) = '$($DesiredStateProperties.$($property.Name))'"
162+
} else {
163+
$whereClause += "$($property.Name) = $($DesiredStateProperties.$($property.Name))"
164+
}
165+
}
166+
}
167+
168+
if ($useWhere) {
169+
$query += $whereClause
170+
}
171+
172+
return $query
173+
}
174+
120175
function GetWmiInstance {
121176
[CmdletBinding()]
122177
param
@@ -134,32 +189,22 @@ function GetWmiInstance {
134189
if ($DesiredState.properties) {
135190
$properties = GetValidCimProperties -CimClass $class -ClassName $wmi_classname -Properties $DesiredState.properties -SkipReadOnly
136191

137-
$query = "SELECT $($properties.Name -join ',') FROM $wmi_classname"
138-
$where = " WHERE "
139-
$useWhere = $false
140-
$first = $true
141-
foreach ($property in $properties) {
142-
# TODO: validate property against the CIM class to give better error message
143-
if ($null -ne $DesiredState.properties.$($property.Name)) {
144-
$useWhere = $true
145-
if ($first) {
146-
$first = $false
147-
} else {
148-
$where += " AND "
149-
}
192+
$query = BuildWmiQuery -ClassName $wmi_classname -Properties $properties -DesiredStateProperties $DesiredState.properties
150193

151-
if ($property.CimType -eq "String") {
152-
$where += "$($property.Name) = '$($DesiredState.properties.$($property.Name))'"
153-
} else {
154-
$where += "$($property.Name) = $($DesiredState.properties.$($property.Name))"
194+
if ($query) {
195+
"Query: $query" | Write-DscTrace -Operation Debug
196+
$wmi_instances = Get-CimInstance -Namespace $wmi_namespace -Query $query -ErrorAction Ignore -ErrorVariable err
197+
198+
if ($null -eq $wmi_instances) {
199+
"No WMI instances found using query '$query'. Retrying with key properties only." | Write-DscTrace -Operation Debug
200+
$keyQuery = BuildWmiQuery -ClassName $wmi_classname -Properties $properties -DesiredStateProperties $DesiredState.properties -KeyPropertiesOnly
201+
202+
$wmi_instances = Get-CimInstance -Namespace $wmi_namespace -Query $keyQuery -ErrorAction Ignore -ErrorVariable err
203+
if ($null -eq $wmi_instances) {
204+
"No WMI instances found using key properties query '$keyQuery'." | Write-DscTrace -Operation Debug
155205
}
156206
}
157207
}
158-
if ($useWhere) {
159-
$query += $where
160-
}
161-
"Query: $query" | Write-DscTrace -Operation Debug
162-
$wmi_instances = Get-CimInstance -Namespace $wmi_namespace -Query $query -ErrorAction Ignore -ErrorVariable err
163208
} else {
164209
$wmi_instances = Get-CimInstance -Namespace $wmi_namespace -ClassName $wmi_classname -ErrorAction Ignore -ErrorVariable Err
165210
}
@@ -217,7 +262,7 @@ function GetCimSpace {
217262
$addToActualState.properties = $instance_result
218263
$result += $addToActualState
219264
} else {
220-
"No WMI instances found for type '$($r.type)'." | Write-DscTrace -Operation Warn
265+
"No WMI instances found for type '$($r.type)'." | Write-DscTrace -Operation Debug
221266
$addToActualState.properties = $null
222267
$result += $addToActualState
223268
}

0 commit comments

Comments
 (0)