Spring til indholdet

Træk versionshistorikken ud af et listeelement med PowerShell

Hver version af et listeelement med sin feltværdi, sit tidspunkt og sin forfatter, skrevet til en CSV-fil. Til at flytte en log fra et felt, der tilføjer tekst, over i sin egen liste. Scriptet fra 2019 og det samme med PnP PowerShell i dag.

Opdateret PowerShellSharePoint Online 3 min. læsning

Et flerlinjet tekstfelt med Append Changes to Existing Text gemmer hver tilføjelse i sin egen version af elementet. Indstillingen kræver, at versionering er slået til på listen. Skal teksterne ud som selvstændige rækker, fx til en aktivitetsliste, er vejen at gå versionerne igennem og tage værdien fra hver af dem. Hvorfor jeg gjorde det, står i Statusloggen, der skulle have været en liste.

Et felt, der tilføjer tekst: hver statusmeddelelse står med navn og tidspunkt fra sin egen version.

Hvad en version indeholder#

Hver version har feltværdierne, som de var i den version, sit versionsnummer (1.0, 2.0 …), tidspunktet og den, der gemte den. For et felt, der tilføjer tekst, er værdien i en version kun det, der blev skrevet i den version. I versioner, hvor nogen ændrede et andet felt, er feltet tomt, og dem sorterer scriptet fra. Det byggede scriptet fra 2019 på. Om det stadig er sådan i SharePoint Online, har jeg ikke efterprøvet.

Med PnP PowerShell#

 1$sites = @(
 2    "https://<tenant>.sharepoint.com/sites/<websted1>",
 3    "https://<tenant>.sharepoint.com/sites/<websted2>"
 4)
 5$listName  = "Opgaver"
 6$fieldName = "Status"          # feltets interne navn
 7$csvPath   = "C:\Udtraek"
 8
 9foreach ($site in $sites) {
10    Connect-PnPOnline -Url $site -Interactive -ClientId "<app-id>"
11
12    $rows = foreach ($item in Get-PnPListItem -List $listName -PageSize 500) {
13        foreach ($v in Get-PnPListItemVersion -List $listName -Identity $item.Id) {
14            $status = $v.Values[$fieldName]
15            if ($status) {
16                [PSCustomObject]@{
17                    ItemId  = $item.Id
18                    Title   = $v.Values["Title"]
19                    Status  = $status
20                    Version = $v.VersionLabel
21                    Created = $v.Created.ToString("yyyy-MM-dd HH:mm:ss")
22                    Author  = $v.CreatedBy.Mail
23                }
24            }
25        }
26    }
27
28    $file = Join-Path $csvPath (($site -split "/")[-1] + ".csv")
29    $rows | Export-Csv $file -NoTypeInformation -Encoding UTF8
30    Write-Host "$site | $(@($rows).Count) meddelelser | $file"
31}
  • -ClientId er en app-registrering i egen tenant. PnP’s fælles app blev fjernet i september 2024.
  • -PageSize 500 henter elementerne side for side, så listen kan være større end 5.000 elementer.
  • Get-PnPListItemVersion giver hver version med VersionLabel, Created, CreatedBy og feltværdierne i Values (PnP’s kildekode). Om CreatedBy.Mail er udfyldt uden et ekstra kald, har jeg ikke efterprøvet.
  • Én fil pr. websted, som i 2019. Importen kan så tage dem én ad gangen.

Er feltet formateret tekst (Enhanced rich text), kommer værdien som HTML og skal renses, før den lægges i et almindeligt tekstfelt.

Rettet i forhold til 2019-udgaven#

  • Brugernavn og adgangskode i scriptet. 2019-udgaven loggede på med SharePointOnlineCredentials og en adgangskode i klar tekst. Den form for login (IDCRL) blev blokeret som standard 16. februar 2026 og kan ikke slås til igen efter 30. april 2026 (Microsoft, MC1184649). Nu Connect-PnPOnline -Interactive.
  • CSOM-filerne fra en SharePoint-server. Add-Type pegede på DLL’erne under Web Server Extensions\16\ISAPI. PnP.PowerShell har dem selv.
  • Alle elementer i ét kald. CreateAllItemsQuery() uden sidestørrelse løber ind i listevisningsgrænsen på 5.000 elementer.
  • VersionId / 512. Versions-id’et er major × 512 + minor, så divisionen giver majorversionen med decimaler for minorversioner. VersionLabel siger det samme læseligt, så kolonnen er udeladt.
  • Ét funktionskald pr. websted, skrevet ud fire gange. Min egen note dengang sagde, at en liste over webstederne var bedre. Nu er det en løkke.

Det der driller#

  • Kun de versioner, der stadig findes. Har listen haft en grænse for antal versioner, er de ældste meddelelser allerede slettet.
  • Forfatteren er den, der gemte versionen. Skrev et flow eller en servicekonto statussen, står den som forfatter.
  • Tidspunkterne kommer sandsynligvis i UTC. Ikke efterprøvet.
  • Den nye liste får importørens navn og tidspunkt i Oprettet af og Oprettet. Skal forfatteren og tidspunktet fra versionen med, kan de sættes bagefter som i Ret Oprettet af og Ændret af med validateUpdateListItem.
  • Ét kald pr. element for versionerne. Et par tusinde elementer tager tid, og SharePoint kan begynde at bremse kaldene.

Alle noter