Patterns & Practices

Guides & Tools

SHARING IS CARING

Patterns & Practices

Collection of tools and guidance meant to help you extend Microsoft 365 to your needs following best practices.

Don’t reinvent the wheel — focus on what truly matters for your organization.

Learn. Reuse. Share.

SEE INITIATIVES

White abstract geometric artwork from Dresden, Germany

Consider when Migrating SharePoint Site

Copy-PnPFile | PnP PowerShell

https:/pnp.github.io/powershell/cmdlets/Copy-PnPFile.html

Move-PnPFolder | PnP PowerShell

https:/pnp.github.io/powershell/cmdlets/Move-PnPFolder.html

Migrating SharePoint Site

This PowerShell will migrate the site to a Document Library for Archiving

#Create a form to collect the site name, subsite name, sub-subsite name, and document library name

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

# Download the image
if($null -eq $imagePath){
$imageUrl = "https://cspowerapplicationsstor.blob.core.windows.net/repository/cleanLogo.png"
$imagePath = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), "cleanLogo.png")
Invoke-WebRequest -Uri $imageUrl -OutFile $imagePath}

# Create the form
$form = New-Object System.Windows.Forms.Form
$form.Text = "Copy Site Data to sites/Archive"
$form.Size = New-Object System.Drawing.Size(300, 500)
$form.StartPosition = "CenterScreen"
$form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog
$form.MaximizeBox = $false
$form.MinimizeBox = $false

# Create a label for site name
$labelForm = New-Object System.Windows.Forms.Label
$labelForm.Text = "Fill out approprate fields"
$labelForm.Size = New-Object System.Drawing.Size(280, 20)
$labelForm.Location = New-Object System.Drawing.Point(10, 60)
$labelForm.Font = New-Object System.Drawing.Font("Arial", 10, [System.Drawing.FontStyle]::Bold)
$labelForm.ForeColor = [System.Drawing.Color]::Teal
$form.Controls.Add($labelForm)

# Create a label for site name
$labelForm2 = New-Object System.Windows.Forms.Label
$labelForm2.Text = "Library Will Remain Until Renamed"
$labelForm2.Size = New-Object System.Drawing.Size(280, 20)
$labelForm2.Location = New-Object System.Drawing.Point(10, 90)
$labelForm2.Font = New-Object System.Drawing.Font("Arial", 10, [System.Drawing.FontStyle]::Bold)
$labelForm2.ForeColor = [System.Drawing.Color]::Teal
$form.Controls.Add($labelForm2)

# Load and add the image
$image = [System.Drawing.Image]::FromFile($imagePath)
$pictureBox = New-Object System.Windows.Forms.PictureBox
$pictureBox.Image = $image
$pictureBox.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::CenterImage
$pictureBox.Size = New-Object System.Drawing.Size(260, 40)
$pictureBox.Location = New-Object System.Drawing.Point(10, 10)
$form.Controls.Add($pictureBox)

# Create a label for site name
$labelSite = New-Object System.Windows.Forms.Label
$labelSite.Text = "Site Name:"
$labelSite.Size = New-Object System.Drawing.Size(280, 20)
$labelSite.Location = New-Object System.Drawing.Point(10, 120)
$labelSite.Font = New-Object System.Drawing.Font("Arial", 10, [System.Drawing.FontStyle]::Bold)
$labelSite.ForeColor = [System.Drawing.Color]::Teal
$form.Controls.Add($labelSite)

# Create a text box for site name
$textBoxSite = New-Object System.Windows.Forms.TextBox
$textBoxSite.Size = New-Object System.Drawing.Size(260, 20)
$textBoxSite.Location = New-Object System.Drawing.Point(10, 150)
$form.Controls.Add($textBoxSite)

# Create a label for subsite name
$labelSubsite = New-Object System.Windows.Forms.Label
$labelSubsite.Text = "Subsite Name (optional):"
$labelSubsite.Size = New-Object System.Drawing.Size(280, 20)
$labelSubsite.Location = New-Object System.Drawing.Point(10, 180)
$labelSubsite.Font = New-Object System.Drawing.Font("Arial", 10, [System.Drawing.FontStyle]::Bold)
$labelSubsite.ForeColor = [System.Drawing.Color]::Teal
$form.Controls.Add($labelSubsite)

