Skip to content

Commit 48ea26d

Browse files
committed
custom variable autocomplete
1 parent b3b7b24 commit 48ea26d

File tree

2 files changed

+282
-1
lines changed

2 files changed

+282
-1
lines changed

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ExecCippReplacemap.ps1

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,14 @@ function Invoke-ExecCippReplacemap {
1010

1111
$Table = Get-CippTable -tablename 'CippReplacemap'
1212
$Action = $Request.Query.Action ?? $Request.Body.Action
13-
$customerId = $Request.Query.tenantId ?? $Request.Body.tenantId
13+
$TenantId = $Request.Query.tenantId ?? $Request.Body.tenantId
14+
if ($TenantId -eq 'AllTenants') {
15+
$customerId = $TenantId
16+
} else {
17+
# ensure we use a consistent id for the table storage
18+
$Tenant = Get-Tenants -TenantFilter $TenantId
19+
$customerId = $Tenant.customerId
20+
}
1421

1522
if (!$customerId) {
1623
return ([HttpResponseContext]@{
@@ -31,11 +38,13 @@ function Invoke-ExecCippReplacemap {
3138
'AddEdit' {
3239
$VariableName = $Request.Body.RowKey
3340
$VariableValue = $Request.Body.Value
41+
$VariableDescription = $Request.Body.Description
3442

3543
$VariableEntity = @{
3644
PartitionKey = $customerId
3745
RowKey = $VariableName
3846
Value = $VariableValue
47+
Description = $VariableDescription
3948
}
4049

4150
Add-CIPPAzDataTableEntity @Table -Entity $VariableEntity -Force
Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
function Invoke-ListCustomVariables {
2+
<#
3+
.FUNCTIONALITY
4+
Entrypoint
5+
.ROLE
6+
CIPP.Core.Read
7+
#>
8+
[CmdletBinding()]
9+
param($Request, $TriggerMetadata)
10+
11+
$APIName = $Request.Params.CIPPEndpoint
12+
13+
$HttpResponse = [HttpResponseContext]@{
14+
StatusCode = [HttpStatusCode]::OK
15+
Body = @{}
16+
}
17+
18+
try {
19+
# Define reserved variables (matching Get-CIPPTextReplacement)
20+
$ReservedVariables = @(
21+
@{
22+
Name = 'tenantid'
23+
Variable = '%tenantid%'
24+
Description = 'The tenant customer ID'
25+
Type = 'reserved'
26+
Category = 'tenant'
27+
},
28+
@{
29+
Name = 'tenantfilter'
30+
Variable = '%tenantfilter%'
31+
Description = 'The tenant default domain name'
32+
Type = 'reserved'
33+
Category = 'tenant'
34+
},
35+
@{
36+
Name = 'tenantname'
37+
Variable = '%tenantname%'
38+
Description = 'The tenant display name'
39+
Type = 'reserved'
40+
Category = 'tenant'
41+
},
42+
@{
43+
Name = 'defaultdomain'
44+
Variable = '%defaultdomain%'
45+
Description = 'The tenant default domain name'
46+
Type = 'reserved'
47+
Category = 'tenant'
48+
},
49+
@{
50+
Name = 'initialdomain'
51+
Variable = '%initialdomain%'
52+
Description = 'The tenant initial domain name'
53+
Type = 'reserved'
54+
Category = 'tenant'
55+
},
56+
@{
57+
Name = 'partnertenantid'
58+
Variable = '%partnertenantid%'
59+
Description = 'The partner tenant ID'
60+
Type = 'reserved'
61+
Category = 'partner'
62+
},
63+
@{
64+
Name = 'samappid'
65+
Variable = '%samappid%'
66+
Description = 'The SAM application ID'
67+
Type = 'reserved'
68+
Category = 'partner'
69+
},
70+
@{
71+
Name = 'cippuserschema'
72+
Variable = '%cippuserschema%'
73+
Description = 'The CIPP user schema extension ID'
74+
Type = 'reserved'
75+
Category = 'cipp'
76+
},
77+
@{
78+
Name = 'cippurl'
79+
Variable = '%cippurl%'
80+
Description = 'The CIPP instance URL'
81+
Type = 'reserved'
82+
Category = 'cipp'
83+
},
84+
@{
85+
Name = 'serial'
86+
Variable = '%serial%'
87+
Description = 'System serial number'
88+
Type = 'reserved'
89+
Category = 'system'
90+
},
91+
@{
92+
Name = 'systemroot'
93+
Variable = '%systemroot%'
94+
Description = 'System root directory'
95+
Type = 'reserved'
96+
Category = 'system'
97+
},
98+
@{
99+
Name = 'systemdrive'
100+
Variable = '%systemdrive%'
101+
Description = 'System drive letter'
102+
Type = 'reserved'
103+
Category = 'system'
104+
},
105+
@{
106+
Name = 'temp'
107+
Variable = '%temp%'
108+
Description = 'Temporary directory path'
109+
Type = 'reserved'
110+
Category = 'system'
111+
},
112+
@{
113+
Name = 'userprofile'
114+
Variable = '%userprofile%'
115+
Description = 'User profile directory'
116+
Type = 'reserved'
117+
Category = 'system'
118+
},
119+
@{
120+
Name = 'username'
121+
Variable = '%username%'
122+
Description = 'Current username'
123+
Type = 'reserved'
124+
Category = 'system'
125+
},
126+
@{
127+
Name = 'userdomain'
128+
Variable = '%userdomain%'
129+
Description = 'User domain'
130+
Type = 'reserved'
131+
Category = 'system'
132+
},
133+
@{
134+
Name = 'windir'
135+
Variable = '%windir%'
136+
Description = 'Windows directory'
137+
Type = 'reserved'
138+
Category = 'system'
139+
},
140+
@{
141+
Name = 'programfiles'
142+
Variable = '%programfiles%'
143+
Description = 'Program Files directory'
144+
Type = 'reserved'
145+
Category = 'system'
146+
},
147+
@{
148+
Name = 'programfiles(x86)'
149+
Variable = '%programfiles(x86)%'
150+
Description = 'Program Files (x86) directory'
151+
Type = 'reserved'
152+
Category = 'system'
153+
},
154+
@{
155+
Name = 'programdata'
156+
Variable = '%programdata%'
157+
Description = 'Program Data directory'
158+
Type = 'reserved'
159+
Category = 'system'
160+
}
161+
)
162+
163+
# Use a hashtable to track variables by name to handle overrides
164+
$VariableMap = @{}
165+
166+
if ($Request.Query.includeSystem -and $Request.Query.includeSystem -ne 'true') {
167+
$ReservedVariables = $ReservedVariables | Where-Object { $_.Category -ne 'system' }
168+
}
169+
170+
# Add reserved variables first
171+
foreach ($Variable in $ReservedVariables) {
172+
$VariableMap[$Variable.Name] = $Variable
173+
}
174+
175+
# Get custom variables from the replace map table
176+
$ReplaceTable = Get-CIPPTable -tablename 'CippReplacemap'
177+
178+
# Get global variables (AllTenants) - these can be overridden by tenant-specific ones
179+
$GlobalVariables = Get-CIPPAzDataTableEntity @ReplaceTable -Filter "PartitionKey eq 'AllTenants'"
180+
if ($GlobalVariables) {
181+
foreach ($Variable in $GlobalVariables) {
182+
if ($Variable.RowKey -and $Variable.Value) {
183+
$VariableMap[$Variable.RowKey] = @{
184+
Name = $Variable.RowKey
185+
Variable = "%$($Variable.RowKey)%"
186+
Description = 'Global custom variable'
187+
Value = $Variable.Value
188+
Type = 'custom'
189+
Category = 'global'
190+
Scope = 'AllTenants'
191+
}
192+
}
193+
}
194+
}
195+
196+
# Get tenant-specific variables if tenantFilter is provided
197+
# These override any global variables with the same name
198+
$TenantFilter = $Request.Query.tenantFilter
199+
if ($TenantFilter -and $TenantFilter -ne 'AllTenants') {
200+
# Try to get tenant to find customerId
201+
try {
202+
$Tenant = Get-Tenants -TenantFilter $TenantFilter
203+
$CustomerId = $Tenant.customerId
204+
205+
# Get variables by customerId
206+
$TenantVariables = Get-CIPPAzDataTableEntity @ReplaceTable -Filter "PartitionKey eq '$CustomerId'"
207+
208+
# If no results found by customerId, try by defaultDomainName
209+
if (-not $TenantVariables) {
210+
$TenantVariables = Get-CIPPAzDataTableEntity @ReplaceTable -Filter "PartitionKey eq '$($Tenant.defaultDomainName)'"
211+
}
212+
213+
if ($TenantVariables) {
214+
foreach ($Variable in $TenantVariables) {
215+
if ($Variable.RowKey -and $Variable.Value) {
216+
# Tenant variables override global ones with the same name
217+
$VariableMap[$Variable.RowKey] = @{
218+
Name = $Variable.RowKey
219+
Variable = "%$($Variable.RowKey)%"
220+
Description = 'Tenant-specific custom variable'
221+
Value = $Variable.Value
222+
Type = 'custom'
223+
Category = 'tenant-custom'
224+
Scope = $TenantFilter
225+
}
226+
}
227+
}
228+
}
229+
} catch {
230+
Write-LogMessage -API $APIName -message "Could not retrieve tenant-specific variables for $TenantFilter : $($_.Exception.Message)" -Sev 'Warning'
231+
}
232+
}
233+
234+
# Convert hashtable values to array and sort
235+
$AllVariables = $VariableMap.Values
236+
$SortedVariables = $AllVariables | Sort-Object @{
237+
Expression = {
238+
switch ($_.Type) {
239+
'reserved' { 1 }
240+
'custom' {
241+
switch ($_.Category) {
242+
'global' { 2 }
243+
'tenant-custom' { 3 }
244+
default { 4 }
245+
}
246+
}
247+
default { 5 }
248+
}
249+
}
250+
}, Name
251+
252+
$HttpResponse.Body = @{
253+
Results = @($SortedVariables)
254+
Metadata = @{
255+
TenantFilter = $TenantFilter
256+
TotalCount = $SortedVariables.Count
257+
ReservedCount = @($SortedVariables | Where-Object { $_.Type -eq 'reserved' }).Count
258+
CustomCount = @($SortedVariables | Where-Object { $_.Type -eq 'custom' }).Count
259+
}
260+
}
261+
262+
} catch {
263+
$HttpResponse.StatusCode = [HttpStatusCode]::InternalServerError
264+
$HttpResponse.Body = @{
265+
Results = @()
266+
Error = $_.Exception.Message
267+
}
268+
Write-LogMessage -API $APIName -message "Failed to retrieve custom variables: $($_.Exception.Message)" -Sev 'Error'
269+
}
270+
271+
return $HttpResponse
272+
}

0 commit comments

Comments
 (0)