@@ -49,9 +49,6 @@ function Invoke-CIPPSharePointTemplateDeploy {
4949 Set-CIPPAsyncDeploymentStep - JobId $DeploymentId - Name $TenantFilter - StepIndex $Index - StepStatus $Status - Message $Message
5050 }
5151
52- # Extracts the group display name from a stored permission entry: the frontend saves plain
53- # strings, but older entries may be autocomplete objects ({label,value}).
54- $GetPrincipalName = { param ($Principal ) $Principal.value ?? $Principal }
5552 $CreateMissingGroups = $TemplateData.createMissingGroups -eq $true
5653 $SkipIfExists = $TemplateData.skipIfExists -eq $true
5754
@@ -108,9 +105,34 @@ function Invoke-CIPPSharePointTemplateDeploy {
108105 $Team = New-CIPPTeam - DisplayName $SiteTemplate.displayName - Description ($SiteTemplate.description ?? ' ' ) - Owner $SiteOwner - TenantFilter $TenantFilter - Headers $Headers - APIName $APIName
109106 $SiteUrl = $Team.SiteUrl
110107 $Results.Add (" [$TenantFilter ] Created Team '$ ( $SiteTemplate.displayName ) ' with site $SiteUrl " )
108+ $RawLanguage = [string ](($SiteTemplate.language.value ?? $SiteTemplate.language ))
109+ if ($RawLanguage -and $RawLanguage -ne ' default' ) {
110+ $Results.Add (" [$TenantFilter ] $ ( $SiteTemplate.displayName ) : site language '$RawLanguage ' was not applied — Teams sites use the tenant default SharePoint language." )
111+ Write-LogMessage - headers $Headers - API $APIName - tenant $TenantFilter - message " SharePoint template site '$ ( $SiteTemplate.displayName ) ': language LCID $RawLanguage skipped for Teams site (tenant default applies)." - sev Info
112+ }
111113 } else {
112114 Update-DeployStep - Index $SiteIndex - Status ' running' - Message " Step 2 of ${TotalSteps} : Creating SharePoint site"
113- $null = New-CIPPSharepointSite - SiteName $SiteTemplate.displayName - SiteDescription ($SiteTemplate.description ?? $SiteTemplate.displayName ) - SiteOwner $SiteOwner - TemplateName ' Team' - TenantFilter $TenantFilter - Headers $Headers - APIName $APIName
115+ $SiteParams = @ {
116+ SiteName = $SiteTemplate.displayName
117+ SiteDescription = ($SiteTemplate.description ?? $SiteTemplate.displayName )
118+ SiteOwner = $SiteOwner
119+ TemplateName = ' Team'
120+ TenantFilter = $TenantFilter
121+ Headers = $Headers
122+ APIName = $APIName
123+ }
124+ # language "default" (or missing) → Lcid 0 so New-CIPPSharepointSite uses tenant default.
125+ # A specific language → pass that LCID. Always pass Lcid so we don't fall back to the
126+ # helper's legacy English default used by AddSite.
127+ $RawLanguage = [string ](($SiteTemplate.language.value ?? $SiteTemplate.language ))
128+ $ParsedLcid = 0
129+ if ($RawLanguage -and $RawLanguage -ne ' default' ) {
130+ if (-not [int ]::TryParse($RawLanguage , [ref ]$ParsedLcid ) -or $ParsedLcid -le 0 ) {
131+ throw " Site language '$RawLanguage ' on '$ ( $SiteTemplate.displayName ) ' is not a valid LCID."
132+ }
133+ }
134+ $SiteParams.Lcid = $ParsedLcid
135+ $null = New-CIPPSharepointSite @SiteParams
114136 $SharePointInfo = Get-SharePointAdminLink - Public $false - tenantFilter $TenantFilter
115137 $SitePath = $SiteTemplate.displayName -replace ' ' -replace ' [^A-Za-z0-9-]'
116138 $SiteUrl = " https://$ ( $SharePointInfo.TenantName ) .sharepoint.com/sites/$SitePath "
@@ -121,25 +143,22 @@ function Invoke-CIPPSharePointTemplateDeploy {
121143 # here must mark this site step failed — do not report succeeded after swallowing errors.
122144 $StepFailures = [System.Collections.Generic.List [string ]]::new()
123145
146+ # Root-level permissions, grouped per permission level.
124147 # Set-CIPPSharePointObjectPermission only throws when nothing was granted. Partial
125148 # outcomes (some Failed / Not found) still return a message — treat those as failures.
126- $TestPermissionOutcome = {
127- param ([string ]$Outcome , [string ]$Context )
128- if ($Outcome -match ' Failed for|Not found by display name' ) {
129- $StepFailures.Add (" ${Context} : $Outcome " )
130- Write-LogMessage - headers $Headers - API $APIName - tenant $TenantFilter - message " SharePoint template site '$ ( $SiteTemplate.displayName ) ': ${Context} : $Outcome " - sev Error
131- }
132- }
133-
134- # Root-level permissions, grouped per permission level.
135149 Update-DeployStep - Index $SiteIndex - Status ' running' - Message " Step 3 of ${TotalSteps} : Applying site permissions"
136150 $RootPermGroups = @ ($SiteTemplate.permissions ) | Group-Object - Property permissionLevel
137151 foreach ($PermGroup in $RootPermGroups ) {
138- $GroupNames = @ ($PermGroup.Group | ForEach-Object { & $GetPrincipalName $_.principal }) | Where-Object { $_ }
152+ # Frontend may store principals as plain strings or autocomplete {label,value} objects.
153+ $GroupNames = @ ($PermGroup.Group | ForEach-Object { $_.principal.value ?? $_.principal }) | Where-Object { $_ }
139154 try {
140155 $PermResult = Set-CIPPSharePointObjectPermission - SiteUrl $SiteUrl - PermissionLevel $PermGroup.Name - GroupNames $GroupNames - CreateMissingGroups:$CreateMissingGroups - TenantFilter $TenantFilter - Headers $Headers - APIName $APIName
141156 $Results.Add (" [$TenantFilter ] $ ( $SiteTemplate.displayName ) : $PermResult " )
142- & $TestPermissionOutcome $PermResult " Root permissions ($ ( $PermGroup.Name ) )"
157+ if ($PermResult -match ' Failed for|Not found by display name' ) {
158+ $FailMsg = " Root permissions ($ ( $PermGroup.Name ) ): $PermResult "
159+ $StepFailures.Add ($FailMsg )
160+ Write-LogMessage - headers $Headers - API $APIName - tenant $TenantFilter - message " SharePoint template site '$ ( $SiteTemplate.displayName ) ': $FailMsg " - sev Error
161+ }
143162 } catch {
144163 $FailMsg = " Root permissions ($ ( $PermGroup.Name ) ) failed: $ ( $_.Exception.Message ) "
145164 $StepFailures.Add ($FailMsg )
@@ -159,11 +178,15 @@ function Invoke-CIPPSharePointTemplateDeploy {
159178
160179 $LibPermGroups = @ ($Library.permissions ) | Group-Object - Property permissionLevel
161180 foreach ($PermGroup in $LibPermGroups ) {
162- $GroupNames = @ ($PermGroup.Group | ForEach-Object { & $GetPrincipalName $_.principal }) | Where-Object { $_ }
181+ $GroupNames = @ ($PermGroup.Group | ForEach-Object { $_ .principal.value ?? $_.principal }) | Where-Object { $_ }
163182 try {
164183 $PermResult = Set-CIPPSharePointObjectPermission - SiteUrl $SiteUrl - ListId $NewLibrary.ListId - PermissionLevel $PermGroup.Name - GroupNames $GroupNames - CreateMissingGroups:$CreateMissingGroups - TenantFilter $TenantFilter - Headers $Headers - APIName $APIName
165184 $Results.Add (" [$TenantFilter ] $ ( $SiteTemplate.displayName ) /$ ( $Library.name ) : $PermResult " )
166- & $TestPermissionOutcome $PermResult " Library '$ ( $Library.name ) ' permissions ($ ( $PermGroup.Name ) )"
185+ if ($PermResult -match ' Failed for|Not found by display name' ) {
186+ $FailMsg = " Library '$ ( $Library.name ) ' permissions ($ ( $PermGroup.Name ) ): $PermResult "
187+ $StepFailures.Add ($FailMsg )
188+ Write-LogMessage - headers $Headers - API $APIName - tenant $TenantFilter - message " SharePoint template site '$ ( $SiteTemplate.displayName ) ': $FailMsg " - sev Error
189+ }
167190 } catch {
168191 $FailMsg = " Library '$ ( $Library.name ) ' permissions ($ ( $PermGroup.Name ) ) failed: $ ( $_.Exception.Message ) "
169192 $StepFailures.Add ($FailMsg )
0 commit comments