Drift
Endringslogg
Sjekk ut release notes for høydepunkter og mer detaljert endringslogg for siste hovedversjon.
1.0.0 - 10.09.2026
Sikkerhet
-
Gjeste-webdelen kan ikke lenger gi eksterne rollen Eier — rollen er låst til Gjest: Hele invitasjonskjeden er bygget for eksterne brukere (
ProcessGuestsposter alltid til Graph/invitations), men webdelen tilbød likevel fire roller opp til Eier — og gjester kan ikke eie en Microsoft 365-gruppe, så runbooken feilet. Rollen er nå låst til Gjest (gjestemedlemskap i M365-gruppen viaAdd-PnPMicrosoft365GroupMember— standardmodellen for eksterne i Microsoft 365, gir tilgang til team, område, Planner osv.; lagres somMemberi listen) eller Ingen rolle, i alle lag: radioknappene og property pane-dropdownen viser kun de to valgene, lagretOwnerfra eldre versjoner klemmes til Gjest ved retry og i webdel-konfigurasjonen, ogAddGuestToSite-runbooken avviserOwnermed tydelig feilmelding som siste skanse. Det gamle Besøkende-valget (Visitor) er fjernet fra UI — mer begrenset tilgang gis via SP-gruppevalget (Besøkende-gruppen pre-velges som før) — men gamleVisitor-rader æres fortsatt av runbooken ved retry.AccessPreviewPaneler forenklet tilsvarende (Eier-grenen og warning-varianten er død kode og fjernet), og statuslisten viser fortsatt historiske Besøkende/Eier-rader korrekt. -
Sensitivitetsmerking flyttet ut av Logic App-en — hemmeligheter eksponeres ikke lenger i kjørehistorikken:
Apply_sensitivity_label-scopet iProcessProvisionRequestgjorde en 12-actions ROPC-dans (legg tjenestekontoen til som gruppe-eier, vent 2 minutter, hent fire Key Vault-secrets, URL-enkod dem, hent token, PATCH mot Graph beta, fjern eieren).secureDatavar feilplassert inne iinputspå Key Vault-kallet for passordet, og manglet helt på URL-enkodingen, token-kallet og PATCH-en. Tjenestekontoens passord, appens client secret og et levende delegert Graph-token var dermed lesbare for alle med lesetilgang til Logic App-ens kjørehistorikk, ved hver bestilling med merke. Hele scopet er fjernet, og operasjonen gjøres nå iConfigureSpace-runbooken, der Automation-jobboutput bare inneholder det skriptet selv skriver. Har du kjørt en tidligere versjon medenableSensitivity = true, bør du rotere både tjenestekontoens passord og app-secreten etter oppgradering. -
ROPC-flyten, Key Vault-en og Entra ID-appen er fjernet — løsningen har ingen hemmeligheter i drift: sensitivitetsmerker settes nå app-only med Automation-kontoens managed identity via
Set-PnPTenantSite -SensitivityLabel, som går gjennom SharePoints tenant-admin-API og propagerer container-merket til gruppen på tjenersiden. Det omgår Graph-begrensningen forassignedLabels(som fortsatt står, re-verifisert august 2026 — men gjelder en annen vei enn den vi bruker). Målt 4. august 2026 i testtenant: virker, og merket er på gruppen innen 15 sekunder; feilmodusen i pnp/powershell#4917 reproduserte ikke. Runbooken leser alltid tilbakeassignedLabelsog feiler med en melding som navngir de sannsynlige årsakene hvis merket ikke landet.Kravet om en tjenestekonto uten MFA er dermed borte — en tilbakevendende innvending i kundenes sikkerhetsgjennomganger. Fjernet i sin helhet: Azure Key Vault med secretene
appid/appSecret/sausername/sapassword, API-tilkoblingenbestillingsportalen-kv(6 tilkoblinger → 5), Entra ID-app-registreringen med client secret,createentraidapp.ps1,appmanifest.json,Get-CredentialEndDates.ps1,Refreshing-app-secret.md, parametreneappName/keyVaultName,-SkipCreateEntraIDAppSecret, og ~230 linjer ideploy.ps1(secret-generering, Key Vault-validering med globalt unikt navnefallback, credential-prompt, pingback av secret-/sertifikatutløp). Installasjonen har dermed ett steg mindre og krever ikke lenger Global Administrator for å opprette en app-registrering.Tjenestekontoen beholdes — den er fortsatt områdeeier, identiteten bak de fire delegerte API-tilkoblingene og den som poster velkomstmeldingen i Teams. Det som falt bort er kravet om at MFA må være avslått.
enableSensitivity-parameteren er også fjernet. Etter at ROPC-apparatet forsvant hadde den bare én effekt: å seede listeelementetEnableSensitivityLabelsved førstegangs listepopulering — og den effekten uteble i upgrade-modus og når man svartenpå template-prompten. Ingenting deployes betinget:SyncLabels,IP Labels-listen ogInformationProtectionPolicy.Read.Allsettes opp uansett, og Logic App-en har alltid lest bryteren fra innstillinger-listen. Funksjonaliteten skrus nå av og på utelukkende der, uten å kjøredeploy.ps1på nytt. Også ute:-EnableSensitivity-switchen iGenerateParameters.ps1og «Sensitivity labels»-linja i pre-flight, som antydet at noe ble installert.Eksisterende installasjoner: ARM sletter ikke ressurser som fjernes fra en mal, så Key Vault, KV-tilkoblingen og app-registreringen blir liggende og må fjernes manuelt. Har miljøet kjørt med
enableSensitivity = true, bør tjenestekontoens passord roteres — se Oppgraderingsveiledningen.Sidefiks:
Get-Credentialreturnerer$nullnår den avbrytes, noe som ville krasjet skriptet på.UserName. -
Tjenestekontoen etterlates ikke lenger som gruppe-eier ved feil:
Remove_service_account_from_groupkjørte kunrunAfter: Succeeded, så en feilet merking ga tjenestekontoen permanent eierskap på gruppen. Nåtry/finallyi runbooken. Samme feil iPost_Welcome_Messageer rettet ved å utløse fjerningen påSucceeded/Failed/TimedOut.
Ny funksjonalitet
-
Bestilleren registreres som gjestens sponsor i Entra ID:
sponsorser Entras innebygde felt for hvem i organisasjonen som er ansvarlig for en ekstern bruker. Inviterer man manuelt fra Entra-portalen, setter Microsoft automatisk den som inviterer som sponsor — men Bestillingsportalen inviterer app-only med managed identity, så det finnes ingen brukerinviterer å registrere, og feltet har til nå stått tomt på alle BP-inviterte gjester. Løsningen sender nåRequestedByfraGuest Requests-listen gjennomProcessGuestRequesttilProcessGuests, som slår opp bestilleren i Entra (mailelleruserPrincipalName) og registrerer vedkommende medPOST /users/{id}/sponsors/$ref. Gjelder både nye og eksisterende gjester, og er standardfunksjonalitet uten bryter: sponsor gir ingen rettigheter — den dokumenterer ansvar — så i motsetning tilguestEntraGrouper det ingen sikkerhetsbeslutning kunden må ta stilling til. Ingen nye tillatelser: UAMI-ens eksisterendeUser.ReadWrite.Alldekker kallet, og sponsor er kjerne-B2B, ikke Entra ID Governance.Best effort by design. Hele steget ligger i et eget
Set_guest_sponsor-scope, ogResponsekjører videre påSucceeded/Failed/TimedOut. En sponsor som ikke lar seg sette kan dermed aldri velte en ellers vellykket invitasjon.Skippeder bevisst utelatt: scopet hoppes kun over når selve invitasjonen feilet, og da skal kjøringen feile slik at kalleren markerer forespørselen somFailed. Det er relevant fordi Entra tillater maks fem sponsorer per gjest, og en mye brukt ekstern konsulent treffer det taket. Rader utenRequestedBy(retry, elementer opprettet direkte i listen) og bestillere som ikke lar seg slå opp hoppes over på samme måte.ProcessGuestser lagt til i oppgraderingssettet (deploy.ps1 -Upgrade), som til nå bare deployetProcessProvisionRequestogProcessGuestRequest. Uten det ville en oppgradering sendtRequestedByEmailtil en flyt som ikke leser feltet. -
Valgfri felles Entra ID-gruppe for inviterte gjester (
guestEntraGroup): Ny valgfri installasjonsparameter som gjør at hver gjest invitert viaInviteGuests-webdelen — i tillegg til tenant-invitasjonen og tilgangen på det inviterte området — legges inn i en angitt Entra ID-gruppe. Organisasjonen kan dermed gi alle gjester en felles grunntilgang ett sted, f.eks. lesetilgang på hub-området og app-katalogen (etterspurt av en kunde som har opprettet en egen Entra ID-gruppe for formålet). Parameteren tar gruppens objekt-ID (anbefalt) eller visningsnavn — et visningsnavn må matche nøyaktig én gruppe, ellers feiler forespørselen med en tydelig melding i stedet for å gjette. Verdien flyter fraparameters.jsonviadeploy.ps1ogProcessGuestRequestLogic App inn iAddGuestToSite-runbooken som et nytt[STEP 3/3]: gjestens objekt-ID slås opp (samme UPN-utledning som M365-gruppesteget, nå felles iResolve-GuestObjectId), og medlemskapet legges til medPOST /groups/{id}/members/$ref— idempotent, «already exist» fra Graph behandles som suksess ved retry. Krever ingen nye tillatelser (Automation-identitetens eksisterendeGroup.ReadWrite.Alldekker kallet); sikkerhetsgrupper og M365-grupper støttes, rolletildelbare og on-prem-synkroniserte grupper kan ikke skrives via Graph. Tom/utelatt parameter = funksjonen er av, og eldreparameters.json-filer fungerer uendret. -
Tenant-register for Bestillingsportalen-instanser (
bp_ProvisionUrls) — URL-en er ikke lenger hardkodet, og flere installasjoner kan dele tenant: Webdelene og Teams-appen finner nå området via en tenant-omfattende storage entity somdeploy.ps1vedlikeholder automatisk (upsert per installasjon, med visningsnavn fra ny valgfri parameterprovisionInstanceTitle; kan også administreres manuelt medSet-PnPStorageEntity -Key bp_ProvisionUrlsmot tenant app-katalogen). Verdien er en ren URL eller et JSON-array av{title, url}der første element er standardinstansen. URL-oppløsning: på SharePoint-sider vinner property pane-verdien, med registeret som fallback (standardverdien er fjernet fra webdel-manifestet, så nye sider følger registeret); i Teams, der det ikke finnes noe property pane, vinner registeret.requestsSiteAlias-kravet er tilsvarende myket opp — ethvert alias fungerer, og pre-flight-fiksen ved aliaskollisjon er nå bare å velge et ledig alias (rename-workarounden er historie). Gjeste-webdelensguestRequestSiteUrl-fallback bruker også registeret. Erstatter PP365 sin aldri-utgittepp365_ProvisionUrl(PR #1762), som ikke fulgte med porten. -
Instansvelger i Teams-appen: Har tenanten flere registrerte instanser, tilgangsfiltreres de (lesetilgang sjekkes per instans, parallelt) — brukere med tilgang til én instans sendes rett inn, brukere med tilgang til flere får en velger (valget huskes per bruker, med
Bytt bestillingsportal-meny i appen), og brukere uten tilgang får korrekt feilmelding.TeamsAppConfig.jsonog områdetyper lastes først etter at instansen er valgt, og bytte remonterer webdelen slik at alle data hentes på nytt. -
Bestillings-webdelen (ProjectProvision) er flyttet inn i dette repoet fra Prosjektportalen 365: Webdelen som lar brukere bestille nye samarbeidsområder (og Teams-appen den utgjør) bygges og distribueres nå som del av
bp-provision-web-parts.sppkg— Prosjektportalen 365 er ikke lenger en forutsetning for bestillingsflaten. Komponent-id-en (e88cea29-09a0-4ce4-a38c-e0d74b65f619) er beholdt, så eksisterende Bestillingsportalen-sider og Teams-appen fortsetter å virke etter oppgradering. Viktig oppgraderingsrekkefølge for tenants med Prosjektportalen 365: oppgrader først PP365 til en versjon uten webdelen, og distribuer deretter denne pakken i samme vedlikeholdsvindu — appkatalogen tillater ikke to pakker med samme komponent-id, og siden viser «finner ikke komponenten» i mellomtiden. Ny webdel-egenskapprovisionAccessGroupTitlestyrer hvilken SharePoint-gruppe som gir tilgang når tilgangsstyring er på (standard «Bestillingsportalen»). -
Migrering til managed identity: Logic Apps autentiserer nå mot Microsoft Graph, SharePoint REST og Azure Automation med en delt user-assigned managed identity (
bestillingsportalen-uami) i stedet for client secret og sertifikat. Sertifikatet og sertifikat-fornying (renew-certificate.ps1,Renewing-certificate.md) er fjernet. Migreringen etterlot først én client secret til ROPC-flyten for sensitivitetsmerker; den flyten, Key Vault-en og app-registreringen er fjernet senere i samme versjon, se Sikkerhet-seksjonen over.deploy.ps1oppretter identityen via bicep, tildeler app-roller (AssignUamiPermissions) og senderuamiNametil alle Logic App-maler. Eksisterende installasjoner må kjøre én fulldeploy.ps1(uten-Upgrade) og deretter re-autorisere de delegerte API-tilkoblingene — se Oppgraderingsveiledningen. -
InviteGuests-webdel (SPFx 1.22 + Fluent UI v9): Ny frittstående SharePoint-webdel for å invitere eksterne gjester til et eksisterende område uten å gå via bestillingsskjemaet. Bygget medOverlayDrawer+TagPicker(basert på Prosjektportalen 365sProvisionDrawer/Guest-mønster) ogDataGridfor statusvisning (basert påProvisionStatus-mønsteret). Prosjektet ligger underSource/SharePointFramework/ProvisionWebParts/. -
Guest RequestsSharePoint-liste: Ny støtteliste på Bestillingsportalen-admin-området som lagrer alle gjesteforespørsler med felter for status, GuestId, InviteRedeemUrl og ErrorMessage. Opprettes automatisk via PnP-templaten (Source/Templates/Objects/Lists/Guest Requests.xml). -
ProcessGuestRequestLogic App: Ny wrapper-Logic App som lytter påGuest Requests-listen (1-min polling), kaller eksisterendeProcessGuestsLogic App, lagrer GuestId/InviteRedeemUrl, kjører deretterAddGuestToSite-runbooken og setter til slutt Status tilInvited(ellerFailedmed feilmelding via Catch-blokken hvis noe i kjeden feiler — Status reflekterer dermed sluttresultatet inkl. tilgangstildeling). Azure Automation-konnektoren returnerer alltid HTTP 200 selv når runbookens internestatuserFailed, så en eksplisittCheck_runbook_status-If-handling leserbody('Add_Guest_To_Site')?.properties?.statusetterpå og setterFailed+ runbook-exception som ErrorMessage hvis runbooken faktisk feilet. -
Site-fokusert e-post fra
ProcessGuestRequestmed to varianter: Etter at runbooken har lagt til gjesten på siten sender Logic App-en en branded HTML-e-post viaoffice365-konnektoren (POST /Mail) —Check_if_guest_is_new-If grener på@empty(InviteRedeemUrl):- Ny i tenanten (
InviteRedeemUrlikke-tom):Send_guest_invitation_emailmed emne «Du har fått tilgang til {SiteTitle}» og «Kom i gang»-knapp som peker påInviteRedeemUrl(gjesten må akseptere tenant-invitasjonen først). - Eksisterende tenant-gjest (
InviteRedeemUrltom):Send_site_access_emailmed samme emne, men «Gå til området»-knapp som peker rett påtriggerBody()?['SiteUrl'](ingen invitasjon å akseptere — gjesten er allerede inne i tenanten og kan gå direkte til området).
Begge har samme HTML-template og hilsen tilpasses med fornavn dersom det er satt. Speiler
Send_guest_invitation_email-mønsteret fraProcessProvisionRequest, men med site-fokus i stedet for generisk «collaboration invitation» — og legger til den eksisterende-gjest-varianten som upstream ikke har. NytenantNameARM-parameter (tildelt viaspoTenantNamei deploy.ps1) brander e-posten med firmanavn, og nyoffice365-API-connection (gjenbrukerbestillingsportalen-o365opprettet avapiconnections.json). - Ny i tenanten (
-
Tilgangstildeling på siten ved invitasjon: Webdelen viser nå to nye seksjoner i invite-drawer for å gi gjesten faktisk tilgang utover bare tenant-invitasjonen:
- Områderolle-seksjon: radio-velger med
Ingen/Besøkende/Medlem/Eier(defaultBesøkende). Hybrid-routing i runbooken — på M365-gruppe-koblede siter brukes Graph-cmdletene (Add-PnPMicrosoft365GroupOwner/Member) for Eier/Medlem, mens Besøkende alltid håndteres via SPAssociatedVisitorGroup. På andre site-typer går alle tre roller via tilsvarende SP-associated-grupper. - SharePoint-brukergruppe-seksjon (valgfritt): "Ikke legg til", "Legg til i eksisterende gruppe" (dropdown), eller "Opprett ny gruppe" (navn + tilgangsnivå Read/Contribute/Edit/Full Control).
- Områderolle-seksjon: radio-velger med
-
AddGuestToSiterunbook: Ny PowerShell-runbook (Source/Runbooks/AddGuestToSite.ps1) som kalles avProcessGuestRequestLogic App etter vellykket tenant-invitasjon. Kjører først CSOMWeb.EnsureUser($guestEmail)for å materialisere gjesten i målsitens user info-liste (uten dette feiler gruppe-cmdletene siden en fersk B2B-gjest enda ikke er en SP-prinsipal på siten), deretter hybrid-routing forM365GroupRole(Graph-cmdlet på gruppe-koblede siter, SP-associated-gruppe ellers) og endelig SP-brukergruppe viaGet-PnPGroup+Add-PnPGroupMember/New-PnPGroup. Hver kjøring logger med[INIT]/[STEP 1/2]/[STEP 2/2]/[DONE]-prefikser for å enklere kunne se hvilke steg som fullførte ved delvis feil. Runbook-RESSURSEN opprettes via ny Source/ARMTemplates/runbooks.bicep som deploy.ps1 alltid kjører (også med-SkipBicepDeployi upgrade-mode), og innholdet lastes opp fraSource/Runbooks/og publiseres automatisk av skriptet. -
Guest Requests-skjema utvidet: Syv nye felt —FirstName(Text),LastName(Text),Company(Text),M365GroupRole(Choice),SPGroupAction(Choice),SPGroupName(Text),SPPermissionLevel(Choice) — som bærer profil-data og brukerens valg fra drawer-en gjennom Logic App-en og inn i runbooken. -
Profil-data per gjest i InviteDrawer: Drawer-en viser nå Fornavn/Etternavn/Selskap-felter per gjest.
GraphServiceslår opp e-postadressen mot Entra ID viaMSGraphClientV3(/users?$filter=mail eq … or userPrincipalName eq … or otherMails/any(o:o eq …)); hvis brukeren finnes, fylles Fornavn/Etternavn fragivenName/surnameog blir readonly med "Finnes i Entra ID"-badge. KreverUser.ReadBasic.All-permission registrert ipackage-solution.json(admin må godkjenne i SharePoint Admin → API access etter første deploy).invitedUserDisplayNamesettes fra Fornavn+Etternavn på Graph-invitasjonen. -
inviteMode-property på webdelen (Single/Multi, defaultMulti): Single = én gjest om gangen med vanlig<Input>; Multi = TagPicker som støtter lim-inn med komma/semikolon/linjeskift som separatorer. I Multi-modus vises en<GuestTabList>(en Tab per gjest) når 2+ gjester er valgt + per-gjest-bryterne er på. -
perGuestProfileMode+perGuestRoleMode-properties (beggeDisabled/Optional/Enforced, defaultOptional): To brytere på toppen av drawer-en — "Detaljer per gjest" viser/skjuler profilfelter (Fornavn/Etternavn/Selskap); "Rolle og brukergruppe per gjest" flytter M365- og SP-gruppe-seksjonene inn i per-gjest-området. Admin kan tvinge på (Enforced), tvinge av (Disabled), eller la bruker styre (Optional). -
inviteAccessLevel-property på webdelen (Owner/Member/Anyone, defaultOwner): Styrer hvem som ser Inviter-knappen. Default skjuler knappen for alle som ikke er M365-gruppe-eier (eller site collection admin).SiteService.getCurrentUserAccessLevel()sjekker mot sitens AssociatedOwnerGroup / AssociatedMemberGroup ved bruk avweb.currentUser.groups. Merk at dette er en UI-sjekk — server-side dekkes behovet av list-permissions påGuest Requests-listen (se punktet under om fjernet server-side sjekk). -
(Fjernet)
Server-side autorisasjonsjekk i ProcessGuestRequest: Et tidligere forsøk på SP REST-basert autorisasjon mot målsitens AssociatedOwner/MemberGroup ble fjernet — SharePoint-connectoren authentiserer som connection-brukeren, som typisk mangler tilgang til mål-sitene → 403 og workflow stuck. Erstatning: list-permissions på Guest Requests + SPFx UI-sjekk dekker sikkerhetsbehovet. -
PATCH av Entra-profilfelter etter invitasjon:
ProcessGuestsLogic App PATCH-ergivenName/surname/companyNamepå/users/{invitedUser.id}rett etter at invitasjonen er opprettet — slik at navn og selskap fra drawer-en faktisk settes på Entra-brukeren (ikke bare lagres på listen). Bruker managed identityensUser.ReadWrite.All. PATCH-en er wrappet i enIfså den hoppes over hvis alle tre feltene er tomme. -
Kopier-invitasjonslenke i
InviteStatus: Ny kolonne med enCopy16Regular-knapp påInvited-rader som kopiererInviteRedeemUrltil clipboard vianavigator.clipboard.writeText. Tooltip viser "Kopier invitasjonslenke" / "Kopiert!" som feedback. SidensendInvitationMessage: false, må admin uansett dele lenken manuelt — denne knappen gjør det til ett klikk. -
AssignManagedIdentityPermissionsi upgrade-mode:deploy.ps1s funksjon for å tildeleSites.FullControl.All+Group.ReadWrite.All+User.Read.Alltil automation account-managed identityen kjøres nå også i upgrade-flyten (tidligere kun i full deploy). Idempotent — sjekker per AppRoleId.User.Read.Alltrengs fordiAdd-PnPMicrosoft365GroupMember/Ownerslår opp gjesten viaGET /users/{email}før den poster tilmembers/$ref; uten dette returnerer brukeroppslaget 403 «Insufficient privileges». -
Automatisk SPFx-bygging og publisering i deploy-scriptet: Ny
DeploySPFxPackages-funksjon kjørernpm install(ved behov) +npm run buildfor alle SPFx-løsninger underSource/SharePointFramework/*/og publiserer.sppkgtil tenant app-katalog viaAdd-PnPApp -Overwrite -Publish. Kan hoppes over med-SkipSPFxDeploy.
Forbedringer
-
Repoet er klargjort for open source: README er skrevet om for eksterne lesere (engelsk sammendrag, målgruppe, kortversjon av forutsetningene, anbefalt leserekkefølge og forholdet til Provision Assist), ny
SECURITY.mdmed privat sårbarhetsrapportering, og CONTRIBUTING beskriver hvordan webdelene bygges lokalt. Dokumentasjonen omtaler konsekvent «organisasjonen»/«tenanten» i stedet for «kunden», skjermbilder med reelle miljøer er redigert, og opphavsangivelsene bruker SoftwareOne gjennomgående. Standardverdien for innstillingenCompanyName(firmanavnet i gjesteinvitasjons-e-poster) er endret fra «Puzzlepart» til «SoftwareOne» – gjelder kun nye installasjoner, siden eksisterende elementer aldri overskrives; sett din egen verdi iProvisioning Request Settings. -
Teams-appen publiseres nå automatisk av
deploy.ps1—Sync to Teams-knappen brukes ikke lenger: Knappen i SharePoint-appkatalogen er upålitelig (deaktivert eller «Failed to sync» i mange tenanter), så løsningen skiper nå sitt eget Teams-app-manifest (ProvisionWebParts/teams/manifest.json, med versjon synkronisert frapackage-solution.json). Etter opplasting av.sppkgpakker skriptet manifest + ikoner tilbestillingsportalen-teams-app.zipog publiserer den til Teams-appkatalogen via Graph — appen matches på komponent-id (externalId), så en app som tidligere ble synkronisert fra PP365 oppdateres i stedet for å dupliseres, og re-kjøring med samme versjon er no-op. Krever delegertAppCatalog.ReadWrite.Allpå PnP-appen (lagt til i registreringskommandoen i Deployment-guide.md); mangler tillatelsen produseres zip-en likevel, med instruksjoner for manuell opplasting i Teams admin center.developer-metadataene ipackage-solution.jsoner samtidig oppdatert til SoftwareOne med reelleprivacyUrl/termsOfUseUrl— tomme verdier der gir ugyldig Teams-manifest og er en kjent årsak til atSync to Teamsfeiler. -
SPFx-verktøykjeden er løftet fra 1.22.1 til 1.23.2: eslint 9 med flat config, oppdaterte @rushstack-pakker og @types/jest 30. Ingen funksjonell endring for sluttbrukere.
-
Standard listeelementer seedes nå av PnP-malen (
<pnp:DataRows>) i stedet for Excel-import: de fem listene Provisioning Request Settings, Provisioning Types, Teams Templates, Time Zones og Locales (411 elementer) ble populert avdeploy.ps1viaImport-ExcelfraSource/Settings/SharePoint List items.xlsx— en destruktiv slett-og-reseed som bare kjørte ved nyinstallasjon, slik at nye innstillinger aldri nådde oppgraderte miljøer uten manuelle copy-paste-steg (jf. den gamle prosedyren i Approval-flow.md). Verdiene ligger nå som<pnp:DataRows KeyColumn="..." UpdateBehavior="Skip">iSource/Templates/Objects/Lists/*.xml: eksisterende elementer røres aldri (heller ikke runtime-verdier skrevet avSyncGroupSettings), og manglende standardelementer legges til automatisk ved re-apply — også i upgrade-modus.TenantURLløses med{hosturl}-tokenet,Image/Icon-URL-ene med{hosturl}{site}/SiteAssets/..., ogSPOManagedPather malens eneste parameter (defaultsitesipnp:Preferences, overstyres avdeploy.ps1via-Parameters). Excel-fila ogImportExcel-modulkravet er fjernet, og ~170 linjer seed-kode ideploy.ps1er borte. Tre stille skavanker rettet i samme slengen:ExternalSharing-kolonnen for Provisioning Types ble aldri importert (alle typer endte somfalseuansett regnearkverdi — nå seedes de riktige verdiene), den dødeHideSiteClassifications-grenen er fjernet (raden fantes ikke og$global:siteClassificationsble aldri satt), og det ødelagte EDU-filteret for Teams-maler er fjernet (det sjekket en kolonne som ikke fantes, så alle 18 maler ble alltid seedet — det er nå den dokumenterte oppførselen). Merk: kunder som bevisst har slettet et standardelement (f.eks. en områdetype) får det tilbake ved oppgradering, og standardelementer må ikke gis nytt navn — Title er nøkkelen (unntatt Time Zones som bruker TimeZoneId pga. duplikat visningsnavn). MedskipApplySPOTemplate = trueseedes ingenting lenger — seedingen følger malen. -
GenerateParameters.ps1foreslårmanagedPathfra tenantens egen innstilling: verdien kom fra malen (sites) uansett hva tenanten var satt opp med, ogdeploy.ps1bygger område-URL-er fra den — en tenant medOpprett gruppeområder undersatt til/teams/fikk dermed feil URL-er uten at noe protesterte. Skriptet tilbyr nå å lese innstillingen fra tenanten. Dette er det ene steget Azure CLI ikke kan gjøre (az account get-access-tokenmothttps://<tenant>-admin.sharepoint.comfeiler medInteractionRequireduten en egen SPO-scopet pålogging), så det går viaGet-PnPTenantog koster én interaktiv pålogging som SharePoint-administrator — derfor en prompt, ikke noe som skjer uansett. Verdien leses fraNewTeamSiteManagedPathpåGet-PnPTenantInternalSetting— ikkeGet-PnPTenant, som ikke har den, og heller ikkeNewSiteManagedPath, som gjelder ikke-gruppekoblede områder; løsningens område er et gruppekoblet team site, ogNewTeamSiteManagedPather det admin-senterets «Opprett gruppeområder under» skriver. VerkenSet-SPOTenantellerSet-PnPTenantdokumenterer innstillingen, så kandidatlista har fallback tilNewSiteManagedPathog til andre*ManagedPath*-properties, og verdien kontrolleres motAvailableManagedPathsForSiteCreation. Finnes ingen verdi, spør skriptet om den framfor å beholde en mulig feil standard. Hoppes over med-Force, uten PnP.PowerShell, eller hvis PnP-appen ikke finnes i tenanten. -
-SkipAppRoles: installasjon uten Global Administrator: app-rolletildelingen er det eneste steget ideploy.ps1som krever GA (ev. Privileged Role Administrator + Cloud Application Administrator) — i mange kommuner får ikke konsulenten den rollen. Med-SkipAppRolesinstalleres alt annet, og skriptet skriver ut en ferdig kommando med tenant-ID og begge identitetenes object-ID-er utfylt, som kundens GA kjører etterpå.AssignPermissionsToManagedIdentity.ps1er utvidet til handover-modus (-AutomationIdentityId/-UamiId/-TenantId) med begge rollelistene innbakt — GA-en trenger den ene fila, PowerShell 7+ og Microsoft.Graph-modulen, ingenting annet fra installasjonen. Graph-innloggingen i skriptet ber nå kun omAppRoleAssignment.ReadWrite.All+Application.Read.All(tidligere ba den i tillegg om RoleManagement/Application.ReadWrite/DelegatedPermissionGrant — unødvendig, og consent-dialogen så mer dramatisk ut enn operasjonen er). Logic Apps får 401/403 frem til kommandoen er kjørt; DEPLOYMENT SUMMARY viserSKIPPEDmed kommandoen i detaljene. Dokumentert i installasjonsveiledningen. -
PRE-DEPLOYMENT CHECKLIST og
-Preflight: forhåndssjekkene stoppet på første feil, så mangler ble oppdaget én re-kjøring om gangen — RBAC i én runde, resource providers i neste, hver med sin egen bestilling til kundens admin. Nå registrerer alle sjekkene resultatet sitt og kjøres til ende, og resultatet vises som en samlet sjekkliste medOK/MISSING/WARNING/SKIPPEDper punkt og enFix:-linje med konkret løsning for hver mangel — hele mangellisten i én kjøring.MISSINGstopper fortsatt før noe opprettes;WARNINGgjør ikke. Tre nye sjekker i samme rennet: app-rolle-rettigheter (aktiv GA eller PRA+CAA via kontoens directory-roller — best-effort, siden PIM-eligible roller ikke synes før aktivering, derforWARNINGog aldriMISSING), tenant app-katalog (Get-PnPTenantAppCatalogUrlpå admin-tilkoblingen) og Node.js 22.14+ (SPFx-bygget er siste deploy-steg, så manglende Node dukket ellers opp etter at alt annet var ferdig). Ny-Preflight-parameter kjører kun sjekkene og avslutter med exit-kode 0/1 — rask oversikt over hva som mangler før man booker tid til den ekte kjøringen. Krever samme innlogginger som en deploy, men ingenting opprettes eller endres. -
Pre-flight sjekker og registrerer resource providers: et ferskt abonnement har ikke
Microsoft.Automation/Microsoft.Logicregistrert, og deployen feilet medMissingSubscriptionRegistration— først for Automation-kontoen, med Logic Apps som neste vegg.ValidateResourceProviderssjekker de fire namespacene løsningen bruker (Microsoft.Automation,Microsoft.ManagedIdentity,Microsoft.Logic,Microsoft.Web, filtrert etter hvilke deploy-steg som faktisk skal kjøre). Uregistrerte providers registreres automatisk — startet i bakgrunnen rett etter bekreftelsesprompten og ventet på rett før Azure-deployen, så områdeopprettelsen absorberer ventetiden. Registrering er en abonnementsoperasjon (Owner på ressursgruppen hjelper ikke), så når permissions-endepunktet bekrefter at kontoen mangler abonnementsrettigheter, stopper pre-flight med de nøyaktigeaz provider register-kommandoene en abonnementsadministrator må kjøre. Wildcard-matchingen er trukket ut i fellesTestActionMatch/TestAzureActionsom RBAC-sjekken også bruker. -
Pre-flight verifiserer at kontoen kan opprette RBAC-rolletildelinger:
azureresources.bicepinneholder toMicrosoft.Authorization/roleAssignments(Automation Job/Runbook Operator for managed identityen), og ARM autoriserer disse ved innsending — en konto med bare Contributor får hele deployen synkront avvist, uten deployment-record, og azure-cli (verifisert på 2.77.0) sluker 400-kroppen og viser bare «The content for this response was already consumed». NyValidateAzureRbacsjekkerroleAssignments/writemot permissions-endepunktet (ressursgruppen hvis den finnes, ellers abonnementet) og stopper med en tydelig melding om Owner/User Access Administrator før noe kjøres. En feilet sjekk blokkerer ikke — kun en bekreftet manglende rettighet. Hoppes over med-SkipBicepDeploy, der ingen rolletildelinger deployes. I samme gate:ValidateArmTemplateskompilerer nå også begge bicep-malene lokalt, som fanger blokkert Bicep-nedlasting og kompileringsfeil — den andre veien til samme uleselige feilbilde. -
PRE-FLIGHT SUMMARY viser rot-områdets språk: provisjonering av områder med et annet språk enn tenantens rot-område har gitt problemer, men språket var ikke synlig noe sted under installasjonen. Ny
Root site language-linje viser LCID og språknavn forhttps://<tenant>.sharepoint.com, lest fra rot-webbensWeb.Languageover en separat PnP-tilkobling (-ReturnConnection, så admin-tilkoblingen pre-flight står på er urørt, og tokenet fra første pålogging gjenbrukes — ingen ekstra nettleser-prompt). Første forsøk brukteSiteProperties.LcidfraGet-PnPTenantSite, men den populeres ikke pålitelig — en reell tenant rapporterte 0. Språknavnet slås opp fra LCID-en viaCultureInfoframfor en oppslagstabell, siden løsningens egenLocales-liste ligger på området kjøringen er i ferd med å opprette. Ren visningsverdi: feiler oppslaget skrives årsaken (første linje) og installasjonen fortsetter. -
-ParametersPathpådeploy.ps1: skriptet leste hardkodet.\parameters.json, så det å jobbe mot flere kundemiljøer krevde at man kopierte riktig fil overparameters.jsonfør hver kjøring — med den åpenbare feilmuligheten at man kjørte deploy mot én kunde med en annens parametre. Filen kan nå angis eksplisitt (./deploy.ps1 -ParametersPath .\parameters-contoso.json), default er uendret. Stien valideres før modulsjekk og de tre innloggingene, så en skrivefeil stopper umiddelbart i stedet for etter tre MFA-runder, og feilmeldingen lister parameterfilene som faktisk ligger i mappen. PRE-FLIGHT SUMMARY viser hvilken fil verdiene kom fra.GenerateParameters.ps1skriver ut den ferdigedeploy.ps1-kommandoen inkludert-ParametersPathnår-OutputPathikke er standardfilen, og.gitignoredekker nåparameters-*.json(unntattparameters.template.json). -
StatusReasoninneholder nå den faktiske feilen: de tiHandle_Error-scopene skrev en hardkodet streng, så den egentlige Graph-/SPO-feilmeldingen aldri nådde listeelementet. De åtte container-scopene bruker nåresult()+Filter_failed_actions_*/Compose_error_message_*(samme mønster somProcessGuestRequest) og skriver f.eks. «Failed during space type validation: Provision_Group: Insufficient privileges …».result()rapporterer bare de umiddelbare barne-actionene, så ved dypt nestede feil navngis grenen framfor det innerste kallet. ForConfigure_space(en connector-action, ikke et scope) leses jobbensproperties.exception, som er runbookens egen oppsummering med navn på hvert feilende steg.Skippeder bevisst ikke lagt til i utløseren — dokumentasjonen hevdet feilaktig at den var med. -
Runbook-jobber som feiler med HTTP 200 fanges nå i provisjoneringsflyten: Azure Automation-connectoren returnerer HTTP 200 selv når jobben internt er
Failed.ProcessGuestRequesthar hatt en eksplisittCheck_runbook_status-sjekk siden denne versjonen;ProcessProvisionRequesthadde den ikke, så en feiletConfigureSpacekunne gå videre som om alt gikk bra. NyCheck_runbook_statusetterConfigure_space, ogUpdate_status_to_Space_Createder kjedet etter sjekken i stedet for parallelt med den (ellers kunne bestillingen bli stemplet «Space Created» førTerminaterakk å stoppe kjøringen). -
ConfigureSpace.ps1kjører nå fail-fast per steg:$ErrorActionPreferencevar aldri satt, så ikke-terminerende PnP-feil gikk rett forbi alle 22 catch-blokkene og kjøringen rapporterte suksess selv om enkeltsteg ikke hadde gjort noe. Nå settesStop, og en nyInvoke-Step-hjelper gjenoppretter «registrer og gå videre»-oppførselen på ett sted i stedet for 22 identiske try/catch.Write-StepSummaryskriver en per-steg-tabell til jobbloggen. Merk: steg som tidligere feilet stille vil nå rapporteres — en bestilling som «alltid har fungert» kan begynne å feile, og det er reelle feil som var skjult. -
Tre bugs i
ConfigureSpace.ps1: (1)externalSharing,joinHubogapplyPnPTemplateer strenger fra Logic App-en men ble testet medif ($x)/-eq $true— strengen"false"er truthy, så ekstern deling ble slått på når den skulle vært av; (2) dokumentbiblioteket var hardkodet til"Dokumenter"i tre steg, som feilet på alle ikke-norske områder — slås nå opp viaBaseTemplate/IsDefaultDocumentLibrary; (3)AddSiteCollectionAdminssendte""videre tilAdd-PnPSiteCollectionAdminfordi"" -split ","gir ett tomt element. -
Eksplisitte PnP-tilkoblinger i
ConfigureSpace.ps1: 11 implisitteConnect-PnPOnline-bytter er erstattet avConnect-Admin/Connect-Sitesom hvert steg kaller selv. Stegene er dermed rekkefølge-uavhengige, og tenant-admin-cmdletene kjører ikke lenger mens tilkoblingen står på selve området. Sensitivitetsmerket settes nå førSetExternalSharing, siden container-merket overstyrer områdets privacy- og delingsinnstillinger. Tenantnavnet utledes fra[System.Uri].Hosti stedet forSubstring/IndexOf('.'), som brakk på alt som ikke varhttps://tenant.sharepoint.com/…. -
Medlemskapstest og paging i
Process_Owners_and_Members: testene varcontains(string(body('Get_group_members')), id)— substring-match mot serialisert JSON. Id-ene projiseres nå ut med toSelect-actions og testene gjør et reelt array-oppslag.Get_group_members/Get_group_ownershentet dessuten uten$top, så Graph returnerte standard sidestørrelse 100 — grupper med flere enn 100 medlemmer fikk stille feil svar for alle forbi første side. Satt til$top=999. -
Kortere provisjonering:
Delay_while_owner_is_addedlå inne i eier-løkken med ett minutt per iterasjon, og kunne ikke hjelpe «er allerede eier»-sjekken uansett (den leser et øyeblikksbilde tatt før løkken). Erstattet av én 30-sekunders venting etter løkken.Wait_for_viva_engage_community_to_provisionvar 2 minutter rett førUntil-løkken som allerede poller operasjonsstatus — redusert til 30 sekunder. Ventingene rundt gruppe-, team-, teamify-, clone- og områdeopprettelse er bevisst urørt: de gater asynkron propagering i Teams/SPO og krever måling i testtenant før de kan gjøres om til polling. -
Dokumentasjonen konsolidert:
Architecture.md(diagrammene flyttet til Teknisk løsningsbeskrivelse kap. 1),Bestillingsportalen.md(unike Guest Requests-feltbeskrivelser flyttet til Data-stores.md; resten dupliserte CHANGELOG/Data-access-security) ogCost-estimates.md(2020-tall uten informasjonsverdi) er fjernet. Tillatelsestabellene i Managed-identity-migration.md er erstattet med lenke til Data-access-security.md, som er kanonisk kilde for tillatelseslistene — tre kopier hadde allerede sklidd fra hverandre. -
Managed-identity-migration.mdfjernet: dokumentet beskrev migreringen fra client secret/sertifikat til managed identity i 1.0.0, og hadde etter at ROPC-flyten og Key Vault forsvant flere avsnitt som omtalte Key Vault som gjeldende — inkludert en verifikasjonssjekkliste som ba leseren bekrefte en Key Vault-policy som ikke finnes. Bakgrunnen dekkes av Datatilgang og sikkerhet, oppgradering av eldre installasjoner av Oppgraderingsveiledningen, og designer-roundtrip-advarselen er flyttet tilCONTRIBUTING.md. Alle innkommende lenker er pekt om. -
Minimerte runtime-tilganger på user-assigned managed identity: Alle HTTP-kallene i Logic Apps og alle runbook-operasjoner er kartlagt mot dokumentert minste Graph-tillatelse. To roller er strammet inn:
Directory.ReadWrite.All→GroupSettings.ReadWrite.All(eneste bruk var å deaktivere gjestedeling per gruppe) og GraphSites.FullControl.All→Sites.Read.All(eneste bruk var lesekallene i CheckSiteExists). Identiteten har dermed ingen tenant-vid katalog-skrivetilgang. SharePointSites.FullControl.Allbeholdes på både UAMI (områdeopprettelse —Sites.Selecteder umulig mot områder som ikke finnes ennå) og Automation-kontoens identity (tenant-admin-cmdlets i ConfigureSpace + tilpasninger mot provisjonerte områder). Eksisterende migrerte miljøer: fjern de to gamle rollene manuelt fra UAMI-en i Entra (deploy tildeler kun manglende roller, fjerner aldri). Se kall-for-kall-begrunnelse i Data-access-security.md. -
Trygg re-kjøring av
deploy.ps1mot eksisterende miljø: Svarer dunpå «Site already exists»-prompten hoppes nå også liste-reseedingen over (før ble Settings-, Provisioning Types-, Teams Templates- og Time Zones-listene alltid slettet og gjenopprettet fra pakkens standardverdier i fresh-modus — også vedn— slik at tilpasninger som AdminGroupId, ApproverEmail og egne provisioning types gikk tapt). Liste-ID-ene hentes fortsatt, så Logic Apps kan deployes. Bestillingsdata har aldri vært berørt. -
GenerateParameters.ps1– automatisk generering av parameters.json: Nytt hjelpeskript forankret i en eksplisitt mål-tenant: det spør hvilken tenant (kunde) parametrene gjelder (-Tenanteller prompt), logger Azure CLI inn i den tenanten, viser hvem du er logget inn som, og tilbyr kun abonnementer som tilhører mål-tenanten (med tenant-domene i stedet for bare GUID i velgeren) — laget for konsulenter som jobber mot flere kundetenants. Skriptet hentertenantId/subscriptionIdfra konteksten ogfullTenantName/spoTenantNamefra Graph (initial-domenet), og fyller resten med standardverdier fraparameters.template.json(beskrivelser og nye parametre holdes dermed i sync). Tjenestekonto-UPN promptes eller angis som parameter (-ServiceAccountUPN;-Forcefor uovervåket kjøring). Skriptet gjør kun lesekall mot Azure. -
PnP.PowerShell 3.2+ og PowerShell 7.4+ kreves og håndheves:
VerifyModulessjekker nå minimumsversjon (før kun at modulen fantes) og gir presis beskjed omUpdate-Moduleved for gammel versjon; skriptet krever PowerShell 7.4+ (PnP 3.x-krav, før kun «Core»). Skriptet laster i tillegg PnP.PowerShell før første Az-cmdlet for å unngå assembly-konflikten mellom modulene (Method 'get_Services' in type '...LoggingBuilder' ... does not have an implementation— oppstår når nyere Az lastes først i økten; start nytt PowerShell-vindu hvis den likevel treffer). -
Runbooks kjører nå på PowerShell 7.4 med PnP.PowerShell 3.2: Alle tre runbookene (
ConfigureSpace,GetSiteTemplates,AddGuestToSite) er samlet irunbooks.bicepog kjører i et nytt Azure Automation runtime environment (bestillingsportalen-ps74: PowerShell 7.4, PnP.PowerShell 3.2, Az-pakke) — erstatter den klassiske PowerShell 7.2-modellen med PnP 2.4.0 og den eldgamleAz.Accounts1.6.2. Sidenrunbooks.bicepdeployes i både full- og upgrade-modus, får eksisterende miljøer runtime-oppgraderingen viadeploy.ps1 -Upgrade. -
Power Automate-flyten er nå med i leveransen:
Provisioning Request Approvalfulgte upstream sin Power Apps-løsningspakke, som ble droppet da SPFx-webdelen erstattet appen — repoet har aldri inneholdt den, og installasjonsveiledningen forutsatte stilltiende at den fantes i miljøet (stemte kun der Bestillingsportalen hadde vært installert før). NySource/Flows/Bestillingsportalen-Flows_unmanaged.zip(32 KB) er avledet fra upstream-pakken og trimmet til kun det som brukes: flyt-definisjonen, de fire connection references og de fire environment variables flyten faktisk bruker. Canvas-appen, dens ni miljøvariabler og upstream-flytenCheck Space Availabilityer fjernet — sistnevnte har PowerApps-trigger og kalles kun fra canvas-appen (SPFx-webdelen sjekker tilgjengelighet viaCheckSiteExists-Logic Appen), og en importert kopi lar seg heller ikke aktivere (shared_logicflows-tilkoblingsfeil). Flyten pakkes i Draft-tilstand slik at importen ikke gjør et aktiveringsforsøk som feiler medFlowNotOriginalAuthor; aktivering gjøres eksplisitt i konfigurasjonsveiledningens Steg 2. Miljøer med tilpassede flyter kan fortsatt eksportere/importere egne pakker. -
Authorize-ApiConnections.ps1— guidet autorisering av API-tilkoblingene: Nytt hjelpeskript som sjekker status på de fire delegerte API-tilkoblingene, genererer samtykkelenker via ARM (listConsentLinks), åpner dem i nettleseren (logg inn som tjenestekontoen), fanger samtykket på en lokal lytter (http://localhost:8155/) og fullfører autoriseringen viaconfirmConsentCode— hele veien til verifisertConnected, uten portalnavigasjon. Håndterer begge redirect-variantene til API-hubben (med og uten kvitteringskode), og varsler om den forventede «created from a different organization»-advarselen (lenken genereres av admin-sesjonen mens tjenestekontoen samtykker). Selve innloggingen kan ikke automatiseres (delegert OAuth krever at tjenestekontoen selv logger inn); flyt-aktivering/-deling forblir manuelt av samme grunn. -
CustomerSpecificrunbook — fast utvidelsespunkt for kundetilpasninger:ProcessProvisionRequestkjører nå runbookenCustomerSpecificrett etterConfigureSpace, med samme parametersett (unntattspaceImage). Runbooken opprettes avdeploy.ps1med et tomt no-op-innhold kun hvis den ikke finnes, og overskrives aldri av senere deploys/upgrades — i motsetning til de øvrige runbookene som holdes i sync med repoet. Kundespesifikke etterkonfigurasjonssteg (ekstra lister, tilganger, integrasjoner) legges her, og kjører som Automation-kontoens system-assigned managed identity. -
Runbook-innholdet deployes direkte fra repoet — manuelt innlimingssteg fjernet: Plassholder-URI-ene mot upstream-repoet er borte;
runbooks.bicepoppretter tomme runbook-skall, ogdeploy.ps1laster opp innholdet fraSource/Runbooks/via management-APIet og publiserer. Innholdet er dermed alltid i sync med repoet ved hver deploy/upgrade. Merk: endringer gjort direkte på runbookene i Azure Portal overskrives — kundetilpasninger i runbooks skal gjøres i repoet det deployes fra. -
Robust tenant-validering i
GenerateParameters.ps1: Tenant-inputen resolves nå til tenant-ID via det offentlige OpenID-discovery-endepunktet før innlogging — skrivefeil gir umiddelbar, tydelig feil, en UPN limt inn ved et uhell auto-korrigeres til domenedelen, feiletaz loginstopper skriptet (før fortsatte det stille på forrige cachede sesjon), og etter innlogging verifiseres at sesjonen faktisk står i mål-tenanten. -
Gjenbruk av eksisterende innloggingssesjoner — færre MFA-runder ved gjentatte kjøringer: Både
deploy.ps1ogGenerateParameters.ps1sjekker nå om det finnes cachede sesjoner som matcher mål-miljøet før de starter ny innlogging: Az PowerShell-konteksten (matcher tenant → tilbys gjenbruk med stille subscription-bytte), Azure CLI (az account list-cachen sjekkes mot tenant/subscription → tilbys gjenbruk), og PnP-tokenet gjenbrukes innenfor kjøringen slik at kun første PnP-tilkobling viser nettleserprompt (bevisst ikke persistert på tvers av økter, for å unngå kundetenant-tokens liggende på disk). Du blir alltid spurt (y= gjenbruk /n= logg inn på nytt); med-SkipConfirmation/-Forcegjenbrukes matchende sesjoner automatisk. -
PnP-autentisering er nå utelukkende interaktiv — sertifikatstøtten er fjernet: Installasjonen er attended by design (interaktive prompts hele veien), så app-only/sertifikat-støtten er fjernet helt i tråd med PnP sin egen veiledning:
pnpCertPath-parameteren er borte, alle PnP-tilkoblinger (admin-site, nytt område, app-katalog,-SkipSharepointSite-grenen som tidligere ignorerte sertifikatet) går gjennom én fellesConnectPnP-funksjon medConnect-PnPOnline -Interactive, og sertifikatpassord-prompten er fjernet. Før falt tompnpCertPathdessuten tilbake på credential-basert pålogging som feiler med MFA. Installasjonsveiledningen viserRegister-PnPEntraIDAppForInteractiveLogin(delegerte tilganger: GraphGroup.ReadWrite.All+ SharePointAllSites.FullControl) — eller gjenbruk av Prosjektportalen-appen. Oppgradering fra eldre versjon: fjernpnpCertPathfraparameters.json. -
Entra ID-appen er nå valgfri uten sensitivitetsmerker (mellomsteg — appen og
enableSensitivityer begge fjernet helt senere i samme versjon, se Sikkerhet-seksjonen):deploy.ps1krevde at appen fantes selv om den etter managed identity-migreringen kun brukes av ROPC-flyten for sensitivitetsmerker (dokumentasjonen sa allerede at den kunne slettes). Nå: mangler appen ogenableSensitivityerfalse, hopper deploy over den med tydelig melding (SKIPPEDi rapporten) —createentraidapp.ps1trengs altså ikke i standardoppsettet. Mangler den ogenableSensitivityertrue, feiler deploy tidlig med presis beskjed.GenerateParameters.ps1sjekker i tillegg om både PnP-appen (Prosjektportalen-standard) og Entra ID-appen finnes i tenanten, og next-steps-teksten sier eksakt hva som trengs for konfigurasjonen din. -
Tidlig validering av tjenestekontoen:
deploy.ps1verifiserer nå atserviceAccountUPNfinnes i tenanten før noe opprettes (før krasjet installasjonen kryptisk midt i site-opprettelsen når kontoen manglet, siden den brukes som-OwnersiNew-PnPSite), med advarsel hvis kontoen mangler lisenser eller en brukbar Power Automate-plan — godkjenningsflyten krever seeded Power Automate (E1/E3/E5); frontline-planer (F1/F3) gir kryptiske feil (FlowNotOriginalAuthor,shared_logicflows) først ved aktiveringen i konfigurasjonsveiledningens Steg 2.GenerateParameters.ps1validerer at kontoen finnes ved generering, med re-prompt ved skrivefeil. Kontoen vises også (verifisert med visningsnavn) i pre-flight-oppsummeringen. -
Pre-flight-bekreftelse i
deploy.ps1: Etter innlogging — men før noe opprettes — viser skriptet en oppsummering av hvilket miljø du faktisk er koblet til (Entra ID-tenant, Azure-subscription med navn, innlogget konto, SharePoint-tenant) og hva som vil bli satt opp/oppdatert (per komponent, med skip-flagg reflektert), og krever eksplisittyfor å fortsette. Beskytter mot deploy til feil tenant/subscription. Hopp over med-SkipConfirmationfor automatiserte kjøringer. -
Deployment summary i
deploy.ps1: Skriptet skriver nå ut en statusrapport på slutten av hver kjøring (også ved feilavbrudd) med én linje per delkomponent —OK/FAILED/WARNING/SKIPPED. Alleaz deployment-kall exit-kode-sjekkes (før kunne en feilet Logic App-deployment passere ubemerket og skriptet rapportere suksess), feilede app-rolletildelinger samles opp og rapporteres i stedet for å forsvinne i utskriften, en feilet SPFx-bygging stopper ikke lenger resten av deployen, og skriptet avslutter med exit-kode 1 hvis noen komponenter feilet. Gjenstående manuelle steg (autorisere API-tilkoblinger, aktivere flyter) listes opp til slutt. -
Forbedret feilhåndtering i bestillingsflyt: Implementert omfattende feilhåndtering som automatisk oppdaterer Provisioning Requests-listen med status "Space Creation Failed" når feil oppstår i både Logic App og ConfigureSpace runbook. Dette gir bedre synlighet på feiltilstander og enklere feilsøking.
-
Upgrade-mode utvidet:
DeployUpgradeLogicAppdeployer nå BÅDEProcessProvisionRequestOGProcessGuestRequest. SPFx-løsninger bygges og publiseres også i upgrade-mode (med mindre-SkipSPFxDeployer satt). -
Navigasjon bevares i upgrade-mode:
Invoke-PnPSiteTemplatekjøres uten-ClearNavigationnår-Upgradeer aktiv, slik at egendefinerte nav-lenker ikke slettes. -
Tydeligere "Site already exists"-prompt: Prompten i
CreateRequestsSharePointSiteforklarer nå tydelig aty= re-anvend PnP-template (oppdaterer lister/felter/innstillinger) ogn= hopp over template men fortsett med Logic Apps / SPFx.nstopper ikke lenger hele scriptet. -
Race-condition-guard i
DeployUpgradeLogicApp: Kaster nå tydelig feilmelding hvis$global:requestsListIdeller$global:guestRequestsListIder tomme før Logic Apps deployes. -
InviteDrawer UX-justeringer: M365-gruppe-seksjonen skjules helt på siter uten M365-gruppe (i stedet for gråtonet variant). Default SP-gruppe-valg er nå
Legg til i eksisterende gruppemed sitens associated Visitors-gruppe pre-valgt (fraSiteService.getSiteContext).GuestPickerre-skrevet etter PP365-mønster meduseTagPickerFilter— den maskinskrevne e-posten vises som klikkbar option med Avatar i dropdown. -
AccessPreviewPanel — tilgangsoversikt i invite-drawer: Alltid-synlig
<MessageBar>som dynamisk lister hva gjesten faktisk får tilgang til basert på valgt M365-rolle + SP-gruppe + om siten er M365-gruppe-koblet. Skifter mellomintent='info'(begrenset tilgang) ogintent='warning'(Owner/Member på gruppe-koblet site = Teams + alle gruppe-ressurser + OneNote/Planner) med advarsels-footer som oppmuntrer til mer begrenset rolle. Adresserer det grunnleggende M365-gruppe-medlemskaps-kaskade-problemet hvor "Member" gir mye mer tilgang enn brukere intuitivt forstår.
Feilrettinger
-
Bestillingsskjemaet skiller nå «området finnes ikke» fra «du har ikke tilgang»: Peker den konfigurerte URL-en på et område som ikke finnes (HTTP 404), vises den nye meldingen «Fant ikke Bestillingsportalen på {url}» i stedet for den misvisende tilgangsmeldingen — feilkonfigurasjon maskeres ikke lenger som tilgangsproblem. (Port av PP365 PR #1762-delen som ikke fulgte med flyttingen av webdelen.)
-
MinimumOwners-innstillingen fraInnstillinger for bestillinghåndheves nå i bestillingsskjemaet: Verdier ≥ 2 gir inline valideringsmelding på eierfeltet («Det kreves minst {0} eiere …») og deaktivert bestill-knapp til kravet er oppfylt, i begge skjemavarianter. Manglende/ugyldig/0/1gir nøyaktig dagens oppførsel. (Port av PP365 PR #1763.) -
Navnesjekken i bestillingsskjemaet fanger nå også ventende bestillinger, gjenbrukte aliaser og områder i papirkurven — og revalideres ved innsending: Tilgjengelighetssjekken på områdenavnet er debounced med sekvensvakt (utdaterte svar kan ikke overskrive nyere), respekterer 64-tegnsgrensen for gruppealias (delt
calculateAliasValue), og sjekker i tillegg til levende områder både bestillinger underveis iProvisioning Requests-listen (ny melding «Det finnes allerede en bestilling med samme adresse») og aliaser som er opptatt av eksisterende M365-grupper eller områder i tenant-papirkurven (viaGetValidSiteUrlFromAlias). Ved innsending revalideres alt — konflikt gir egen toast («Adressen er ikke ledig») i stedet for generisk feil — og en dobbeltklikk-vakt med spinner hindrer to identiske bestillinger. Samtidig rettet: dobbel skråstrek i beregnede område-URL-er (//sites/) og literal «undefined» i navn/alias når navnekonvensjon ikke er konfigurert. (Port av gjenstående PP365-endringer som ikke fulgte med flyttingen av webdelen — upstream-deltaet er med dette fullt innhentet.) -
Personfelter sendes nå via
validateUpdateListItemi stedet for klientsideensureUser— bestilling virker for brukere med kun lesetilgang: Eiere/medlemmer/bestilt-på-vegne-av ble tidligere oppløst medensureUserfør innsending, som krever mer enn lesetilgang på bestillingsområdet og feilet for vanlige brukere. Nå sendes vanlige felter først, deretter oppløses personfeltene server-side; feiler oppløsningen slettes den halvferdige bestillingen og en egen feilmelding vises («Personer kunne ikke legges til»). Personvelgeren dedupliserer også søketreff og identifiserer valg på e-post/principal-nøkkel i stedet for visningsnavn, så to brukere med samme navn kan skilles (e-post vises på valgte brukere). (Port av PP365 PR #1766.) -
SP-gruppeseksjonen forklarer nå sin rolle i forhold til gjesterollen: Med rollen Gjest får brukeren allerede tilgang via M365-gruppen (som er medlem av områdets medlemsgruppe) — seksjonen presenteres da som et rent tillegg, standard handling er ingen ekstra gruppe, og standardvalget heter «Bare legg til i standard SharePoint-medlemsgruppe» (siden gjesten uansett lander der via M365-gruppen) — mot «Ikke legg til i SharePoint-gruppe» når ingen rolle er valgt. Uten rollen forklarer seksjonen at en SP-gruppe (eller senere direkte deling) er eneste vei til tilgang, og velges verken rolle eller gruppe viser tilgangsforhåndsvisningen en advarsel om at invitasjonen alene ikke gir tilgang til området.
-
Gjesterollen feilet med 404 på gruppekoblede områder:
Add-PnPMicrosoft365GroupMemberfikk gjestens e-postadresse, men Graph adresserer brukere med objekt-id eller UPN — og en gjests UPN ernavn_domene#EXT#@tenant, aldri e-posten, så oppslaget gaNot Found (404)for samtlige gjester. Runbooken utleder nå UPN-en fra claims-loginName somEnsureUserallerede returnerer, slår opp objekt-id-en via Graph og bruker den i kallet. Re-invitasjon av en som alt er medlem (Graph 400 «already exist») behandles nå som suksess i stedet for å feile forespørselen. -
Gjesteinvitasjon med «Opprett ny gruppe» feilet på ikke-engelske områder: Runbooken sendte webdelens engelske nivånavn (
Edit,Read…) rett tilSet-PnPGroupPermissions -AddRole, men rolledefinisjonsnavn er språkavhengige per område — på norsk heter nivået «Redigering», og jobben stoppet medRole definition 'Edit' not found. Nivået slås nå opp via den språkuavhengigeRoleTypeKind(Reader/Contributor/Editor/Administrator) med fallback til eksakt navnematch for egendefinerte nivåer, og områdets faktiske rollenavn brukes i kallet. -
Tom
guestRequestSiteUrlpeker nå på/sites/bestillingsportalen: Fallbacken var gjeldende område — som bare fungerte når webdelen sto på portalen selv. Tomt felt betyr nå standard-aliaset fra installasjonen på gjeldende tenant, og feltet viser den utledede URL-en som placeholder. Miljøer med annet alias setter URL-en eksplisitt, som før. -
Per-gjest-modus i invite-draweren starter nå med de konfigurerte standardene: Nye gjesterader arvet ikke
defaultM365GroupRole,defaultSpGroupName/Besøkende-fallbacken (autoSelectVisitorGroup) ellerdefaultSpPermissionLevel— de falt stille tilbake til hardkodede verdier ved innsending. Radene seedes nå fra samme standarder som delt modus. -
Manglende gruppenavn i per-gjest-modus ga stille blokkert innsending: Valideringsmeldingen «Gruppenavn er påkrevd» ble kun vist i delt modus; i per-gjest-modus ble innsendingen blokkert uten synlig tilbakemelding. Meldingen vises nå på den aktive gjestens SP-gruppeseksjon også.
-
Installasjonsveiledningen delt i to: Deployment-guide.md dekker nå kun den skriptede delen (forutsetninger, parametre,
deploy.ps1, API-autorisering, SPFx) — leseren er den tekniske installatøren med Azure-tilganger. Ny Configuration-guide.md tar over derfra med alt som gjøres uten Azure-tilganger: godkjenningsoppsett, flyt-import/-aktivering, deling, støtte-Logic Apps, aktivering av maler/huber, administratorgruppe, auto-approval og Teams-appen (tidligere Steg 4–10, omnummerert til 1–7). Nytt Steg 8: Verifiser med en testbestilling beskriver ende-til-ende-testen (som vanlig bruker, ikke tjenestekontoen), statusløpet, hvor feil leses (StatusReason + runbookens stegtabell) og opprydding. Begge veiledningene advarer nå om token-forsinkelsen første døgn: managed identity-tokens caches i opptil ~24 timer, så en fersk installasjon kan gi sporadiske 401/403 ogRoles on the request ''som leger seg selv — ikke et konfigurasjonsproblem. Alle kryssreferanser (Approval-flow, Teknisk løsningsbeskrivelse, Flows/README, deploy-output, ConfigureSpace-meldinger, README-navigasjonen) er pekt om. -
F-lisenser friskmeldt for tjenestekontoen: dokumentasjonen og lisenssjekken advarte mot frontline-lisenser (F1/F3) basert på én
FlowNotOriginalAuthor-feil — som viste seg å være miljøspesifikk for et utviklingsmiljø. En F3-lisensiert tjenestekonto er nå verifisert gjennom hele løpet i en reell kundetenant (import, aktivering og kjøring av godkjenningsflyten).FLOW_O365_S1regnes derfor som brukbar plan i pre-flight-sjekken; kun uprovisjonerte viral-prøvelisenser (FLOW_P2_VIRAL) gir fortsatt advarsel. Forutsetningene, parameterbeskrivelsen og feilsøkingsboksen i konfigurasjonsveiledningens Steg 2 er justert tilsvarende — lisensbytte er siste utvei ved aktiveringsfeil, ikke førstevalg. -
Velkomstmeldingen feilet når tjenestekontoen selv var bestiller:
Post_Welcome_Messagelegger tjenestekontoen til som midlertidig gruppe-eier for å poste i Teams-kanalen — men når tjenestekontoen selv sendte inn bestillingen er den allerede eier fra opprettelsen, og Graph svarer 400 «One or more added object references already exist». Å bare svelge feilen ville vært verre:Remove_service_account_from_groupetterpå hadde fjernet et legitimt eierskap. Flyten leser nå eierlisten først og hopper over både tillegget (inkludert to-minutters-ventingen) og fjerningen når kontoen allerede eier gruppen — midlertidig eierskap ryddes kun når flyten selv la det til. -
ConfigureSpacefeilet hele bestillingen når JoinHub var aktiv uten valgt hub:JoinHubkommer fra provisioning-typen og hub-ID-en fra brukerens valg i webdelen — erHub Sites-listen tom (GetHubSites aldri kjørt, eller ingen hub medEnabled = true), kommer ID-en tom inn, og runbooken feilet med det kryptiske «Hub site with id '' was not found in the tenant». Det er et konfigurasjonshull, ikke en provisjoneringsfeil: steget hopper nå over med en melding som peker på GetHubSites ogEnabled-flagget (konfigurasjonsveiledningens Steg 4–5). -
Retry på tilkobling i
ConfigureSpacemot transiente token-feil: PnP henter token lat — første kall etterConnect-PnPOnline— og identity-endepunktet i Automation-sandboxen har gitt tomme/uparserbare svar under raske påfølgende token-forespørsler (hvert steg kobler til på nytt). Steget feilet da med[Managed Identity] The error response was either empty or could not be parsed— sett i praksis på to av stegene i én kjøring. Connect-hjelperne tvinger nå token-hentingen umiddelbart (Get-PnPWeb) inne i en retry-løkke med økende backoff (4 forsøk), så hikken aldri når stegresultatene. -
GenerateParameters.ps1fant ikke ressursgruppa og regionen til et miljø som allerede var installert:resourceGroupNameogregionkom rett fra mal-defaultene, så en parameterfil generert for et eksisterende miljø sarg-bestillingsportaleninorwayeastuansett hva kunden faktisk brukte (sett i praksis: ressursgruppa hetBestillingsportalenog sto inortheurope). Å deploye med det feiler ikke — det bygger en komplett andre installasjon i en ny ressursgruppe og etterlater den gamle. Skriptet slår nå oppProcessProvisionRequest-Logic Appen i abonnementet — navnet er identisk i alle versjoner av løsningen, ogsåprovisionassist-*-generasjonen, mens ressursgruppenavn og region er frie valg ingen default kan gjette — og fyller begge verdiene fra funnet. Flere treff rapporteres i stedet for å gjettes på, ingen treff behandles som nyinstallasjon, og et eksplisitt-Regionbeholdes med en advarsel om avviket. -
npå template-prompten lastet likevel opp pakkens bilder: valget lover å «leave the site untouched (only reads the list ids)», menUploadAssetsvar gated på upgrade-modus alene — ikke på svaret. Pakkens bilder og ikoner ble derfor skrevet over områdets egne uansett. Nå hopper den over når malen hoppes over. -
New-AzResourceGroupba om bekreftelse mot en eksisterende ressursgruppe: «Provided resource group already exists. Are you sure you want to update it?» er en interaktivShouldContinuesom verken-Forceeller-SkipConfirmationdemper, så en uovervåket kjøring mot et eksisterende miljø ville stått og ventet på et svar — og «Created resource group» etterpå var direkte misvisende. Ressursgruppa opprettes nå bare når den mangler; finnes den, sier kjøringen det og oppgir regionen den står i. -
Områdekonfigurasjonen slettet kundens egne bilder ved hver re-deploy: steget som oppretter
SiteAssets/Provisioning Requestmed undermappeneProvTypesImagesogProvTypesIconssjekket først om hovedmappa fantes — og slettet den rekursivt (Remove-PnPFolder -Force) hvis den gjorde, før den bygde strukturen på nytt. På en nyinstallasjon var det et no-op; på en re-deploy eller en full oppgradering av et miljø i drift kastet det alle bilder og ikoner kunden hadde lastet opp for sine egne provisioning types, ogImage/Icon-URL-ene på de listeelementene pekte etterpå på slettede filer. Ingenting krevde nullstillingen:UploadAssetslegger ut pakkens egne filer og overskriver sine egne navn uansett. Mappene resolves nå medResolve-PnPFolder, som oppretter det som mangler og returnerer det som finnes — eksisterende innhold røres ikke. -
«Connected to SPO» sa ikke hvor eller som hvem: linja bekreftet bare at
Connect-PnPOnlineikke kastet. Siden den innloggingen kan fullføre stille fra PnPs token-cache på disk, er det nettopp tenanten og identiteten man trenger å se — begge skrives nå ut, sammen med admin-URL-en kjøringen er koblet til. -
Et feilet områdeoppslag kunne ende i tilbudet om å slette kundens område:
Get-PnPTenantSitefeiler både når området ikke finnes og når den innloggede kontoen ikke får lese tenantens områdeegenskaper — feil konto plukket i PnP-nettleserprompten (den gjenbruker gjerne en cachet konto fra en annen tenant), manglende SharePoint-administrator-rolle, eller throttling. Lest med-ErrorAction SilentlyContinuevar de to umulige å skille: begge ga$null, altså «ingen site her». En kjøring mot et eksisterende miljø gikk dermed inn i opprettelsesløpet, og to prompts senere sto tilbudet «PERMANENTLY delete this group (including its site)» på en produksjonsportal — sett i praksis i en dev-tenant der PnP hadde logget inn med en gjestekonto fra en annen tenant. Tre lag med retting: nyGetSiteExistenceStateklassifiserer feilen og skillerNotFound(kun «File Not Found»/«Cannot get site»/404) fraUnknown, og etUnknownstopper kjøringen med årsak og sannsynlig konto-forklaring i stedet for å gjette; pre-flight rapporterer det samme somMISSINGpåSharePoint tenant site lookup, så kjøringen stopper før noe er endret; og gruppe-sjekken sammenligner nå gruppas faktiske område-URL (over Graph, som virker uavhengig av SPO-admin-tilgangen) med målområdet — eier gruppa nettopp det området vi sikter på, er det installasjonen vi oppgraderer og ikke rester fra et mislykket forsøk, og sletting tilbys ikke. PRE-FLIGHT SUMMARY viser i tilleggSigned in as (PnP)ved siden av Az- og CLI-identitetene, siden det er den identiteten som avgjør om området kan leses og malen anvendes. -
GA-sjekken meldte «ingen Global Administrator» til en permanent Global Administrator:
CheckAppRoleRightsspurte/me/transitiveMemberOf/microsoft.graph.directoryRoleog leste.valuefra første side. Den transitive varianten paginerer over kontoens hele medlemskapssett og brukerdirectoryRole-castet per side, så en konto med mange gruppemedlemskap får side etter side med"value": []og en@odata.nextLink— verifisert i kundetenant: 20 sider, alle tomme, på en konto med GA, Privileged Role Administrator, SharePoint-, Teams- og Power Platform-administrator. Å lese første side «beviste» dermed at kontoen ikke hadde noen roller i det hele tatt, og sjekken ba en GA om å kjøre-SkipAppRoles. Bytter til/me/memberOf/…, som returnerer alle rollene i ett svar. Advarselen navngir nå også rollene kontoen faktisk har, og sier at PIM-roller må aktiveres og at en rolle arvet via en gruppe ikke er synlig i dette oppslaget — «ingen GA funnet» alene lot deg ikke skille de tre. -
Modulsjekken så ikke en modul som var lastet i økten:
VerifyModulesbrukteGet-InstalledModule, som er den smaleste av de tre måtene en modul kan være brukbar — den ser bare det PowerShellGet har registrert, og altså ikke en kopi pakket ut for hånd eller importert fra en sti utenforPSModulePath. Kjører du en side-lastet versjon (måten man tester en ny PnP-release), stoppet skriptet med «PnP.PowerShell module not installed» om en modul som var lastet og virket. Sjekken ser nå på lastet modul først (en lastet modul vinner uansett — PowerShell laster ikke en annen versjon inn i samme økt), deretterPSModulePathogGet-InstalledModule, og skriver ut versjon og hvor den kom fra. Av samme grunn hopper ogsåImport-Module PnP.PowerShellover seg selv når modulen alt er lastet: import etter navn feiler for en side-lastet kopi. -
MFA-kravet på Azure-skriving oppdages nå før kjøringen, ikke midt i den: tenanter som håndhever «MFA for Azure» avviser skriveoperasjoner fra en sesjon som autentiserte med passord alene. Lesing går fint, så ingenting merkes før første deployment — og den ligger på
azureresources.bicep, altså etter at hele SharePoint-delen er kjørt. Symptomet erAADSTS50076fra CLI-en ellerRequestDisallowedByAzurefra ARM. Ny pre-flight-sjekkMFA on the Azure sessionleseramr-claimet ut av ARM-tokenet (kun claimet; tokenet logges aldri) og oppgir kommandoene som fikser det. Merk at--scopealene ikke holder: utfordringen CLI-en får tilbake er en Conditional Access authentication context ({"acrs":{"essential":true,"values":["p1"]}}), og uten--claims-challengeleverer Entra tilbake det samme passord-tokenet uten å spørre om noe — sett i praksis:iatblir nyere,amrstår fortsattpwd. Sjekken ber derfor om at man kjøreraz logoutog deretter nøyaktig denaz login-kommandoen CLI-en selv skriver ut, inkludert--claims-challenge.WARNINGog ikkeMISSINGmed vilje: håndhevingen avhenger av tenantens policy, og en passord-sesjon ble sett fullføre en hel installasjon samme dag — å blokkere ville stoppet kjøringer som virker. -
Provisjonering stoppet etter en pre-1.0-oppgradering: runbook-kallet gikk uten Authorization-header:
bestillingsportalen-automationer den eneste tilkoblingen som skiftet autentiseringsmodell i 1.0 — fra Entra ID-appens credentials til den user-assigned managed identityen. På en nyinstallasjon opprettes den for managed identity og melderReady; på en oppgradering finnes den fra før med app-registreringens sertifikat-credentials, og ARM bytter bareparameterValueTypetilAlternative. Den gamle credentialen blir liggende, klarer ikke å fornye seg (AADSTS700027når Key Vault-sertifikatet er rotert) og låser tilkoblingen iError— designeren kaller den «Invalid connection», og Logic App-runtime sender runbook-kallet uten Authorization-header, såConfigureSpacealdri starter og bestillingen feiler med «Authentication failed. The 'Authorization' header is missing.» Logic App-definisjonen var korrekt hele tiden (connectionProperties.authentication.type = ManagedServiceIdentityverifisert i den deployede arbeidsflyten); feilen satt i selve tilkoblingsressursen.deploy.ps1sletter nå tilkoblingen og gjenoppretter den gjennomapiconnections.jsonnår statusen ikke erReady/Connected, og verifiserer resultatet. Sjekken ligger etter mal-deployen, ikke før: en tilkobling med en død credential står med den statusen den sist rakk å registrere — typiskConnectedfra den opprinnelige installasjonen, fordi ingenting har prøvd å fornye den siden — og det er malens egen oppdatering som utløser fornyelsen og først da setterError. En sjekk før deployen finner altså ingenting å reparere på nettopp den kjøringen som ødelegger tilkoblingen, og lar miljøet stå igjen ødelagt til neste kjøring (sett i praksis i et kundemiljø). Trygt å gjøre: en managed identity-tilkobling holder ingen credentials og trenger ingen autorisering, i motsetning til de fire delegerte. Verifisert mot både et oppgradert miljø (Error) og en nyinstallasjon (Ready). -
To PnP.PowerShell 1.x-cmdletnavn i
ConfigureSpacesom ikke finnes i 3.x:Add-PnPUserToGroup(linje 301, besøkende-steget) ogSet-PnPLabel(linje 507, oppbevaringsmerke-steget) ble fjernet av PnP før 3.x og finnes ikke i verken 3.2.0 eller 3.4.0 — heller ikke som aliaser. Begge stegene feilet altså med «not recognized» hver gang en bestilling hadde besøkende eller et oppbevaringsmerke; med fail-fast per steg felte de hele bestillingen. Erstattet medAdd-PnPGroupMember -GroupogSet-PnPRetentionLabel, som tar samme argumenter. Funnet ved å parse alle PnP-kall i repoet (AST) og verifisere cmdlet- og parameterflaten mot den importerte modulen — samme sjekk mot 3.2.0 som kontroll, så metodens blindsoner (dynamiske parametre påNew-PnPSite) kunne skilles fra reelle funn. -
«Connected to SPO» ble skrevet ut uten å være verifisert:
Connect-PnPOnlinekaster ikke når den fullfører fra token-cachen som en konto uten rettigheter i tenanten — feilen kommer først på neste tenant-admin-lesing, langt nok ned i kjøringen at den leses som et rettighetsproblem og ikke som en innlogging som traff feil konto. Linja bekreftet altså noe den ikke hadde sjekket. Nå gjøres en lesing mot tenant-admin-API-et rett etter innloggingen: går den, skrives URL og konto ut som før; går den ikke, sier linja eksplisitt at tilkoblingen ikke er brukbar, og den nye pre-flight-sjekkenSharePoint admin accessblokkerer kjøringen med kontoen, feilen og kommandoen som tømmer cachen. Alias-sjekken rapportererSKIPPEDmed en peker dit i stedet for å legge på en andre rød linje for samme årsak. -
PnP-innloggingen kan binde seg stille til en konto fra en annen tenant: PnP.PowerShell lagrer MSAL-cachen på disk (
%LOCALAPPDATA%\.m365pnppowershell\pnp.msal.cache) uavhengig av-PersistLogin, så-Interactivefullfører uten å spørre som den kontoen som ligger der. Symptomet er ikke en innloggingsfeil, menUnauthorizedpå første tenant-admin-lesing — og å logge inn på nytt hjelper ikke, siden ingenting spør.Connect-PnPOnline -ForceAuthenticationløser det heller ikke i praksis; det som virker er å slette cachefila. Pre-flight-sjekken over oppgir kommandoen når den treffer. PRE-FLIGHT SUMMARY viser i tilleggSigned in as (PnP), siden Az-, CLI- og PnP-innloggingene er tre uavhengige identiteter. -
$deployUserble lest føraz account setog kunne komme fra feil tenant: UPN-en brukes til å gi installasjonsbrukeren site collection admin og til deployment-pingbacken, menaz ad signed-in-user showkjørte før abonnementet ble valgt — den returnerte altså den kontoen Azure CLI tilfeldigvis stod på, som med cachede sesjoner i flere tenanter godt kan være en bruker i en helt annen tenant. Oppslaget er flyttet etteraz account set. Samtidig erSet-PnPTenantSite -Ownerspakket i egen try/catch: tildelingen er en bekvemmelighet, den kan legitimt feile for en gjestekonto, og en feil der skal ikke rive med seg hele områdesteget og dermed installasjonen. -
Alias-valideringen blokkerte re-deploy etter URL-endring på området:
ValidateSiteAliassjekket kollisjon mot tjenestekontoen uansett, men kollisjonen er bare relevant når et nytt område skal opprettes — aliaset blir gruppensmailNicknameved opprettelse og aldri igjen. Etter en URL-endring i SharePoint admin-senter (som endrer URL-en men ikke gruppens mailNickname) mårequestsSiteAliassettes til det nye URL-segmentet for at Logic Apps skal redeployes mot riktig URL — og det segmentet kan gjerne være tjenestekontoens navn, nøyaktig kollisjonen sjekken finnes for ved nyinstallasjon. Sjekken hopper nå over seg selv når området allerede finnes på den beregnede URL-en. -
New-PnPSitehang til evig tid fordi tjenestekontoen var eneste eier: området ble opprettet med-Owners <tjenestekontoen>, og gruppekoblede områder gir kun tilgang via gruppemedlemskap — installasjonsbrukeren som kjørte cmdlet-en hadde dermed ingen tilgang til det nye området, ogNew-PnPSitesin «vent til området er klart»-løkke polte et område den aldri fikk åpnet. Symptomet var at skriptet hang på «Creating the site …» mens admin-senteret viste området som opprettet med tjenestekontoen som eier. Nå opprettes området uten-Owners(kalleren blir automatisk gruppe-eier og -medlem, så ventingen fullfører), og tjenestekontoen legges til rett etterpå som både eier og medlem — eierskap gir ikke medlemskap i Microsoft 365-grupper, og godkjenningsflyten og Teams-velkomstmeldingen kjører som denne kontoen. Tildelingen gjøres idempotent med az CLI (fungerer uavhengig av PnP-appens delegerte Graph-tillatelser), og feiler den, fortsetter kjøringen med en tydelig manuell instruks i stedet for å stoppe. -
Områdeopprettelsen kollapset når aliaset var opptatt av en bruker: kunder har gjerne en tjenestekonto som
bestillingsportalen@kunde.no, og aliaset ble utledet frarequestsSiteName— altsåbestillingsportalen. Aliaset blir Microsoft 365-gruppensmailNicknameog deler navnerom med alle brukere og grupper, så det var opptatt. SharePoint feiler ikke på det: det opprettet gruppen sombestillingsportalen1. Skriptet leste ikke URL-enNew-PnPSitereturnerte, så alt videre pekte på/sites/bestillingsportalen, som ikke fantes — og kjøringen døde iSet-PnPTenantSitemedObject reference not set to an instance of an object, etter fem minutter uten spor av den egentlige årsaken. Tre rettinger: (1) nyttrequestsSiteAlias-parameter, som faller tilbake til gammel utledning når det er tomt slik at eksisterende installasjoner peker på området sitt — standardverdien er fortsattbestillingsportalen, fordi Teams-appen har URL-en/<managedPath>/bestillingsportalenhardkodet og området må ligge der; er aliaset opptatt, er framgangsmåten å opprette området på et ledig alias og deretter endre URL-en (URL-endringen rører ikke gruppensmailNickname), dokumentert i installasjonsveiledningen; (2) nyValidateSiteAliasi pre-flight som stopper kjøringen før noe opprettes hvis aliaset kolliderer med tjenestekontoens UPN/mailNickname eller med en annen bruker i tenanten, med den framgangsmåten somFix-tekst — de eksisterende sjekkene så bare etter grupper på aliaset, som var nettopp det som glapp; (3)New-PnPSite-returverdien brukes nå, så en omdøpt URL gir en tydelig advarsel og resten av kjøringen følger området som faktisk ble opprettet i stedet for å kollapse. -
throw('... {0}', $melding)formaterte ikke: feilmeldingen fra områdeopprettelsen nådde konsollet med en bokstavelig{0}i seg, fordithrowmed komma kaster en to-elements array framfor å formatere. Bruker-fnå. -
403 «Insufficient privileges» når gjest legges i Medlem-/Eier-gruppen på M365-gruppe-koblet site:
Add-PnPMicrosoft365GroupMember/Ownerresolver gjesten viaGET /users/{email}før den poster tilmembers/$ref. Managed identityen hadde bareGroup.ReadWrite.All, så brukeroppslaget feilet med 403.User.Read.Alllagt til iAssignManagedIdentityPermissions— kjørdeploy.ps1 -Upgradefor å tildele den ekstra appen til eksisterende automation account. -
Sitelogoparameteren virket ikke:
deploy.ps1lestelogoUrlfraparameters.json, men parameteren hetersiteLogoPath— verdien ble alltid tom. Rettet til å lesesiteLogoPath. -
Entra ID-appen ba om unødvendige application-tillatelser (mellomsteg —
appmanifest.jsonog hele app-registreringen er fjernet senere i samme versjon, se Sikkerhet-seksjonen):appmanifest.jsoner trimmet til kun den delegerteGroup.ReadWrite.All-tillatelsen (ROPC for sensitivitetsmerker). Alle application-rollene ligger på managed identities etter migreringen — nye installasjoner får dermed en app uten tenant-vide app-tillatelser. Eksisterende installasjoner: se fase 2 i Oppgraderingsveiledningen. -
AssignPermissionsToManagedIdentity.ps1: default-scopene matcher nå detdeploy.ps1tildeler automation-kontoens identity (Group.ReadWrite.All+User.Read.All, pluss-IncludeSharePointSitesFullControl), og skriptet returnerer exit-kode 1 hvis én eller flere tildelinger feiler (før kunne alle feile med exit 0). -
api.idiapiconnections.json: tre av tilkoblingene manglet ledende/i managed API-referansen; normalisert for alle seks.
Om versjonshistorikken
Versjonshistorikken for Bestillingsportalen starter på 1.0.0. Taggen v0.9.0 i
repoet er arvet fra oppstrøms pnp/provision-assist-m365-linjen
og svarer ikke til en Bestillingsportalen-release — den peker på en commit fra
februar 2025, lenge før arbeidet som utgjør 1.0.0. Den er beholdt som den er, siden
den er publisert, men skal ikke brukes til å resonnere om hva et miljø kjører.
Versjonsnummeret ligger i VERSION i repo-rot. Se CONTRIBUTING.md
for versjonsskjemaet og release-rutinen.