Skip to content

Commit 77684ea

Browse files
authored
Merge pull request #15 from KelvinTegelaar/dev
[pull] dev from KelvinTegelaar:dev
2 parents 101ec62 + c83c1bd commit 77684ea

14 files changed

Lines changed: 250 additions & 113 deletions

Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecOnboardTenantQueue.ps1

Lines changed: 60 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -443,38 +443,75 @@ function Push-ExecOnboardTenantQueue {
443443

444444
if ($OnboardingSteps.Step4.Status -eq 'succeeded') {
445445
if ($Item.StandardsExcludeAllTenants -eq $true) {
446-
$AddExclusionObj = [PSCustomObject]@{
447-
label = '{0} ({1})' -f $Tenant.displayName, $Tenant.defaultDomainName
448-
value = $Tenant.defaultDomainName
449-
addedFields = @{
450-
customerId = $Tenant.customerId
451-
defaultDomainName = $Tenant.defaultDomainName
446+
$GroupTable = Get-CIPPTable -tablename 'TenantGroups'
447+
$MembersTable = Get-CIPPTable -tablename 'TenantGroupMembers'
448+
$ExclusionGroupName = 'Excluded onboarded tenants'
449+
450+
# Find existing exclusion group
451+
$ExclusionGroup = Get-CIPPAzDataTableEntity @GroupTable -Filter "PartitionKey eq 'TenantGroup'" | Where-Object { $_.Name -eq $ExclusionGroupName }
452+
if (-not $ExclusionGroup) {
453+
$ExclusionGroupId = [guid]::NewGuid().ToString()
454+
$ExclusionGroup = @{
455+
PartitionKey = 'TenantGroup'
456+
RowKey = $ExclusionGroupId
457+
Name = $ExclusionGroupName
458+
Description = 'Tenants excluded from top-level standards during onboarding'
459+
GroupType = 'static'
452460
}
461+
Add-CIPPAzDataTableEntity @GroupTable -Entity $ExclusionGroup -Force
462+
$Logs.Add([PSCustomObject]@{ Date = (Get-Date).ToUniversalTime(); Log = "Created tenant group '$ExclusionGroupName'" })
463+
} else {
464+
$ExclusionGroupId = $ExclusionGroup.RowKey
465+
}
466+
467+
# Add tenant to the exclusion group if not already a member
468+
$MemberRowKey = '{0}-{1}' -f $ExclusionGroupId, $Tenant.customerId
469+
$ExistingMember = Get-CIPPAzDataTableEntity @MembersTable -Filter "PartitionKey eq 'Member' and RowKey eq '$MemberRowKey'"
470+
if (-not $ExistingMember) {
471+
Add-CIPPAzDataTableEntity @MembersTable -Entity @{
472+
PartitionKey = 'Member'
473+
RowKey = $MemberRowKey
474+
GroupId = $ExclusionGroupId
475+
customerId = $Tenant.customerId
476+
} -Force
477+
}
478+
479+
# Ensure the group is in excludedTenants of all AllTenants templates
480+
$GroupExclusionObj = [PSCustomObject]@{
481+
label = $ExclusionGroupName
482+
value = $ExclusionGroupId
483+
type = 'Group'
453484
}
454-
$Table = Get-CIPPTable -tablename 'templates'
455-
$ExistingTemplates = Get-CIPPAzDataTableEntity @Table -Filter "PartitionKey eq 'StandardsTemplateV2'" | Where-Object { $_.JSON -match 'AllTenants' }
485+
$TemplatesTable = Get-CIPPTable -tablename 'templates'
486+
$ExistingTemplates = Get-CIPPAzDataTableEntity @TemplatesTable -Filter "PartitionKey eq 'StandardsTemplateV2'" | Where-Object { $_.JSON -match 'AllTenants' }
456487
foreach ($AllTenantsTemplate in $ExistingTemplates) {
457488
$object = $AllTenantsTemplate.JSON | ConvertFrom-Json
458-
$NewExcludedTenants = [System.Collections.Generic.List[object]]::new()
459-
if (!$object.excludedTenants) {
489+
if (-not $object.excludedTenants) {
460490
$object | Add-Member -MemberType NoteProperty -Name 'excludedTenants' -Value @() -Force
461491
}
462-
foreach ($ExcludedStandardsTenant in $object.excludedTenants) {
463-
$NewExcludedTenants.Add($ExcludedStandardsTenant)
464-
}
465-
$NewExcludedTenants.Add($AddExclusionObj)
466-
$object.excludedTenants = $NewExcludedTenants
467-
$JSON = ConvertTo-Json -InputObject $object -Compress -Depth 10
468-
$Table.Force = $true
469-
Add-CIPPAzDataTableEntity @Table -Entity @{
470-
JSON = "$JSON"
471-
RowKey = $AllTenantsTemplate.RowKey
472-
GUID = $AllTenantsTemplate.GUID
473-
PartitionKey = 'StandardsTemplateV2'
492+
$AlreadyHasGroup = $object.excludedTenants | Where-Object { $_.value -eq $ExclusionGroupId -and $_.type -eq 'Group' }
493+
if (-not $AlreadyHasGroup) {
494+
$NewExcludedTenants = [System.Collections.Generic.List[object]]::new()
495+
foreach ($ExcludedEntry in $object.excludedTenants) {
496+
$NewExcludedTenants.Add($ExcludedEntry)
497+
}
498+
$NewExcludedTenants.Add($GroupExclusionObj)
499+
$object.excludedTenants = $NewExcludedTenants
500+
$JSON = ConvertTo-Json -InputObject $object -Compress -Depth 10
501+
$TemplatesTable.Force = $true
502+
Add-CIPPAzDataTableEntity @TemplatesTable -Entity @{
503+
JSON = "$JSON"
504+
RowKey = $AllTenantsTemplate.RowKey
505+
GUID = $AllTenantsTemplate.GUID
506+
PartitionKey = 'StandardsTemplateV2'
507+
}
474508
}
475509
}
476510

477-
$Logs.Add([PSCustomObject]@{ Date = (Get-Date).ToUniversalTime(); Log = 'Set All Tenant Standards Exclusion' })
511+
# Bust the tenant groups cache so standards pick up the new member
512+
$null = Get-TenantGroups -SkipCache
513+
514+
$Logs.Add([PSCustomObject]@{ Date = (Get-Date).ToUniversalTime(); Log = 'Set All Tenant Standards Exclusion via group' })
478515
}
479516
$Logs.Add([PSCustomObject]@{ Date = (Get-Date).ToUniversalTime(); Log = "Testing API access for $($Tenant.defaultDomainName)" })
480517
$OnboardingSteps.Step5.Status = 'running'

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Endpoint/Autopilot/Invoke-AddAPDevice.ps1

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,36 @@ function Invoke-AddAPDevice {
5151
if ($NewStatus.status -ne 'finished') { throw 'Could not retrieve status of import - This job might still be running. Check the autopilot device list in 10 minutes for the latest status.' }
5252
Write-LogMessage -headers $Request.Headers -API $APIName -tenant $($Request.body.TenantFilter.value) -message "Created Autopilot devices group. Group ID is $GroupName" -Sev 'Info'
5353

54+
# Apply group tags from CSV if any devices have them
55+
$DevicesWithGroupTags = @($rawDevices | Where-Object { $_.groupTag -and $_.groupTag.Trim() -ne '' })
56+
$GroupTagResults = [System.Collections.Generic.List[string]]::new()
57+
if ($DevicesWithGroupTags.Count -gt 0) {
58+
$TenantFilter = $Request.Body.TenantFilter.value
59+
try {
60+
$AutopilotDevices = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeviceIdentities?$top=999' -tenantid $TenantFilter
61+
foreach ($Device in $DevicesWithGroupTags) {
62+
try {
63+
$APDevice = $AutopilotDevices | Where-Object { $_.serialNumber -eq $Device.SerialNumber } | Select-Object -First 1
64+
if ($APDevice) {
65+
$body = @{ groupTag = $Device.groupTag } | ConvertTo-Json
66+
New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeviceIdentities/$($APDevice.id)/UpdateDeviceProperties" -tenantid $TenantFilter -body $body -method POST | Out-Null
67+
$GroupTagResults.Add("Set group tag '$($Device.groupTag)' for device '$($Device.SerialNumber)'")
68+
} else {
69+
$GroupTagResults.Add("Could not find Autopilot device for serial '$($Device.SerialNumber)' to set group tag - device may still be syncing")
70+
}
71+
} catch {
72+
$GroupTagResults.Add("Failed to set group tag for device '$($Device.SerialNumber)': $($_.Exception.Message)")
73+
}
74+
}
75+
} catch {
76+
$GroupTagResults.Add("Failed to retrieve Autopilot devices for group tag assignment: $($_.Exception.Message)")
77+
}
78+
}
79+
5480
[PSCustomObject]@{
55-
Status = 'Import Job Completed'
56-
Devices = @($NewStatus.devicesStatus)
81+
Status = 'Import Job Completed'
82+
Devices = @($NewStatus.devicesStatus)
83+
GroupTagStatus = $GroupTagResults
5784
}
5885
$StatusCode = [HttpStatusCode]::OK
5986
} catch {

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ExecUpdateDriftDeviation.ps1

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ function Invoke-ExecUpdateDriftDeviation {
99
param($Request, $TriggerMetadata)
1010

1111
$APIName = $TriggerMetadata.FunctionName
12-
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug'
12+
Write-LogMessage -Headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug'
1313

1414
try {
1515
$TenantFilter = $Request.Body.TenantFilter
@@ -25,7 +25,7 @@ function Invoke-ExecUpdateDriftDeviation {
2525
success = $true
2626
result = "All drift customizations removed for tenant $TenantFilter"
2727
})
28-
Write-LogMessage -tenant $TenantFilter -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Removed all drift customizations for tenant $TenantFilter" -Sev 'Info'
28+
Write-LogMessage -tenant $TenantFilter -Headers $Request.Headers -API $APINAME -message "Removed all drift customizations for tenant $TenantFilter" -Sev 'Info'
2929
} else {
3030
$Deviations = $Request.Body.deviations
3131
$Reason = $Request.Body.reason
@@ -39,7 +39,7 @@ function Invoke-ExecUpdateDriftDeviation {
3939
success = $true
4040
result = $Result
4141
}
42-
Write-LogMessage -tenant $TenantFilter -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Updated drift deviation status for $($Deviation.standardName) to $($Deviation.status) with reason: $Reason" -Sev 'Info'
42+
Write-LogMessage -tenant $TenantFilter -Headers $Request.Headers -API $APINAME -message "Updated drift deviation status for $($Deviation.standardName) to $($Deviation.status) with reason: $Reason" -Sev 'Info'
4343
if ($Deviation.status -eq 'DeniedRemediate') {
4444
$Setting = $Deviation.standardName -replace 'standards\.', ''
4545
$StandardTemplate = Get-CIPPTenantAlignment -TenantFilter $TenantFilter | Where-Object -Property standardType -EQ 'drift'
@@ -62,7 +62,7 @@ function Invoke-ExecUpdateDriftDeviation {
6262
}
6363
}
6464
if (-not $MatchedTemplate) {
65-
Write-LogMessage -tenant $TenantFilter -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Could not find IntuneTemplate $TemplateId in drift standard settings for remediation" -Sev 'Warn'
65+
Write-LogMessage -tenant $TenantFilter -Headers $Request.Headers -API $APINAME -message "Could not find IntuneTemplate $TemplateId in drift standard settings for remediation" -Sev 'Warn'
6666
} else {
6767
$MatchedTemplate | Add-Member -MemberType NoteProperty -Name 'remediate' -Value $true -Force
6868
$MatchedTemplate | Add-Member -MemberType NoteProperty -Name 'report' -Value $true -Force
@@ -132,7 +132,7 @@ function Invoke-ExecUpdateDriftDeviation {
132132
}
133133
}
134134
Add-CIPPScheduledTask -Task $PersistentTaskBody -hidden $false
135-
Write-LogMessage -tenant $TenantFilter -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Scheduled persistent drift remediation task (12h recurrence) for $Setting" -Sev 'Info'
135+
Write-LogMessage -tenant $TenantFilter -Headers $Request.Headers -API $APINAME -message "Scheduled persistent drift remediation task (12h recurrence) for $Setting" -Sev 'Info'
136136
}
137137
}
138138
if ($Deviation.status -eq 'deniedDelete') {
@@ -148,10 +148,10 @@ function Invoke-ExecUpdateDriftDeviation {
148148
Write-Host "Going to delete Policy with ID $($Policy.ID) Deviation Name is $($Deviation.standardName)"
149149
$null = New-GraphPostRequest -uri "https://graph.microsoft.com/beta/$($URLName)/$($ID)" -type DELETE -tenant $TenantFilter
150150
"Deleted Policy $($ID)"
151-
Write-LogMessage -tenant $TenantFilter -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Deleted Policy with ID $($ID)" -Sev 'Info'
151+
Write-LogMessage -tenant $TenantFilter -Headers $Request.Headers -API $APINAME -message "Deleted Policy with ID $($ID)" -Sev 'Info'
152152
} else {
153153
"could not find policy with ID $($ID)"
154-
Write-LogMessage -tenant $TenantFilter -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Could not find Policy with ID $($ID) to delete for remediation" -sev 'Warn'
154+
Write-LogMessage -tenant $TenantFilter -Headers $Request.Headers -API $APINAME -message "Could not find Policy with ID $($ID) to delete for remediation" -sev 'Warn'
155155
}
156156

157157

@@ -162,7 +162,7 @@ function Invoke-ExecUpdateDriftDeviation {
162162
success = $false
163163
error = $_.Exception.Message
164164
}
165-
Write-LogMessage -tenant $TenantFilter -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Failed to update drift deviation for $($Deviation.standardName): $($_.Exception.Message)" -Sev 'Error'
165+
Write-LogMessage -tenant $TenantFilter -Headers $Request.Headers -API $APINAME -message "Failed to update drift deviation for $($Deviation.standardName): $($_.Exception.Message)" -Sev 'Error'
166166
}
167167
}
168168
}
@@ -175,7 +175,7 @@ function Invoke-ExecUpdateDriftDeviation {
175175
})
176176

177177
} catch {
178-
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Failed to update drift deviation: $($_.Exception.Message)" -Sev 'Error'
178+
Write-LogMessage -Headers $Request.Headers -API $APINAME -message "Failed to update drift deviation: $($_.Exception.Message)" -Sev 'Error'
179179
return ([HttpResponseContext]@{
180180
StatusCode = [HttpStatusCode]::BadRequest
181181
Body = @{error = $_.Exception.Message }

Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAutopilotStatusPage.ps1

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -93,22 +93,29 @@ function Invoke-CIPPStandardAutopilotStatusPage {
9393

9494
# Remediate if the state is not correct
9595
if ($Settings.remediate -eq $true) {
96-
try {
97-
$Parameters = @{
98-
TenantFilter = $Tenant
99-
ShowProgress = $Settings.ShowProgress
100-
BlockDevice = $Settings.BlockDevice
101-
InstallWindowsUpdates = $InstallWindowsUpdates
102-
AllowReset = $Settings.AllowReset
103-
EnableLog = $Settings.EnableLog
104-
ErrorMessage = $Settings.ErrorMessage
105-
TimeOutInMinutes = $Settings.TimeOutInMinutes
106-
AllowFail = $Settings.AllowFail
107-
OBEEOnly = $Settings.OBEEOnly
108-
}
96+
if ($StateIsCorrect -eq $true) {
97+
Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Autopilot Enrollment Status Page is already configured correctly.' -sev Info
98+
} else {
99+
try {
100+
$Parameters = @{
101+
TenantFilter = $Tenant
102+
ShowProgress = $Settings.ShowProgress
103+
BlockDevice = $Settings.BlockDevice
104+
InstallWindowsUpdates = $InstallWindowsUpdates
105+
AllowReset = $Settings.AllowReset
106+
EnableLog = $Settings.EnableLog
107+
ErrorMessage = $Settings.ErrorMessage
108+
TimeOutInMinutes = $Settings.TimeOutInMinutes
109+
AllowFail = $Settings.AllowFail
110+
OBEEOnly = $Settings.OBEEOnly
111+
}
109112

110-
Set-CIPPDefaultAPEnrollment @Parameters
111-
} catch {
113+
Set-CIPPDefaultAPEnrollment @Parameters
114+
Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Autopilot Enrollment Status Page settings have been updated.' -sev Info
115+
} catch {
116+
$ErrorMessage = Get-CippException -Exception $_
117+
Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to update Autopilot Enrollment Status Page: $($ErrorMessage.NormalizedError)" -sev Error -LogData $ErrorMessage
118+
}
112119
}
113120
}
114121

Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardDisableGuests.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ function Invoke-CIPPStandardDisableGuests {
121121
Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to process bulk disable guests request: $($ErrorMessage.NormalizedError)" -sev Error -LogData $ErrorMessage
122122
}
123123
} else {
124-
Write-LogMessage -API 'Standards' -tenant $tenant -message "No guests accounts with a login longer than $checkDays days ago." -sev Info
124+
Write-LogMessage -API 'Standards' -tenant $tenant -message "No guests accounts with a login longer than $checkDays days ago - all guest accounts are already compliant." -sev Info
125125
}
126126
}
127127
if ($Settings.alert -eq $true) {

0 commit comments

Comments
 (0)