# Create a text box for subsite name
$textBoxSubsite = New-Object System.Windows.Forms.TextBox
$textBoxSubsite.Size = New-Object System.Drawing.Size(260, 20)
$textBoxSubsite.Location = New-Object System.Drawing.Point(10, 210)
$form.Controls.Add($textBoxSubsite)

# Create a label for sub-subsite name
$labelSubSubsite = New-Object System.Windows.Forms.Label
$labelSubSubsite.Text = "Sub-Subsite Name (optional):"
$labelSubSubsite.Size = New-Object System.Drawing.Size(280, 20)
$labelSubSubsite.Location = New-Object System.Drawing.Point(10, 240)
$labelSubSubsite.Font = New-Object System.Drawing.Font("Arial", 10, [System.Drawing.FontStyle]::Bold)
$labelSubSubsite.ForeColor = [System.Drawing.Color]::Teal
$form.Controls.Add($labelSubSubsite)

# Create a text box for sub-subsite name
$textBoxSubSubsite = New-Object System.Windows.Forms.TextBox
$textBoxSubSubsite.Size = New-Object System.Drawing.Size(260, 20)
$textBoxSubSubsite.Location = New-Object System.Drawing.Point(10, 270)
$form.Controls.Add($textBoxSubSubsite)

# Create a label for document Library name
$labeldocLibrary = New-Object System.Windows.Forms.Label
$labeldocLibrary.Text = "Document Library: $documentLibrary"
$labeldocLibrary.Size = New-Object System.Drawing.Size(280, 20)
$labeldocLibrary.Location = New-Object System.Drawing.Point(10, 300)
$labeldocLibrary.Font = New-Object System.Drawing.Font("Arial", 10, [System.Drawing.FontStyle]::Bold)
$labeldocLibrary.ForeColor = [System.Drawing.Color]::Teal
$form.Controls.Add($labeldoclibrary)

# Create a text box for document Library name
$textdocLibrary = New-Object System.Windows.Forms.TextBox
$textdocLibrary.Size = New-Object System.Drawing.Size(260, 20)
$textdocLibrary.Location = New-Object System.Drawing.Point(10, 330)
$textdocLibrary.Text = $documentLibrary  # Set default value
$form.Controls.Add($textdocLibrary)

# Create a button
$button = New-Object System.Windows.Forms.Button
$button.Text = "OK"
$button.Size = New-Object System.Drawing.Size(75, 23)
$button.Location = New-Object System.Drawing.Point(100, 370)
$form.Controls.Add($button)

# Add event handler for text box text changed event
$textdocLibrary.Add_TextChanged({
    if ([string]::IsNullOrWhiteSpace($textdocLibrary.Text)) {
        $button.Enabled = $false  # Enable the button if text box is not empty
    } else {
        $button.Enabled = $true  # Disable the button if text box is empty
    }
})

if ($null -eq $documentLibrary) {
$button.Enabled = $false  # Disable the button initially
}

# Define the button click event
$button.Add_Click({
    $form.Tag = @{
        SubSitesiteName = $textBoxSubSubsite.Text
        SiteName = $textBoxSite.Text
        SubsiteName = $textBoxSubsite.Text
        DocLibrary = $textdocLibrary.Text
    }
    $form.Close()
})

# Show the form
$form.ShowDialog()

# Output the collected data
$form.Tag

# Get the site and subsite names from the form

$siteName = $form.Tag.SiteName -replace '\s', ''
# Output the site name
Write-Host "Site Name entered: $siteName"

$subsiteName = $form.Tag.SubsiteName -replace '\s', ''
if ($form.Tag.SubsiteName) {
Write-Host "Site Name entered: $subsiteName"
}
$subSubsiteName = $form.Tag.SubSitesiteName -replace '\s', ''
if ($form.Tag.SubSitesiteName) {
Write-Host "Site Name entered: $subSubsiteName"
}

if ($form.Tag.DocLibrary) {
    $documentLibrary = $form.Tag.DocLibrary -replace '\s', ''
    } 
    else {
    $documentLibrary = $documentLibrary
    }
Write-Host "Document Library: $documentLibrary"

#Set Variables
$contentType = ""
$listsFolder = ""
$clinetId = "<app id>"
$tenant = "domain.onmicrosoft.com"
$thumbprint = "cert thumbprint"
$siteBaseUrl = "https://domain.sharepoint.com/"
$siteDestinationURL = "sites/Archive"
$siteMigrateUrl = $siteBaseUrl + $siteDestinationURL

