From 110339fa013cb7549e643c86a93cf01a61fc2924 Mon Sep 17 00:00:00 2001
From: Roland Easily grant API permissions with the Office 365 CLI Logging in to Office 365 with pnpm manager Init local repo Add all Files to local repo Show last commit show full history Importend: only for spfx < 13.1 or by using the \"locale\" command argument Sample Folder structure prettify your imports src Interface to define our Data structure Interface to define our Data Access services Mocking Service for testing in local Workbench development Source Reference Sample Advantages Init context in react webpart component source init service in react webpart component Get items from list Source Using PnPJS and Async/Await to Really Simplify Your API Calls async/await joelfmrodrigues - demos Create Sample init git add office fabric react Latest version Latest Beta version Create report for upgrade Roland Oechslin Senior Sharepoint/M365 Expert and Developer, BLS AG, Bern, Switzerland Programming, New Technologies @rolandoechslin Let\u2019s get back to the quote from Ignite\u2026 why are subsites the spawn of the devil? Generally speaking, it\u2019s hard to argue with the fact that site collections are more flexible. Each site collection can be viewed as a granular \u2018unit of work\u2019. They allow you to control permissions, features, storage, branding and target data protection and retention controls at a more targeted level. A flat architecture like this allows you to \u2018plug and play\u2019 site collections into whatever kind of navigational hierarchy is required \u2013 the announcement of the SharePoint Hub site at Microsoft Ignite is a feature being built to allow you to build this navigation thru the User Interface. You will be able to associate a site collection with a SharePoint Hub by the click of a button and easily move it from one Hub to another if required. This is great news. Source: https://joannecklein.com/2017/11/03/sharepoint-site-collection-advantages/ Check Install Update Uninstall (all) Connect with Delegated Access Connect with App ID and Certificate Connect with Client Secret -The required Office 365 role to run PnP Powershell with Scopes Latest Version Latest Version - https://www.powershellgallery.com/packages/Microsoft.Online.SharePoint.PowerShell/16.0.8119.0 Latest Version Load Data from SP-List Code -SharePoint add-in, custom Web API and SPFx (v1.1) write-manifests.json SPFx unit tests and code coverage quality gates in Azure DevOps \u2013 Velin Georgiev Apply a DevOps process to your SPFx project (Part 1) https://blog.velingeorgiev.com/unit-test-your-sharepoint-framework-solution-with-jest https://www.youtube.com/watch?v=iDt7MJX9Lj0&t=20s https://www.youtube.com/watch?v=lFkNqcf-Thg https://www.eliostruyf.com/sharepoint-framework-unit-tests-with-jest/ http://bit.ly/pnp-devops-1 http://bit.ly/pnp-devops-2 http://bit.ly/pnp-devops-3 http://bit.ly/pnp-devops-4 -Create Simple ImageMap in SPO Microsoft 365 guest sharing settings reference How to properly configure sharing settings in the SharePoint Admin Center https://github.com/SharePoint/PnP-PowerShell/tree/master/Samples/Provisioning.SelfHostedWithAzureWebJob/Engine To get the list of all the Office 365 groups in descending order: To get the list of all private Office 365 groups in your tenant: To get list of deleted Office 365 groups in descending order: How to resolve the error The alias is being used by another group in your organization To get the list of orphaned Office 365 groups in your tenant: To determine where a group was provisioned (Planner, Yammer, Teams etc.) To get the list of Teams integrated Office 365 group list: -Introducing the idea of Archive Hub Sites - How to get the hubId in SharePoint Framework - Fix broken Hub Sites in SharePoint Online Reference the Log class Log your message from your WebPart Search Query for multilingual news Testing in chrome console ## News 2023 Sample mit Flow und Azure Function Provisioning complex Modern Sites with Azure Functions and Microsoft Flow \u2013 Part 1 \u2013 Architecture Success runs Failed runs Know how many Site Designs and Site Scripts you have: Delete a Site Design or a Site Script based on its unique identifier: Use Microsoft Graph to evaluate SharePoint Urls -Renewing SharePoint Certificates on premise Stream (built on SharePoint), the new version of Microsoft Stream Maintenance mode DisableTelemetry Debug localization Search vertical layout refresh Hide the navigation Error Handling install npm package add to gulpfile.js List global npm packages versions List detail global npm package versions from one package Why TypeScript pluralsight typescript course http://sharepoint.handsontek.net/2017/12/11/asset-packaging-and-the-goodies-from-sharepoint-framework-1-4 https://joelfmrodrigues.wordpress.com/2018/03/02/sharepoint-framework-checklist/ go into solution folder search f\u00fcr \"@micorosoft/sp-\" update all
+
@@ -1712,6 +1719,10 @@
+
Links¶
+Profile¶
+code $PROFILE
+
Import-Module -Name CLI.Microsoft365.PowerShell.Predictor
+Import-Module posh-git
+Import-Module -Name Terminal-Icons
+oh-my-posh init pwsh --config "$env:POSH_THEMES_PATH/jandedobbeleer.omp.json" | Invoke-Expression
+
+
Resources¶
ResourcesAndres Bohren - PowerShellScripts
Syntax¶
diff --git a/rezepte/kochtips/index.html b/rezepte/kochtips/index.html
index bde5cc93..95dbbdc9 100755
--- a/rezepte/kochtips/index.html
+++ b/rezepte/kochtips/index.html
@@ -1687,6 +1687,13 @@
Salzkartoffel
+Salzkartoffel
Salate¶
+
diff --git a/search/search_index.json b/search/search_index.json
index dd9ace99..1ee2d73f 100755
--- a/search/search_index.json
+++ b/search/search_index.json
@@ -1 +1 @@
-{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Tips and tricks","text":"
"},{"location":"#admin-shortcut-list","title":"Admin Shortcut List","text":"
"},{"location":"#feedback","title":"Feedback","text":"
"},{"location":"#m365-docs","title":"M365 Docs","text":"
"},{"location":"#start-spfx-training","title":"Start SPFx Training","text":"
"},{"location":"#start-spfx-react-development","title":"Start SPFx React Development","text":"
"},{"location":"#start-teams-development","title":"Start Teams Development","text":"
"},{"location":"#reference-samples","title":"Reference Samples","text":"
"},{"location":"#m365-full-stack-spfx","title":"M365 Full Stack / SPFx","text":"
"},{"location":"#enterprise-reference-samples","title":"Enterprise Reference Samples","text":"
"},{"location":"#pnpjs-v3","title":"PnPjs-V3","text":"
"},{"location":"#fluent-ui-9","title":"Fluent UI 9","text":"
"},{"location":"#learning-spfx-videos","title":"Learning SPFx Videos","text":"
"},{"location":"#dev-tenant","title":"DEV-Tenant","text":"
"},{"location":"#development-roadmap","title":"Development Roadmap","text":"
"},{"location":"#code-guideline","title":"Code Guideline","text":"
"},{"location":"#performance-guideline","title":"Performance Guideline","text":"
"},{"location":"#design-guideline","title":"Design Guideline","text":"
"},{"location":"#code-review-checklist","title":"Code Review Checklist","text":"
"},{"location":"#security-guideline","title":"Security Guideline","text":"
"},{"location":"#granting-permission","title":"Granting Permission","text":"
m365 spo login https://<tenant>-admin.sharepoint.com\n
"},{"location":"#content-style-guide","title":"Content Style Guide","text":"spo serviceprincipal grant add --resource 'Microsoft Graph' --scope 'Mail.Read'\n
"},{"location":"#coding-patterns","title":"Coding Patterns","text":"
"},{"location":"#spfx-workflow","title":"SPFx Workflow","text":"
"},{"location":"#sharepoint-pnp-community","title":"SharePoint PNP Community","text":"
"},{"location":"#create-project-pnpm","title":"Create Project (pnpm)","text":"
yo @microsoft/sharepoint \u2013package-manager pnpm\n
pnpm i tslint@5.9.1 -DE\n
"},{"location":"#check-package-version","title":"Check Package Version","text":"pnpm i typescript@2.4.2 -DE\n
"},{"location":"#git-basics","title":"Git Basics","text":"node \u2013v\nnpm \u2013v\nyo --generators\ngulp \u2013v\ntsc \u2013v\ntsd --version\n
git init\n
git add -A\ngit commit -m \"init repo\"\n
git show --name-only\n
git log --full-history --src/path/to/file.js\n
"},{"location":"#developmentlocal-workbench","title":"Development(local workbench)","text":"gulp serve\n
"},{"location":"#developmentonline-workbench","title":"Development(online workbench)","text":"https://localhost:4321/temp/workbench.html\n
gulp serve --nobrowser\n
/_layouts/15/workbench.aspx?forceLocale=de-de\n
"},{"location":"#prepare-deployment-solution","title":"Prepare Deployment Solution","text":"/_layouts/workbench.aspx\n
gulp clean\n
gulp build --ship\n
gulp bundle --ship\n
"},{"location":"#debug-in-vscode","title":"Debug in vs.code","text":"gulp package-solution --ship\n
"},{"location":"#checklist-spfx-initial","title":"Checklist SPFx initial","text":"
"},{"location":"#update-version","title":"Update Version","text":"
npm version
to upgrade the version of your SPFx solutionnpm version major\n
npm version minor\n
"},{"location":"#add-imported-pnp-modules","title":"Add imported pnp modules","text":"npm version patch\n
npm install @pnp/logging @pnp/common @pnp/odata @pnp/sp @pnp/graph --save\n
npm install @pnp/spfx-controls-react@latest --save --save-exact\n
"},{"location":"#localizations","title":"Localizations","text":"npm install @pnp/spfx-property-controls@latest --save --save-exact\n
{\n\"cdnBasePath\": \"<!-- PATH TO CDN -->\",\n\"debugLocale\": \"de-de\"\n}\n
"},{"location":"#app-permission","title":"App Permission","text":"gulp serve --locale=de-de\n
"},{"location":"#sharepoint-online-data","title":"SharePoint Online Data","text":"
"},{"location":"#msgraph-data","title":"MSGraph Data","text":"
"},{"location":"#scoped-service","title":"Scoped service","text":"
"},{"location":"#data-service","title":"Data Service","text":"
"},{"location":"#data-model","title":"Data Model","text":"
export interface IHelpDeskItem {\n id?: number;\n title?: string;\n description?: string;\n level?: string;\n status?: string;\n assignedTo?: string;\n resolution?: string;\n}\n
import { IHelpDeskItem } from \"./../models/IHelpDeskItem\";\nimport { WebPartContext } from \"@microsoft/sp-webpart-base\";\n\nexport default interface IDataService {\n getTitle(): string;\n isConfigured(): boolean;\n getItems(context: WebPartContext): Promise<IHelpDeskItem[]>;\n addItem(item: IHelpDeskItem): Promise<void>;\n deleteItem(id: number): Promise<void>;\n}\n
"},{"location":"#get-data-with-sharepoint-rest","title":"Get Data with Sharepoint REST","text":"import { IHelpDeskItem } from \"./../models/IHelpDeskItem\";\nimport IDataService from \"./IDataService\";\nimport { IWebPartContext } from \"@microsoft/sp-webpart-base\";\n\nexport default class MockDataService implements IDataService {\n...\n private _webPartContext: IWebPartContext;\n private _listId: string;\n\n constructor(webPartContext: IWebPartContext, listId: string) {\n this._webPartContext = webPartContext;\n this._listId = listId;\n }\n...\n\n public getItems(context: IWebPartContext): Promise<IHelpDeskItem[]> {\n return new Promise<IHelpDeskItem[]>((resolve, reject) => {\n setTimeout(() => resolve([\n {\n id : 1,\n title : \"That doesn't work\",\n description : \"When I do that, it doesn't work\",\n level : \"Low\",\n status: \"Open\",\n resolution: \"Do this and it will work!\",\n assignedTo: \"S\u00e9bastien Levert\",\n }\n ]), 300);\n });\n }\n}\n
"},{"location":"#get-data-with-pnp-js-core","title":"Get Data with Pnp-JS-Core","text":"public getItems(context: WebPartContext): Promise<IHelpDeskItem[]> {\nreturn new Promise<IHelpDeskItem[]>((resolve, reject) => {\n context.spHttpClient\n .get( `${this._webPartContext.pageContext.web.absoluteUrl}/_api/web/lists/GetById('${this._listId}')/items` +\n `?$select=*,HelpDeskAssignedTo/Title&$expand=HelpDeskAssignedTo`, SPHttpClient.configurations.v1)\n .then(res => res.json())\n .then(res => {\n let helpDeskItems:IHelpDeskItem[] = [];\n\n for(let helpDeskListItem of res.value) {\n helpDeskItems.push(this.buildHelpDeskItem(helpDeskListItem));\n }\n\n resolve(helpDeskItems);\n })\n .catch(err => console.log(err));\n});\n}\n
public onInit(): Promise<void> {\n return super.onInit().then(_ => {\n pnpSetup({\n spfxContext: this.context\n });\n });\n}\n
public render(): void {\n const element: React.ReactElement<IListContentProps> = React.createElement(\n ListContent,\n {\n context: this.context,\n dataService: this.getDataService(),\n list: this.properties.list\n }\n );\n\n ReactDom.render(element, this.domElement);\n}\n
"},{"location":"#get-search-data-with-asyncawait","title":"Get Search Data with async/await","text":"public getItems(context: WebPartContext): Promise<IHelpDeskItem[]> {\nreturn new Promise<IHelpDeskItem[]>((resolve, reject) => {\n\n sp.web.lists.getById(this._listId).items\n .select(\"*\", \"HelpDeskAssignedTo/Title\")\n .expand(\"HelpDeskAssignedTo\").getAll().then((sessionItems: any[]) => {\n let helpDeskItems:IHelpDeskItem[] = [];\n\n for(let helpDeskListItem of sessionItems) {\n helpDeskItems.push(this.buildHelpDeskItem(helpDeskListItem));\n }\n\n resolve(helpDeskItems);\n });\n\n});\n}\n
private async _getSiteData(): Promise<ISPSite[]> {\n\n var thisDomain: string = location.host.split(\".\")[0];\n var exclusions: string[] = [\"https://\" + thisDomain + \"-my.sharepoint.com\", \"https://\" + thisDomain + \".sharepoint.com/portals/personal\"];\n var exclusionString: string = \" -Path:\" + exclusions.join(\" -Path:\");\n exclusionString += \" -Path=https://\" + thisDomain + \".sharepoint.com\";\n\n try {\n\n let result = await sp.search(<SearchQuery>{\n Querytext: \"contentclass:sts_site \" + exclusionString,\n RowLimit: 500,\n TrimDuplicates: false,\n Properties: [{\n Name:\"EnableDynamicGroups\",\n Value: {\n BoolVal: true,\n QueryPropertyValueTypeIndex: QueryPropertyValueType.BooleanType\n }\n }],\n SelectProperties: [\"Title\", \"Path\", \"SiteLogo\"]\n });\n\n return this.processSearchResults(result);\n\n } catch (e) {\n\n console.error(e);\n return null;\n\n }\n\n }\n
public async getShipmentStatuses(serviceProps: IServiceProperties): Promise<IStatus[]> {\n\n try {\n\n let items = await sp\n .web\n .lists\n .getByTitle(\"SL_ShippingStatuses\")\n .items\n .select(\"Id\", \"Title\", \"SortOrder\", \"CanBeCancelled\")\n .orderBy(\"SortOrder\")\n .get(spODataEntityArray<Item, IStatus>(Item));\n\n return items;\n\n } catch (e) {\n\n console.error(e);\n return null;\n\n }\n}\n
"},{"location":"#get-data-from-msgraph","title":"Get Data from MSGraph","text":"private async _getItems() {\n let select = '*';\n let expand = 'File';\n let filter = '';\n\n // filter by selected term if required\n if (this.props.term !== undefined && this.props.term !== null && this.props.term.length > 0) {\n const term = this.props.term[0];\n\n select = `${select},TaxCatchAll/Term`;\n expand = `${expand},TaxCatchAll`;\n filter = `TaxCatchAll/Term eq '${term.name}'`;\n }\n\n const items = await sp.web.lists.getById(this.props.list).items\n .select(select)\n .expand(expand)\n .filter(filter)\n .get();\n\n // update state\n this.setState({\n items: items ? items : []\n });\n console.log('List Items:', this.state.items);\n}\n
"},{"location":"#start-office-fabric-react","title":"Start Office Fabric React","text":"
create-react-app demo-office-fabric-react-ts --scripts-version=react-scripts-ts\n
git init\ngit add .\ngit commit -m \"Initial commit.\"\n
"},{"location":"#generator-for-sp-applications","title":"Generator for SP applications","text":"npm install office-ui-fabric-react@5.132.0 --save\n
"},{"location":"#upgrade-yo-generator-spfx","title":"Upgrade yo generator SPFx","text":"
npm list -g --depth=0\n
npm ls -g --depth=0 @microsoft/generator-sharepoint\n
npm outdated --global\n
"},{"location":"#spfx-version-upgrade","title":"SPFx Version Upgrade","text":"npm install @microsoft/generator-sharepoint@latest --global\n
"},{"location":"#office-365-cli","title":"Office 365 CLI","text":"
npm i -g @pnp/cli-microsoft365@latest\n
npm i -g @pnp/cli-microsoft365@next\n
"},{"location":"#update-spfx-packages","title":"Update SPFx packages","text":"m365 spfx project upgrade --shell powershell --toVersion 1.12.1 --output md > report.md\n
"},{"location":"#custom-yo-spfx-generator","title":"Custom yo spfx generator","text":"
"},{"location":"#add-external-js-frameworks","title":"Add External JS-Frameworks","text":"
"},{"location":"#spfx-utilities","title":"SPFx Utilities","text":"
"},{"location":"#team-development-tools","title":"Team Development Tools","text":"
"},{"location":"about/about/","title":"About","text":""},{"location":"about/about/#author","title":"Author","text":"
"},{"location":"about/help/#deployment-to-github-pages","title":"Deployment to GitHub Pages","text":"
"},{"location":"angular/elements/","title":"Angular","text":""},{"location":"angular/elements/#elements","title":"Elements","text":"mkdocs gh-deploy\n
"},{"location":"angular/elements/#angularjs","title":"AngularJS","text":"
"},{"location":"articles/sitecollection-versus-subsite/","title":"Sitecollection versus subsite","text":""},{"location":"articles/sitecollection-versus-subsite/#advantages-of-subsites","title":"Advantages of Subsites","text":"
"},{"location":"articles/sitecollection-versus-subsite/#disadvantages-of-site-collections","title":"Disadvantages of Site Collections","text":"
"},{"location":"articles/sitecollection-versus-subsite/#my-thoughts","title":"My thoughts","text":"
"},{"location":"js/guide/","title":"Guide","text":""},{"location":"js/guide/#ref","title":"Ref","text":"
"},{"location":"js/guide/#styleguide","title":"Styleguide","text":"
"},{"location":"js/guide/#books","title":"Books","text":"
"},{"location":"js/guide/#arrays","title":"Arrays","text":"
"},{"location":"js/guide/#technologie-radar","title":"Technologie Radar","text":"
"},{"location":"js/pwa/","title":"PWA","text":""},{"location":"js/pwa/#overview","title":"Overview","text":"
"},{"location":"powershell/graphsdk-ps/","title":"Graph SDK Powershell","text":"
"},{"location":"powershell/graphsdk-ps/#learning","title":"Learning","text":"
"},{"location":"powershell/graphsdk-ps/#security","title":"Security","text":"
"},{"location":"powershell/graphsdk-ps/#azure-automation","title":"Azure Automation","text":"
"},{"location":"powershell/graphsdk-ps/#uddate-process","title":"Uddate Process","text":"
"},{"location":"powershell/graphsdk-ps/#work","title":"Work","text":"
Get-InstalledModule | Where-Object {$_.Name -match \"Microsoft.Graph\"}\n
Install-Module -Name \"Microsoft.Graph\"\n
Update-Module Microsoft.Graph\n
Uninstall-Module Microsoft.Graph\n\n# Uninstall all Sub-modules of Graph\nGet-InstalledModule Microsoft.Graph.* | ForEach-Object { if($_.Name -ne \"Microsoft.Graph.Authentication\") {\n Uninstall-Module $_.Name }\n}\n\n# Uninstall the dependant module\nUninstall-Module Microsoft.Graph.Authentication\n
# Connect to Microsoft Graph\nConnect-MgGraph -Scopes \"User.Read.All\"\n\n# Get All users\n$users = Get-MgUser\n$users | Select-Object DisplayName, UserPrincipalName, Mail\n
# App Config\n$TenantID = \"<placeholder>\"\n$ClientID = \"<placeholder>\" # App ID\n$CertThumbPrint = \"<placeholder>\"\n\n# Connect to Microsoft Graph using App\nConnect-MgGraph -ClientID $ClientID -TenantId $TenantID -CertificateThumbprint $CertThumbPrint\n
"},{"location":"powershell/pnp-ps/","title":"PnP Powershell","text":""},{"location":"powershell/pnp-ps/#information","title":"Information","text":"# App Registration details\n$TenantID = \"<placeholder>\"\n$ClientID = \"<placeholder>\"\n$ClientSecret = \"<placeholder>\"\n\n$Body = @{\n Grant_Type = \"client_credentials\"\n Scope = \"https://graph.microsoft.com/.default\"\n Client_Id = $ClientID\n Client_Secret = $ClientSecret\n}\n\n$Connection = Invoke-RestMethod `\n -Uri https://login.microsoftonline.com/$TenantID/oauth2/v2.0/token `\n -Method POST `\n -Body $body\n\n# Get the Access Token\n$Token = $Connection.access_token\n\n# Connect to Microsoft Graph\nConnect-MgGraph -AccessToken $Token\n
"},{"location":"powershell/pnp-ps/#references","title":"References","text":"
"},{"location":"powershell/pnp-ps/#security-authentication","title":"Security / Authentication","text":"
"},{"location":"powershell/pnp-ps/#tools-plugin","title":"Tools / Plugin","text":"
"},{"location":"powershell/pnp-ps/#login-with-an-application-admin","title":"Login with an Application admin","text":"
"},{"location":"powershell/pnp-ps/#documentation","title":"Documentation","text":"
"},{"location":"powershell/pnp-ps/#specific-version","title":"Specific Version","text":"
"},{"location":"powershell/pnp-ps/#latest-version","title":"Latest Version","text":"
"},{"location":"powershell/pnp-ps/#check","title":"Check","text":"Get-InstalledModule | foreach { $b = (find-module $_.name).version ; if ($b -ne $_.version) { Write-host \"$($_.name) has an update from $($_.version) to $b\" } }\n
"},{"location":"powershell/pnp-ps/#update-module-to-the-latest-version","title":"Update Module to the latest version","text":"Get-Module SharePointPnPPowerShell* -ListAvailable | Select-Object Name,Version | Sort-Object Version -Descending\n
"},{"location":"powershell/pnp-ps/#delete-the-old-version","title":"Delete the old version","text":"Update-Module SharePointPnPPowerShell*\n
"},{"location":"powershell/pnp-ps/#install-a-specific-version","title":"Install a specific version","text":"Get-InstalledModule -Name \"SharePointPnPPowerShellOnline\" -RequiredVersion 3.8.1904.0 | Uninstall-Module\n
"},{"location":"powershell/pnp-ps/#connect-with-app-permission","title":"Connect with App Permission","text":"Install-Module -Name SharePointPnPPowerShellOnline -RequiredVersion 3.0.1808.1\n
Initialize-PnPPowerShellAuthentication -ApplicationName DemoApp -Tenant tenant.onmicrosoft.com -Store CurrentUser\n\n$url = \"https://tenant.sharepoint.com\"\n$clientid = \"<placeholder>\"\n$thumbprint = \"<placeholder>\"\n$tenant = 'tenant.onmicrosoft.com'\n\nConnect-PnPOnline -Url $url -ClientId $clientid -Thumbprint $thumbprint -Tenant $tenant\n
"},{"location":"powershell/pnp-ps/#list-all-commands","title":"List all commands","text":"# Load PNP the Right Way\n$pnp = Get-Command Connect-Stuff -ErrorAction SilentlyContinue\nif (!$pnp) {Install-Module SharePointPnPPowerShellOnline -Force}\nImport-Module SharePointPnPPowerShellOnline\n
"},{"location":"powershell/pnp-ps/#create-guid","title":"Create Guid","text":"Get-Command | ? { $_.ModuleName -eq \"SharePointPnPPowerShellOnline\" }\n
"},{"location":"powershell/pnp-ps/#delete-all-listitems","title":"Delete all listitems","text":"[guid]::NewGuid() | Select-Object -ExpandProperty Guid | clip\n
"},{"location":"powershell/pnp-ps/#upload-documents","title":"Upload Documents","text":"Get-PnPList -Identity Lists/MyList | Get-PnPListItem -PageSize 100 -ScriptBlock { Param($items) \n$items.Context.ExecuteQuery() } | % {$_.DeleteObject()}\n
"},{"location":"powershell/pnp-ps/#site-classification","title":"Site Classification","text":"function UploadDocuments(){\nParam(\n [ValidateScript({If(Test-Path $_){$true}else{Throw \"Invalid path given: $_\"}})] \n $LocalFolderLocation,\n [String] \n $siteUrl,\n [String]\n $documentLibraryName\n)\nProcess{\n $path = $LocalFolderLocation.TrimEnd('\\')\n\n Write-Host \"Provided Site :\"$siteUrl -ForegroundColor Green\n Write-Host \"Provided Path :\"$path -ForegroundColor Green\n Write-Host \"Provided Document Library name :\"$documentLibraryName -ForegroundColor Green\n\n try{\n $credentials = Get-Credential\n\n Connect-PnPOnline -Url $siteUrl -CreateDrive -Credentials $credentials\n\n $file = Get-ChildItem -Path $LocalFolderLocation -Recurse\n $i = 0;\n Write-Host \"Uploading documents to Site..\" -ForegroundColor Cyan\n (dir $path -Recurse) | %{\n try{\n $i++\n if($_.GetType().Name -eq \"FileInfo\"){\n $SPFolderName = $documentLibraryName + $_.DirectoryName.Substring($path.Length);\n $status = \"Uploading Files :'\" + $_.Name + \"' to Location :\" + $SPFolderName\n Write-Progress -activity \"Uploading Documents..\" -status $status -PercentComplete (($i / $file.length) * 100)\n $te = Add-PnPFile -Path $_.FullName -Folder $SPFolderName\n } \n }\n catch{\n }\n }\n }\n catch{\n Write-Host $_.Exception.Message -ForegroundColor Red\n }\n\n }\n}\n\n\n#UploadDocuments -LocalFolderLocation {Local Folder Location} -siteUrl {Site collection URL} -documentLibraryName {Document Library Name}\n
Connect-PnPOnline -Scopes \"Directory.ReadWrite.All\"\n
Enable-PnPSiteClassification -Classifications \"HBI\",\"LBI\",\"Top Secret\" -UsageGuidelinesUrl ```\n\"http://aka.ms/sppnp\" -DefaultClassification \"HBI\"\n
Add-PnPSiteClassification -Classifications \"SBI\",\"MBI\"\n
Remove-PnPSiteClassification -Classifications \"SBI\"\n
Update-PnPSiteClassification -Classifications \"HBI\",\"LBI\",\"Top Secret\" -UsageGuidelinesUrl http://aka.ms/sppnp\" -DefaultClassification \"HBI\"\n
"},{"location":"powershell/pnp-ps/#tips","title":"Tips","text":"Disable-PnPSiteClassification\n
"},{"location":"powershell/pnp-ps/#documents-list","title":"Documents List","text":"
"},{"location":"powershell/pnp-ps/#list-properties","title":"List Properties","text":"
"},{"location":"powershell/pnp-ps/#fields","title":"Fields","text":"Connect-PnPOnline -Url https://toddklindt.sharepoint.com/sites/8884aced -Credentials Me\nGet-PnPView -List Documents\nGet-PnPView -List Documents -Identity 3c4126aa-d2fe-4b57-9a70-e03ebb9c76ef\n$view = Get-PnPView -List Documents -Identity 3c4126aa-d2fe-4b57-9a70-e03ebb9c76ef\n$view\n$view | select *\n$view.ViewQuery\nGet-PnPProperty -ClientObject $view -Property ViewQuery\n$view.ViewQuery\n$view\n$view | select *\n
"},{"location":"powershell/pnp-ps/#copy-list","title":"Copy-List","text":"
"},{"location":"powershell/powerapps/","title":"Teams Powershell","text":"
"},{"location":"powershell/powerapps/#check-version","title":"Check Version","text":"
"},{"location":"powershell/powerapps/#update-module-to-latest-version","title":"Update Module to latest version","text":"Get-Module Microsoft.PowerApps* -ListAvailable | Select-Object Name,Version | Sort-Object Version -Descending\n
"},{"location":"powershell/powerapps/#delete-old-version","title":"Delete old version","text":"Update-Module Microsoft.PowerApps*\n
"},{"location":"powershell/powerapps/#connect","title":"Connect","text":"# Admin\nGet-InstalledModule -Name \"Microsoft.PowerApps.Administration.PowerShell\" -RequiredVersion 2.0.56 | Uninstall-Module\n\n## Maker\nGet-InstalledModule -Name \"Microsoft.PowerApps.PowerShell\" -RequiredVersion 1.0.9 | Uninstall-Module\n
"},{"location":"powershell/powerapps/#disconnect","title":"Disconnect","text":""},{"location":"powershell/powershell/","title":"Links","text":""},{"location":"powershell/powershell/#resources","title":"Resources","text":"Add-PowerAppsAccount\n
"},{"location":"powershell/powershell/#syntax","title":"Syntax","text":"
"},{"location":"powershell/powershell/#hashtable","title":"Hashtable","text":"Get-Command -Name Get-PnPSite -Syntax\n
"},{"location":"powershell/powershell/#coding-tips","title":"Coding Tips","text":"
"},{"location":"powershell/powershell/#testing-tips","title":"Testing Tips","text":"
"},{"location":"powershell/powershell/#performance-tips","title":"Performance Tips","text":"
"},{"location":"powershell/powershell/#vscode-settings","title":"VS.Code Settings","text":"
"},{"location":"powershell/powershell/#blogs","title":"Blogs","text":"
"},{"location":"powershell/powershell/#office-365-groups","title":"Office 365 Groups","text":"
"},{"location":"powershell/powershell/#sharepoint-2016","title":"SharePoint 2016","text":"
"},{"location":"powershell/powershell/#modules","title":"Modules","text":"
"},{"location":"powershell/powershell/#slides","title":"Slides","text":"$env:PSModulePath\n(Get-Module -ListAvailable Pnp.*).path\n\nGet-InstalledModule | select name, version\n
"},{"location":"powershell/powershell/#azuread","title":"AzureAD","text":"
"},{"location":"powershell/powershell/#loaded-modules","title":"Loaded Modules","text":"Install-Module -Name AzureAD\n
"},{"location":"powershell/spo-ps/","title":"SPO Powershell","text":"[System.AppDomain]::CurrentDomain.GetAssemblies() | Where-Object Location | Sort-Object -Property FullName | Select-Object -Property FullName, Location, GlobalAssemblyCache, IsFullyTrusted | Out-GridView\n
"},{"location":"powershell/spo-ps/#check-version","title":"Check Version","text":"Get-Module Microsoft.Online.SharePoint.PowerShell* -ListAvailable | Select-Object Name,Version | Sort-Object Version -Descending\n
"},{"location":"powershell/spo-ps/#update-module-to-the-latest-version","title":"Update Module to the latest version","text":"
"},{"location":"powershell/spo-ps/#delete-the-old-version","title":"Delete the old version","text":"Update-Module Microsoft.Online.SharePoint.PowerShell\n
"},{"location":"powershell/spo-ps/#check-different-file-version","title":"Check Different File Version","text":"Get-InstalledModule -Name \"Microsoft.Online.SharePoint.PowerShell\" -RequiredVersion 16.0.8119.0 | Uninstall-Module\n
"},{"location":"powershell/spo-ps/#credential-manager","title":"Credential Manager","text":"Get-ChildItem -Path 'C:\\Program Files\\WindowsPowerShell\\Modules\\Microsoft.Online.SharePoint.PowerShell\\*Microsoft.SharePoint*.dll' -Recurse | ft Name,@{Label=\"Version\";Expression={$_.VersionInfo.FileVersion}} -AutoSize\n\n# Search in GAC_MSIL\nGet-ChildItem -Path C:\\Windows\\Microsoft.NET\\assembly\\GAC_MSIL\\*Microsoft.SharePoint*.dll -Recurse | ft Name,@{Label=\"Version\";Expression={$_.VersionInfo.FileVersion}} -AutoSize\n
"},{"location":"powershell/spo-ps/#connect","title":"Connect","text":"
"},{"location":"powershell/spo-ps/#disconnect","title":"Disconnect","text":"Connect-SPOService https://devro-admin.sharepoint.com -Credential admin@devro.onmicrosoft.com\n
"},{"location":"powershell/spo-ps/#uls-correlation-id","title":"ULS-Correlation ID","text":"Disconnect-SPOService\n
"},{"location":"powershell/spo-ps/#security","title":"Security","text":"get-splogevent -starttime (get-date).addminutes(-20) | where-object { $_.correlation -eq \"e434f79b-68bb-40d2-0000-03a47eae1bf9\" } | fl message > c:\\errors1.txt\n
"},{"location":"powershell/teams/","title":"Teams Powershell","text":"get-sposite | ?{$_.DenyAddAndCustomizePages -eq 'Disabled'}\n ```\n\n## Ressources\n\n- [resources-to-learn-powershell-for-office-365](https://absolute-sharepoint.com/2018/03/resources-to-learn-powershell-for-office-365.html)\n\n## Tenant Configuration\n\n### Remove Feedback Button\n\n```Powershell\nSet-SPOTenant -UserVoiceForFeedbackEnabled:$false\n
"},{"location":"powershell/teams/#check-version","title":"Check Version","text":"
"},{"location":"powershell/teams/#update-module-to-latest-version","title":"Update Module to latest version","text":"Get-Module MicrosoftTeams* -ListAvailable | Select-Object Name,Version | Sort-Object Version -Descending\n
"},{"location":"powershell/teams/#delete-old-version","title":"Delete old version","text":"Update-Module MicrosoftTeams\n
"},{"location":"powershell/teams/#connect","title":"Connect","text":"Get-InstalledModule -Name \"MicrosoftTeams\" -RequiredVersion 0.9.0 | Uninstall-Module\n
"},{"location":"powershell/teams/#disconnect","title":"Disconnect","text":"
"},{"location":"powershell/teams/#teamsmanagment","title":"Teamsmanagment","text":"
"},{"location":"rezepte/kochtips/","title":"Kochtips","text":""},{"location":"rezepte/kochtips/#salzkartoffel","title":"Salzkartoffel","text":"
"},{"location":"security/learning/","title":"Security","text":""},{"location":"security/learning/#check-pw","title":"Check PW","text":"
"},{"location":"security/learning/#training","title":"Training","text":"
"},{"location":"security/learning/#azure-ad-breached","title":"Azure AD breached","text":"
"},{"location":"security/learning/#azure-sentinel","title":"Azure Sentinel","text":"
"},{"location":"security/learning/#resources","title":"Resources","text":"
"},{"location":"security/learning/#checklist","title":"Checklist","text":"
"},{"location":"security/learning/#tools","title":"Tools","text":"
"},{"location":"security/learning/#firewall","title":"Firewall","text":"
"},{"location":"security/learning/#sharepoint-onprem","title":"Sharepoint OnPrem","text":"
"},{"location":"security/learning/#sharepoint-online","title":"SharePoint Online","text":"
"},{"location":"security/learning/#office-365-azuread","title":"Office 365 / AzureAD","text":"
"},{"location":"security/learning/#file","title":"File","text":"
"},{"location":"security/learning/#spfx-tooling","title":"SPFx Tooling","text":"
"},{"location":"security/learning/#lockfiles","title":"Lockfiles","text":"
"},{"location":"security/learning/#block-websites","title":"Block websites","text":"
"},{"location":"security/learning/#cookies","title":"Cookies","text":"
"},{"location":"security/learning/#blogger-and-sites","title":"Blogger and Sites","text":"
"},{"location":"spfx/ace/","title":"ACE","text":""},{"location":"spfx/ace/#github-samples","title":"Github Samples","text":"
"},{"location":"spfx/adaptive-cards/","title":"Adaptive Cards","text":""},{"location":"spfx/adaptive-cards/#reference","title":"Reference","text":"
"},{"location":"spfx/adaptive-cards/#samples","title":"Samples","text":"
"},{"location":"spfx/adaptive-cards/#community-demo","title":"Community Demo","text":"
"},{"location":"spfx/adaptive-cards/#images","title":"Images","text":"
"},{"location":"spfx/ai/","title":"AI","text":"
"},{"location":"spfx/ai/#azure-openai-service","title":"Azure OpenAI Service","text":"
"},{"location":"spfx/ai/#gpt-prompts","title":"GPT Prompts","text":"
"},{"location":"spfx/ai/#samples","title":"Samples","text":"
"},{"location":"spfx/ai/#learning","title":"Learning","text":"
"},{"location":"spfx/ai/#semantic-kernel","title":"Semantic Kernel","text":"
"},{"location":"spfx/ai/#text-analyse","title":"Text Analyse","text":"
"},{"location":"spfx/ai/#frameworks","title":"Frameworks","text":"
"},{"location":"spfx/ai/#monitor-azure-openai-service","title":"Monitor Azure OpenAI Service","text":"
"},{"location":"spfx/architecture/","title":"Architecture","text":"
"},{"location":"spfx/architecture/#checklist-solution","title":"Checklist Solution","text":"
"},{"location":"spfx/architecture/#user-settings","title":"User Settings","text":"
"},{"location":"spfx/architecture/#build-applications","title":"Build applications","text":"
"},{"location":"spfx/architecture/#template-and-icons","title":"Template and Icons","text":"
"},{"location":"spfx/azure/","title":"Azure","text":"
"},{"location":"spfx/azure/#azure-account-identity-services","title":"Azure Account / Identity services","text":"
"},{"location":"spfx/azure/#administration-with-azure-cli","title":"Administration with Azure-CLI","text":"
"},{"location":"spfx/azure/#bicep","title":"Bicep","text":"
"},{"location":"spfx/azure/#granting-access-using-sharepoint-app-only","title":"Granting access using SharePoint App-Only","text":"
"},{"location":"spfx/azure/#keyvault","title":"KeyVault","text":"
"},{"location":"spfx/azure/#azure-managed-identities","title":"Azure Managed Identities","text":"
"},{"location":"spfx/azure/#azure-logic-app","title":"Azure Logic App","text":"
"},{"location":"spfx/azure/#azure-automation","title":"Azure-Automation","text":"
"},{"location":"spfx/azure/#azure-automation-teams-powershell","title":"Azure Automation Teams Powershell","text":"
"},{"location":"spfx/azure/#azure-functions","title":"Azure-Functions","text":"
"},{"location":"spfx/azure/#app-register","title":"App Register","text":"
"},{"location":"spfx/azure/#azure-services","title":"Azure Services","text":"
"},{"location":"spfx/azure/#azure-log-analytics","title":"Azure Log Analytics","text":"
"},{"location":"spfx/azure/#tips","title":"Tips","text":"
"},{"location":"spfx/azure/#token","title":"Token","text":"
"},{"location":"spfx/azure/#manage-group-settings","title":"Manage Group Settings","text":"
"},{"location":"spfx/azure/#naming-policy","title":"Naming Policy","text":"
"},{"location":"spfx/azure/#permission-reference","title":"Permission Reference","text":"
"},{"location":"spfx/azure/#microsoft-identity-platform","title":"Microsoft identity platform","text":"
"},{"location":"spfx/azure/#security","title":"Security","text":"
"},{"location":"spfx/azure/#scripts","title":"Scripts","text":"
"},{"location":"spfx/azure/#remote-working","title":"Remote working","text":"
"},{"location":"spfx/azure/#office-365-management-activity-api-m365-audit-logs","title":"Office 365 Management Activity API (M365 Audit Logs)","text":"
"},{"location":"spfx/azure/#azure-ad-cross-tenant-migration","title":"Azure AD Cross Tenant Migration","text":"
"},{"location":"spfx/azure/#azure-ad-assessment-tools","title":"Azure AD Assessment Tools","text":"
"},{"location":"spfx/blogger/","title":"Blogger","text":""},{"location":"spfx/blogger/#o365","title":"O365","text":"
"},{"location":"spfx/blogger/#teams","title":"Teams","text":"
"},{"location":"spfx/blogger/#list-formatting","title":"List Formatting","text":"
"},{"location":"spfx/blogger/#onprem","title":"OnPrem","text":"
"},{"location":"spfx/bot/","title":"BOT","text":"
"},{"location":"spfx/bot/#bot-framework-cognitive-service","title":"Bot Framework & Cognitive Service","text":""},{"location":"spfx/bot/#ai","title":"AI","text":"
"},{"location":"spfx/bot/#qna-makers","title":"QnA Makers","text":"
"},{"location":"spfx/bot/#bot-framework-composer","title":"Bot Framework Composer","text":"
"},{"location":"spfx/bot/#samples","title":"Samples","text":"
"},{"location":"spfx/bot/#power-virtual-agent","title":"Power Virtual Agent","text":"
"},{"location":"spfx/bot/#patterns","title":"Patterns","text":"
"},{"location":"spfx/bot/#create-bot-in-teams","title":"Create Bot in Teams","text":"
"},{"location":"spfx/branding/","title":"Branding","text":""},{"location":"spfx/branding/#overview","title":"Overview","text":"
"},{"location":"spfx/branding/#docs","title":"Docs","text":"
"},{"location":"spfx/branding/#css","title":"CSS","text":"
"},{"location":"spfx/branding/#designing-header","title":"Designing Header","text":"
"},{"location":"spfx/businessobjects/","title":"Business-Objects","text":""},{"location":"spfx/businessobjects/#async","title":"Async","text":"
private async loadScripts(): Promise<void> {\n return new Promise<void>(async (resolve) => {\n if(this._context) {\n resolve();\n }\n\n const response = this.loadScript(layoutsUrl + 'init.js', 'Sod');\n resolve();\n });\n }\n
"},{"location":"spfx/classic/","title":"Classic sites","text":"private async _loadList(): Promise<void> {\n this.setState({\n loading: true\n });\n let items = await pnp.sp.web.lists.getByTitle(\"Events\").items.select(\"Id\", \"Title\", \"SPFxDescription\", \"SPFxThumbnail\")\n .orderBy(\"Modified\", false).get();\n _items = items.map((item: IList, index: number) => {\n return {\n thumbnail: item.SPFxThumbnail != null ? item.SPFxThumbnail.Url : \"\",\n key: item.Id,\n name: item.Title,\n description: item.SPFxDescription\n }\n });\n this.setState({\n sortedItems: _items,\n columns: _buildColumns(),\n loading: false,\n newsFeedVisible: false\n });\n _lastQueryDate = moment();\n}\n
"},{"location":"spfx/column-formating/","title":"Column Formating","text":""},{"location":"spfx/column-formating/#reference","title":"Reference","text":"
"},{"location":"spfx/column-formating/#tools","title":"Tools","text":"
"},{"location":"spfx/column-formating/#ressources","title":"Ressources","text":"
"},{"location":"spfx/column-formating/#samples","title":"Samples","text":"
"},{"location":"spfx/column-formating/#add-scripts-for-formating","title":"Add Scripts for formating","text":"
"},{"location":"spfx/column-formating/#view-formating","title":"View formating","text":"
"},{"location":"spfx/communication-site/","title":"Communication Site","text":""},{"location":"spfx/communication-site/#sitecoloums-format","title":"SiteColoums Format","text":"
"},{"location":"spfx/configuration/","title":"Configuration","text":"
"},{"location":"spfx/cortex/","title":"Project Cortex","text":""},{"location":"spfx/cortex/#overview","title":"Overview","text":"
"},{"location":"spfx/cosmos-db/","title":"Cosmos DB","text":""},{"location":"spfx/cosmos-db/#tips","title":"Tips","text":"
"},{"location":"spfx/custom-web-api/","title":"Custom Web API","text":""},{"location":"spfx/custom-web-api/#securing","title":"Securing","text":"
"},{"location":"spfx/custom-web-api/#samples","title":"Samples","text":"
"},{"location":"spfx/debug/#webcast","title":"Webcast","text":"
"},{"location":"spfx/debug/#tips","title":"Tips","text":"
"},{"location":"spfx/debug/#exclude-mock-data","title":"Exclude mock data","text":"
"},{"location":"spfx/debug/#azure-token","title":"Azure Token","text":"
"},{"location":"spfx/delve/","title":"Delve","text":""},{"location":"spfx/delve/#search-konfiguration","title":"Search Konfiguration","text":"
"},{"location":"spfx/deployment/","title":"Deployment","text":""},{"location":"spfx/deployment/#app-catalog","title":"App Catalog","text":"
"},{"location":"spfx/deployment/#azure-devops-azure-pipline","title":"Azure DevOps / Azure Pipline","text":"
"},{"location":"spfx/deployment/#alm","title":"ALM","text":"
"},{"location":"spfx/deployment/#arm","title":"ARM","text":"
"},{"location":"spfx/deployment/#cicd","title":"CI/CD","text":"
"},{"location":"spfx/deployment/#deployment-to-cdn","title":"Deployment to CDN","text":"
"},{"location":"spfx/deployment/#deployment-to-sp-library","title":"Deployment to SP Library","text":"{\n\"cdnBasePath\": \"https://publiccdn.sharepointonline.com/cloud67.sharepoint.com/cdn/topnavmenu\"\n}\n
"},{"location":"spfx/deployment/#deployment-to-azure-storage","title":"Deployment to Azure Storage","text":"
"},{"location":"spfx/deployment/#appsettings","title":"AppSettings","text":"
"},{"location":"spfx/deployment/#automate-project-documentation","title":"Automate Project Documentation","text":"
"},{"location":"spfx/dev-ops/","title":"Dev-Ops","text":""},{"location":"spfx/dev-ops/#tips-tricks","title":"Tips & Tricks","text":"
"},{"location":"spfx/dev-ops/#jest-setup","title":"Jest Setup","text":"
"},{"location":"spfx/docker/","title":"Docker","text":""},{"location":"spfx/docker/#spfx-images","title":"SPFx Images","text":"
"},{"location":"spfx/docker/#tips","title":"Tips","text":"
"},{"location":"spfx/docker/#devcontainer","title":"DevContainer","text":"
"},{"location":"spfx/documentsets/","title":"Document Sets","text":""},{"location":"spfx/documentsets/#overview","title":"Overview","text":"
"},{"location":"spfx/documentsets/#issues","title":"Issues","text":"
"},{"location":"spfx/documentsets/#tools","title":"Tools","text":""},{"location":"spfx/documentsets/#metalogix-content-matrix-87","title":"Metalogix Content Matrix 8.7","text":"
"},{"location":"spfx/events/","title":"Events/meetings","text":""},{"location":"spfx/events/#how-to-create-online-meetingsevents","title":"How to create online meetings/events","text":"
"},{"location":"spfx/extensions/","title":"Extensions","text":""},{"location":"spfx/extensions/#custom-forms-extensions","title":"Custom Forms Extensions","text":"
"},{"location":"spfx/extensions/#tipps","title":"Tipps","text":"
"},{"location":"spfx/extensions/#samples","title":"Samples","text":"
"},{"location":"spfx/extensions/#full-page","title":"Full Page","text":"
"},{"location":"spfx/extensions/#site-footer","title":"Site footer","text":"
"},{"location":"spfx/extensions/#listview","title":"ListView","text":"
"},{"location":"spfx/extensions/#bots","title":"Bots","text":"
"},{"location":"spfx/extensions/#clarity","title":"Clarity","text":"
"},{"location":"spfx/extensions/#comments","title":"Comments","text":"
"},{"location":"spfx/extensions/#change-browser-favicon-icon","title":"Change browser favicon icon","text":"
"},{"location":"spfx/extensions/#google-analytics","title":"Google Analytics","text":"
"},{"location":"spfx/extensions/#matamo-piwik-analytics","title":"Matamo (Piwik) Analytics","text":"
"},{"location":"spfx/extensions/#inject-css","title":"Inject CSS","text":"
"},{"location":"spfx/extensions/#spa","title":"SPA","text":"
"},{"location":"spfx/extensions/#navigations","title":"Navigations","text":"
"},{"location":"spfx/extensions/#placeholders","title":"Placeholders","text":"
"},{"location":"spfx/flow/","title":"Power Automate (aka. Flow)","text":""},{"location":"spfx/flow/#support","title":"Support","text":"private _topPlaceholder : PlaceholderContent;\npublic onInit(void){\n this.context.placeholderProvider.changedEvent.add(this, this._handlePlaceholderChange.bind(this));\n}\n\nprivate _handlePlaceholderChange(){\n if (!this._topPlaceholder)\n {\n // We don't have a placeholder populated yet. Let's try and get it.\n this._topPlaceholder = this.context.placeholderProvider.tryCreateContent(PlaceholderName.Top);\n } else {\n // We have a placeholder - let's make sure that it still exists.\n let index:number = this.context.placeholderProvider.placeholderNames.indexOf(PlaceholderName.Top);\n if ( index < 0)\n {\n // The placeholder is no longer here.\n this._topPlaceholder.dispose();\n this._topPlaceholder = undefined;\n }\n }\n if ( this._topPlaceholder )\n {\n this._topPlaceholder.innerText = 'Hello World!';\n }\n}\n
"},{"location":"spfx/flow/#video","title":"Video","text":"
"},{"location":"spfx/flow/#api","title":"API","text":"
"},{"location":"spfx/flow/#connectors","title":"Connectors","text":"
"},{"location":"spfx/flow/#limits","title":"Limits","text":"
"},{"location":"spfx/flow/#admin-security","title":"Admin Security","text":"
"},{"location":"spfx/flow/#export-import-flows","title":"Export / Import Flows","text":"
"},{"location":"spfx/flow/#samples","title":"Samples","text":"
"},{"location":"spfx/flow/#copy-move-documents","title":"Copy / Move Documents","text":"
"},{"location":"spfx/flow/#error-messages","title":"Error Messages","text":"
"},{"location":"spfx/flow/#json-in-flow","title":"JSON in Flow","text":"
"},{"location":"spfx/flow/#disable-flow","title":"Disable Flow","text":"
"},{"location":"spfx/flow/#azure-logic-app","title":"Azure Logic App","text":"Connect-PnPOnline -Url https://<teantUrl>/sites/<name>\n\n# disable\nSet-PnPSite -DisableFlows:$true\n\n# enable\nSet-PnPSite -DisableFlows:$false\n
"},{"location":"spfx/fluidframework/","title":"Fluid Framework","text":""},{"location":"spfx/fluidframework/#overview","title":"Overview","text":"
"},{"location":"spfx/fluidframework/#samples","title":"Samples","text":"
"},{"location":"spfx/forms/","title":"Forms Tools","text":""},{"location":"spfx/forms/#microsoft-forms","title":"Microsoft Forms","text":""},{"location":"spfx/forms/#limits","title":"Limits","text":"
"},{"location":"spfx/forms/#frameworks","title":"Frameworks","text":"
"},{"location":"spfx/forms/#redux-forms","title":"Redux-Forms","text":"
"},{"location":"spfx/forms/#tips","title":"Tips","text":"
"},{"location":"spfx/governance/","title":"Governance","text":""},{"location":"spfx/governance/#collaboration","title":"Collaboration","text":"
"},{"location":"spfx/governance/#overview","title":"Overview","text":"
"},{"location":"spfx/governance/#information-architecture","title":"Information Architecture","text":"
"},{"location":"spfx/governance/#sharepoint-home-site","title":"SharePoint Home Site","text":"
"},{"location":"spfx/governance/#content-type","title":"Content Type","text":"
"},{"location":"spfx/governance/#imagemap","title":"ImageMap","text":"
"},{"location":"spfx/governance/#external-sharing","title":"External Sharing","text":"
"},{"location":"spfx/governance/#organization-asset-libraries","title":"Organization Asset Libraries","text":"
"},{"location":"spfx/governance/#user-profile-delete-user","title":"User profile / Delete user","text":"
"},{"location":"spfx/governance/#external-user","title":"External user","text":"
"},{"location":"spfx/governance/#sitecollections-versus-subsites","title":"SiteCollections versus SubSites","text":"
"},{"location":"spfx/governance/#tips-creating-sites","title":"Tips Creating Sites","text":"
"},{"location":"spfx/governance/#backup","title":"Backup","text":"
"},{"location":"spfx/governance/#auditusage-reports-scripts","title":"Audit/Usage Reports Scripts","text":"
"},{"location":"spfx/governance/#ad-mistakes","title":"AD Mistakes","text":"
"},{"location":"spfx/governance/#handling-teams-and-groups","title":"Handling Teams and Groups","text":"
"},{"location":"spfx/governance/#tips","title":"Tips","text":"
"},{"location":"spfx/governance/#sam","title":"SAM","text":"
"},{"location":"spfx/governance/#security-and-compliance-dlp","title":"Security and Compliance - DLP","text":"
"},{"location":"spfx/governance/#records-management-rm","title":"Records Management (RM)","text":"
"},{"location":"spfx/governance/#practise-german","title":"Practise (German)","text":"
"},{"location":"spfx/governance/#practise-english","title":"Practise (English)","text":"
"},{"location":"spfx/graph/","title":"Microsoft Graph","text":""},{"location":"spfx/graph/#top-links","title":"Top Links","text":"
"},{"location":"spfx/graph/#best-practise","title":"Best Practise","text":"
"},{"location":"spfx/graph/#permission","title":"Permission","text":"
"},{"location":"spfx/graph/#learning","title":"Learning","text":"
"},{"location":"spfx/graph/#working-with-sharepoint","title":"Working with Sharepoint","text":"
"},{"location":"spfx/graph/#query-count-filter-search-orderby","title":"Query (Count / Filter / Search / OrderBy)","text":"
"},{"location":"spfx/graph/#azure-functions","title":"Azure Functions","text":"
"},{"location":"spfx/graph/#samples","title":"Samples","text":"
"},{"location":"spfx/graph/#spfx-samples","title":"SPFx Samples","text":"
"},{"location":"spfx/graph/#microsoft-graph-toolkit-mgt","title":"Microsoft Graph Toolkit (MGT)","text":"
"},{"location":"spfx/graph/#mgt-samples","title":"MGT Samples","text":"
"},{"location":"spfx/graph/#files-handling","title":"Files Handling","text":"
"},{"location":"spfx/graph/#granular-permission","title":"Granular Permission","text":"
"},{"location":"spfx/graph/#graph-developer-proxy","title":"Graph Developer Proxy","text":"
"},{"location":"spfx/groups/","title":"Groups","text":""},{"location":"spfx/groups/#must-read","title":"Must read","text":"
"},{"location":"spfx/groups/#overview","title":"Overview","text":"
"},{"location":"spfx/groups/#provisioning","title":"Provisioning","text":"
"},{"location":"spfx/groups/#tipps","title":"Tipps","text":"
"},{"location":"spfx/groups/#powershell","title":"Powershell","text":"# SiteCollection URL <site>\n<site>/_layouts/15/groupstatus.aspx?Target=PLANNER\n\n# XML Provisioning Engine - SiteCollection Token {site}\n{site}/_layouts/15/groupstatus.aspx?Target=PLANNER\n
Get-UnifiedGroup | Select Id, DisplayName, ManagedBy, Alias, AccessType, WhenCreated, @{Expression={([array](Get-UnifiedGroupLinks -Identity $_.Id -LinkType Members)).Count }; Label=\u2019Members\u2019} | Sort-Object whencreated | Format-Table displayname, alias, managedby, Members, accesstype, whencreated\n
Get-UnifiedGroup | Where-Object {$_.AccessType -eq \u2018Private\u2019} | Sort-Object whencreated | Format-Table displayname, alias, managedby, accesstype, whencreated\n
Get-AzureADMSDeletedGroup | Sort-Object DeletedDateTime -Descending | Format-Table Id, DisplayName, Description, Visibility, DeletedDateTime\n
Get-AzureADMSDeletedGroup -All:$true | Remove-AzureADMSDeletedDirectoryObject\n
$Groups = Get-UnifiedGroup | Where-Object {([array](Get-UnifiedGroupLinks -Identity $_.Id -LinkType Owners)).Count -eq 0} `\n\n| Select Id, DisplayName, ManagedBy, WhenCreated\n\nForEach ($G in $Groups) {\n\nWrite-Host \u201cWarning! The following group has no owner:\u201d $G.DisplayName\n\n}\n
Get-UnifiedGroup |Where-Object {$_.ProvisioningOption -eq \u2018YammerProvisioning\u2019} |select DisplayName,Alias,ProvisioningOption,GroupSKU,SharePointSiteUrl,SharePointDocumentsUrl,AccessType\n
"},{"location":"spfx/hubsite/","title":"HubSite","text":"Get-UnifiedGroup |Where-Object {$_.ProvisioningOption -eq \u2018ExchangeProvisioningFlags:481\u2019}|select DisplayName,Alias,ProvisioningOption,GroupSKU,SharePointSiteUrl,SharePointDocumentsUrl,AccessType\n
"},{"location":"spfx/hubsite/#planning","title":"Planning","text":"
"},{"location":"spfx/hubsite/#integration","title":"Integration","text":"
"},{"location":"spfx/hubsite/#navigation","title":"Navigation","text":"
"},{"location":"spfx/hubsite/#tips","title":"Tips","text":"
"},{"location":"spfx/hubsite/#csom","title":"CSOM","text":"cls\n\n$tenantAdmin = \"https://contoso-admin.sharepoint.com\"\n$hubSite = \"https://contoso.sharepoint.com/sites/hub\"\n$extensionGUID = \"6da1a9e8-471d-4f39-80e6-a7ded02e8881\"\n$extensionName = \"Extension Name\"\n$extensionTitle = \"Extension Title\"\n\ntry\n{\nConnect-PnPOnline -Url $tenantAdmin -UseWebLogin\n} catch {\nWrite-Host \"Unable to connect.\"\nexit\n}\n\n$HubSite = Get-PnPHubSite $hubSite\n$HubSiteId = $HubSite.SiteId\n$ModernSites = (Get-PnPTenantSite -Template 'GROUP#0') + (Get-PnPTenantSite -Template 'SITEPAGEPUBLISHING#0')\n$SitesFromHub = New-Object System.Collections.ArrayList\n\nWrite-Host (\"Searching {0} sites:\" -f $HubSite.Title) -BackgroundColor Gray\nforeach ($ModernSite in $ModernSites){\n $site = Get-PnPHubSite $ModernSite.Url\n if($site.SiteUrl){\n if($site.SiteId -eq $HubSiteId){\n Write-Host (\"* {0} - {1}\" -f $ModernSite.Title, $ModernSite.Url)\n $SitesFromHub.Add($ModernSite) | Out-Null\n }\n }\n}\n\nWrite-Host \"\"\nWrite-Host \"Installing at:\" -BackgroundColor Gray\nforeach ($SiteHub in $SitesFromHub){\n Write-Host (\"* {0} - {1} ... \" -f $SiteHub.Title, $SiteHub.Url) -NoNewline\n Connect-PnPOnline -Url $SiteHub.Url -UseWebLogin\n Add-PnPCustomAction -ClientSideComponentId $extensionGUID -Name $extensionName -Title $extensionTitle -Location ClientSideExtension.ApplicationCustomizer -Scope site\n Write-Host \"Done\" -BackgroundColor Green\n Disconnect-PnPOnline\n}\n\nWrite-Host \"All Done\"\n
"},{"location":"spfx/hubsite/#search-api","title":"Search API","text":"
"},{"location":"spfx/intranet/","title":"Intranet","text":""},{"location":"spfx/intranet/#homepage","title":"Homepage","text":" # List all sites being a hub site or associate to a hub site\n$results = Submit-PnPSearchQuery -Query 'contentclass=sts_site' -RefinementFilters 'departmentid:string(\"{*\",linguistics=off)' -TrimDuplicates $false -SelectProperties @(\"Title\",\"Path\",\"DepartmentId\",\"SiteId\") -All -RelevantResults\n\n# Filter out the hub sites\n$hubSites = $results |? { $_.DepartmentId.Trim('{','}') -eq $_.SiteId }\n\n# Loop over the hub sites\nforeach( $hub in $hubSites ) {\n Write-Host $hub.Title - $hub.Path -ForegroundColor Green\n # Filter out sites associated to the current hub\n $associatedSites = ($results |? { $_.DepartmentId -eq $hub.DepartmentId -and $_.SiteId -ne $hub.SiteId })\n foreach($site in $associatedSites) {\n Write-Host \"`t\"$site.Title - $site.Path -ForegroundColor Yellow\n }\n}\n
"},{"location":"spfx/js/","title":"JS","text":""},{"location":"spfx/js/#frameworks","title":"Frameworks","text":"
"},{"location":"spfx/js/#common-cheatsheets","title":"Common Cheatsheets","text":"
"},{"location":"spfx/js/#es6","title":"ES6","text":"
"},{"location":"spfx/js/#interview-questions","title":"Interview Questions","text":"
"},{"location":"spfx/js/#helper","title":"Helper","text":""},{"location":"spfx/js/#local-storage","title":"Local Storage","text":"
"},{"location":"spfx/libraries/","title":"Libraries Components","text":""},{"location":"spfx/libraries/#intro","title":"Intro","text":"
"},{"location":"spfx/libraries/#service-locator-pattern","title":"Service Locator pattern","text":"
"},{"location":"spfx/libraries/#tips","title":"Tips","text":"
"},{"location":"spfx/libraries/#samples","title":"Samples","text":"
"},{"location":"spfx/listitem/","title":"Listitem","text":""},{"location":"spfx/listitem/#system-upddate","title":"System Upddate","text":"
"},{"location":"spfx/listitem/#managing-lists","title":"Managing Lists","text":"
"},{"location":"spfx/listitem/#audience-targeting","title":"Audience Targeting","text":"
"},{"location":"spfx/logging/","title":"Logging","text":""},{"location":"spfx/logging/#logging-with-sp-core-library","title":"Logging with sp-core-library","text":"
import { Log } from \"@microsoft/sp-core-library\";\n
"},{"location":"spfx/logging/#logging-with-pnp-logging","title":"Logging with pnp-logging","text":"Log.verbose(\"HelloWorld\", \"Here is a verbose log\", this.context.serviceScope);\nLog.info(\"HelloWorld\", \"Here is an informational message.\", this.context.serviceScope);\nLog.warn(\"HelloWorld\", \"Oh Oh, this might be bad\", this.context.serviceScope);\nLog.error(\"HelloWorld\", new Error(\"Oh No! Error! Ahhhhhh!!!!\"), this.context.serviceScope);\n
"},{"location":"spfx/logging/#logging-with-appinsights","title":"Logging with AppInsights","text":"
"},{"location":"spfx/metadata/","title":"Metadata","text":""},{"location":"spfx/metadata/#colums","title":"Colums","text":"
"},{"location":"spfx/metadata/#design","title":"Design","text":"
"},{"location":"spfx/metadata/#journal","title":"Journal","text":"
"},{"location":"spfx/migration/","title":"Migration","text":""},{"location":"spfx/migration/#overview","title":"Overview","text":"
"},{"location":"spfx/migration/#good-to-know","title":"Good to know","text":"
"},{"location":"spfx/migration/#sharegate","title":"ShareGate","text":"
"},{"location":"spfx/migration/#sharepoint-migration-tool-spmt","title":"SharePoint Migration Tool (SPMT)","text":"
"},{"location":"spfx/migration/#mover","title":"Mover","text":"
"},{"location":"spfx/migration/#sharepoint-manager","title":"SharePoint Manager","text":"
"},{"location":"spfx/migration/#documentid","title":"DocumentID","text":"
"},{"location":"spfx/migration/#permission","title":"Permission","text":"
"},{"location":"spfx/migration/#wsp-repackage","title":"WSP Repackage","text":"
"},{"location":"spfx/migration/#tipps","title":"Tipps","text":"
"},{"location":"spfx/migration/#showcase","title":"Showcase","text":"
"},{"location":"spfx/migration/#google-drive","title":"Google Drive","text":"
"},{"location":"spfx/migration/#tenant-to-teanant","title":"Tenant to Teanant","text":"
"},{"location":"spfx/migration/#migration-streams-classic","title":"Migration Streams (Classic)","text":"
"},{"location":"spfx/modernpage/","title":"Modern page","text":""},{"location":"spfx/modernpage/#news-pages","title":"News pages","text":"
"},{"location":"spfx/modernpage/#news-digest","title":"News digest","text":"/_api/search/query?querytext='IsDocument:True AND FileExtension:aspx AND PromotedState:2'\n
"},{"location":"spfx/mui/","title":"MUI","text":""},{"location":"spfx/mui/#multilingual-pages","title":"Multilingual Pages","text":"
"},{"location":"spfx/mui/#localisation-of-the-user-interface","title":"Localisation of the user interface","text":"
"},{"location":"spfx/mui/#definition-multilingual-intranet","title":"Definition Multilingual Intranet","text":"
"},{"location":"spfx/mui/#samples","title":"Samples","text":"PromotedState:2 AND (SPTranslationLanguage:{CurrentDisplayLanguage} OR (NOT SPTranslatedLanguages:{CurrentDisplayLanguage} AND NOT SPIsTranslation:true))\n
"},{"location":"spfx/network/","title":"Network","text":"
"},{"location":"spfx/network/#dns-basics","title":"DNS-Basics","text":"
"},{"location":"spfx/network/#tools","title":"Tools","text":"
"},{"location":"spfx/network/#it-pro","title":"IT Pro","text":"
"},{"location":"spfx/network/#ssl","title":"SSL","text":"
"},{"location":"spfx/onedrive/","title":"OneDrive","text":""},{"location":"spfx/onedrive/#pre-provision","title":"Pre Provision","text":"
"},{"location":"spfx/onedrive/#sync","title":"Sync","text":"
"},{"location":"spfx/onedrive/#support","title":"Support","text":"
"},{"location":"spfx/patterns/","title":"Patterns","text":""},{"location":"spfx/patterns/#dependency-injection","title":"Dependency Injection","text":"
"},{"location":"spfx/patterns/#slides","title":"Slides","text":"
"},{"location":"spfx/planner/","title":"Planner","text":""},{"location":"spfx/planner/#planer-api","title":"Planer API","text":"
"},{"location":"spfx/planner/#support","title":"Support","text":"
"},{"location":"spfx/planner/#creating-planner","title":"Creating Planner","text":"
"},{"location":"spfx/planner/#powershell-module","title":"Powershell Module","text":"
"},{"location":"spfx/planner/#reports","title":"Reports","text":"
"},{"location":"spfx/planner/#blogs","title":"Blogs","text":"
"},{"location":"spfx/planner/#video","title":"Video","text":"
"},{"location":"spfx/planner/#planner-architecture","title":"Planner Architecture","text":""},{"location":"spfx/planner/#tips","title":"Tips","text":"
"},{"location":"spfx/planner/#tools-frameworks","title":"Tools / Frameworks","text":"
"},{"location":"spfx/provisioning/","title":"Provisioning","text":""},{"location":"spfx/provisioning/#reference","title":"Reference","text":"
"},{"location":"spfx/provisioning/#pnp-provisining-template","title":"PnP-Provisining Template","text":"
"},{"location":"spfx/provisioning/#custom-list-template","title":"Custom List Template","text":"
"},{"location":"spfx/provisioning/#site-templateid","title":"Site TemplateId","text":"
"},{"location":"spfx/provisioning/#fields","title":"Fields","text":"
"},{"location":"spfx/provisioning/#app-bar","title":"App Bar","text":"
"},{"location":"spfx/provisioning/#links","title":"Links","text":"
"},{"location":"spfx/provisioning/#export-multiple-pages","title":"Export multiple pages","text":"
"},{"location":"spfx/provisioning/#convert-pnp-files","title":"Convert PnP Files","text":"
"},{"location":"spfx/provisioning/#create-page-templates","title":"Create Page-Templates","text":"
"},{"location":"spfx/provisioning/#flow-azure-function","title":"Flow / Azure Function","text":"
"},{"location":"spfx/provisioning/#onedrive-for-business","title":"OneDrive for Business","text":"
"},{"location":"spfx/provisioning/#tools","title":"Tools","text":"
"},{"location":"spfx/provisioning/#logic-app-azure-queue","title":"Logic App & Azure Queue","text":"
"},{"location":"spfx/provisioning/#find-empty-general-folder","title":"Find Empty General Folder","text":"
"},{"location":"spfx/recipes/","title":"Recipes","text":""},{"location":"spfx/recipes/#timezones","title":"Timezones","text":"
"},{"location":"spfx/rest/","title":"REST","text":""},{"location":"spfx/rest/#reference","title":"Reference","text":"
"},{"location":"spfx/rest/#api-guidlines","title":"API Guidlines","text":"
"},{"location":"spfx/rest/#tools","title":"Tools","text":"
"},{"location":"spfx/rest/#postman","title":"Postman","text":"
"},{"location":"spfx/rest/#testing","title":"Testing","text":"
"},{"location":"spfx/search/","title":"Search","text":"fetch(`/sites/gridworks/_api/web/lists/getbytitle('SiteRequestsQueue')/items?$select=Id,Title,gwRequestSiteAlias&$orderby=Id desc`, {\nheaders: {\nAccept: 'application/json;odata=verbose;'\n}\n}).then(res => res.json().then(json => {\njson.d.results.forEach(item => {\nconsole.log(`item: ${item.Title}`);\n});\n}));\n
"},{"location":"spfx/search/#tools","title":"Tools","text":"
"},{"location":"spfx/search/#custom-search-result-page","title":"Custom Search Result Page","text":"
"},{"location":"spfx/search/#pnp-modern-search","title":"PnP Modern Search","text":"
"},{"location":"spfx/search/#microsoft-search","title":"Microsoft Search","text":"
"},{"location":"spfx/search/#search-tips","title":"Search Tips","text":"
"},{"location":"spfx/search/#managed-properties","title":"Managed Properties","text":"
"},{"location":"spfx/search/#keyword-query-language-kql-syntax-reference","title":"Keyword Query Language (KQL) syntax reference","text":"
"},{"location":"spfx/search/#crawl-logs","title":"Crawl Logs","text":"
"},{"location":"spfx/search/#reindex","title":"Reindex","text":"
"},{"location":"spfx/search/#content-source","title":"Content Source","text":""},{"location":"spfx/search/#onenote","title":"OneNote","text":"
"},{"location":"spfx/search/#documentid","title":"DocumentID","text":"
"},{"location":"spfx/search/#ranking","title":"Ranking","text":"
"},{"location":"spfx/search/#fileshare","title":"FileShare","text":"
"},{"location":"spfx/search/#teamsites-groups","title":"Teamsites / Groups","text":"
"},{"location":"spfx/search/#search-hubsite","title":"Search HubSite","text":"
"},{"location":"spfx/search/#search-empty-terms-fields","title":"Search Empty Terms Fields","text":"
"},{"location":"spfx/search/#sharing-link","title":"Sharing Link","text":"
"},{"location":"spfx/search/#only-office-files","title":"Only Office Files","text":" # Managed Properties: SharedWithUsersOWSUSER, SharedWithDetails\n {SearchTerms} contentclass:STS_ListItem_DocumentLibrary IsContainer<>true SharedWithUsersOWSUSER=0\n
"},{"location":"spfx/search/#search-query-filter","title":"Search Query Filter","text":"{SearchTerms} ((FileExtension:mp4 OR FileExtension:doc OR FileExtension:docx OR FileExtension:xls OR FileExtension:xlsx OR FileExtension:ppt OR FileExtension:pptx OR FileExtension:pdf) AND (IsDocument:\"True\" OR contentclass:\"STS_ListItem\")) OR ContentType=\"Folder\"\n
"},{"location":"spfx/search/#news-2021","title":"News 2021","text":"
"},{"location":"spfx/search/#news-2020","title":"News 2020","text":"
"},{"location":"spfx/sitedesign/","title":"SiteDesign","text":""},{"location":"spfx/sitedesign/#best-practise","title":"Best practise","text":"
"},{"location":"spfx/sitedesign/#list-templates","title":"List templates","text":"
"},{"location":"spfx/sitedesign/#modern-site-provisioning","title":"Modern Site Provisioning","text":"
"},{"location":"spfx/sitedesign/#deploying","title":"Deploying","text":"
"},{"location":"spfx/sitedesign/#flow-rest","title":"Flow / REST","text":"
"},{"location":"spfx/sitedesign/#reports","title":"Reports","text":"Get-SPOSite -Limit All | ForEach-Object { \n $failedRuns = Get-SPOSiteDesignRun $_.Url | Get-SPOSiteDesignRunStatus | Where-Object {$_.OutcomeCode -ne \"Success\"};\n\n if($failedRuns) {\n Write-Output $_.Url\n $failedRuns\n }\n}\n
"},{"location":"spfx/sitedesign/#tips","title":"Tips","text":"Get-SPOSite -Limit All | ForEach-Object { \n $failedRuns = Get-SPOSiteDesignRun $_.Url | Get-SPOSiteDesignRunStatus | Where-Object {$_.OutcomeCode -eq \"Faulure\"};\n\n if($failedRuns) {\n Write-Output $_.Url\n $failedRuns\n }\n}\n
(Get-SPOSiteDesign | Measure).Count\n
(Get-SPOSiteScript | Measure).Count\n
Remove-SPOSiteDesign -Identity $siteDesignId\n
Remove-SPOSiteScript -Identity $siteScriptId\n\nDelete all Site Designs or Site Scripts at once:\n\n```Powershell\nGet-SPOSiteDesign | foreach { Remove-SPOSiteDesign -Identity $_.Id }\n
"},{"location":"spfx/sitescripts/","title":"SiteScripts","text":"Get-SPOSiteScript | foreach { Remove-SPOSiteScript -Identity $_.Id }\n
"},{"location":"spfx/sitescripts/#pnp-or-site-scripts","title":"PnP or site scripts","text":"
"},{"location":"spfx/sitescripts/#reference","title":"Reference","text":"
"},{"location":"spfx/sitescripts/#tools","title":"Tools","text":"
"},{"location":"spfx/sitescripts/#samples","title":"Samples","text":"
"},{"location":"spfx/sitescripts/#fields","title":"Fields","text":"
"},{"location":"spfx/snippets/","title":"Code Snippets","text":""},{"location":"spfx/snippets/#tips-and-tricks","title":"Tips and Tricks","text":"
"},{"location":"spfx/snippets/#check-url","title":"Check URL","text":"
"},{"location":"spfx/snippets/#pnp-js-core","title":"PNP JS-Core","text":""},{"location":"spfx/snippets/#list-permission","title":"List Permission","text":"import { UrlQueryParameterCollection } from '@microsoft/sp-core-library';\n\nif (queryParameters.getValue('id')) {\nid = parseInt(queryParameters.getValue('id'));\n}\n
"},{"location":"spfx/snippets/#admin-user","title":"Admin User","text":"private _checkProductsPermissions(productsList){\nreturn pnp.sp.web.lists.getByTitle(productsList).getCurrentUserEffectivePermissions()\n.then(perms => {\nlet canEdit = pnp.sp.web.lists.getByTitle(productsList).hasPermissions(perms, PermissionKind.EditListItems);\nlet canView = pnp.sp.web.lists.getByTitle(productsList).hasPermissions(perms, PermissionKind.ViewListItems);\nif(canEdit){\nreturn 'Edit';\n} else if(canView){\nreturn 'View';\n} else {\nreturn 'None';\n}\n})\n.catch((err) => {\nconsole.log('error:', err);\nreturn 'None';\n});\n}\n
"},{"location":"spfx/sp2016/","title":"SP2016","text":""},{"location":"spfx/sp2016/#lifecycle","title":"Lifecycle","text":"// Ensure a user on site collection\nsp.web.ensureUser('john.doe@contoso.onmicrosoft.com').then(console.log);\n\n// Get site collection admins\nsp.web.siteUsers.filter(`IsSiteAdmin eq true`)\n.get().then(console.log);\n\n// Remove a user from site collection admins\nsp.web.siteUsers.getByLoginName('i:0#.f|membership|john.doe@contoso.onmicrosoft.com')\n.update({ IsSiteAdmin: false }).then(console.log);\n\n// Add a user to site collection admins\nsp.web.siteUsers.getByLoginName('i:0#.f|membership|john.doe@contoso.onmicrosoft.com')\n.update({ IsSiteAdmin: true }).then(console.log);\n
"},{"location":"spfx/sp2016/#overview-facts","title":"Overview Facts","text":"
"},{"location":"spfx/sp2016/#setup-development","title":"Setup Development","text":"
"},{"location":"spfx/sp2016/#developmentlocal-workbench","title":"Development(local workbench)","text":"gulp serve\n
"},{"location":"spfx/sp2016/#developmentonline-workbench","title":"Development(online workbench)","text":"https://localhost:4321/temp/workbench.html\n
gulp serve --nobrowser\n
"},{"location":"spfx/sp2016/#deployment","title":"Deployment","text":"/_layouts/15/workbench.aspx\n
gulp clean\n
gulp build --ship\n
gulp bundle --ship\n
"},{"location":"spfx/sp2016/#troubleshooting","title":"Troubleshooting","text":"gulp package-solution --ship\n
"},{"location":"spfx/sp2016/#check-package-version","title":"Check Package Version","text":"
"},{"location":"spfx/sp2016/#react","title":"React","text":"node \u2013v\nnpm \u2013v\nyo --generators\ngulp \u2013v\ntsc \u2013v\ntsd --version\n
"},{"location":"spfx/sp2016/#ie-support","title":"IE Support","text":"
"},{"location":"spfx/sp2019/","title":"SP2019","text":""},{"location":"spfx/sp2019/#setup-development","title":"Setup Development","text":"
"},{"location":"spfx/sp2019/#new-features","title":"New Features","text":"
"},{"location":"spfx/sp2019/#installation","title":"Installation","text":"
"},{"location":"spfx/sp2019/#upgrade","title":"Upgrade","text":"
"},{"location":"spfx/sp2019/#webparts","title":"WebParts","text":"
"},{"location":"spfx/sp2019/#hybrid","title":"Hybrid","text":"
"},{"location":"spfx/sp2019/#configure-cloud-hybrid-search","title":"Configure cloud hybrid search","text":"
"},{"location":"spfx/sp2019/#applauncher","title":"AppLauncher","text":"
"},{"location":"spfx/sp2019/#not-so-good","title":"Not so good","text":"
"},{"location":"spfx/sp2019/#wsa-customer-experience-improvement-program","title":"WSA - Customer Experience Improvement Program","text":"
"},{"location":"spfx/sp2019/#content-script-webpart-typescript","title":"Content Script WebPart (TypeScript)","text":"
"},{"location":"spfx/sp2019/#custom-action","title":"Custom Action","text":"
"},{"location":"spfx/sp2019/#certificates","title":"Certificates","text":"
"},{"location":"spfx/sp2019/#code-tips","title":"Code Tips","text":"
"},{"location":"spfx/sp2019/#architecture-online-sql-onprem","title":"Architecture Online - SQL OnPrem","text":"
"},{"location":"spfx/spaces/","title":"Spaces","text":""},{"location":"spfx/spaces/#intro","title":"Intro","text":"
"},{"location":"spfx/spaces/#pnp-template","title":"PnP-Template","text":"
"},{"location":"spfx/start/","title":"Dev Start","text":""},{"location":"spfx/start/#history-of-sharepoint","title":"History of SharePoint","text":"
"},{"location":"spfx/start/#development-starting","title":"Development starting","text":"
"},{"location":"spfx/starterkit/","title":"Starter Kid","text":""},{"location":"spfx/starterkit/#github","title":"GitHub","text":"
"},{"location":"spfx/starterkit/#tipps","title":"Tipps","text":"
"},{"location":"spfx/starterkit/#performance","title":"Performance","text":"
"},{"location":"spfx/starterkit/#extension","title":"Extension","text":"
"},{"location":"spfx/starterkit/#webpart","title":"WebPart","text":"
"},{"location":"spfx/stream/","title":"Stream","text":""},{"location":"spfx/stream/#links","title":"Links","text":"
"},{"location":"spfx/support/#content-video","title":"Content & Video","text":"
"},{"location":"spfx/support/#troubleshoot","title":"Troubleshoot","text":"
"},{"location":"spfx/support/#sharepoint-documentation","title":"SharePoint Documentation","text":"
"},{"location":"spfx/support/#licence-changes","title":"Licence Changes","text":"
"},{"location":"spfx/support/#partner-secure-application-model","title":"Partner Secure Application Model","text":"
"},{"location":"spfx/support/#sharepoint-spo","title":"SharePoint SPO","text":"
"},{"location":"spfx/support/#storage-limits","title":"Storage Limits","text":"
"},{"location":"spfx/support/#admin-o365","title":"Admin O365","text":"
"},{"location":"spfx/support/#azure-error-codes","title":"Azure Error Codes","text":"
"},{"location":"spfx/support/#spo","title":"SPO","text":"
"},{"location":"spfx/support/#guest-users","title":"Guest Users","text":"
"},{"location":"spfx/support/#external-access","title":"External Access","text":"
"},{"location":"spfx/support/#diagnostics","title":"Diagnostics","text":"
"},{"location":"spfx/support/#performance","title":"Performance","text":"
"},{"location":"spfx/support/#webparts","title":"WebParts","text":"
?maintenancemode=true\n
?disable3PCode=1\n
?disableTelemetry=true\n
?forceLocale=fr-fr\n
?cacheClear=true\n
?env=Embedded is the new ?isDlg=1 \n
?env=WebViewList\n
?Embed=true&sw=bypass\n```html\n\nFilter URL\n\n- [Generate Modern List Filter URL: Managed Metadata](https://piyushksingh.com/2019/05/24/generate-modern-list-filter-url-managed-metadata/)\n- [How to filter a SharePoint list or library using URL parameters](https://natechamberlain.com/2020/05/09/how-to-filter-a-sharepoint-list-or-library-using-url-parameters/)\n\n\nNews Links\n\n- [Edit news links](https://emilymancini.com/2020/01/16/editing-a-news-link-in-sharepoint-online/)\n\nto clear (debug) configs\n\n```html\n?stay=true\n
"},{"location":"spfx/support/#lists","title":"Lists","text":"?test429=true\n
"},{"location":"spfx/support/#create-documentation","title":"Create Documentation","text":"
"},{"location":"spfx/support/#login-error","title":"Login Error","text":"
"},{"location":"spfx/support/#throttling","title":"Throttling","text":"edge://settings/siteData?search=cookie\n
"},{"location":"spfx/support/#graph-api-errors-429","title":"Graph API Errors 429","text":"
"},{"location":"spfx/support/#tips","title":"Tips","text":"
"},{"location":"spfx/support/#invalid-file-names-and-types","title":"Invalid File Names and Types","text":"
"},{"location":"spfx/support/#no-scripts-embedding-scripts","title":"No-Scripts / embedding-scripts","text":"
"},{"location":"spfx/support/#followed-sites","title":"Followed Sites","text":"
"},{"location":"spfx/support/#o365-network-planning","title":"O365 Network planning","text":"
"},{"location":"spfx/support/#clean-o365","title":"Clean O365","text":"
"},{"location":"spfx/support/#classic-features","title":"Classic Features","text":"
"},{"location":"spfx/support/#webdav","title":"WebDAV","text":"
"},{"location":"spfx/support/#makros-vba","title":"Makros /VBA","text":"
"},{"location":"spfx/support/#sway","title":"Sway","text":"
"},{"location":"spfx/teams-adoption/","title":"Teams Adoption","text":""},{"location":"spfx/teams-adoption/#learning","title":"Learning","text":"
"},{"location":"spfx/teams-adoption/#blog","title":"Blog","text":"
"},{"location":"spfx/teams-adoption/#material","title":"Material","text":"
"},{"location":"spfx/teams/","title":"Teams","text":"
"},{"location":"spfx/teams/#start-developing","title":"Start Developing","text":"
"},{"location":"spfx/teams/#support","title":"Support","text":"
"},{"location":"spfx/teams/#overview","title":"Overview","text":"
"},{"location":"spfx/teams/#planing","title":"Planing","text":"
"},{"location":"spfx/teams/#training-video","title":"Training video","text":"
"},{"location":"spfx/teams/#developing","title":"Developing","text":"
"},{"location":"spfx/teams/#coding","title":"Coding","text":"
"},{"location":"spfx/teams/#azure-app-configuration","title":"Azure App Configuration","text":"
"},{"location":"spfx/teams/#personal-app-properties","title":"Personal App Properties","text":"
"},{"location":"spfx/teams/#deployment","title":"Deployment","text":"
"},{"location":"spfx/teams/#teams-toolkit-visual-studio-code","title":"Teams Toolkit Visual Studio Code","text":""},{"location":"spfx/teams/#message-extensions","title":"Message Extensions","text":"
"},{"location":"spfx/teams/#personal-apps","title":"Personal Apps","text":"
"},{"location":"spfx/teams/#administration","title":"Administration","text":"
"},{"location":"spfx/teams/#teams-adviser","title":"Teams Adviser","text":"
"},{"location":"spfx/teams/#microsoft-teams-versus-sharepoint-teams","title":"Microsoft Teams versus Sharepoint Teams","text":"
"},{"location":"spfx/teams/#private-channels","title":"Private Channels","text":"
"},{"location":"spfx/teams/#deep-links","title":"Deep Links","text":"
"},{"location":"spfx/teams/#tipps","title":"Tipps","text":"
"},{"location":"spfx/teams/#querys-reports","title":"Querys / Reports","text":"
"},{"location":"spfx/teams/#blogs","title":"Blogs","text":"https://graph.microsoft.com/beta/groups?$filter=resourceProvisioningOptions/Any(x:x eq 'Team')\n
"},{"location":"spfx/teams/#governance-with-teams","title":"Governance with teams","text":"
"},{"location":"spfx/teams/#governance-tools","title":"Governance Tools","text":"
"},{"location":"spfx/teams/#securing-teams","title":"Securing Teams","text":"
"},{"location":"spfx/teams/#devops","title":"DevOps","text":"
"},{"location":"spfx/teams/#provisioning-with-template","title":"Provisioning with Template","text":"
"},{"location":"spfx/teams/#renaming-teams","title":"Renaming Teams","text":"
"},{"location":"spfx/teams/#teams-for-education","title":"Teams for Education","text":"
"},{"location":"spfx/teams/#presenting-in-teams","title":"Presenting in Teams","text":"
"},{"location":"spfx/teams/#dataverse","title":"Dataverse","text":"
"},{"location":"spfx/testing/","title":"Testing","text":""},{"location":"spfx/testing/#typescript-testing","title":"TypeScript Testing","text":"
"},{"location":"spfx/testing/#toolchain-setup","title":"Toolchain Setup","text":"
"},{"location":"spfx/testing/#playwright","title":"Playwright","text":"
"},{"location":"spfx/testing/#jest","title":"Jest","text":"
"},{"location":"spfx/testing/#testing-hooks","title":"Testing Hooks","text":"
"},{"location":"spfx/testing/#samples","title":"Samples","text":"
"},{"location":"spfx/testing/#tdd","title":"TDD","text":"
"},{"location":"spfx/testing/#generate-test-data","title":"Generate test data","text":"
"},{"location":"spfx/testing/#frontend-testing-witd-playwright","title":"Frontend Testing witd Playwright","text":"
"},{"location":"spfx/theme/","title":"Theme","text":"
"},{"location":"spfx/theme/#get-theme","title":"Get Theme","text":"
"},{"location":"spfx/theme/#section-backgrounds","title":"Section Backgrounds","text":"$t = Get-PnPTenantTheme -Name \"Contoso Team Theme\"\n$t.Palette | ConvertTo-Json | Clip\n
"},{"location":"spfx/theme/#office-fabric-tips","title":"Office Fabric Tips","text":"
"},{"location":"spfx/theme/#responsive-tips","title":"Responsive Tips","text":"
"},{"location":"spfx/theme/#css-tips","title":"CSS Tips","text":"
"},{"location":"spfx/theme/#flexbox","title":"Flexbox","text":"
"},{"location":"spfx/theme/#css-box-model","title":"CSS Box Model","text":"
"},{"location":"spfx/theme/#css-specification","title":"CSS Specification","text":"
"},{"location":"spfx/theme/#tools","title":"Tools","text":"
"},{"location":"spfx/theme/#testing","title":"Testing","text":"
"},{"location":"spfx/theme/#debug","title":"Debug","text":""},{"location":"spfx/theme/#output-theme-variables","title":"Output theme variables","text":"
var palette = window.__themeState__.theme;\nvar containerElement = document.createElement(\"div\");\ncontainerElement.style.padding = \"1em\";\ncontainerElement.style.fontFamily = \"sans-serif\";\ncontainerElement.style.columnCount = \"3\";\ndocument.body.appendChild(containerElement);\nvar arr = Object.keys(palette).map(k => {\nvar colorElement =document.createElement(\"div\");\ncolorElement.style.marginTop = \"1ex\";\nvar nameElement =document.createElement(\"span\");\nnameElement.style.display = \"inline-block\";\nnameElement.style.minWidth= \"150px\";\nnameElement.innerHTML = k\ncolorElement.appendChild(nameElement );\nvar squareElement = document.createElement(\"span\");\nsquareElement.style.display= \"inline-block\";\nsquareElement.style.border= \"solid 1px #888\";\nsquareElement.style.width = \"12px\";\nsquareElement.style.height = \"12px\";\nsquareElement.style.margin = \"0 2px 0 1ex\";\nsquareElement.style.backgroundColor = window.__themeState__.theme[k];\ncolorElement.appendChild(squareElement);\nvar hexElement =document.createElement(\"span\");\nhexElement.innerHTML = window.__themeState__.theme[k];\ncolorElement.appendChild(hexElement);\ncontainerElement.appendChild(colorElement);\n});\n
"},{"location":"spfx/toolchain/","title":"Toolchain","text":"window.spModuleLoader._bundledComponents[\"b6917cb1-93a0-4b97-a84d-7cf49975d4ec\"].PageManager._instance.pageContext.legacyPageContext\n
"},{"location":"spfx/toolchain/#overview","title":"Overview","text":"
"},{"location":"spfx/toolchain/#from-classic-to-modern","title":"From classic to modern","text":"
"},{"location":"spfx/toolchain/#webpack","title":"Webpack","text":"
"},{"location":"spfx/toolchain/#prepare","title":"Prepare","text":"
"},{"location":"spfx/toolchain/#commands","title":"Commands","text":"
"},{"location":"spfx/toolchain/#gulp","title":"Gulp","text":"
"},{"location":"spfx/toolchain/#gulp-dist","title":"gulp dist","text":"
npm install gulp-sequence --save-dev\n
"},{"location":"spfx/toolchain/#deployment","title":"Deployment","text":"if (process.argv.indexOf('dist') !== -1){\nprocess.argv.push('--ship');\n}\n\nconst gulpSequence = require('gulp-sequence');\n\ngulp.task('dist', gulpSequence('clean', 'bundle', 'package-solution'));\n
"},{"location":"spfx/toolchain/#npm","title":"NPM","text":""},{"location":"spfx/toolchain/#package-lockjson","title":"package-lock.json","text":"
"},{"location":"spfx/toolchain/#optimization-packages","title":"Optimization packages","text":"
"},{"location":"spfx/toolchain/#update-packages","title":"Update packages","text":"
"},{"location":"spfx/toolchain/#check-package-version","title":"Check package version","text":"# check\nnpm outdated -g\n\n# install\nnpm -g i npm-check\n\n# interactive update of global packages\nnpm-check -u -g\n\n# interactive update for a project you are working on\nnpm-check -u\n\n# unistall package\nnpm uninstall -g <module>\n
npm list -g --depth 0\n
"},{"location":"spfx/toolchain/#pnpm","title":"PNPM","text":"npm view @microsoft/generator-sharepoint\n
"},{"location":"spfx/toolchain/#packagejson","title":"Package.json","text":"
"},{"location":"spfx/toolchain/#security","title":"Security","text":"
"},{"location":"spfx/toolchain/#installation","title":"Installation","text":"
"},{"location":"spfx/toolchain/#update-spfx-version","title":"Update SPFx version","text":"
npm outdated\n
npm install package-name@latest --save\n
npm install package-name@version --save\n
gulp clean\n
"},{"location":"spfx/toolchain/#test","title":"Test","text":"gulp build\n
"},{"location":"spfx/toolchain/#tips","title":"Tips","text":"gulp serve --nobrowser\n
"},{"location":"spfx/toolchain/#deployment_1","title":"Deployment","text":"
"},{"location":"spfx/toolchain/#dependencies","title":"Dependencies","text":"npm i\ngulp clean\ngulp build\ngulp --ship\ngulp package-solution --ship\n
"},{"location":"spfx/toolchain/#version-manger-nvm-npx","title":"Version Manger (nvm, npx)","text":"npm install saves any specified packages into dependencies by default. Additionally, you can control where and how they get saved with some additional flags:\n\n-P, --save-prod: Package will appear in your dependencies. This is the default unless -D or -O are present.\n\n-D, --save-dev: Package will appear in your devDependencies.\n\n-O, --save-optional: Package will appear in your optionalDependencies.\n
"},{"location":"spfx/typescript/","title":"Typescript","text":""},{"location":"spfx/typescript/#reference","title":"Reference","text":"// check version\nnode --version\n\n// list installed versions of node (via nvm)\nnvm ls\n\n// To list available remote versions on Windows 10 you can type\nnvm list available\n\n// install a specific version of node\nnvm install 10.22.1\nnvm install 8.17.0\n\nnvm list\n\n// switch version of node\nnvm use 10.22.1\n\n# for spfx deployment\n\nnpm i -g gulp\nnpm i -g yo\nnpm i -g @microsoft/generator-sharepoint\ngulp trust-dev-cert\n\n# for spfx advanced\nnpm i -g @pnp/office365-cli\nnpm i -g spfx-fast-serve\nnpm i -g @pnp/generator-spfx\nnpm i -g npm-check\n
"},{"location":"spfx/typescript/#typescript-version-for-spfx","title":"Typescript Version for SPFx","text":"
"},{"location":"spfx/typescript/#tutorial","title":"Tutorial","text":"
"},{"location":"spfx/typescript/#library","title":"Library","text":"
"},{"location":"spfx/typescript/#typings","title":"Typings","text":"
"},{"location":"spfx/typescript/#code-snippets","title":"Code Snippets","text":""},{"location":"spfx/typescript/#isemptystring","title":"isEmptyString","text":"
"},{"location":"spfx/typescript/#_isnull","title":"_isNull","text":"/**\n * Check if the value is null, undefined or empty\n *\n * @param value\n */\nprivate _isEmptyString(value: string): boolean {\nreturn value === null || typeof value === \"undefined\" || !value.length;\n}\n
"},{"location":"spfx/upgrade/","title":"Upgrade","text":""},{"location":"spfx/upgrade/#office-365-cli","title":"Office 365 CLI","text":"/**\n * Check if the value is null or undefined\n *\n * @param value\n */\nprivate _isNull(value: any): boolean {\nreturn value === null || typeof value === \"undefined\";\n}\n
"},{"location":"spfx/upgrade/#update-framework","title":"Update Framework","text":"
npm outdated\n
ornpm install package-name@version --save\n
npm install package-name@latest --save\n
gulp clean\ngulp build\n
"},{"location":"spfx/upgrade/#support-issues","title":"Support Issues","text":""},{"location":"spfx/upgrade/#azure-permission","title":"Azure Permission","text":"bs - Go to the \"API Management\"-section in the SharePoint Preview Admin Center (https://TENANT-admin.sharepoint.com/_layouts/15/online/AdminHome.aspx#/webApiPermissionManagement) - Ensure that no permissions are there anymore - Head over to the App Registrations Page in the Azure Portal. - Click \"View all applications\" - Click \"SharePoint Online Client Extensibility Web Application Principal\" - Choose \"Settings\" > \"Required Permissions\" - Click \"Add\" - \"Select an API\" and choose \"Windows Azure Active Directory\", press \"Select\" - \"Select Permissions\" and choose \"Sign in and read user profile\", press \"Select\" - Click \"Done\" - Click \"Grant permissions\" and \"Yes\" - Update the app package in the app catalog - Head back to the \"API Managment\"-section: - Ensure that \"Windows Azure Active Directory\" is already listed in the approved permissions (this permission should be here because of the previously executed steps). - Approve all permission requests one by one. Once this is done, reload the page to ensure that all permissions are actually approved as the SharePoint UI doesn't always behave as expected. - Wait a couple of minutes - Log out of SharePoint, close all browser windows and log in again - Access your intranet and everything should be fine
m365 spfx project doctor --output md > \"doctor-report.md\"\n
"},{"location":"spfx/versions/#check-versions","title":"Check versions","text":"In the F12 Developer Console, you can call
window.spModuleLoader._bundledComponents[\"b6917cb1-93a0-4b97-a84d-7cf49975d4ec\"].PageManager._instance.pageContext.legacyPageContext\n
"},{"location":"spfx/webparts/#dynamic-default-properties","title":"Dynamic default properties","text":"Connect-PnPOnline https://tenantname-admin.sharepoint.com\n$ctx = Get-PnPContext\n$tenant = New-Object -TypeName \"Microsoft.Online.SharePoint.TenantAdministration.Tenant\" -ArgumentList $ctx\n# Get existing list of blocked web parts\n$ids = @($tenant.DisabledWebPartIds)\n# Add the id for the out of the box Divider web part\n$ids += [Guid]'2161a1c6-db61-4731-b97c-3cdb303f7cbb'\n$ids = $ids | Where-Object {$_}\n$tenant.DisabledWebPartIds = $ids\n$tenant.Update()\nInvoke-PnPQuery\n
"},{"location":"tools/blazor/","title":"Blazor","text":""},{"location":"tools/blazor/#overview","title":"Overview","text":"wget --recursive --no-clobber --page-requisites --html-extension --convert-links --restrict-file-names=windows -domains www.yourwebsite.com --no-parent www.yourwebsite.com/someurl\n
"},{"location":"tools/dev/#email","title":"Email","text":"open last active window
code -r .\n
open in new window
code -n\n
"},{"location":"tools/dev/#vscode-extensions","title":"VS.Code Extensions","text":"settings.json
// Is git enabled\n\"git.enabled\": false,\n
// Path to the git executable\n\"git.path\": null,\n
// Whether auto fetching is enabled.\n\"git.autofetch\": false,\n
Info: https://stackoverflow.com/questions/30331338/remove-git-integrations-from-vscode
"},{"location":"tools/dev/#configure-vscode-intellisense","title":"Configure VSCode Intellisense","text":"Open Site Settings
javascript:(function(){var url = document.location.href.split('/Pages')[0].split('/SitePages')[0].split('/_layouts')[0];if(url.endsWith('.aspx')){url = url.replace(new RegExp('\\/[a-z A-Z 0-1 \\- _]*.aspx'),'')}location.replace(url+\"/_layouts/15/settings.aspx\")}());\n
Open Page in Maintenance Mode
javascript:(function(){location.replace(window.location.href+\"?maintenancemode=true\")})();\n
Go to Classic
javascript:(function(){document.cookie=\"splnu=0;domain=\"+window.location.hostname+\";\"; location.href=location.href;})();\n
Go to Modern
javascript:(function(){document.cookie=\"splnu=1;domain=\"+window.location.hostname+\";\"; location.href= location.href})();\n
Open Web Part Manager
javascript:(function(){location.replace(window.location.href+\"?contents=1\")})();\n
"},{"location":"tools/dev/#delete-node_modules-folder","title":"Delete node_modules Folder","text":"How to effectively delete node_modules on Windows
Firstly install rimraf module globally
npm install rimraf -g\n
@ECHO OFF\nSET FOLDER=%1\nIF [%1]==[] (\n ECHO Delete Folder: \"%CD%\"?\n PAUSE\n SET FOLDER=\"%CD%\"\n CD /\n)\nECHO Deleting folder %FOLDER%\nrimraf %FOLDER%\n
This .bat file should be available under your \"PATH\" environmental variable. In other words, you should be able to run it from any command-line from any location. The easiest approach is to just copy this file to C:\\Windows directory (it's absolutely safe).
Open regedit and go to \"HKEY_CLASSES_ROOT\\Directory\\shell\\\" path.
Right-click on the \"shell\" folder and select New -> Key. Give it the name \"Fast Delete\".
Right-click on a newly created \"Fast Delete\" folder, then New -> Key. Give it the name \"command\".
Double-click on the default value for \"command\" folder and under value data enter:
cmd /c \"cd %1 && fast-del.bat\"\n
"},{"location":"tools/dev/#link-checker","title":"Link Checker","text":"copy($$('a').map(a => a.href).join('\\n'))\n
function Get-UrlStatusCode([string] $Url)\n{\n try\n {\n (Invoke-WebRequest -Uri $Url -UseBasicParsing -DisableKeepAlive).StatusCode\n }\n catch [Net.WebException]\n {\n [int]$_.Exception.Response.StatusCode\n }\n}\n\n\nforeach($line in Get-Content C:\\url.txt) \n{\n if($line -match $regex){\n\n $statusCode = Get-UrlStatusCode $line\n if($statusCode -le \"200\")\n {\n $line + \" => OK\"\n }\n else\n {\n $line + \" => Error\"\n }\n }\n}\n
"},{"location":"tools/gatspy/","title":"Gatspy","text":""},{"location":"tools/gatspy/#blog-template","title":"Blog Template","text":"git log --full-history -- src/path/to/file.js\n
"},{"location":"tools/git/#github","title":"GitHub","text":"(Source: @ChrisO_Brien)
## Tools
Easily grant API permissions with the Office 365 CLI
Logging in to Office 365
m365 spo login https://<tenant>-admin.sharepoint.com\n
spo serviceprincipal grant add --resource 'Microsoft Graph' --scope 'Mail.Read'\n
"},{"location":"#content-style-guide","title":"Content Style Guide","text":"with pnpm manager
yo @microsoft/sharepoint \u2013package-manager pnpm\n
pnpm i tslint@5.9.1 -DE\n
pnpm i typescript@2.4.2 -DE\n
"},{"location":"#check-package-version","title":"Check Package Version","text":"node \u2013v\nnpm \u2013v\nyo --generators\ngulp \u2013v\ntsc \u2013v\ntsd --version\n
"},{"location":"#git-basics","title":"Git Basics","text":"Init local repo
git init\n
Add all Files to local repo
git add -A\ngit commit -m \"init repo\"\n
Show last commit
git show --name-only\n
show full history
git log --full-history --src/path/to/file.js\n
Importend: only for spfx < 13.1
gulp serve\n
https://localhost:4321/temp/workbench.html\n
"},{"location":"#developmentonline-workbench","title":"Development(online workbench)","text":"gulp serve --nobrowser\n
/_layouts/15/workbench.aspx?forceLocale=de-de\n
/_layouts/workbench.aspx\n
"},{"location":"#prepare-deployment-solution","title":"Prepare Deployment Solution","text":"gulp clean\n
gulp build --ship\n
gulp bundle --ship\n
gulp package-solution --ship\n
"},{"location":"#debug-in-vscode","title":"Debug in vs.code","text":"npm version
to upgrade the version of your SPFx solutionnpm version major\n
npm version minor\n
npm version patch\n
"},{"location":"#add-imported-pnp-modules","title":"Add imported pnp modules","text":"npm install @pnp/logging @pnp/common @pnp/odata @pnp/sp @pnp/graph --save\n
npm install @pnp/spfx-controls-react@latest --save --save-exact\n
npm install @pnp/spfx-property-controls@latest --save --save-exact\n
"},{"location":"#localizations","title":"Localizations","text":"{\n\"cdnBasePath\": \"<!-- PATH TO CDN -->\",\n\"debugLocale\": \"de-de\"\n}\n
or by using the \"locale\" command argument
gulp serve --locale=de-de\n
"},{"location":"#app-permission","title":"App Permission","text":"Sample Folder structure
prettify your imports
src
Interface to define our Data structure
export interface IHelpDeskItem {\n id?: number;\n title?: string;\n description?: string;\n level?: string;\n status?: string;\n assignedTo?: string;\n resolution?: string;\n}\n
Interface to define our Data Access services
import { IHelpDeskItem } from \"./../models/IHelpDeskItem\";\nimport { WebPartContext } from \"@microsoft/sp-webpart-base\";\n\nexport default interface IDataService {\n getTitle(): string;\n isConfigured(): boolean;\n getItems(context: WebPartContext): Promise<IHelpDeskItem[]>;\n addItem(item: IHelpDeskItem): Promise<void>;\n deleteItem(id: number): Promise<void>;\n}\n
Mocking Service for testing in local Workbench development
import { IHelpDeskItem } from \"./../models/IHelpDeskItem\";\nimport IDataService from \"./IDataService\";\nimport { IWebPartContext } from \"@microsoft/sp-webpart-base\";\n\nexport default class MockDataService implements IDataService {\n...\n private _webPartContext: IWebPartContext;\n private _listId: string;\n\n constructor(webPartContext: IWebPartContext, listId: string) {\n this._webPartContext = webPartContext;\n this._listId = listId;\n }\n...\n\n public getItems(context: IWebPartContext): Promise<IHelpDeskItem[]> {\n return new Promise<IHelpDeskItem[]>((resolve, reject) => {\n setTimeout(() => resolve([\n {\n id : 1,\n title : \"That doesn't work\",\n description : \"When I do that, it doesn't work\",\n level : \"Low\",\n status: \"Open\",\n resolution: \"Do this and it will work!\",\n assignedTo: \"S\u00e9bastien Levert\",\n }\n ]), 300);\n });\n }\n}\n
"},{"location":"#get-data-with-sharepoint-rest","title":"Get Data with Sharepoint REST","text":"Source
public getItems(context: WebPartContext): Promise<IHelpDeskItem[]> {\nreturn new Promise<IHelpDeskItem[]>((resolve, reject) => {\n context.spHttpClient\n .get( `${this._webPartContext.pageContext.web.absoluteUrl}/_api/web/lists/GetById('${this._listId}')/items` +\n `?$select=*,HelpDeskAssignedTo/Title&$expand=HelpDeskAssignedTo`, SPHttpClient.configurations.v1)\n .then(res => res.json())\n .then(res => {\n let helpDeskItems:IHelpDeskItem[] = [];\n\n for(let helpDeskListItem of res.value) {\n helpDeskItems.push(this.buildHelpDeskItem(helpDeskListItem));\n }\n\n resolve(helpDeskItems);\n })\n .catch(err => console.log(err));\n});\n}\n
"},{"location":"#get-data-with-pnp-js-core","title":"Get Data with Pnp-JS-Core","text":"Reference Sample
Advantages
Init context in react webpart component source
public onInit(): Promise<void> {\n return super.onInit().then(_ => {\n pnpSetup({\n spfxContext: this.context\n });\n });\n}\n
init service in react webpart component
public render(): void {\n const element: React.ReactElement<IListContentProps> = React.createElement(\n ListContent,\n {\n context: this.context,\n dataService: this.getDataService(),\n list: this.properties.list\n }\n );\n\n ReactDom.render(element, this.domElement);\n}\n
Get items from list Source
public getItems(context: WebPartContext): Promise<IHelpDeskItem[]> {\nreturn new Promise<IHelpDeskItem[]>((resolve, reject) => {\n\n sp.web.lists.getById(this._listId).items\n .select(\"*\", \"HelpDeskAssignedTo/Title\")\n .expand(\"HelpDeskAssignedTo\").getAll().then((sessionItems: any[]) => {\n let helpDeskItems:IHelpDeskItem[] = [];\n\n for(let helpDeskListItem of sessionItems) {\n helpDeskItems.push(this.buildHelpDeskItem(helpDeskListItem));\n }\n\n resolve(helpDeskItems);\n });\n\n});\n}\n
"},{"location":"#get-search-data-with-asyncawait","title":"Get Search Data with async/await","text":"Using PnPJS and Async/Await to Really Simplify Your API Calls
async/await
private async _getSiteData(): Promise<ISPSite[]> {\n\n var thisDomain: string = location.host.split(\".\")[0];\n var exclusions: string[] = [\"https://\" + thisDomain + \"-my.sharepoint.com\", \"https://\" + thisDomain + \".sharepoint.com/portals/personal\"];\n var exclusionString: string = \" -Path:\" + exclusions.join(\" -Path:\");\n exclusionString += \" -Path=https://\" + thisDomain + \".sharepoint.com\";\n\n try {\n\n let result = await sp.search(<SearchQuery>{\n Querytext: \"contentclass:sts_site \" + exclusionString,\n RowLimit: 500,\n TrimDuplicates: false,\n Properties: [{\n Name:\"EnableDynamicGroups\",\n Value: {\n BoolVal: true,\n QueryPropertyValueTypeIndex: QueryPropertyValueType.BooleanType\n }\n }],\n SelectProperties: [\"Title\", \"Path\", \"SiteLogo\"]\n });\n\n return this.processSearchResults(result);\n\n } catch (e) {\n\n console.error(e);\n return null;\n\n }\n\n }\n
public async getShipmentStatuses(serviceProps: IServiceProperties): Promise<IStatus[]> {\n\n try {\n\n let items = await sp\n .web\n .lists\n .getByTitle(\"SL_ShippingStatuses\")\n .items\n .select(\"Id\", \"Title\", \"SortOrder\", \"CanBeCancelled\")\n .orderBy(\"SortOrder\")\n .get(spODataEntityArray<Item, IStatus>(Item));\n\n return items;\n\n } catch (e) {\n\n console.error(e);\n return null;\n\n }\n}\n
joelfmrodrigues - demos
private async _getItems() {\n let select = '*';\n let expand = 'File';\n let filter = '';\n\n // filter by selected term if required\n if (this.props.term !== undefined && this.props.term !== null && this.props.term.length > 0) {\n const term = this.props.term[0];\n\n select = `${select},TaxCatchAll/Term`;\n expand = `${expand},TaxCatchAll`;\n filter = `TaxCatchAll/Term eq '${term.name}'`;\n }\n\n const items = await sp.web.lists.getById(this.props.list).items\n .select(select)\n .expand(expand)\n .filter(filter)\n .get();\n\n // update state\n this.setState({\n items: items ? items : []\n });\n console.log('List Items:', this.state.items);\n}\n
"},{"location":"#get-data-from-msgraph","title":"Get Data from MSGraph","text":"Create Sample
create-react-app demo-office-fabric-react-ts --scripts-version=react-scripts-ts\n
init git
git init\ngit add .\ngit commit -m \"Initial commit.\"\n
add office fabric react
npm install office-ui-fabric-react@5.132.0 --save\n
"},{"location":"#generator-for-sp-applications","title":"Generator for SP applications","text":"npm list -g --depth=0\n
npm ls -g --depth=0 @microsoft/generator-sharepoint\n
npm outdated --global\n
npm install @microsoft/generator-sharepoint@latest --global\n
"},{"location":"#spfx-version-upgrade","title":"SPFx Version Upgrade","text":"Latest version
npm i -g @pnp/cli-microsoft365@latest\n
Latest Beta version
npm i -g @pnp/cli-microsoft365@next\n
Create report for upgrade
m365 spfx project upgrade --shell powershell --toVersion 1.12.1 --output md > report.md\n
"},{"location":"#update-spfx-packages","title":"Update SPFx packages","text":"Roland Oechslin
"},{"location":"about/about/#work","title":"Work","text":"Senior Sharepoint/M365 Expert and Developer, BLS AG, Bern, Switzerland
"},{"location":"about/about/#interests","title":"Interests","text":"Programming, New Technologies
"},{"location":"about/about/#twitter","title":"Twitter","text":"@rolandoechslin
"},{"location":"about/help/","title":"Help mkdocs","text":"mkdocs gh-deploy\n
"},{"location":"angular/elements/","title":"Angular","text":""},{"location":"angular/elements/#elements","title":"Elements","text":"Let\u2019s get back to the quote from Ignite\u2026 why are subsites the spawn of the devil?
Generally speaking, it\u2019s hard to argue with the fact that site collections are more flexible. Each site collection can be viewed as a granular \u2018unit of work\u2019. They allow you to control permissions, features, storage, branding and target data protection and retention controls at a more targeted level. A flat architecture like this allows you to \u2018plug and play\u2019 site collections into whatever kind of navigational hierarchy is required \u2013 the announcement of the SharePoint Hub site at Microsoft Ignite is a feature being built to allow you to build this navigation thru the User Interface. You will be able to associate a site collection with a SharePoint Hub by the click of a button and easily move it from one Hub to another if required. This is great news.
Source: https://joannecklein.com/2017/11/03/sharepoint-site-collection-advantages/
"},{"location":"deployment/guide/","title":"Deployment","text":"Check
Get-InstalledModule | Where-Object {$_.Name -match \"Microsoft.Graph\"}\n
Install
Install-Module -Name \"Microsoft.Graph\"\n
Update
Update-Module Microsoft.Graph\n
Uninstall (all)
Uninstall-Module Microsoft.Graph\n\n# Uninstall all Sub-modules of Graph\nGet-InstalledModule Microsoft.Graph.* | ForEach-Object { if($_.Name -ne \"Microsoft.Graph.Authentication\") {\n Uninstall-Module $_.Name }\n}\n\n# Uninstall the dependant module\nUninstall-Module Microsoft.Graph.Authentication\n
Connect with Delegated Access
# Connect to Microsoft Graph\nConnect-MgGraph -Scopes \"User.Read.All\"\n\n# Get All users\n$users = Get-MgUser\n$users | Select-Object DisplayName, UserPrincipalName, Mail\n
Connect with App ID and Certificate
# App Config\n$TenantID = \"<placeholder>\"\n$ClientID = \"<placeholder>\" # App ID\n$CertThumbPrint = \"<placeholder>\"\n\n# Connect to Microsoft Graph using App\nConnect-MgGraph -ClientID $ClientID -TenantId $TenantID -CertificateThumbprint $CertThumbPrint\n
Connect with Client Secret
# App Registration details\n$TenantID = \"<placeholder>\"\n$ClientID = \"<placeholder>\"\n$ClientSecret = \"<placeholder>\"\n\n$Body = @{\n Grant_Type = \"client_credentials\"\n Scope = \"https://graph.microsoft.com/.default\"\n Client_Id = $ClientID\n Client_Secret = $ClientSecret\n}\n\n$Connection = Invoke-RestMethod `\n -Uri https://login.microsoftonline.com/$TenantID/oauth2/v2.0/token `\n -Method POST `\n -Body $body\n\n# Get the Access Token\n$Token = $Connection.access_token\n\n# Connect to Microsoft Graph\nConnect-MgGraph -AccessToken $Token\n
"},{"location":"powershell/pnp-ps/","title":"PnP Powershell","text":""},{"location":"powershell/pnp-ps/#information","title":"Information","text":"-The required Office 365 role to run PnP Powershell with Scopes
"},{"location":"powershell/pnp-ps/#installation-options","title":"Installation Options","text":"Get-InstalledModule | foreach { $b = (find-module $_.name).version ; if ($b -ne $_.version) { Write-host \"$($_.name) has an update from $($_.version) to $b\" } }\n
Get-Module SharePointPnPPowerShell* -ListAvailable | Select-Object Name,Version | Sort-Object Version -Descending\n
"},{"location":"powershell/pnp-ps/#update-module-to-the-latest-version","title":"Update Module to the latest version","text":"Update-Module SharePointPnPPowerShell*\n
"},{"location":"powershell/pnp-ps/#delete-the-old-version","title":"Delete the old version","text":"Get-InstalledModule -Name \"SharePointPnPPowerShellOnline\" -RequiredVersion 3.8.1904.0 | Uninstall-Module\n
"},{"location":"powershell/pnp-ps/#install-a-specific-version","title":"Install a specific version","text":"Install-Module -Name SharePointPnPPowerShellOnline -RequiredVersion 3.0.1808.1\n
"},{"location":"powershell/pnp-ps/#connect-with-app-permission","title":"Connect with App Permission","text":"Initialize-PnPPowerShellAuthentication -ApplicationName DemoApp -Tenant tenant.onmicrosoft.com -Store CurrentUser\n\n$url = \"https://tenant.sharepoint.com\"\n$clientid = \"<placeholder>\"\n$thumbprint = \"<placeholder>\"\n$tenant = 'tenant.onmicrosoft.com'\n\nConnect-PnPOnline -Url $url -ClientId $clientid -Thumbprint $thumbprint -Tenant $tenant\n
# Load PNP the Right Way\n$pnp = Get-Command Connect-Stuff -ErrorAction SilentlyContinue\nif (!$pnp) {Install-Module SharePointPnPPowerShellOnline -Force}\nImport-Module SharePointPnPPowerShellOnline\n
"},{"location":"powershell/pnp-ps/#list-all-commands","title":"List all commands","text":"Get-Command | ? { $_.ModuleName -eq \"SharePointPnPPowerShellOnline\" }\n
"},{"location":"powershell/pnp-ps/#create-guid","title":"Create Guid","text":"[guid]::NewGuid() | Select-Object -ExpandProperty Guid | clip\n
"},{"location":"powershell/pnp-ps/#delete-all-listitems","title":"Delete all listitems","text":"Get-PnPList -Identity Lists/MyList | Get-PnPListItem -PageSize 100 -ScriptBlock { Param($items) \n$items.Context.ExecuteQuery() } | % {$_.DeleteObject()}\n
"},{"location":"powershell/pnp-ps/#upload-documents","title":"Upload Documents","text":"function UploadDocuments(){\nParam(\n [ValidateScript({If(Test-Path $_){$true}else{Throw \"Invalid path given: $_\"}})] \n $LocalFolderLocation,\n [String] \n $siteUrl,\n [String]\n $documentLibraryName\n)\nProcess{\n $path = $LocalFolderLocation.TrimEnd('\\')\n\n Write-Host \"Provided Site :\"$siteUrl -ForegroundColor Green\n Write-Host \"Provided Path :\"$path -ForegroundColor Green\n Write-Host \"Provided Document Library name :\"$documentLibraryName -ForegroundColor Green\n\n try{\n $credentials = Get-Credential\n\n Connect-PnPOnline -Url $siteUrl -CreateDrive -Credentials $credentials\n\n $file = Get-ChildItem -Path $LocalFolderLocation -Recurse\n $i = 0;\n Write-Host \"Uploading documents to Site..\" -ForegroundColor Cyan\n (dir $path -Recurse) | %{\n try{\n $i++\n if($_.GetType().Name -eq \"FileInfo\"){\n $SPFolderName = $documentLibraryName + $_.DirectoryName.Substring($path.Length);\n $status = \"Uploading Files :'\" + $_.Name + \"' to Location :\" + $SPFolderName\n Write-Progress -activity \"Uploading Documents..\" -status $status -PercentComplete (($i / $file.length) * 100)\n $te = Add-PnPFile -Path $_.FullName -Folder $SPFolderName\n } \n }\n catch{\n }\n }\n }\n catch{\n Write-Host $_.Exception.Message -ForegroundColor Red\n }\n\n }\n}\n\n\n#UploadDocuments -LocalFolderLocation {Local Folder Location} -siteUrl {Site collection URL} -documentLibraryName {Document Library Name}\n
"},{"location":"powershell/pnp-ps/#site-classification","title":"Site Classification","text":"Connect-PnPOnline -Scopes \"Directory.ReadWrite.All\"\n
Enable-PnPSiteClassification -Classifications \"HBI\",\"LBI\",\"Top Secret\" -UsageGuidelinesUrl ```\n\"http://aka.ms/sppnp\" -DefaultClassification \"HBI\"\n
Add-PnPSiteClassification -Classifications \"SBI\",\"MBI\"\n
Remove-PnPSiteClassification -Classifications \"SBI\"\n
Update-PnPSiteClassification -Classifications \"HBI\",\"LBI\",\"Top Secret\" -UsageGuidelinesUrl http://aka.ms/sppnp\" -DefaultClassification \"HBI\"\n
Disable-PnPSiteClassification\n
"},{"location":"powershell/pnp-ps/#tips","title":"Tips","text":"Connect-PnPOnline -Url https://toddklindt.sharepoint.com/sites/8884aced -Credentials Me\nGet-PnPView -List Documents\nGet-PnPView -List Documents -Identity 3c4126aa-d2fe-4b57-9a70-e03ebb9c76ef\n$view = Get-PnPView -List Documents -Identity 3c4126aa-d2fe-4b57-9a70-e03ebb9c76ef\n$view\n$view | select *\n$view.ViewQuery\nGet-PnPProperty -ClientObject $view -Property ViewQuery\n$view.ViewQuery\n$view\n$view | select *\n
"},{"location":"powershell/pnp-ps/#fields","title":"Fields","text":"Latest Version
Get-Module Microsoft.PowerApps* -ListAvailable | Select-Object Name,Version | Sort-Object Version -Descending\n
"},{"location":"powershell/powerapps/#update-module-to-latest-version","title":"Update Module to latest version","text":"Update-Module Microsoft.PowerApps*\n
"},{"location":"powershell/powerapps/#delete-old-version","title":"Delete old version","text":"# Admin\nGet-InstalledModule -Name \"Microsoft.PowerApps.Administration.PowerShell\" -RequiredVersion 2.0.56 | Uninstall-Module\n\n## Maker\nGet-InstalledModule -Name \"Microsoft.PowerApps.PowerShell\" -RequiredVersion 1.0.9 | Uninstall-Module\n
"},{"location":"powershell/powerapps/#connect","title":"Connect","text":"Add-PowerAppsAccount\n
"},{"location":"powershell/powerapps/#disconnect","title":"Disconnect","text":""},{"location":"powershell/powershell/","title":"Links","text":""},{"location":"powershell/powershell/#profile","title":"Profile","text":"code $PROFILE\n
Import-Module -Name CLI.Microsoft365.PowerShell.Predictor\nImport-Module posh-git\nImport-Module -Name Terminal-Icons\noh-my-posh init pwsh --config \"$env:POSH_THEMES_PATH/jandedobbeleer.omp.json\" | Invoke-Expression\n
Get-Command -Name Get-PnPSite -Syntax\n
"},{"location":"powershell/powershell/#hashtable","title":"Hashtable","text":"$env:PSModulePath\n(Get-Module -ListAvailable Pnp.*).path\n\nGet-InstalledModule | select name, version\n
"},{"location":"powershell/powershell/#slides","title":"Slides","text":"Install-Module -Name AzureAD\n
"},{"location":"powershell/powershell/#loaded-modules","title":"Loaded Modules","text":"[System.AppDomain]::CurrentDomain.GetAssemblies() | Where-Object Location | Sort-Object -Property FullName | Select-Object -Property FullName, Location, GlobalAssemblyCache, IsFullyTrusted | Out-GridView\n
"},{"location":"powershell/spo-ps/","title":"SPO Powershell","text":"Latest Version - https://www.powershellgallery.com/packages/Microsoft.Online.SharePoint.PowerShell/16.0.8119.0
Get-Module Microsoft.Online.SharePoint.PowerShell* -ListAvailable | Select-Object Name,Version | Sort-Object Version -Descending\n
Update-Module Microsoft.Online.SharePoint.PowerShell\n
"},{"location":"powershell/spo-ps/#delete-the-old-version","title":"Delete the old version","text":"Get-InstalledModule -Name \"Microsoft.Online.SharePoint.PowerShell\" -RequiredVersion 16.0.8119.0 | Uninstall-Module\n
"},{"location":"powershell/spo-ps/#check-different-file-version","title":"Check Different File Version","text":"Get-ChildItem -Path 'C:\\Program Files\\WindowsPowerShell\\Modules\\Microsoft.Online.SharePoint.PowerShell\\*Microsoft.SharePoint*.dll' -Recurse | ft Name,@{Label=\"Version\";Expression={$_.VersionInfo.FileVersion}} -AutoSize\n\n# Search in GAC_MSIL\nGet-ChildItem -Path C:\\Windows\\Microsoft.NET\\assembly\\GAC_MSIL\\*Microsoft.SharePoint*.dll -Recurse | ft Name,@{Label=\"Version\";Expression={$_.VersionInfo.FileVersion}} -AutoSize\n
"},{"location":"powershell/spo-ps/#credential-manager","title":"Credential Manager","text":"Connect-SPOService https://devro-admin.sharepoint.com -Credential admin@devro.onmicrosoft.com\n
"},{"location":"powershell/spo-ps/#disconnect","title":"Disconnect","text":"Disconnect-SPOService\n
"},{"location":"powershell/spo-ps/#uls-correlation-id","title":"ULS-Correlation ID","text":"get-splogevent -starttime (get-date).addminutes(-20) | where-object { $_.correlation -eq \"e434f79b-68bb-40d2-0000-03a47eae1bf9\" } | fl message > c:\\errors1.txt\n
"},{"location":"powershell/spo-ps/#security","title":"Security","text":"get-sposite | ?{$_.DenyAddAndCustomizePages -eq 'Disabled'}\n ```\n\n## Ressources\n\n- [resources-to-learn-powershell-for-office-365](https://absolute-sharepoint.com/2018/03/resources-to-learn-powershell-for-office-365.html)\n\n## Tenant Configuration\n\n### Remove Feedback Button\n\n```Powershell\nSet-SPOTenant -UserVoiceForFeedbackEnabled:$false\n
"},{"location":"powershell/teams/","title":"Teams Powershell","text":"Latest Version
Get-Module MicrosoftTeams* -ListAvailable | Select-Object Name,Version | Sort-Object Version -Descending\n
"},{"location":"powershell/teams/#update-module-to-latest-version","title":"Update Module to latest version","text":"Update-Module MicrosoftTeams\n
"},{"location":"powershell/teams/#delete-old-version","title":"Delete old version","text":"Get-InstalledModule -Name \"MicrosoftTeams\" -RequiredVersion 0.9.0 | Uninstall-Module\n
"},{"location":"powershell/teams/#connect","title":"Connect","text":"private async loadScripts(): Promise<void> {\n return new Promise<void>(async (resolve) => {\n if(this._context) {\n resolve();\n }\n\n const response = this.loadScript(layoutsUrl + 'init.js', 'Sod');\n resolve();\n });\n }\n
Load Data from SP-List Code
private async _loadList(): Promise<void> {\n this.setState({\n loading: true\n });\n let items = await pnp.sp.web.lists.getByTitle(\"Events\").items.select(\"Id\", \"Title\", \"SPFxDescription\", \"SPFxThumbnail\")\n .orderBy(\"Modified\", false).get();\n _items = items.map((item: IList, index: number) => {\n return {\n thumbnail: item.SPFxThumbnail != null ? item.SPFxThumbnail.Url : \"\",\n key: item.Id,\n name: item.Title,\n description: item.SPFxDescription\n }\n });\n this.setState({\n sortedItems: _items,\n columns: _buildColumns(),\n loading: false,\n newsFeedVisible: false\n });\n _lastQueryDate = moment();\n}\n
"},{"location":"spfx/classic/","title":"Classic sites","text":"-SharePoint add-in, custom Web API and SPFx (v1.1)
"},{"location":"spfx/debug/","title":"Debug","text":""},{"location":"spfx/debug/#debug-tricks","title":"Debug Tricks","text":"write-manifests.json
{\n\"cdnBasePath\": \"https://publiccdn.sharepointonline.com/cloud67.sharepoint.com/cdn/topnavmenu\"\n}\n
"},{"location":"spfx/deployment/#deployment-to-sp-library","title":"Deployment to SP Library","text":"SPFx unit tests and code coverage quality gates in Azure DevOps \u2013 Velin Georgiev Apply a DevOps process to your SPFx project (Part 1)
"},{"location":"spfx/dev-ops/#sample","title":"Sample","text":"https://blog.velingeorgiev.com/unit-test-your-sharepoint-framework-solution-with-jest https://www.youtube.com/watch?v=iDt7MJX9Lj0&t=20s https://www.youtube.com/watch?v=lFkNqcf-Thg https://www.eliostruyf.com/sharepoint-framework-unit-tests-with-jest/
"},{"location":"spfx/dev-ops/#devops-pipelines-demos","title":"DevOps pipelines demos","text":"http://bit.ly/pnp-devops-1 http://bit.ly/pnp-devops-2 http://bit.ly/pnp-devops-3 http://bit.ly/pnp-devops-4
"},{"location":"spfx/dev-ops/#unit-tests","title":"Unit Tests","text":"private _topPlaceholder : PlaceholderContent;\npublic onInit(void){\n this.context.placeholderProvider.changedEvent.add(this, this._handlePlaceholderChange.bind(this));\n}\n\nprivate _handlePlaceholderChange(){\n if (!this._topPlaceholder)\n {\n // We don't have a placeholder populated yet. Let's try and get it.\n this._topPlaceholder = this.context.placeholderProvider.tryCreateContent(PlaceholderName.Top);\n } else {\n // We have a placeholder - let's make sure that it still exists.\n let index:number = this.context.placeholderProvider.placeholderNames.indexOf(PlaceholderName.Top);\n if ( index < 0)\n {\n // The placeholder is no longer here.\n this._topPlaceholder.dispose();\n this._topPlaceholder = undefined;\n }\n }\n if ( this._topPlaceholder )\n {\n this._topPlaceholder.innerText = 'Hello World!';\n }\n}\n
"},{"location":"spfx/flow/","title":"Power Automate (aka. Flow)","text":""},{"location":"spfx/flow/#support","title":"Support","text":"Connect-PnPOnline -Url https://<teantUrl>/sites/<name>\n\n# disable\nSet-PnPSite -DisableFlows:$true\n\n# enable\nSet-PnPSite -DisableFlows:$false\n
"},{"location":"spfx/flow/#azure-logic-app","title":"Azure Logic App","text":"-Create Simple ImageMap in SPO
"},{"location":"spfx/governance/#permission","title":"Permission","text":"Microsoft 365 guest sharing settings reference
How to properly configure sharing settings in the SharePoint Admin Center
https://github.com/SharePoint/PnP-PowerShell/tree/master/Samples/Provisioning.SelfHostedWithAzureWebJob/Engine
"},{"location":"spfx/groups/#permissions","title":"Permissions","text":"# SiteCollection URL <site>\n<site>/_layouts/15/groupstatus.aspx?Target=PLANNER\n\n# XML Provisioning Engine - SiteCollection Token {site}\n{site}/_layouts/15/groupstatus.aspx?Target=PLANNER\n
"},{"location":"spfx/groups/#powershell","title":"Powershell","text":"To get the list of all the Office 365 groups in descending order:
Get-UnifiedGroup | Select Id, DisplayName, ManagedBy, Alias, AccessType, WhenCreated, @{Expression={([array](Get-UnifiedGroupLinks -Identity $_.Id -LinkType Members)).Count }; Label=\u2019Members\u2019} | Sort-Object whencreated | Format-Table displayname, alias, managedby, Members, accesstype, whencreated\n
To get the list of all private Office 365 groups in your tenant:
Get-UnifiedGroup | Where-Object {$_.AccessType -eq \u2018Private\u2019} | Sort-Object whencreated | Format-Table displayname, alias, managedby, accesstype, whencreated\n
To get list of deleted Office 365 groups in descending order:
Get-AzureADMSDeletedGroup | Sort-Object DeletedDateTime -Descending | Format-Table Id, DisplayName, Description, Visibility, DeletedDateTime\n
How to resolve the error The alias is being used by another group in your organization
Get-AzureADMSDeletedGroup -All:$true | Remove-AzureADMSDeletedDirectoryObject\n
To get the list of orphaned Office 365 groups in your tenant:
$Groups = Get-UnifiedGroup | Where-Object {([array](Get-UnifiedGroupLinks -Identity $_.Id -LinkType Owners)).Count -eq 0} `\n\n| Select Id, DisplayName, ManagedBy, WhenCreated\n\nForEach ($G in $Groups) {\n\nWrite-Host \u201cWarning! The following group has no owner:\u201d $G.DisplayName\n\n}\n
To determine where a group was provisioned (Planner, Yammer, Teams etc.)
Get-UnifiedGroup |Where-Object {$_.ProvisioningOption -eq \u2018YammerProvisioning\u2019} |select DisplayName,Alias,ProvisioningOption,GroupSKU,SharePointSiteUrl,SharePointDocumentsUrl,AccessType\n
To get the list of Teams integrated Office 365 group list:
Get-UnifiedGroup |Where-Object {$_.ProvisioningOption -eq \u2018ExchangeProvisioningFlags:481\u2019}|select DisplayName,Alias,ProvisioningOption,GroupSKU,SharePointSiteUrl,SharePointDocumentsUrl,AccessType\n
"},{"location":"spfx/hubsite/","title":"HubSite","text":"-Introducing the idea of Archive Hub Sites - How to get the hubId in SharePoint Framework - Fix broken Hub Sites in SharePoint Online
cls\n\n$tenantAdmin = \"https://contoso-admin.sharepoint.com\"\n$hubSite = \"https://contoso.sharepoint.com/sites/hub\"\n$extensionGUID = \"6da1a9e8-471d-4f39-80e6-a7ded02e8881\"\n$extensionName = \"Extension Name\"\n$extensionTitle = \"Extension Title\"\n\ntry\n{\nConnect-PnPOnline -Url $tenantAdmin -UseWebLogin\n} catch {\nWrite-Host \"Unable to connect.\"\nexit\n}\n\n$HubSite = Get-PnPHubSite $hubSite\n$HubSiteId = $HubSite.SiteId\n$ModernSites = (Get-PnPTenantSite -Template 'GROUP#0') + (Get-PnPTenantSite -Template 'SITEPAGEPUBLISHING#0')\n$SitesFromHub = New-Object System.Collections.ArrayList\n\nWrite-Host (\"Searching {0} sites:\" -f $HubSite.Title) -BackgroundColor Gray\nforeach ($ModernSite in $ModernSites){\n $site = Get-PnPHubSite $ModernSite.Url\n if($site.SiteUrl){\n if($site.SiteId -eq $HubSiteId){\n Write-Host (\"* {0} - {1}\" -f $ModernSite.Title, $ModernSite.Url)\n $SitesFromHub.Add($ModernSite) | Out-Null\n }\n }\n}\n\nWrite-Host \"\"\nWrite-Host \"Installing at:\" -BackgroundColor Gray\nforeach ($SiteHub in $SitesFromHub){\n Write-Host (\"* {0} - {1} ... \" -f $SiteHub.Title, $SiteHub.Url) -NoNewline\n Connect-PnPOnline -Url $SiteHub.Url -UseWebLogin\n Add-PnPCustomAction -ClientSideComponentId $extensionGUID -Name $extensionName -Title $extensionTitle -Location ClientSideExtension.ApplicationCustomizer -Scope site\n Write-Host \"Done\" -BackgroundColor Green\n Disconnect-PnPOnline\n}\n\nWrite-Host \"All Done\"\n
"},{"location":"spfx/hubsite/#csom","title":"CSOM","text":" # List all sites being a hub site or associate to a hub site\n$results = Submit-PnPSearchQuery -Query 'contentclass=sts_site' -RefinementFilters 'departmentid:string(\"{*\",linguistics=off)' -TrimDuplicates $false -SelectProperties @(\"Title\",\"Path\",\"DepartmentId\",\"SiteId\") -All -RelevantResults\n\n# Filter out the hub sites\n$hubSites = $results |? { $_.DepartmentId.Trim('{','}') -eq $_.SiteId }\n\n# Loop over the hub sites\nforeach( $hub in $hubSites ) {\n Write-Host $hub.Title - $hub.Path -ForegroundColor Green\n # Filter out sites associated to the current hub\n $associatedSites = ($results |? { $_.DepartmentId -eq $hub.DepartmentId -and $_.SiteId -ne $hub.SiteId })\n foreach($site in $associatedSites) {\n Write-Host \"`t\"$site.Title - $site.Path -ForegroundColor Yellow\n }\n}\n
"},{"location":"spfx/intranet/","title":"Intranet","text":""},{"location":"spfx/intranet/#homepage","title":"Homepage","text":"Reference the Log class
import { Log } from \"@microsoft/sp-core-library\";\n
Log your message from your WebPart
Log.verbose(\"HelloWorld\", \"Here is a verbose log\", this.context.serviceScope);\nLog.info(\"HelloWorld\", \"Here is an informational message.\", this.context.serviceScope);\nLog.warn(\"HelloWorld\", \"Oh Oh, this might be bad\", this.context.serviceScope);\nLog.error(\"HelloWorld\", new Error(\"Oh No! Error! Ahhhhhh!!!!\"), this.context.serviceScope);\n
"},{"location":"spfx/logging/#logging-with-pnp-logging","title":"Logging with pnp-logging","text":"/_api/search/query?querytext='IsDocument:True AND FileExtension:aspx AND PromotedState:2'\n
"},{"location":"spfx/modernpage/#news-digest","title":"News digest","text":"Search Query for multilingual news
PromotedState:2 AND (SPTranslationLanguage:{CurrentDisplayLanguage} OR (NOT SPTranslatedLanguages:{CurrentDisplayLanguage} AND NOT SPIsTranslation:true))\n
"},{"location":"spfx/mui/#samples","title":"Samples","text":"Testing in chrome console
fetch(`/sites/gridworks/_api/web/lists/getbytitle('SiteRequestsQueue')/items?$select=Id,Title,gwRequestSiteAlias&$orderby=Id desc`, {\nheaders: {\nAccept: 'application/json;odata=verbose;'\n}\n}).then(res => res.json().then(json => {\njson.d.results.forEach(item => {\nconsole.log(`item: ${item.Title}`);\n});\n}));\n
"},{"location":"spfx/search/","title":"Search","text":" # Managed Properties: SharedWithUsersOWSUSER, SharedWithDetails\n {SearchTerms} contentclass:STS_ListItem_DocumentLibrary IsContainer<>true SharedWithUsersOWSUSER=0\n
"},{"location":"spfx/search/#only-office-files","title":"Only Office Files","text":"{SearchTerms} ((FileExtension:mp4 OR FileExtension:doc OR FileExtension:docx OR FileExtension:xls OR FileExtension:xlsx OR FileExtension:ppt OR FileExtension:pptx OR FileExtension:pdf) AND (IsDocument:\"True\" OR contentclass:\"STS_ListItem\")) OR ContentType=\"Folder\"\n
"},{"location":"spfx/search/#search-query-filter","title":"Search Query Filter","text":"## News 2023
Sample mit Flow und Azure Function
Provisioning complex Modern Sites with Azure Functions and Microsoft Flow \u2013 Part 1 \u2013 Architecture
Success runs
Get-SPOSite -Limit All | ForEach-Object { \n $failedRuns = Get-SPOSiteDesignRun $_.Url | Get-SPOSiteDesignRunStatus | Where-Object {$_.OutcomeCode -ne \"Success\"};\n\n if($failedRuns) {\n Write-Output $_.Url\n $failedRuns\n }\n}\n
Failed runs
Get-SPOSite -Limit All | ForEach-Object { \n $failedRuns = Get-SPOSiteDesignRun $_.Url | Get-SPOSiteDesignRunStatus | Where-Object {$_.OutcomeCode -eq \"Faulure\"};\n\n if($failedRuns) {\n Write-Output $_.Url\n $failedRuns\n }\n}\n
"},{"location":"spfx/sitedesign/#tips","title":"Tips","text":"Know how many Site Designs and Site Scripts you have:
(Get-SPOSiteDesign | Measure).Count\n
(Get-SPOSiteScript | Measure).Count\n
Delete a Site Design or a Site Script based on its unique identifier:
Remove-SPOSiteDesign -Identity $siteDesignId\n
Remove-SPOSiteScript -Identity $siteScriptId\n\nDelete all Site Designs or Site Scripts at once:\n\n```Powershell\nGet-SPOSiteDesign | foreach { Remove-SPOSiteDesign -Identity $_.Id }\n
Get-SPOSiteScript | foreach { Remove-SPOSiteScript -Identity $_.Id }\n
"},{"location":"spfx/sitescripts/","title":"SiteScripts","text":"Use Microsoft Graph to evaluate SharePoint Urls
"},{"location":"spfx/snippets/#querystring","title":"QueryString","text":"import { UrlQueryParameterCollection } from '@microsoft/sp-core-library';\n\nif (queryParameters.getValue('id')) {\nid = parseInt(queryParameters.getValue('id'));\n}\n
"},{"location":"spfx/snippets/#pnp-js-core","title":"PNP JS-Core","text":""},{"location":"spfx/snippets/#list-permission","title":"List Permission","text":"private _checkProductsPermissions(productsList){\nreturn pnp.sp.web.lists.getByTitle(productsList).getCurrentUserEffectivePermissions()\n.then(perms => {\nlet canEdit = pnp.sp.web.lists.getByTitle(productsList).hasPermissions(perms, PermissionKind.EditListItems);\nlet canView = pnp.sp.web.lists.getByTitle(productsList).hasPermissions(perms, PermissionKind.ViewListItems);\nif(canEdit){\nreturn 'Edit';\n} else if(canView){\nreturn 'View';\n} else {\nreturn 'None';\n}\n})\n.catch((err) => {\nconsole.log('error:', err);\nreturn 'None';\n});\n}\n
"},{"location":"spfx/snippets/#admin-user","title":"Admin User","text":"// Ensure a user on site collection\nsp.web.ensureUser('john.doe@contoso.onmicrosoft.com').then(console.log);\n\n// Get site collection admins\nsp.web.siteUsers.filter(`IsSiteAdmin eq true`)\n.get().then(console.log);\n\n// Remove a user from site collection admins\nsp.web.siteUsers.getByLoginName('i:0#.f|membership|john.doe@contoso.onmicrosoft.com')\n.update({ IsSiteAdmin: false }).then(console.log);\n\n// Add a user to site collection admins\nsp.web.siteUsers.getByLoginName('i:0#.f|membership|john.doe@contoso.onmicrosoft.com')\n.update({ IsSiteAdmin: true }).then(console.log);\n
"},{"location":"spfx/sp2016/","title":"SP2016","text":""},{"location":"spfx/sp2016/#lifecycle","title":"Lifecycle","text":"gulp serve\n
https://localhost:4321/temp/workbench.html\n
"},{"location":"spfx/sp2016/#developmentonline-workbench","title":"Development(online workbench)","text":"gulp serve --nobrowser\n
/_layouts/15/workbench.aspx\n
"},{"location":"spfx/sp2016/#deployment","title":"Deployment","text":"gulp clean\n
gulp build --ship\n
gulp bundle --ship\n
gulp package-solution --ship\n
"},{"location":"spfx/sp2016/#troubleshooting","title":"Troubleshooting","text":"node \u2013v\nnpm \u2013v\nyo --generators\ngulp \u2013v\ntsc \u2013v\ntsd --version\n
"},{"location":"spfx/sp2016/#react","title":"React","text":"-Renewing SharePoint Certificates on premise
"},{"location":"spfx/sp2019/#userprofile","title":"Userprofile","text":"Stream (built on SharePoint), the new version of Microsoft Stream
"},{"location":"spfx/support/","title":"Support","text":""},{"location":"spfx/support/#top-limitations","title":"Top limitations","text":"Maintenance mode
?maintenancemode=true\n
?disable3PCode=1\n
DisableTelemetry
?disableTelemetry=true\n
Debug localization
?forceLocale=fr-fr\n
Search vertical layout refresh
?cacheClear=true\n
Hide the navigation
?env=Embedded is the new ?isDlg=1 \n
?env=WebViewList\n
?Embed=true&sw=bypass\n```html\n\nFilter URL\n\n- [Generate Modern List Filter URL: Managed Metadata](https://piyushksingh.com/2019/05/24/generate-modern-list-filter-url-managed-metadata/)\n- [How to filter a SharePoint list or library using URL parameters](https://natechamberlain.com/2020/05/09/how-to-filter-a-sharepoint-list-or-library-using-url-parameters/)\n\n\nNews Links\n\n- [Edit news links](https://emilymancini.com/2020/01/16/editing-a-news-link-in-sharepoint-online/)\n\nto clear (debug) configs\n\n```html\n?stay=true\n
Error Handling
?test429=true\n
"},{"location":"spfx/support/#lists","title":"Lists","text":"edge://settings/siteData?search=cookie\n
"},{"location":"spfx/support/#throttling","title":"Throttling","text":"https://graph.microsoft.com/beta/groups?$filter=resourceProvisioningOptions/Any(x:x eq 'Team')\n
"},{"location":"spfx/teams/#blogs","title":"Blogs","text":"$t = Get-PnPTenantTheme -Name \"Contoso Team Theme\"\n$t.Palette | ConvertTo-Json | Clip\n
"},{"location":"spfx/theme/#section-backgrounds","title":"Section Backgrounds","text":"var palette = window.__themeState__.theme;\nvar containerElement = document.createElement(\"div\");\ncontainerElement.style.padding = \"1em\";\ncontainerElement.style.fontFamily = \"sans-serif\";\ncontainerElement.style.columnCount = \"3\";\ndocument.body.appendChild(containerElement);\nvar arr = Object.keys(palette).map(k => {\nvar colorElement =document.createElement(\"div\");\ncolorElement.style.marginTop = \"1ex\";\nvar nameElement =document.createElement(\"span\");\nnameElement.style.display = \"inline-block\";\nnameElement.style.minWidth= \"150px\";\nnameElement.innerHTML = k\ncolorElement.appendChild(nameElement );\nvar squareElement = document.createElement(\"span\");\nsquareElement.style.display= \"inline-block\";\nsquareElement.style.border= \"solid 1px #888\";\nsquareElement.style.width = \"12px\";\nsquareElement.style.height = \"12px\";\nsquareElement.style.margin = \"0 2px 0 1ex\";\nsquareElement.style.backgroundColor = window.__themeState__.theme[k];\ncolorElement.appendChild(squareElement);\nvar hexElement =document.createElement(\"span\");\nhexElement.innerHTML = window.__themeState__.theme[k];\ncolorElement.appendChild(hexElement);\ncontainerElement.appendChild(colorElement);\n});\n
window.spModuleLoader._bundledComponents[\"b6917cb1-93a0-4b97-a84d-7cf49975d4ec\"].PageManager._instance.pageContext.legacyPageContext\n
"},{"location":"spfx/toolchain/","title":"Toolchain","text":"install npm package
npm install gulp-sequence --save-dev\n
add to gulpfile.js
if (process.argv.indexOf('dist') !== -1){\nprocess.argv.push('--ship');\n}\n\nconst gulpSequence = require('gulp-sequence');\n\ngulp.task('dist', gulpSequence('clean', 'bundle', 'package-solution'));\n
"},{"location":"spfx/toolchain/#deployment","title":"Deployment","text":"# check\nnpm outdated -g\n\n# install\nnpm -g i npm-check\n\n# interactive update of global packages\nnpm-check -u -g\n\n# interactive update for a project you are working on\nnpm-check -u\n\n# unistall package\nnpm uninstall -g <module>\n
"},{"location":"spfx/toolchain/#check-package-version","title":"Check package version","text":"List global npm packages versions
npm list -g --depth 0\n
List detail global npm package versions from one package
npm view @microsoft/generator-sharepoint\n
"},{"location":"spfx/toolchain/#pnpm","title":"PNPM","text":"npm outdated\n
npm install package-name@latest --save\n
npm install package-name@version --save\n
gulp clean\n
gulp build\n
"},{"location":"spfx/toolchain/#test","title":"Test","text":"gulp serve --nobrowser\n
"},{"location":"spfx/toolchain/#tips","title":"Tips","text":"npm i\ngulp clean\ngulp build\ngulp --ship\ngulp package-solution --ship\n
"},{"location":"spfx/toolchain/#dependencies","title":"Dependencies","text":"npm install saves any specified packages into dependencies by default. Additionally, you can control where and how they get saved with some additional flags:\n\n-P, --save-prod: Package will appear in your dependencies. This is the default unless -D or -O are present.\n\n-D, --save-dev: Package will appear in your devDependencies.\n\n-O, --save-optional: Package will appear in your optionalDependencies.\n
"},{"location":"spfx/toolchain/#version-manger-nvm-npx","title":"Version Manger (nvm, npx)","text":"// check version\nnode --version\n\n// list installed versions of node (via nvm)\nnvm ls\n\n// To list available remote versions on Windows 10 you can type\nnvm list available\n\n// install a specific version of node\nnvm install 10.22.1\nnvm install 8.17.0\n\nnvm list\n\n// switch version of node\nnvm use 10.22.1\n\n# for spfx deployment\n\nnpm i -g gulp\nnpm i -g yo\nnpm i -g @microsoft/generator-sharepoint\ngulp trust-dev-cert\n\n# for spfx advanced\nnpm i -g @pnp/office365-cli\nnpm i -g spfx-fast-serve\nnpm i -g @pnp/generator-spfx\nnpm i -g npm-check\n
"},{"location":"spfx/toolchain/#eslint","title":"ESLint","text":"Why TypeScript
pluralsight typescript course
/**\n * Check if the value is null, undefined or empty\n *\n * @param value\n */\nprivate _isEmptyString(value: string): boolean {\nreturn value === null || typeof value === \"undefined\" || !value.length;\n}\n
"},{"location":"spfx/typescript/#_isnull","title":"_isNull","text":"/**\n * Check if the value is null or undefined\n *\n * @param value\n */\nprivate _isNull(value: any): boolean {\nreturn value === null || typeof value === \"undefined\";\n}\n
"},{"location":"spfx/upgrade/","title":"Upgrade","text":""},{"location":"spfx/upgrade/#office-365-cli","title":"Office 365 CLI","text":"http://sharepoint.handsontek.net/2017/12/11/asset-packaging-and-the-goodies-from-sharepoint-framework-1-4
https://joelfmrodrigues.wordpress.com/2018/03/02/sharepoint-framework-checklist/
go into solution folder
npm outdated\n
search f\u00fcr \"@micorosoft/sp-\" update all
npm install package-name@version --save\n
or npm install package-name@latest --save\n
gulp clean\ngulp build\n
"},{"location":"spfx/upgrade/#support-issues","title":"Support Issues","text":""},{"location":"spfx/upgrade/#azure-permission","title":"Azure Permission","text":"bs - Go to the \"API Management\"-section in the SharePoint Preview Admin Center (https://TENANT-admin.sharepoint.com/_layouts/15/online/AdminHome.aspx#/webApiPermissionManagement) - Ensure that no permissions are there anymore - Head over to the App Registrations Page in the Azure Portal. - Click \"View all applications\" - Click \"SharePoint Online Client Extensibility Web Application Principal\" - Choose \"Settings\" > \"Required Permissions\" - Click \"Add\" - \"Select an API\" and choose \"Windows Azure Active Directory\", press \"Select\" - \"Select Permissions\" and choose \"Sign in and read user profile\", press \"Select\" - Click \"Done\" - Click \"Grant permissions\" and \"Yes\" - Update the app package in the app catalog - Head back to the \"API Managment\"-section: - Ensure that \"Windows Azure Active Directory\" is already listed in the approved permissions (this permission should be here because of the previously executed steps). - Approve all permission requests one by one. Once this is done, reload the page to ensure that all permissions are actually approved as the SharePoint UI doesn't always behave as expected. - Wait a couple of minutes - Log out of SharePoint, close all browser windows and log in again - Access your intranet and everything should be fine
m365 spfx project doctor --output md > \"doctor-report.md\"\n
"},{"location":"spfx/versions/#check-versions","title":"Check versions","text":"In the F12 Developer Console, you can call
window.spModuleLoader._bundledComponents[\"b6917cb1-93a0-4b97-a84d-7cf49975d4ec\"].PageManager._instance.pageContext.legacyPageContext\n
"},{"location":"spfx/webparts/#dynamic-default-properties","title":"Dynamic default properties","text":"Connect-PnPOnline https://tenantname-admin.sharepoint.com\n$ctx = Get-PnPContext\n$tenant = New-Object -TypeName \"Microsoft.Online.SharePoint.TenantAdministration.Tenant\" -ArgumentList $ctx\n# Get existing list of blocked web parts\n$ids = @($tenant.DisabledWebPartIds)\n# Add the id for the out of the box Divider web part\n$ids += [Guid]'2161a1c6-db61-4731-b97c-3cdb303f7cbb'\n$ids = $ids | Where-Object {$_}\n$tenant.DisabledWebPartIds = $ids\n$tenant.Update()\nInvoke-PnPQuery\n
"},{"location":"tools/blazor/","title":"Blazor","text":""},{"location":"tools/blazor/#overview","title":"Overview","text":"wget --recursive --no-clobber --page-requisites --html-extension --convert-links --restrict-file-names=windows -domains www.yourwebsite.com --no-parent www.yourwebsite.com/someurl\n
"},{"location":"tools/dev/#email","title":"Email","text":"open last active window
code -r .\n
open in new window
code -n\n
"},{"location":"tools/dev/#vscode-extensions","title":"VS.Code Extensions","text":"settings.json
// Is git enabled\n\"git.enabled\": false,\n
// Path to the git executable\n\"git.path\": null,\n
// Whether auto fetching is enabled.\n\"git.autofetch\": false,\n
Info: https://stackoverflow.com/questions/30331338/remove-git-integrations-from-vscode
"},{"location":"tools/dev/#configure-vscode-intellisense","title":"Configure VSCode Intellisense","text":"Open Site Settings
javascript:(function(){var url = document.location.href.split('/Pages')[0].split('/SitePages')[0].split('/_layouts')[0];if(url.endsWith('.aspx')){url = url.replace(new RegExp('\\/[a-z A-Z 0-1 \\- _]*.aspx'),'')}location.replace(url+\"/_layouts/15/settings.aspx\")}());\n
Open Page in Maintenance Mode
javascript:(function(){location.replace(window.location.href+\"?maintenancemode=true\")})();\n
Go to Classic
javascript:(function(){document.cookie=\"splnu=0;domain=\"+window.location.hostname+\";\"; location.href=location.href;})();\n
Go to Modern
javascript:(function(){document.cookie=\"splnu=1;domain=\"+window.location.hostname+\";\"; location.href= location.href})();\n
Open Web Part Manager
javascript:(function(){location.replace(window.location.href+\"?contents=1\")})();\n
"},{"location":"tools/dev/#delete-node_modules-folder","title":"Delete node_modules Folder","text":"How to effectively delete node_modules on Windows
Firstly install rimraf module globally
npm install rimraf -g\n
@ECHO OFF\nSET FOLDER=%1\nIF [%1]==[] (\n ECHO Delete Folder: \"%CD%\"?\n PAUSE\n SET FOLDER=\"%CD%\"\n CD /\n)\nECHO Deleting folder %FOLDER%\nrimraf %FOLDER%\n
This .bat file should be available under your \"PATH\" environmental variable. In other words, you should be able to run it from any command-line from any location. The easiest approach is to just copy this file to C:\\Windows directory (it's absolutely safe).
Open regedit and go to \"HKEY_CLASSES_ROOT\\Directory\\shell\\\" path.
Right-click on the \"shell\" folder and select New -> Key. Give it the name \"Fast Delete\".
Right-click on a newly created \"Fast Delete\" folder, then New -> Key. Give it the name \"command\".
Double-click on the default value for \"command\" folder and under value data enter:
cmd /c \"cd %1 && fast-del.bat\"\n
"},{"location":"tools/dev/#link-checker","title":"Link Checker","text":"copy($$('a').map(a => a.href).join('\\n'))\n
function Get-UrlStatusCode([string] $Url)\n{\n try\n {\n (Invoke-WebRequest -Uri $Url -UseBasicParsing -DisableKeepAlive).StatusCode\n }\n catch [Net.WebException]\n {\n [int]$_.Exception.Response.StatusCode\n }\n}\n\n\nforeach($line in Get-Content C:\\url.txt) \n{\n if($line -match $regex){\n\n $statusCode = Get-UrlStatusCode $line\n if($statusCode -le \"200\")\n {\n $line + \" => OK\"\n }\n else\n {\n $line + \" => Error\"\n }\n }\n}\n
"},{"location":"tools/gatspy/","title":"Gatspy","text":""},{"location":"tools/gatspy/#blog-template","title":"Blog Template","text":"git log --full-history -- src/path/to/file.js\n
"},{"location":"tools/git/#github","title":"GitHub","text":"pandoc -o output.docx -f markdown -t docx filename.md\n
"},{"location":"training/react-learning/#libs","title":"Libs","text":"cd C:\\ProgrammeBLS\\projects\nnpx create-react-app quickstart --template typescript\n
"},{"location":"training/react-learning/#jsx-tsx-converter","title":"JSX, TSX Converter","text":"More Infos
(Source: @ChrisO_Brien)
## Tools
kOqnRrPia63hB0xxC5Wf5-izBB_;H_ zf^sVSx_&$q+h!dzkd9Zl+CzQ@3P!Q!jb-e4E*leV&(D^2Ji6o-Fw~I{MI7WaQy&8t zfCBv(XsVUq{)$DUCmX=>#k-G&Yt5;UmDn z$U^7sY$M9>U*j-MoE+?lqzcj(_=17cCAN)=pFc {ZoC_ZM#_2;eLct>1dxo4YxTfR$>j}@6Z1r9Aljs5x7ixK) zx1?FNOGg#p;b3$nfl@zz{Gd`3NPK!~NdG#-zmM}44l*;5r3rRcf^*vhPx53TxzW-# z^V@6a0^mu25w(@Qn;2Zl@+!F{stUI9kcH-kNzh!C$odM_H7~Gx0>NV$wr$cGE*HQk zHnl=SLrNG?jN3Q) 2qyvKi zEob6pN3oYjAX h*1h;Wl{RXHSL$PKUprd&%Ytszaj6h7!m3j@ m!XQ}XzC+=>Z!dur?&A#z&IcKm zILv|n2tEvQlm6|nsIU>2>P4R|M;p-uwBzwxuo+`Z -Pss15)1oe zP@oS#F#QYm1xN*Qvlh9rhk?waK>TwNm{8%5HecKR?Usa}ZrI5t(j10AU=XqwcA850 z{rdsZ!hlu;mo}^y;P1aQ7%V*jqN{eOjRtxDc0%B{XtKTb%OL;#&o7o3C>H e}DHx(BB99pMUZE)&I9%)_EDI+i8*i{1EUYSwLC9 z6da*xAfKf9MI2Y3N+aaT>MSJPPyw{5^QKqr}F?CBxh7_tRvfONq0Y9HAO9w;KPW z{A5G3o3Dg}w}1t| zCgxvxD*Vq5UMffHBd;1-!_aKdBfrJF6 z;K2X Ba&FZ=)AlQ7!V^>+jR z&o!G40HrrTlmG!kCrpBht&IBx?KIMZz)lXDVAc3(?#z=z|MxG%O|$(+ZHW2~^bo_D zGYJr5&~CL3U4=D(wHp8!^#0_vDTKhVR-1L0=-P63!s =_Kt#Fi(=a;U}kEH+Vq6) zutJUhTQw#kARv(aWS~qwhe2j>aelrL(r5soNQHMF2U8!Q(O D&PA zdoO@{6QH6fYGZ~)76KL0AYoYrR*j7ELw7zye3dx=ZP<88IXFcvIvL OB4#K|D?0AD5dnUjvdue{alxlO_N3re059l kRWA0k8nz-wQw>G}VJpuKTCQ31UZwUN4CF5s$)`f1wulp@Bj0V`HynbY$I# zyF<67kTpo0Hz4={mNk5`t!v0z!18Tv)4;)PG`=hv0oRF}gQMc>p ||63 !Omtyp80a(u(`A7{S79+rK)|T07$e z@DIQq)GFw>>$>> q_nEv=A=n4X@A!-Tz#IS;g(i4IT&^YPu9Y=3 z+CjTRG-_{e*9CSSA%sXxZ`i@QaTj@Dkj4u1NJ2K71{hEZ+4Te4gmhWrpb!Wf1_LJe zK} d@uzkbjMRrJ#Z3bRo60!vt<;=KsZM!nAm?hqs^HSkCmKo?VJn`gGb+~8 zjQ^~3m}WR=kX2nbkn@A*r~C6Jz~dCy1`}GuF4E2=*yl5?5t7~khP%2v+i#N7>l!_s z2f=chIAq(jf_-l;sL7UHWS9i``ULEq)&z`DR4zKGw7 +%ECVw&tFRb?C9O<=% zh2@qE|M`gw%>9xZf%&}Z^JWKXb}Vp=h186?gLh!ibpdxCYNHcg!v*F@AchdV#=^=< zxG62)_sU9Zcu28bE5if9{#B6g(gdw?)QX(YU0YjQ; ASql;FgUiN=(c9uRk`*s8GYxl7Mf1!)P z^m@13^RsESFL#H)ZLJ5g5iBc9f4Jx7bPmiQ_bp*y3kOkOJE#)7ev+(N9$UU-tPe(i z@VFxK=TB1H5$8}L_Padhd}zWTJvB88$_PaKcMpm=kDv(VS&%v }4(YB!ko#3?;KRNaim zNnp!UZ?o@ZJMl}SF<2_OYKA3Y(%qvr>+(-s_d92QeQxS|PrFgl-rvC7KSZ_W`R5MT zO$RUlAtr_S&cGr9n@1_Po`DCM71j?mC~(#@oYY*{f}pEdlqnFgP?~#e!AH*_{Z@HW z$jJW|eP6CK7`&;u=CL|nVT38dnN{6^R(?zZr+Q;c;~jx~#e>b)IJQdm4*yiu(#aAj z95-UUy9Tyxo;T9$)wUu$92{~QlFOm&lOD5!gW7{&UEUh7Y~{mr50^44%#9@k>kzc& zAq&SEg1ZB|%)yI+U=6ToFM X@EQ;fUJb( zGAhaL@6&wiC_tfk1qK!mVS;W2@p%&HZE_pC1K+-FKmz3O;udeHjC-wMW>Xjx_4H4c z5R!X(d|7*D_e86g5~=qxYPm?qXEDJ(aFTdJoH#4$-PT2Wm-e7!XzF+AzOTitXd&0> zxD&lwF6F6*kbjn*RrU)xjCgvv=2k=>`LEkrh6HF-B5>qZP@XaQE_g7^%plZrz0VGG z9%MHoec{qZf_Teyy(7UI*>9weQb`RzN81Q-tOnO^eMm<0r&zUmWMIAt-8m)6F8k#c z_)hsM_>~;Obwnd-`)lEeMHT!En@tBivX@3tZ6J8%{`}X!iD!hH^w q zCl!bRsxliSDBK5gA`+=4+9?$!Yj@|biG!aYcq6^09u%vsuyF;q^y< X@Lv5RPws>q9 zbeEgHadT;w;#KWTRu#{Umj0s!_==P2PvV(nOBhM9R8Q0tk0vLr^4_oGO|9X%tgg-Z zzNz7Xbfg4riIiqWzfYRh!o(7j^u?Broy^mb8l&9Ki`*Q=MHw5@@AczCrR7uGZv75R z&!8^*1Min-G%2Or)OCEO2+n=3dkmmJNl8i6iDWyj{eKKMFQ*a>ETj^u?DOt;_lma^ z-@w%QUahj0>F=B96-7PO+AhDdJ{}ZN+>~-`>a{ds;QYq()9q=^&X1#W{>wo|LnBlP zzNT#0VzT?OgTt(jty(Q?Pnzkq3# cp<){zg1Ah6IaU>OLePLc~|GQA)UCmnVW7hRVM=QkmP zCd+ztJawf0i^*{Ru=vv%L$eEDJ?@qXISMO0pwq-mTP(x9=Tx@U>EW(tWgA5|oubSS zwtssfQ)vEPL 8au^^<))ivi6MQy0?nTZ2EW|Qct=f z;MfrxRG7D}{;9ogQyEp53^Pi?-orG0g6`Gb8?~`s=-F#wqim9MB_{ati s `CSGX7iLPRM*`5e>5+4gs*5zN1 zOw#S^Nd2~+V2V>pV2zAV6ys{`(GK+Ya4Dor=qQo3Of ?LHm9<&anRE#qT4KT-GO %hAWpW`2Zkys0kH zc>TxzV$xe0{%S$RjQX?&Vg9S&cod#mUszFDm^hpK;ZC{mJazu4;Ca& C&$?8&%S#_vrPJ)_c$Y88sVIM*L1I~{PBpllM}N5&ne`h)5Ksrg zqZ@$= e6Xt`*_2 20vgQ9ozm*=vW}rfGQoN z(gaeGG}xG?lNC1J%%~9|htE}kIvh};zBYULkbrmZGQ2>;qCFmCX$_0(eOT%#oAv>G z=`;%n^Hw|yn+hfkgE{f>=FWoiTbjdN*>);nTf3bFtGTJQg}Z|e45wHs*j@-+y?Otp zYW4>l^|WBt_ZEy?QG41C^li(M_`>Gf+6L2XSieqRn-206Nz0A9r{?-kksdh#j?QoQ zZ?@1MJ$>Qi_pR+c?*(J%1b;qH9~~ShpY^0`$JV)h%IoW|CojZ>*!(Vv5+!d~Tr7W^ zB5d_weIukg!{0{naA|15Plpw&?u~PGk*7(CSCWS9-n?&bF|IrRBre`KM*q~#wbp8% zN~?)beazaZn)3Qc+);Lht#2BeQt#T!6jHdIszruFm2oL|S@j92^7KvD)*gP*5~;HC zZYc~Hym(7BWNLf90eKTDmt!Z3 p5&v-F5*HzeM$utsRCVjG6 g{rqos5PuQ&_sL@k`Oyki|>UJ{!4QhY^p8bcnF zP6?YGoJemBz9;;!Pd52au|(p+;U5eFeI09#qG48>oYUmB)W>5p{Z1DUv{OBv@ynx;}t2=e5EvM>*WH*CofiiEvi`B_tY&XdvXWuw&J~)fL zA2Sp=5nWR*rtX|`%fz==$=kovS)))bQ$t?*N{)0){sWH6(86VcWLL{#PZ(_u1y%0c zm6fflCGl)Ey7+z-WGE21bL=83{`cq4PFQEVju#gUhbOF1b8oNlzSlray}uzgh+2h~ z14Xobcz!H3-@7qh4wMKHsI`R54Fv<@-lh^CA7U+#3$C+S))&!Lzf~Fejcu3f7bwP= zC!QmDh1^_RA5l+fzB@(I9L7jCbMp3v>a#wXqit^S 3sn z1-Bq|)OFW!)}HV3mxUIo{u!}7Upp$gTRuGHYF>Hcuff~jyd3o~iV0J{N4Q!t!CCEA z+WHDU&aQ|7x!!?oQFqz+f>{4bs!h$PubA*jHsYU+nmG`mzK|=Rn850$pTK#~x;1On zx_TwtlDOx}u54PLn|az^>kaSfq!4kpXFLxqKanF)-C}lSXYJ8b`|c3hUi; 1Qc|(qvNxZn(k?$f$M;fjrsmBftTulD)h8Zi{pc?orKhGleru9ZQGlOKAK`g;_ zm?3U1RnM-dO(EfGx gNx=EQ|C>p-H(!~om1#atz9$#rRiE=cGDu1T&Vfrrfj_BA;C1<-< zR`}?Df7P{skR5?VbS%DUzz&|j-%iy&xS@xpvGO`IP(Nmf2i !{?_&1=fTdslp^OpPdBJ zz`T0jWB?98WR@`Ylc=*m>j99mu*f6rtZ#NW(J4>MfYwJblduI_Y^DM~e*1|KwHcP? zMJI3XVhEkEUzG}m=n2?u1<2&cs)p00A<3zjc}vh#=tO`c)7p3kLM*^M=D0l5YXDO( zLXN|#55fD0>AWvJHT6ef56M9Ec3`2^@qJf>ust`<2Rxl@etMcRIJyxu*YZtCGk;KC zgJEk^yCS_`(?afmlGf@&f6uuSw2t+SL3Kxzl^s0N&qgpcZ@}fbsWZ5lTeBM!$y8!r zEP@SgN_*13Fl}|jf4fJ-D~!=xc>1pbKkmQSl#*&xy@{F+LofJjDr?Is)aZU*DB;yp z?rl#c2i~dlpBp_gyj7s-C(``Ps5!y2dTFsVeCixfE!At$`|FTw5RzWT-Lrg#-!T2) zz#`UyhYe9ghT(AWFacx_owSjoNz6MPZuyJ6aHH%wp5Jog0iDvDuB-*I?diWNdI>v5 z=ZmK<6bW4Vi-r4|#HaXBe(fbq_n@Ihg@@&3!k&sB3TbhW=f5PHQ#&|tDr(bg`BFzF zY2%zlT5Fp{Ip0Cig{;s_9yzWrUL+Q!$`|FraV8(^&*^zE$GVfzQw?lxp+j7c+Z8s( zUZsZ(HY$`W1cP9#a$$1dLh_hduvP18hSsXz+KmNV8v5fVlamfwp*XB^rgcKdUe4<} zJy&xq%>~Q&dgTif#=iDVpgtvqPG6iH^x28i*6oRNd|bs W`Shj(p*>u5Ur^B?z6(>e#P3?5hFvFrE;w}^`ZkdXF*c(!I0vXzf3Q{ZC>@G0no zxbOlCYvkH#27P)~R0~g-MyNwA`X)i$*WRmLSWbFJ0R2K&nY?q!zk##$eEX3Yd=j0m zue35&Kv=WZM6IQm;JnZG5Kr8nulJuU++LjUn!RT;ar^VpNP3c3$gAPbI}0r0+A0@! zG@bi?WseJIz4?2w=75NC1tfunn_ECP8!}Q5N)>(hyOzNT9~5ar(=BgevDB#mwY~o5 zJy^KwY7u#E;3mX8N`g!bfi=QDf3`QC9T`amv6(Us^3+^brt}x7pu)0-94R0Un-G?s zR0kk>H49A!i>%FK{XL1<*)0=Z<(5L+KpDd R)w3!}(bFeRP$M zqUIWItk*{;tYJ(D$C>gT `D{&y$-@G;c%eU%H{3p~ACySm!sbEPXD!@=ek- zX+L`Cn)mRDHx=(g(=X|*O0jafy}w@aMQt NTQP+^fkgo0d zpzsOgaT|xnO$1=|L&P)7Eh!-Tb7fH*1Y0$E$ mUuc5I~8!a2vXwh|K*`QTK? zwQB8!Xu7e|;Wi72u7&n<)edQlyXyyfeMo*STrz{7W78Q-_%c3sIMh-noNH^{N2_b* z6y7;e`5HqN+VyfW994?y&iVN&t#kRiJ@D5t-1? yc19;ph(+l2^9CmS%if zVEtI>RbGb@-mV3U>Sr2heflCgdroZ3G;}9eTj56LK4?6r{cobbB^7i P^f}?hcZbg# zao|yhMC*wh*$?jz_3q>043BboqT6Z`0bUsIV)LEC`;Ho~e`u2zN<6~jrD7A-u22ii zsqnf6)5WB;(~r*Y#kYi)U&LXT>1weQ^d5Xqi7@I_=mLQeOF8E69xwN%puzP(|9n z%rRmIvt}!ZseVT2lJeJ>XMl|61KbhO(?M@YJsO0XCR$fSwtWW`0tkPAzc(v3JWn&f zyeyo4`&q-r^{rp@pN0C)=-fO)cu6cNtK82cl|`+d2@w)+$;aU=#w^vEL@L^y?#+GT z_Hvm+&s}(^WgX%j<|kNfNX{uf+*a1@Ieeapga $0Z9&9A3`Pv5(x_EIIb`GAbLNvDc0af{S;-hHh# z^XYbvmpkx4k98*b4A<18eX_LQ99nI63Y9!hSu1@K_9Y_m-g%!AT{^yW4&RSOa>r&? zG-WnC-?%Bpk}srGtnxL!VxDf)*=CKFRNun@+rCkMweSXWif%pNaZ~ng6yMV18m!>h zSo=j`n!H+Fks8Ouee351AC*|rRelwn%Ggz&A94#f`r>YotT8uaajG8KHQew!3I^uv z))@J0vZ&(1u_nFNT|W;yfi_9YQ#-jGRRjxBo1T@0$;)Sz+^R8;PVL<2meRhsd)1&h zJ&ZkJqlagl5)d7Dtcok`a*O6d9f5m*E`U|~Q^KM2B`SI0pI(^8mJG^K_mxhIWr!ng zyY;Y;_gk7}!v?`8RK*}i_K<8 ~TzI$2Q?YW~WmC6muE_W?GK saDQ)V#7XlgVJl0cmzFZ>1R5Ekj+pgKs1v z6BDo6^tnHAemzpy`(sd5OxZ(Py|%C0V)r+Kdp !YBV(a%cO^ZC`H*GW7fm(t?+>vF+HyDvcDHBO6xHa= zho;q0s+2i}B!-O*#cXnk4$jl`J 6y Vq*5kK)@@lj%1*hx0cZ>`#3`yP_&|Bua z5lwVY+)eP!a%FzWu-;-T=ewb!dQcK?mtNJn9<4S~L)x%kQ$4`UUN2QnpC;7m%BrFO z9@LM34FfQaa8yde!JDAl(nnWi9QT3TBuZXYA<7vFp&gp&sW)Sy8+Ot{6NNH0rly%| zBKd7#z`74RJ1qgvjIrB<{oKjWB1A{ AN_J;XCeFEVC(6X*u4Hk$SG_?&9}n=c;`7#PL|TF>jsS;j}V>%|gB+ zp)g?Tav8e?s#6Hb`gCx5a&$BWn1yPBR*Ik_+`p0I*_nMt P(6v9l= zBy0IV@Z^@j?WEMi7rf^gL^j-wq)l@-*3L7yB>CkVS%HyUeZn+E!S$U})1=g(&J6x8 zK93@>;ABmURpf%zL~J26i@0LImlF3aocH5|vz*x({f)8Ojf0`_>CQ)m2^O{OH2Pt& z#C2J_RtK_^PFo2Q*nxb-x#4iQP+U{)MQO E-uM*U=EVj{raq=q1B2xo_6 zd0p7V)mj^Uil8H4Nn(&;=USY0^Ir^Xp8EP(>(Hycvj(ZJZyu=Gx*^{<8>+!KHfwP6 z#c$j26)!%eOH9&N?iJ7IUW*IXto&Ro;F4;aA!Fqe)V2^6@LEq%tE<$HUZMfLP+GkTe;yug@N4DnUE?+E^mF;oPe(d}b*JS4*+#o^GjYbUNS=9u%{LN;ba4ne}V4dP;Ei<^?ej&!-U$j|ch1~PHtSHwAm1>Mnw{ES~Rjs`?s z=t_LsIc#xOc!>p%*O23i4^DY`RU$pLU#~o95%nWcEK2z1 zy<$l}tCd~XkLG+WRO)>AaT*%F16yiM*09Z(J_w lDOj7%sK2 ^%!F$ zuU4a-rc?Rq@{Wo?LW$7RnI6omqmV(R6Tw@45hU6pRq}9CP%IncMb7NS6F2;ZrNYos z)?NLb#OJVi!1ux_;A_F|KL&bj*Xb-+L3Pj}*Q gE>gQHy@iNUTFn1x9Yf(zlw(S_f!9eudjfLs%!rx6a)zaL|Rg5kZzRj?vgG6 z>1IGhl W7y``!P0?^&){ENAA-KKtzR>}Nmw7x!mM1;lu_ zc{*%V1@{$}%ZQzl6do6b8_e;^5}1b>k2E>4M#Jk}WicJ24+b;?E?q;GVIB$E_g?KR z{Tig+BKWkrL<3>xKzNb`l`*$?BiGm}J34F~a0Sud8fqI)AT|uUt;xnsCdqtW4{@Yb zn7Q-|nBi5nWe5%%W))$@6Wz|=B*=>c(-0R8oZ8MC&<}?II|T?6WM8_7rB}EdBUmb% z@)WicE~_MY6kG)B)}%F57!zOZ@N=_WlUcaSrv_xcO}6~)Vo=MYs@XHqtDU|xq~^8P zylkjntBJYWizU`K*%@4#Ah2V2p8iuMCka_|rrap7szCeuefgr1l$ihnoq!)fuNOVC z?ScKSyGgOaA%s8+F^iE3I#v3^x0T@U;h?2wX_*IR#r{|Zkh(jgd}^g78j9O~HPD;k z1qoC$9(&tiyO^EyQ7Jmb_Ix<=KDX3tiB5S|zvYMXcFj9Z17?wu0X{q|1HkR`yM#fx z$PzbvBCBbeRP`+1`u0oJ%BwqE`S=>}IIcg_tPIUFGH0;NLm-#b)Wm~$o}D#6$Ir*8 z18k#`H@gUhUkn=7WwB!3fV5~9r@B_?o9+AYRwc 8x}*&5l^)HC~Rhvz ?_pEId@w=zStEozE!C&O;VQPyD(RDqAWt5KIDFRi(+9%v5-mlrSn6z0f z;gM%BcP1c&wNNC|(NH7wZCr|0b~4A0L69d~RpH0Pky2bbRk5|&d15%ax!AAb)nBF^ z4MNv{!+L+s0gxG}zQ2@Qzn%S D;J%K}2GZ~Vl5@B^Q-G(`WrQEPC z!gjW^igMvn9QRdIBkhyZ{v0_d4HxFs1I{xY3yWfIZtgbN3b+gO!1pYFS2f?G0n~Hv z>JS$!i_d6%*)lH0h0mPUX Z^N**S-}DW)cGeb_Mu^3ibb_~z6`T@gE0-t!TY@v*Cfj4mAJV+JE81m_OeUZ zD&;Kd(Pt@L(a6T{TgVUvu=pJMPHVLe->8iW(@|;8TrcZT&DzWS{kToNu_|^~NF=mv z7;Z?4jm@6Zd0DJrgFK6+3g0#zYw5wfV9!EymsOSM@cccpvS{INt!4eJx91$pv|1(a ze7S!)fOPRLdd~o2gBxitvji0ggZCdkQ_1%k)uQudtFjdLy5jY~4Fe|fZ4I7)@~q8I z{hk3xYXjq1r(myY4!}TUXTrn9jgN(ZEb+)*7FQ_a(Cz!g!QWT_1PLmzkoLfQT*3=> z)NpZ?;5-m}^@e47CEUBtFI0%YKu8&pR=iKKM`x4zA<$hf4ayl>op~oYIN5xQ^BLCLX^2& z`*B#*P2U~-?qdq(kYC$5&hp%-IS+V$vMPWW#|z_irb)0 of3v#Df|JxrTS9(Vs!w~Q$!uDV>5}7ipam-kIOyi zA7HshyPX@3+YF08p5MSMW;T$&o7vU?8-7wF*Z?GPYO&za(X~#k!a=f-Il&gMvY_L2 z*#l~WU460HGVwnE;ApBL6}*}QEZBN4pq1ajk*pWwrArGCz#0Wl-unVnG7@4LkY9ir zV5A$^W|_IyF2T>wAc7)EE1}p{md8%*Y(8CoWgI~n`bgG`C!@pPoMw0Mn-pCbr8<5W z{kV3he{PY>%fb2$iwg>}!>EiA8Ec&~$>8F}@T_V9$3E+KTDMis*OZcXwU`ic?MZDG z&;cKMEN~GY`K&s1&F&AbW)BCnyD_jpgYntb*q27Y(OC_gQYlXfAs$BaTK-4tLk6 z^i^ZNM{zP(I^UI~-_I2k(={7eD(Hti<=*{*qFP(ySfB*;4R9x5e1i_D+bjS5xtUvS zlDC!gsOO=$)$tBHwA*$H?zd&dwvjTdC3OCG+#5m%9ymbdV%GBlkiM{pf_IPi=4ZFv z!QyPuH{Ie*jM+oZdvx3VegT^cW1UFs-dmo*&7G - sQcC3}Z`$eeu zo>1$nOJ;J
+zLa$tt#uE9p2?JtXb>&|HWC*Iwy zZWTh+o+5-pg <>LP=XDXgaHL|I@;w6uhdBPXmJ+sV^! zDt8ErI&NKc3~(2%)^;`0?@!0fT2HHaRhjpAc&LnoHC^wi@4O^Du{TPv{ks3qDbH}2 z!c`?Wn!YV{KIej>A>a0cPsz(kOBc1OGHlOW7gH{dh_dDRs6bpDu`Ww%hBMuvoyq{> zUA}|(B V8JSFs-fhy6Ol3roh>;kE(X0T;#BGuv@drR*$FQO8(sjb?UFIGf zosd(z)XE5ly<|CV W}`3@VK0%xRro0I^x{Rw%|GEKkeh!OxWFKkh$> zgeFa%qq3Y9!0&{^3Ibm5^cVVKn=iNX)pT!!%Zd;T@i$*FFsQ1j#f&%IJ&3B&k7#{b zG%rG>0d;cs_6eTK=LcT~hsTBv&nidyg0<>us~kl_meuzZ+>%Dr+euPs63vA8-s0$X z#YIjqMsZ(;;TLnWu0$OwUwG78oe5!HwZCV$SiA>#mo!U|So4MU$LL$CaBtO1<%H#p z{*gmnSs92#ggwsfS=8Zd%ea0zX=uUs!>@11 S`yi~Ea^K*n(koNZ zO5oxRNwbHJfhYyr8U*UntI4fyi}6RzIYVv%9b%t9(v|gUtry2DDuu%BSaGW4119Mc z%Kd=mRVgg$?RfuuNRJt)2Spyu5OrYW))z0igeaYdA-L5T_pIwnde@41l!^CjzU-lp zITD;IDhW=k T)qZu6aK kkxyRRY)I6q1x2ztq_uOP6s`=cib~LHIPl1$zfuQOVL%+7T>w5z@l7bOH5D&de;v zU#Rm|k$8?)3Pt@hkmS7N>;hSp#R?LY+(KU0mniu%?3yDMhNf~) |5sGL+sHUf&>N`{qzk}CI$Q8 sLKcL*zhQA6<&VA^%k1I>6 b(@O zgU6V!#ZJY2dG3dLa Bb4(h(%GaUnT2!N_G5Iq1aW7vD6UoF0Ois~0} zQU(TVi&6k&awp}(K~Q=Gm=L2NkyG5i=Vqp=f1aKP_9(XRWL%ozCrrE{&{mmQoTruA z7NPViW6AKtouMc(DW}6k*#HR58yb#yNlRYf$cv7Rt-dj^);!z^RGdJb4tRe6O|Aw^ zltAd}yW*?}5Va-?15yv!dE}Ad;fjS&S?N-Y87^dy_JKI23gGBTeEhwGI}i}ha)B+N zR=sm!L?q!^pd%2M$&!gT#Qgx&p@slMlQy!aC*^_cJFqWkiLkmkoURrN*kA@uAjL?M zzFR>s;*>aUhluSq8}+D+JBnQIJYZ)JDKWA$4z}h9lH{IUsr=w^)b huR H656Kv(#1lFnfkDtEAxteqI z!)DWK2$n{VuG~mJ^agOmLjFseC Rnm?i(D6SyT!f!; z-s$kMSJ{EPVGeew*lj$vbF(QWn{Q4N?<}=w-@X7b0{za&xfJkerR3z)fB;^8%2WfO zF#xh@N$b@u0CZmh&iO7ExtU@bF(f6O7;+kQyZ^;PBdoayjV(`_Up$!`o{V)9R%D%; z^{Pvf^ck=a0DO`$K z!=1L?oyW-Wn6i94ov*8#+g528$tVEZrvq{a0OpQgCM*EGaUcry>d!Sp<#-j?X4wML zNrh^d>6Ll;ND|`+-SUDr#!j^vtIN4~00meKq-?j^{2n?#r~0Fh%rR#`E}X9lVf|$% z8&-FMHc>jb;PBxbxh1oEeqMKPZ!aPbg8%TZ9<}a}<($vBvjJMTX}a8|yHjoiJqYv< zoPbo~ 19yCVpkks1W2!`FvepEGjX*4> zKUydcaPh~1DslqOhdZqmOiWcE>!d884i?402KYO`IZgs~P8te|b{&%rO@ImLk7G%n zm^=p{7U1n74>&Is8Hdb2qt*2^t=IzrVMq#4=N+LwIzRv(V4`$Zsz9;2cwz rr}7!S#ycm7;O`b>HG^It$9V%JiTmqFN}8cvE Zg_F8YbF3-kMGo1E-o*nXp6lYf$RdfOO=~k zlv_WMXY&g|cL>qql0X%f$Tn`u{_av>rgH_ NsE_Nz zKI=;YI*=_p$Oz>4$?7vJvaTLh0khByP#gp 3B!OKTSNuJy!;RUpvZ0XE+3ph>_5=eDty;BM_$%%gur2kQ7T`^~paKrq>&`1_2A zvfdRokowXq(n4JAi)ZBlV(+z2x`BRrK~*Zh$3&hySaTx1_+v=uv}t+$gXVc!4T^@Q z#HlGMMF3U|NM#5_44j d~&Ym~fulOCGCA6HjZtl!);eDg=t_o)i}FV=9$H|UG6t?v{7ZV9aDnC^7=Ku#Kw z@t4d7cyum7F%mdp5%C%R(a;Yxv?q;nnd%s0wY^u{o}B3e_4-8*iFsk4GlplW^xNG| z_9o=K>YY`ZzE@|kiDPR%`7ciEJ0nnP0bn~RX@`&=u*Z9MZ15K;DK6GKohHmWH94GV zov}ts`pbcTx t zRwi c_EO8b$qI<=0!E9VHj z3|6$;UpkZsjJ!G{oi3RF^52BaKfg2+)%M*XLG>h^5l;t`2lq5;KzBi%q~36ML|k^J z8o1H@ufti5*)x2;jWi|z{6On(QRn^a|L&f@T0@P4p`Q_vZ);Numnv$i?Ra~KrTxDT zp?q~NN4dZ+g0#^(UghZi1En5<|N1etxid!G6T+1e_#fA`Sidua`fq(;d9%Kk*%lTb zLh=P&*mRrIg{i(${vU(#?*>$8nW4yz-&g;X?*IK^5lS*X+qlhc{Z!$90QG-=5Wxq9 z3nUc)sk6GgOb*1k?^I!d*@;$T7cu{++=`%`mG5H?8O3In*TxOSSbkma7dZZ =Fr2A*BZIAv#q5Dr85D4z_-x(k; z2--p5DKkPg`&qEg*|PXHa3?oH5GbBwU$N&GmQT*vM6#%g-v8eW>|Z!)1sY_M>ryYA zE-qK^C(~Pcrz(=AxI1gO=&r2gIqxPcE?f-Et8RNF>&Sc0UU$;}Z_YXZ@*06=tiO=Z z9k_QJ%XZ#MeRkv;7i&7dnJKg{$ARXpLEC7U){p#R*LvnZmFoXogwR7S7q>-IV!=}_ z?31%CN=Y8OIvJB@-I9(HN_NP5_V0k}@P8lXP6IBi9I$hT4W>=OS}Lvb4Rt3w>tZt- zm`!^4-IvJzi)8%g*R_(5_F_3<=k*KRhI)FQ{_+m~Mwzun`H~)q)&Kh^-kIU?I6EId zvNQ=T{Z~G^{l5;#(LJ5;bbkdpkDz~jj-7aLZkIR7#-Jod|0ZUjm5h~bPsIOOYuf1j zzn}gfcAxmq_Zc~CA0sf50eURJzC}`ktboh)KP&LRI; h5zwwuE(ERe{GW8{g03E-DY=0 zAK4?1#Hs4W<+Idk55eH!iz~=f=D+=Ji>cP@d-hK17WU1~S}tjBszT2^6Y}q;u5) #Y5fWJ=Fk_sX;y{eRB%*I&P0>;@jKg+JTaH0Y*a7@%GX zo%y%Nq%Z+Q+}tByY~l&X1~Mu1<|_365w5n~b^=thNt-PXym@cVqxqaWW*SNVt@mYr zUteE5!}N8$JfL&)hI?5vHtWrVm^(p>Xxch>HN|G!O64&Y6RWP5la>!+-|oW Duu)0W}guNDbwBbp^gd}8FF7p0x_@!htv^&T+NkN9?R@HlagTmnET!_V$;qqS{ zX8jG;W1CDpHvD{-m>&UQV6ChL=5^C}}yFv!cV}5 %^a%35MK~egm+f%tifX>qXJD2>sI @gL0TJlHg*A`uf=_FR@4~ zObWNX%_rqzPY4Sb`H`c_t&`E=kZS+i~vfV;y3@M#Y;2biW zO{XyW5zQE9qG6>?b+W!WBWt%psm6zM>&6@PD`)jci<`S YPz5*70dj)F6+O23u{p~Pp>*@=!e90b?GK>J=58libmnjh{UWKNOdrD z$35m8-B1?NNCn}7`IaxDRRwvRO`e!W2D!a0o*NO4aJ=p{JHGTU%&?xC`-S?<>afx# zVu04+2B~miG^q0uTQMy(aCJGeb%j(_^B~cEa9ZDd$bI^tvNLNikRy-XyXc>d2UJLT zLQJ2Q5l)!Vc Pa$q?9QzVT2P*D_fpNcbCb>bBFviDR+96Q%~wp^~1 zID>ly6)1L#3up1s7E;|Cd5)+I*M< zKYR z82#9+2US!Pw^!ec3OL&v@$@P`pel5TV3x|i(OF_cV!N0Yv@9`;4|$)M%~`EpbT<6C zc9_84ZT#eJL?~26 zEva}1ndb7k9mhn~jh>x9ZmnUE;-7t$R%x-niI_%(L+4~&FahUPH&N=KY(*pZwYO oCv~J%YtH|b%m`Cb{ - RH>g<7$3FBGdxN+klhS$sPODI>Mzw^rrnz$Iu4Q$
^O4h+<(yL|P+IEh?rs?5yHo8<3m)*n||_z+i!5x--mc}cc#JUzia zUH*cy6@R0`eQn*+?97_As7CoyagpoS+cIrBeQ$YjN=Z%VWpz4=6WRi{^YR|6knk5j znu^q7`|74N_9V#}v^7{_-%1_)kYo*4=ro(hT_`qa`DTBszj7p9`Ac`#-9YFYsy&aM z@f`Z5XI|8#tGu^a$hz22h@G^4!7HThRwu!eKS#=tKYnkMmI+VN1UhK_7B`Xf^i`&p zb8w<3%4eFiM9O5f3H8OitcgJq!HIJL1Byj++lgKD=R>Nr{gW N;DQXXx(b1z=wODRuX9kC+qQADmWW9D`7vIXjJxA zt5j|5 3i?ZKyi@iK&_IU~KHs7^|6zF~D``WFvH@KD(xg#g80Xj7qw z%+J~FWio6CpB2F8`PVEjP7W`Wq7%@gB5So%n+UTr`k +aGDriB}!e!Lblzf44huW`;POcPsOSmNkpT;w-iW+*JAG6OtL7fN91F+|ME) zzD$9aV9GYr;NcToV#^Yua1PNvMbGFPj7Y<%-~K|H$@RI%X&n6kuHW}%-iAjz?_+B7 z=w9JIExg?;Zz 7$CGuEJo%pD*eI1ehf6T6-`~^4?JUZ$e2*10#xQ!~-@a(H9m%OLR^M}biSAQ_ z+MT`JcYC2qi*)WTrPO3UnlNOuE@wSZ;HE6HABY&XqRl~l>CXp9srGt;8{*ht1>b48a%*I*-2} z2-CHbnm}be NCoBK&FmgI&$Le6ewvB=^)#0-ft^m8_3z9V6V7tq zv5M?Zen&&hKReC=xDa!ZP0DLMLh_YLGy-mFMd?)ep{Df=d?ll(FrEylN9}396qQZp zh_Z?DlQ9E4Yrd3p*Y^?-!_Ar7UHb|3sjj~(nKbdr9|YI#&gra8vuaS7-LsmiAr43+ zPPfhw0uAut$ZbqV^@&jvko<6>-la;dD)WRW8^J|9v=?iRH{q$AnY_B-(=sF7w`a%* z{xl1>DGNdJ!v}|W1b(9ZLtGF&b4%Q1Wr2e$$D)&;7i5(Ms7WZPbOcu2xN9s+qk?8V zhZe+Iy_Y=P7gpjezY(_;55Ax8`1ZS(SAldO89HVL@sfm0&nTt;J=Ln<<>cHSCa}nX z40f{fsvf0$4Krg+xZ9Rr3mtn5FJTdWmyx26le@lv!>c!+(>Fp(=kbNk(ly%Yy93T+ z4XS{H_Fh*8v%j$b93A5-G(V{^2m~P!AM tZ_6dsiO!W=l4Y&_- z_k o`;(kEH4)FdFN(L zIaLT8Hui}s#UF-h^Usdwdt5N7WkW2^%jc){d6DYXCw}tg?;MYPLDl|iP$6JF%E?)i zW*2abGi~M`bS4XH$qmrN$t`)zTIt!^O^reulyG?!W_n*DkGn$hjy?DFtHNquX231E zxT*s|k?-S#r!#%tGT+>JFN~w3Q7{`k@;a;yRK`g2^qM1QN?$igML(Kl33AnnL{XE4 zWY8>)Tj#ODhr?zI<>NY85$|}x=8@njE(?gRTyrYCF0+sLRhV#aZ|PG^*9}4oJOJBf z0%phCPZkE`6NX=tg)R8jb-o)J{^ajeq44^cG_%J=Yk&EuKAW9theucN6pi81XfTkl zC?!i2(xA)F6nP9&B)&OG(&3$PshQN>B9o-O-kK$t+_;_Vz8n(@beP)+SU{ZYe#ev7 zjv5N3{B$|buj!(>yOge-n(!m>WAP;at!+3-l`H1 4I{sQ LeI5uz9{)JB!il`j+ItRruIJm|KSe?#DyBN300|dm zq#Vg*>E4Go*6zWRVJWH;(J3l3i?Nmi$d7S-KTGtxn>NMVdL@p8;B3xaeBrd^N%$e# zYii+UIX>(Ly{-B+6Dl3d;!l {u1tf`8|x*ASrU@p!2P@)lXs-?|M->vPR2$8G#MgiGqK?b_TjShLO$DU2d60 z=iKs(U`tfh(B?+y0PXE&^~{B2gc24 c2TRej&wrnOTwx#TnV+mJplE3m?eJXxHtd-^ zy2`j^I=_vZXz`r=!QsITjXfGhWN2VU*~(1qwG-92Jt20}Ew?PmkZJ_jjNm*O`Le#q zqdL9sZEgf6QFWUwMU%`#q?e69)TwoK9RAE@*@+ez6si~8^50%v^z{BBkA d!!LP$%>wQxQq*+^%P(WFYI2+mJ3~hYZ1?0vDv@n>KS{4YDTZw~<$|DO}MY$bb zYNIzwqeo4!G`j@PE~mr#hWy&%ve8=TwPpFj6< =ZYC$!!je z6*x>z*Y;pW$@#LTX}U>rf49ta-HEW^>p`{E2cOV7wWh_W6g3;u0FFtAddY}6WE_rl zx%rvq>#9h{1D3L*r&M0i 9a zMepF%OIqnDBNR;fxxprAf{t^d#CwSJ1ez8YE5EOwjyF-U<95@V8fri=)Vr~4Bvp6r zdHq^4b$7se=;&vR_4uNuPg^I3x&~%(e5Ds-PF~gImz|qbi}@_uZO=yQ0hoqtvGOzR zyG2hggqg*}a{kBorI;?e>-FmG;6h`UIMDOHg;2@7ZF~L#S&muft;`T&J5|hQVU-NS zHD00s^w%VOJQ!6!{n~3on%w>2`A~?rY qz3Bq zdjy8yM@){LUL8evq=xQs@k_{zO97<(ZTx7l?`*2XUg7etAG)42_T4JdFJ3Jn=;^Cq zU~Gi2lzvv|PvP_)m^;gBHRs#Uol7L(v?9s1BPn){@V@Yf;G>tnp5B*qyww$L)gCN8 zR%YyON-xMmd4SyZ+*6f&b !NQk7|+ zZ;+>v<@G^$e9+#sqb7s+qKEHAtu;+?LO=pfngvoXr>C-=fHlrtBg2cfk)#pOUS6b3 zX9T}ap8p{HJgZeQ Ae)e{c9 z6rq{HJxUXy-Z5k|&F= kXg-zAYGxX`KvTlkIoNaR10u^}CWEm4Y8>mxm=5Dt6i zilprAjV*b@x1(BuDEvA8{PVrbs|UwHwd2!SG4h|q-jPJK5jPVJywcz3NDPosyPa)A zHj;VwmHMK}&X{Sz-8l@FMk8ZS4N(Y}H|3>-)VxB=;P-n9X=lrl3wqf$`f92brH$N3 zqRt6Las|Cd>y%cz5v2pQj9ySHC9JbxR{85G4jSS6mUnEA`TO4TEj$%6q!wuDBQzS2 z3L@_lIsPg+hc}v9eOnWygU!-IBj^@WVUTjgj)6jcsrlSx(C8<&PT$9~fwS@L#!ya? zILVqV0Yj9={%cPALAn?Gd=|9jqfc2XbACR0EUR=$zih~=S;L3-B u>dx61AyBE@YB%Ch%)l`O-wT&=#`&loI<%P~>mjVPkD&INIkj)`138XCu>L4F~ zyap2!na}ckae1~e0%~(z@)Sw ^?Bmu10o~=#9prN=ja-;m z-hD`+^C)bbu0t`iH$7T&4#9IVJ`}(A&1Jw4YCd>|u?MpY@QZ>SYQUkE=nZ Y*&O5S9uy>y*ddk)g>sF#Xx9N93!gyb}*s|oRck(I;eaSp(=~t!K zoQ(Ml4H;oMLk95VzYbk>_If nOAr$Z1tETIMm71{K#nj=j$&Q0!xZ z`o+0VdxzPQ8_3xzOtvLwRm>O-S1=z++P)t3xBDrQHP025VTwFGZg_L`&|13g;L|~; zcpOKa+asaf)-%nTnnG0j7j|CS*Rfe#p{m4!)KS0__3KwhpNF)Flm}f7HAbIVpOf;c z`k#dz?ehgdTX7;K+P*GnT#AN;34F_QC-uXWGMVVJ6R8goa>AeRy1-e*Q A!x6p^SE5kgT44>|0-<~rMHjc;qs`x *%0Mh_@igBZ)Zvh3#Mib z^{HPPBBdo=yQo+2w1e%pJw8uyYu)~QwJ!F@tlm74U%12q7 rdUiMvPBxD5J$eWCa$aPf29k;&3ATxsd5RsKPE+aP0Maxve~u zZ8ti!l;yTsk#R_-{7*D6+34DZj-8a_%dT7s1VTlS+P`XMV6qzIFt%S>FxKAB9E&rQ zAaLOSHn3Xv)xe^!#txgw+R~`o?9A0PQ`{(zDf@#s7We(kAtv9|jQrB$hsYRlV)H^; zZ|-H)M=}$pWpSlq3l5~`%!$Y-J)uEk5qa+O;9>4)S812>;netOyo1L_UdbFyee(b^ zJ9F}O22=7UBXKx!7KYa@l!5n)IV6$dIg;B4nKJp^6MAmlSW68|-g~%XJ?z6SKlaUU zEWnpE5B!{mu1);ttpq2