Skip to content

Commit ee0f5b7

Browse files
committed
template run fixes
1 parent aa175cb commit ee0f5b7

File tree

2 files changed

+139
-101
lines changed

2 files changed

+139
-101
lines changed

Modules/CIPPCore/Public/New-CIPPTemplateRun.ps1

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,30 +21,35 @@ function New-CIPPTemplateRun {
2121
}
2222
if ($TemplateSettings.templateRepo) {
2323
Write-Host 'Grabbing data from required community repo'
24-
$Files = (Get-GitHubFileTree -FullName $TemplateSettings.templateRepo.value -Branch $TemplateSettings.templateRepoBranch.value).tree | Where-Object { $_.path -match '.json$' -and $_.path -notmatch 'NativeImport' } | Select-Object *, @{n = 'html_url'; e = { "https://github.com/$($SplatParams.FullName)/tree/$($SplatParams.Branch)/$($_.path)" } }, @{n = 'name'; e = { ($_.path -split '/')[ -1 ] -replace '\.json$', '' } }
25-
#if there is a migration table file, file the file. Store the file contents in $migrationtable
26-
$MigrationTable = $Files | Where-Object { $_.name -eq 'MigrationTable' } | Select-Object -Last 1
27-
if ($MigrationTable) {
28-
$MigrationTable = (Get-GitHubFileContents -FullName $TemplateSettings.templateRepo.value -Branch $TemplateSettings.templateRepoBranch.value -Path $MigrationTable.path).content | ConvertFrom-Json
29-
}
30-
foreach ($File in $Files) {
31-
if ($File.name -eq 'MigrationTable' -or $file.name -eq 'ALLOWED COUNTRIES') { continue }
32-
$ExistingTemplate = $ExistingTemplates | Where-Object { $_.displayName -eq $File.name } | Select-Object -First 1
33-
$Template = (Get-GitHubFileContents -FullName $TemplateSettings.templateRepo.value -Branch $TemplateSettings.templateRepoBranch.value -Path $File.path).content | ConvertFrom-Json
34-
if ($ExistingTemplate) {
35-
$UpdateNeeded = $false
36-
if ($ExistingTemplate.sha -ne $File.sha -or !$ExistingTemplate.sha) {
37-
$UpdateNeeded = $true
38-
}
39-
if ($UpdateNeeded) {
40-
Write-Host "Template $($File.name) needs to be updated as the SHA is different"
24+
try {
25+
$Files = (Get-GitHubFileTree -FullName $TemplateSettings.templateRepo.value -Branch $TemplateSettings.templateRepoBranch.value).tree | Where-Object { $_.path -match '.json$' -and $_.path -notmatch 'NativeImport' } | Select-Object *, @{n = 'html_url'; e = { "https://github.com/$($SplatParams.FullName)/tree/$($SplatParams.Branch)/$($_.path)" } }, @{n = 'name'; e = { ($_.path -split '/')[ -1 ] -replace '\.json$', '' } }
26+
#if there is a migration table file, file the file. Store the file contents in $migrationtable
27+
$MigrationTable = $Files | Where-Object { $_.name -eq 'MigrationTable' } | Select-Object -Last 1
28+
if ($MigrationTable) {
29+
$MigrationTable = (Get-GitHubFileContents -FullName $TemplateSettings.templateRepo.value -Branch $TemplateSettings.templateRepoBranch.value -Path $MigrationTable.path).content | ConvertFrom-Json
30+
}
31+
foreach ($File in $Files) {
32+
if ($File.name -eq 'MigrationTable' -or $file.name -eq 'ALLOWED COUNTRIES') { continue }
33+
$ExistingTemplate = $ExistingTemplates | Where-Object { $_.displayName -eq $File.name } | Select-Object -First 1
34+
$Template = (Get-GitHubFileContents -FullName $TemplateSettings.templateRepo.value -Branch $TemplateSettings.templateRepoBranch.value -Path $File.path).content | ConvertFrom-Json
35+
if ($ExistingTemplate) {
36+
$UpdateNeeded = $false
37+
if ($ExistingTemplate.sha -ne $File.sha -or !$ExistingTemplate.sha) {
38+
$UpdateNeeded = $true
39+
}
40+
if ($UpdateNeeded) {
41+
Write-Host "Template $($File.name) needs to be updated as the SHA is different"
42+
Import-CommunityTemplate -Template $Template -SHA $File.sha -MigrationTable $MigrationTable
43+
}
44+
} else {
45+
Write-Host "Template $($File.name) needs to be created"
4146
Import-CommunityTemplate -Template $Template -SHA $File.sha -MigrationTable $MigrationTable
4247
}
43-
} else {
44-
Write-Host "Template $($File.name) needs to be created"
45-
Import-CommunityTemplate -Template $Template -SHA $File.sha -MigrationTable $MigrationTable
46-
4748
}
49+
} catch {
50+
$Message = "Failed to get data from community repo $($TemplateSettings.templateRepo.value). Error: $($_.Exception.Message)"
51+
Write-LogMessage -API 'Community Repo' -tenant $TenantFilter -message $Message -sev Error
52+
return "Failed to get data from community repo $($TemplateSettings.templateRepo.value). Error: $($_.Exception.Message)"
4853
}
4954
} else {
5055
foreach ($Task in $Tasks) {

Modules/CIPPCore/Public/Tools/Import-CommunityTemplate.ps1

Lines changed: 113 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -13,97 +13,130 @@ function Import-CommunityTemplate {
1313

1414
$Table = Get-CippTable -TableName 'templates'
1515

16+
try {
17+
if ($Template.RowKey) {
18+
Write-Host "This is going to be a direct write to table, it's a CIPP template. We're writing $($Template.RowKey)"
19+
$Template = $Template | Select-Object * -ExcludeProperty Timestamp
1620

17-
if ($Template.RowKey) {
18-
Write-Host "This is going to be a direct write to table, it's a CIPP template. We're writing $($Template.RowKey)"
19-
$Template = $Template | Select-Object * -ExcludeProperty timestamp
20-
Add-CIPPAzDataTableEntity @Table -Entity $Template -Force
21-
} else {
22-
if ($Template.mailNickname) { $Type = 'Group' }
23-
if ($Template.'@odata.type' -like '*conditionalAccessPolicy*') { $Type = 'ConditionalAccessPolicy' }
24-
Write-Host "The type is $Type"
25-
switch -Wildcard ($Type) {
21+
# Support both objects and json string in repo (support pretty printed json in repo)
22+
if (Test-Json $Template.JSON -ErrorAction SilentlyContinue) {
23+
$NewJSON = $Template.JSON | ConvertFrom-Json
24+
} else {
25+
$NewJSON = $Template.JSON
26+
}
27+
28+
# Check for existing object
29+
$Existing = Get-CIPPAzDataTableEntity @Table -Filter "RowKey eq '$($Template.RowKey)' and PartitionKey eq '$($Template.PartitionKey)'" -ErrorAction SilentlyContinue
2630

27-
'*Group*' {
28-
$RawJsonObj = [PSCustomObject]@{
29-
Displayname = $Template.displayName
30-
Description = $Template.Description
31-
MembershipRules = $Template.membershipRule
32-
username = $Template.mailNickname
33-
GUID = $Template.id
34-
groupType = 'generic'
35-
} | ConvertTo-Json -Depth 100
36-
$entity = @{
37-
JSON = "$RawJsonObj"
38-
PartitionKey = 'GroupTemplate'
39-
SHA = $SHA
40-
GUID = $Template.id
41-
RowKey = $Template.id
31+
if ($Existing) {
32+
if ($Existing.PartitionKey -eq 'StandardsTemplateV2') {
33+
# Convert existing JSON to object for updates
34+
if (Test-Json $Existing.JSON -ErrorAction SilentlyContinue) {
35+
$ExistingJSON = $Existing.JSON | ConvertFrom-Json
36+
} else {
37+
$ExistingJSON = $Existing.JSON
38+
}
39+
# Extract existing tenantFilter and excludedTenants
40+
$tenantFilter = $ExistingJSON.tenantFilter
41+
$excludedTenants = $ExistingJSON.excludedTenants
42+
$NewJSON.tenantFilter = $tenantFilter
43+
$NewJSON.excludedTenants = $excludedTenants
4244
}
43-
Add-CIPPAzDataTableEntity @Table -Entity $entity -Force
44-
break
4545
}
46-
'*conditionalAccessPolicy*' {
47-
Write-Host $MigrationTable
48-
$Template = ([pscustomobject]$Template) | ForEach-Object {
49-
$NonEmptyProperties = $_.psobject.Properties | Where-Object { $null -ne $_.Value } | Select-Object -ExpandProperty Name
50-
$_ | Select-Object -Property $NonEmptyProperties
51-
}
52-
$id = $Template.id
53-
$Template = $Template | Select-Object * -ExcludeProperty lastModifiedDateTime, 'assignments', '#microsoft*', '*@odata.navigationLink', '*@odata.associationLink', '*@odata.context', 'ScopeTagIds', 'supportsScopeTags', 'createdDateTime', '@odata.id', '@odata.editLink', '*odata.type', '[email protected]', createdDateTime, '[email protected]'
54-
Remove-ODataProperties -Object $Template
55-
$RawJson = ConvertTo-Json -InputObject $Template -Depth 100 -Compress
56-
#Replace the ids with the displayname by using the migration table, this is a simple find and replace each instance in the JSON.
57-
$MigrationTable.objects | ForEach-Object {
58-
if ($RawJson -match $_.ID) {
59-
$RawJson = $RawJson.Replace($_.ID, $($_.DisplayName))
46+
# Re-compress JSON and save to table
47+
$NewJSON = [string]($NewJSON | ConvertTo-Json -Depth 100 -Compress)
48+
$Template.JSON = $NewJSON
49+
$Template | Add-Member -MemberType NoteProperty -Name SHA -Value $SHA -Force
50+
Add-CIPPAzDataTableEntity @Table -Entity $Template -Force
51+
} else {
52+
if ($Template.mailNickname) { $Type = 'Group' }
53+
if ($Template.'@odata.type' -like '*conditionalAccessPolicy*') { $Type = 'ConditionalAccessPolicy' }
54+
Write-Host "The type is $Type"
55+
switch -Wildcard ($Type) {
56+
57+
'*Group*' {
58+
$RawJsonObj = [PSCustomObject]@{
59+
Displayname = $Template.displayName
60+
Description = $Template.Description
61+
MembershipRules = $Template.membershipRule
62+
username = $Template.mailNickname
63+
GUID = $Template.id
64+
groupType = 'generic'
65+
} | ConvertTo-Json -Depth 100
66+
$entity = @{
67+
JSON = "$RawJsonObj"
68+
PartitionKey = 'GroupTemplate'
69+
SHA = $SHA
70+
GUID = $Template.id
71+
RowKey = $Template.id
6072
}
73+
Add-CIPPAzDataTableEntity @Table -Entity $entity -Force
74+
break
6175
}
62-
$entity = @{
63-
JSON = "$RawJson"
64-
PartitionKey = 'CATemplate'
65-
SHA = $SHA
66-
GUID = $ID
67-
RowKey = $ID
68-
}
69-
Add-CIPPAzDataTableEntity @Table -Entity $entity -Force
70-
break
71-
}
72-
default {
73-
$URLName = switch -Wildcard ($Template.'@odata.id') {
74-
'*CompliancePolicies*' { 'DeviceCompliancePolicies' }
75-
'*deviceConfigurations*' { 'Device' }
76-
'*DriverUpdateProfiles*' { 'windowsDriverUpdateProfiles' }
77-
'*SettingsCatalog*' { 'Catalog' }
78-
'*configurationPolicies*' { 'Catalog' }
79-
'*managedAppPolicies*' { 'AppProtection' }
80-
'*deviceAppManagement*' { 'AppProtection' }
76+
'*conditionalAccessPolicy*' {
77+
Write-Host $MigrationTable
78+
$Template = ([pscustomobject]$Template) | ForEach-Object {
79+
$NonEmptyProperties = $_.psobject.Properties | Where-Object { $null -ne $_.Value } | Select-Object -ExpandProperty Name
80+
$_ | Select-Object -Property $NonEmptyProperties
81+
}
82+
$id = $Template.id
83+
$Template = $Template | Select-Object * -ExcludeProperty lastModifiedDateTime, 'assignments', '#microsoft*', '*@odata.navigationLink', '*@odata.associationLink', '*@odata.context', 'ScopeTagIds', 'supportsScopeTags', 'createdDateTime', '@odata.id', '@odata.editLink', '*odata.type', '[email protected]', createdDateTime, '[email protected]'
84+
Remove-ODataProperties -Object $Template
85+
$RawJson = ConvertTo-Json -InputObject $Template -Depth 100 -Compress
86+
#Replace the ids with the displayname by using the migration table, this is a simple find and replace each instance in the JSON.
87+
$MigrationTable.objects | ForEach-Object {
88+
if ($RawJson -match $_.ID) {
89+
$RawJson = $RawJson.Replace($_.ID, $($_.DisplayName))
90+
}
91+
}
92+
$entity = @{
93+
JSON = "$RawJson"
94+
PartitionKey = 'CATemplate'
95+
SHA = $SHA
96+
GUID = $ID
97+
RowKey = $ID
98+
}
99+
Add-CIPPAzDataTableEntity @Table -Entity $entity -Force
100+
break
81101
}
82-
$id = $Template.id
83-
$RawJson = $Template | Select-Object * -ExcludeProperty id, lastModifiedDateTime, 'assignments', '#microsoft*', '*@odata.navigationLink', '*@odata.associationLink', '*@odata.context', 'ScopeTagIds', 'supportsScopeTags', 'createdDateTime', '@odata.id', '@odata.editLink', '[email protected]', '[email protected]', createdDateTime, '[email protected]'
84-
Remove-ODataProperties -Object $RawJson
85-
$RawJson = $RawJson | ConvertTo-Json -Depth 100 -Compress
102+
default {
103+
$URLName = switch -Wildcard ($Template.'@odata.id') {
104+
'*CompliancePolicies*' { 'DeviceCompliancePolicies' }
105+
'*deviceConfigurations*' { 'Device' }
106+
'*DriverUpdateProfiles*' { 'windowsDriverUpdateProfiles' }
107+
'*SettingsCatalog*' { 'Catalog' }
108+
'*configurationPolicies*' { 'Catalog' }
109+
'*managedAppPolicies*' { 'AppProtection' }
110+
'*deviceAppManagement*' { 'AppProtection' }
111+
}
112+
$id = $Template.id
113+
$RawJson = $Template | Select-Object * -ExcludeProperty id, lastModifiedDateTime, 'assignments', '#microsoft*', '*@odata.navigationLink', '*@odata.associationLink', '*@odata.context', 'ScopeTagIds', 'supportsScopeTags', 'createdDateTime', '@odata.id', '@odata.editLink', '[email protected]', '[email protected]', createdDateTime, '[email protected]'
114+
Remove-ODataProperties -Object $RawJson
115+
$RawJson = $RawJson | ConvertTo-Json -Depth 100 -Compress
86116

87-
#create a new template
88-
$RawJsonObj = [PSCustomObject]@{
89-
Displayname = $Template.displayName ?? $template.Name
90-
Description = $Template.Description
91-
RAWJson = $RawJson
92-
Type = $URLName
93-
GUID = $ID
94-
} | ConvertTo-Json -Depth 100 -Compress
117+
#create a new template
118+
$RawJsonObj = [PSCustomObject]@{
119+
Displayname = $Template.displayName ?? $template.Name
120+
Description = $Template.Description
121+
RAWJson = $RawJson
122+
Type = $URLName
123+
GUID = $ID
124+
} | ConvertTo-Json -Depth 100 -Compress
95125

96-
$entity = @{
97-
JSON = "$RawJsonObj"
98-
PartitionKey = 'IntuneTemplate'
99-
SHA = $SHA
100-
GUID = $ID
101-
RowKey = $ID
102-
}
103-
Add-CIPPAzDataTableEntity @Table -Entity $entity -Force
126+
$entity = @{
127+
JSON = "$RawJsonObj"
128+
PartitionKey = 'IntuneTemplate'
129+
SHA = $SHA
130+
GUID = $ID
131+
RowKey = $ID
132+
}
133+
Add-CIPPAzDataTableEntity @Table -Entity $entity -Force
104134

135+
}
105136
}
106137
}
138+
} catch {
139+
Write-Warning "Community template import failed. Error: $($_.Exception.Message)"
140+
Write-Information $_.InvocationInfo.PositionMessage
107141
}
108-
109142
}

0 commit comments

Comments
 (0)