$siteSourceBaseUrl = if ($subsiteName) {
    if ($subSubsiteName) {
        $siteName + "/" + $subsiteName + "/" + $subSubsiteName
    } else {
        $siteName + "/" + $subsiteName
    }
} else {
    $siteName
}

$subsite = $siteSourceBaseUrl -replace "/", "_"

#$siteSourceBaseUrl = $form.Tag.SiteName 
$siteDestinationFolder = "$documentLibrary/$subsite"
$listsFolder = $siteDestinationFolder + "/Lists"
$doclistName = $siteDestinationFolder.Split('/')[0]
$siteDestinationRoot = $siteDestinationURL + "/" + $siteDestinationFolder -replace "/$subsite", ''
$siteDestinationFullPath = $siteDestinationURL + "/" + $siteDestinationFolder 
$siteUrl = $siteBaseUrl + $siteSourceBaseUrl
$contentType = $subsite + "ContentTypeTemplate.xml"

     # Connect to the destination site
     Connect-PnPOnline -Url $siteMigrateUrl -ClientId $clinetId -Tenant $tenant -Thumbprint $thumbprint

     # Check if the document library exists in the destination site
     $libraryExists = Get-PnPList -Identity $documentLibrary -ErrorAction SilentlyContinue
 
         if (-not $libraryExists) {
             # Create the document library in the destination site
             New-PnPList -Title $documentLibrary -Template DocumentLibrary
         }
 
     # Create the field Creators and Last Update by if it doesn't exist
     # Check if the field exists
     $field = Get-PnPField -List $doclistName -Identity "LastUpdateBy" -ErrorAction SilentlyContinue
         
         if ($null -eq $field) {
             Add-PnPField -List $doclistName -DisplayName "LastUpdateBy" -InternalName "LastUpdateBy" -Type Text
             Write-Host "Field 'LastUpdateBy' created."
         } else {
             Write-Host "Field 'LastUpdateBy' already exists."
         }
 
     $field = Get-PnPField -List $doclistName -Identity "Creator" -ErrorAction SilentlyContinue
 
         if ($null -eq $field) {
             Add-PnPField -List $doclistName -DisplayName "Creator" -InternalName "Creator" -Type Text
             Write-Host "Field 'Creator' created."
         } else {
             Write-Host "Field 'Creator' already exists."
         }
 
     # Check if the folder exists in the destination site
     $folderExists = Get-PnPFolder -Url $siteDestinationFolder -ErrorAction SilentlyContinue
 
         if (-not $folderExists) {
             # Create the folder in the destination site
             Add-PnPFolder -Name $subsite -Folder "/$siteDestinationRoot"
             Add-PnPFolder -Name "Lists" -Folder "$siteDestinationFolder"
         }
 
         # Collect the folders and files from the source site    
         try {
         
     # Connect to the source site
     Connect-PnPOnline -Url $siteUrl -ClientId $clinetId -Tenant $tenant -Thumbprint $thumbprint
 
             # Retrieve all lists including the properties you'll need for filtering.
             $lists = Get-PnPList -Includes Title, BaseTemplate, Hidden, RootFolder.ServerRelativeUrl
 
             $documentLibraries = $lists | Where-Object {
                 $_.BaseTemplate -eq 101 -or 
                 (-not $_.Hidden)  -and ($_.Title -notmatch 'Health & Safety Documents') -and 
                 ($_.Title -notmatch 'Forms') -and ($_.Title -notmatch 'Workflow Tasks') -and 
                 ($_.RootFolder.ServerRelativeUrl -notmatch 'Lists')
             }            
 
             # Initialize an array to store all folders
 
             $folders = @()
             $allfolders = @()
             $docLibraries = @()
             $folderfiles = @()
             $topDocumentFolders = @()
             $listsSections = @()
             $files1stLevel = @()    
             $rootLists = @()                    
 
                 # Loop through each document library and get folders
                 foreach ($library in $documentLibraries) { #$library = $documentLibraries[1]
                     $libraryRootFolder = Get-PnPFolder -Url $library.RootFolder.ServerRelativeUrl 
                     $RootCellar = $libraryRootFolder.Name #$library.Title
                     $docLibraries += $libraryRootFolder 
             
                     # Get all top level folders in the document library
                     $docsRootDir = Get-PnPFolderItem -FolderSiteRelativeUrl $RootCellar -ItemType Folder 
                     $docsRootDir = $docsRootDir | Where-Object { $_.Name -ne "Forms" }
                     $topDocumentFolders += $docsRootDir 
                     
                     # Get all top level files in the document library
                     $libraryItems = Get-PnPFolderItem -FolderSiteRelativeUrl $RootCellar -ItemType File -Recursive
                     $libraryLevelFiles = Get-PnPFolderItem -FolderSiteRelativeUrl $RootCellar -ItemType File 
                     $siteFiles = $libraryItems | Where-Object {$libraryLevelFiles -notcontains $_}
 
                     # Acquire the properties of the files
                     foreach ($item in $libraryLevelFiles) {
                         $listItem = Get-PnPProperty -ClientObject $item -Property ListItemAllFields
                     
                         if ($null -ne $listItem.Id){ #($listItem -and $null -ne $listItem.Id) {
                             $folderfiles += $listItem    
                             $files1stLevel += $listItem
                         }
                     }
 
                     foreach ($item in $siteFiles) {
                     $fileItem = Get-PnPProperty -ClientObject $item -Property ListItemAllFields
             
                         if ($null -ne $fileItem.Id) {
                             $folderfiles += $fileItem    
                         }
                     }
                 }
                 
                 # Retrieve all lists and libraries
                 $lists = Get-PnPList
 
                 # Filter lists that are in the root directory
                 $rootLists = $lists | Where-Object {-not $_.Hidden -and $_.Title -notmatch "Tasks" -and $_.Title -notmatch "Documents"} 
                 $listFolders = $rootLists | Where-Object {$_.RootFolder.ServerRelativeUrl -notmatch "Lists"} 
                 $listsSections = $rootLists | Where-Object {$listFolders -notcontains $_}
 
             # Extract the content types and lists from the source site
             Get-PnPSiteTemplate -Out $contentType -Handlers ContentTypes -Force
             
             }
             catch {
                 # Handle the error
                 Write-Host "Error details: $_"
                 exit
             }
 
     # Connect to the destination site
     Connect-PnPOnline -Url $siteMigrateUrl -ClientId $clinetId -Tenant $tenant -Thumbprint $thumbprint 
 
         # Apply the template to the destination site
         # Invoke-PnPSiteTemplate -Path $contentType -Verbose
         
         # Create the document librarry folders in the destination site
         foreach ($library in $docLibraries) {
             $RootCellar = $library.Name 
             $libraryLanding = $siteDestinationFolder + "/" + $RootCellar   
 
             # Check if the folder exists in the destination site
             $folderExists = Get-PnPFolder -Url $libraryLanding -ErrorAction SilentlyContinue
             if (-not $folderExists) {
                 # Create the folder in the destination site
                 Add-PnPFolder -Name $RootCellar -Folder $siteDestinationFolder 
             }
             $allfolders += $library    
         }
 
         # Copy each file to the root directories in destination site
         foreach ($file in $files1stLevel) { 
             $fieldValues = $file.FieldValues
             $title = $fieldValues["Title"]
             #$pageName = $fieldValues["FileLeafRef"] 
             $SourcePageURL = $fieldValues["FileRef"] 
             $SourceUrl = $fieldValues["FileDirRef"] 
             $pageLanding = $SourceUrl -replace "^/$siteSourceBaseUrl", $siteDestinationFolder 
             $pagetoCopy = $SourcePageURL -replace "^/$siteSourceBaseUrl", "$siteDestinationFolder" 
             
             # Check if the file exists in the destination site
             $fileExists = Get-PnPFile -Url $pagetoCopy -ErrorAction SilentlyContinue
             if ($fileExists) {
                 Write-Host "File already exists in the destination site." -ForegroundColor Yellow
                 continue
             }
             else {
             Copy-PnPFile -SourceUrl $SourcePageURL -TargetUrl $pageLanding -Force
             Write-Host "File copied successfully." 
             }
         }
 
         # Add the folder depth field values to the files
         Function InitializeAndAddField {
             param (
                 [array]$folders,
                 [string]$fieldName
             )
             $folders | ForEach-Object {
                 if (-not $_.PSObject.Properties[$fieldName]) {
                     $_ | Add-Member -MemberType NoteProperty -Name $fieldName -Value ($_.ServerRelativeUrl -split '/').Count
                 } else {
                     $_.$fieldName = ($_.ServerRelativeUrl -split '/').Count
                 }
             }
             return $folders
         }
         
         $topDocumentFolders = InitializeAndAddField -folders $topDocumentFolders -fieldName "FolderDepth"
         $topDocumentFolders = $topDocumentFolders  | Where-Object { $_.Name -ne "Forms" }
         foreach($top in $topDocumentFolders){
             Write-Host "Folder: $($top.ServerRelativeUrl) Depth: $($top.FolderDepth)"
         }
 
         # Function to recursively process folders and their subfolders
     function Copy-FoldersRecursively {
         param (
             [array]$folders
         )
     
         foreach ($folder in $folders) { 
             # Process the current folder
             $folderUrl = $folder.ServerRelativeUrl -replace "^/$siteDestinationFullPath", "/$siteSourceBaseUrl" 
             $lastSlashIndex = $folderUrl.LastIndexOf('/')
             $folderPath = $folderUrl.Substring(0, $lastSlashIndex)
             $itemCount = $folder.ItemCount
             Write-Output "Processing folder: $folderUrl"
             
             # Replace the source URL with the destination URL
             $destinationUrl = $folderPath -replace "^/$siteSourceBaseUrl", "$siteDestinationFolder"
             $nextLevelFolder = $folderUrl -replace "^/$siteSourceBaseUrl", "$siteDestinationFolder"
             
             try {
                 if($itemCount -ne 0){
             
                     Copy-PnPFolder -SourceUrl $folderUrl -TargetUrl $destinationUrl -Force -Overwrite
                     Write-Host "Copied folder from $folderUrl to $destinationUrl" -ForegroundColor Green
                 } else {
                     # Create the empty folder at the destination
                     Add-PnPFolder -Name (Split-Path $folderUrl -Leaf) -Folder $destinationUrl -ErrorAction SilentlyContinue
                     Write-Host "Created empty folder at $destinationUrl" -ForegroundColor Yellow
                 }
                 } catch {
                     Write-Host "Error copying or creating folder from $folderUrl to $destinationUrl" -ForegroundColor Blue
                     Write-Host "Error details: $_" -ForegroundColor Magenta
                 }
     
             Start-Sleep -Seconds 5
             # Get subfolders of the current folder
             $subfolders = Get-PnPFolderItem -FolderSiteRelativeUrl $nextLevelFolder -ItemType Folder -ErrorAction SilentlyContinue
             if ($subfolders) {
                 # Log retrieved subfolders for debugging
                 Write-Output "Retrieved subfolders for $($folderUrl): $($subfolders | ForEach-Object { $_.ServerRelativeUrl })"
                 
                 # Filter out subfolders named "Forms"
                 $filteredSubfolders = $subfolders | Where-Object { $_.Name -ne "Forms" }
                 
                 # Recursively process subfolders
                 Copy-FoldersRecursively -folders $filteredSubfolders
             } else {
                 Write-Output "No subfolders found for $folderUrl"
             }
         }
     }
 
     # Measure the execution time of the Copy-FoldersRecursively function
     $executionTime = Measure-Command {
         Copy-FoldersRecursively -folders $topDocumentFolders
     }
 
     # Display the elapsed time
     Write-Host "The Copy-FoldersRecursively function took $($executionTime.TotalSeconds) seconds to complete."
 
     # If needed, add a sleep based on the measured time
     if ($executionTime.TotalSeconds -lt 5) {
         Write-Host "Adding a sleep of 5 seconds to ensure all files are available for update."
         Start-Sleep -Seconds 5
     }
 
     foreach ($item in $folderfiles) { #$item = $folderfiles[10]
                 $fieldValues = $null
                 $fieldValues = $item.FieldValues
                 $title = $fieldValues["Title"]
                 $itemId = $fieldValues["ID"]
             if($null -ne $itemId) {
                 $userEditor = ""
                 $userCreator = ""
 
                 # Access metadata
                 $created = $fieldValues["Created"]
                 $modified = $fieldValues["Modified"]
                 $author = $fieldValues["Author"]
                 $editor = $fieldValues["Editor"]
                 $userCreated = $author.Email
                 $userEdited = $editor.Email
                 $fileName = $fieldValues["FileLeafRef"]   
                 $fileUrl = $fieldValues["FileDirRef"]
                 
                 $destinationUrlFile = $fileUrl -replace "^/$siteSourceBaseUrl", "/$siteDestinationFullPath"
                 #$archiveFolder = $siteDestinationFullPath -replace "/$subsite", "" 
                 $DestinationFileName = $destinationUrlFile + "/" + $fileName 
                 $NewFile = Get-PnPFile -Url $DestinationFileName -AsListItem 
                 if ($null -ne $NewFile.Id) {
                 $values = @()           
                     # Prepare the values to update
                     $values = @{
                         "Creator" = $userCreated
                         "Created" = $created
                         "LastUpdateBy" = $userEdited
                         "Modified" = $modified
                     }
 
                 $pnpUser = "i:0#.f|membership|" + $userEdited
                 $userEditor = Get-PnPUser -Identity $pnpUser -ErrorAction SilentlyContinue
                 if ($userEditor) {
                     $values["Editor"] = $userEdited
                 }
                 $pnpCreator = "i:0#.f|membership|" + $userCreated
                 $userCreator = Get-PnPUser -Identity $pnpCreator -ErrorAction SilentlyContinue
                 if ($userCreator) {
                     $values["Author"] = $userCreated
                 }
 
                 # Update the metadata on the new file with the modified and modified by source values
                
                     Write-Host "Updating metadata for file: $DestinationFileName with ID: $($NewFile.Id)"
 
                     Set-PnPListItem -List $doclistName -Identity $NewFile.Id -Values $values
                 }
             }
         }
 
 
     # Copy the lists and libraries to the destination site
     # Connect to the source site
     Connect-PnPOnline -Url $siteUrl -ClientId $clinetId -Tenant $tenant -Thumbprint $thumbprint
 
     foreach($root in $listsSections | Where-Object { $_.Title -notmatch "QuickLinks" -and $_.Title -notmatch "Page Content" -and $_.Title -notmatch "Microfeed"}){
     # Define the SharePoint list name
         $listName = ""
         $listXml = ""    
         $listName = $root.Title
         $listXml = $subsite + $listName + ".xml"
         #Connect-PnPOnline -Url $siteMigrateUrl -ClientId $clinetId -Tenant $tenant -Thumbprint $thumbprint 
             
     # Extract the content types and lists from the source site
     Get-PnPSiteTemplate -Out  $listXml -ListsToExtract $listName -Handlers Lists -Force # $listName -Handlers Lists
     Add-PnPDataRowsToSiteTemplate -Path $listXml -List $listName 
     }       
 
     # Connect to the destination site
     Connect-PnPOnline -Url $siteMigrateUrl -ClientId $clinetId -Tenant $tenant -Thumbprint $thumbprint        
 
     foreach($root in $listsSections | Where-Object { $_.Title -notmatch "QuickLinks" -and $_.Title -notmatch "Page Content" -and $_.Title -notmatch "Microfeed"}){
         # Define the SharePoint list name
             $listName = ""
             $listCreating = ""
             $listUrl = ""
             $listXml = ""    
             $listName = $root.Title
             $listCreating = $subsite + "_" + $listName
             $listUrl = $siteUrl + "/Lists/" + $listName 
             $listXml = $subsite + $listName + ".xml"
 
     # Upload the template XML to the destination site
 
     if($listXml -ne "") {     
     Add-PnPFile -Path $listXml -Folder $listsFolder 
     <#try {
         Set-PnPList -Identity $listName -Title $listCreating
         Write-Output "Successfully renamed list: $listName to $listCreating"
     } catch {
         Write-Output "Failed to rename list: $listName"
         Write-Output "Error: $($_.Exception.Message)"
     }#>
     Remove-Item -Path $listXml -Force
     }
 }
 Add-PnPFile -Path $contentType -Folder $listsFolder 
 Remove-Item -Path $contentType -Force

Get approval for changes in SharePoint lists by Power Automate

Using Get Changes action we ca determine what happened to an item, but it takes some steps to have a clean output.

If Manager Out

# Manager name
if(equals(outputs('Compose_Area_Manager_Status'),'disabled'), triggerBody()?['RegionalCenterManager'],triggerBody()?['RVPO'])
# Manager email
if(equals(outputs('Compose_Area_Manager_Status'),'disabled'), triggerBody()?['RCM_Email'],triggerBody()?['RVPO_Email'])

Rejecting Manager

outputs('Post_adaptive_card_to_Power_Platform')?['body']?['responder']?['displayName']

Refunds

Understand how to handle refunds, manage disputes, and maintain positive customer relationships during payment issues.

Enhance your architectural journey with the Études Architect app.

  • Collaborate with fellow architects.
  • Showcase your projects.
  • Experience the world of architecture.
White abstract geometric artwork from Dresden, Germany