diff --git a/.github/workflows/cleanupnightlyreleases.yml b/.github/workflows/cleanupnightlyreleases.yml index 6f1e47531..014a4640b 100644 --- a/.github/workflows/cleanupnightlyreleases.yml +++ b/.github/workflows/cleanupnightlyreleases.yml @@ -11,18 +11,14 @@ jobs: # This workflow contains a single job called "cleanup" cleanup: # The type of runner that the job will run on - runs-on: ubuntu-latest + runs-on: windows-latest # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v4 with: - ref: dev - - name: Setup .NET 6.0 - uses: actions/setup-dotnet@v4 - with: - dotnet-version: '6.0.x' + ref: dev - name: Unlist nightly nuget packages env: POWERSHELLGALLERY_API_KEY : ${{ secrets.POWERSHELLGALLERY_API_KEY }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 21ec4fcb3..877aa9e91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,105 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). + ## [Current Nightly] ### Added +- Added support for `WAM` login for Windows OS to support Windows Hello, FIDO keys, Conditional Access policies and other secure authentication modes. +- Added `-SkipCertCreation` parameter in `Register-PnPAzureADApp` cmdlet to prevent creation and uploading of certificates in the Entra ID app. +- Added support to `-ValidateConnection` in managed identity authentication. +- Added `New-PnPSearchExternalConnection`, `Get-PnPSearchExternalConnection`, `Set-PnPSearchExternalConnection` and `Remove-PnPSearchExternalConnection` cmdlets to manage external connections for Microsoft Search [#4231](https://github.com/pnp/powershell/pull/4231) +- Added `Get-PnPSearchExternalSchema` and `Set-PnPSearchExternalSchema` cmdlets to manage the schema for external connections for Microsoft Search [#4231](https://github.com/pnp/powershell/pull/4231) +- Added `OverrideSharingCapability`, `RequestFilesLinkExpirationInDays` & `RequestFilesLinkEnabled` parameters to `Set-PnPTenantSite` cmdlet. + +### Changed + +- Added output for clientid/Entra App Id when using `-Verbose` with `Connect-PnPOnline` +- Added `-OutputTask` switch to `Add-PnPPlannerTask` cmdlet which will return the just created task so inspect its ID, ETag, etc. values. +- Improved `Invoke-PnPGraphMethod` cmdlet now to also support a hashtable value for the AdditionalHeaders parameter besides the current Dictionary. See documentation. +- Improved managed identity authentication for connecting to different M365 services. +- Improved error message for `Export-PnPPage` cmdlet when the page doesn't exist. +- Improved `Register-PnPEntraIDApp` & `Register-PnPEntraIDAppForInteractiveLogin` cmdlets to better work in non-commercial cloud environments. +- Improved `Get-PnPDiagnostics` cmdlet to properly handle a scenrio where there's no correlationId. + +### Fixed + +- Removed version check dependency on version.txt located in Github repo. Use metadata from powershellgallery.com instead. +- Fix issue with `Get-PnPDiagnostics` cmdlet not working correctly if `CorrelationId` is null. +- Fix issue with App-only authentication not properly fetching tokens. +- Fix issue with Power Platform cmdlets not working correctly in non-commercial cloud environments. +- Fix issue with `Get-PnPFlow` not working correctly when `-AsAdmin` parameter is specified due to API changes. [#4244](https://github.com/pnp/powershell/pull/4244) +- Fix `Connect-PnPOnline` not returning correct `ClientId` in the connection object. + +### Removed + +### Contributors + +- Erwin van Hunen [erwinvanhunen] +- Giacomo Pozzoni [jackpoz] +- Nishkalank Bezawada [NishkalankBezawada] +- Reshmee Auckloo [reshmee011] +- Koen Zomers [koenzomers] + +## [2.10.0] + +### Added + +- Added Register-PnPEntraIdAppForInteractiveLogin cmdlet + +### Fixed + +### Removed + +### Contributors + +- Erwin van Hunen [erwinvanhunen] + +## [2.9.0] + +### Fixed +Fixed app registration on Windows + +### Contributors + +- Erwin van Hunen [erwinvanhunen] + +## [2.8.0] + +### Added +- Added in depth verbose logging to all cmdlets which is revealed by adding `-Verbose` to the cmdlet execution [#4023](https://github.com/pnp/powershell/pull/4023) +- Added `-CoreDefaultShareLinkScope` and `-CoreDefaultShareLinkRole` parameters to `Set-PnPTenant` cmdlet. [#4067](https://github.com/pnp/powershell/pull/4067) +- Added `-Identity` parameter to the `Get-PnPFileSharingLink` cmdlet allowing for the retrieval of sharing links based on the file's unique identifier, file instance, listitem instance, or server relative path and supporting retrieval of sharing links for multiple files, such as all in a document library [#4093](https://github.com/pnp/powershell/pull/4093) +- Added `Remove-PnPAzureADUser` which allows removal of a user from Azure Active Directory / Entra ID [#4123](https://github.com/pnp/powershell/pull/4123) +- Added support for `GuestSharingGroupAllowListInTenantByPrincipalIdentity` and `OneDriveSharingCapability` parameters in `Set-PnPTenant` cmdlet. [#4122](https://github.com/pnp/powershell/pull/4122) +- Added `-AsListItem` paramter to `Get-PnPFolder` cmdlet to return as folder as a list item object. [#4151](https://github.com/pnp/powershell/pull/4151) +- Added support for handling `$ErrorActionPreference` global variable to make it work with PnP PowerShell cmdlets. [#4079](https://github.com/pnp/powershell/pull/4079) +- Added `-Folder` parameter to `Add-PnPDocumentSet` cmdlet to allow creation of document sets in a specific folder instead of the list root folder. [#4029](https://github.com/pnp/powershell/pull/4029) + +### Fixed +- `Get-PnPTeamsChannel` and `Get-PnPTeamsPrimaryChannel` returning `unknownFutureValue` as MembershipType instead of `shared` [#4054](https://github.com/pnp/powershell/pull/4054) +- Fixed using a AzureADUserPipeBind with `New-PnPAzureADUserTemporaryAccessPass`, `Get-PnPAvailableSensitivityLabel` and `Set-PnPSearchExternalItem` to not work when passing in the User ID GUID [#4123](https://github.com/pnp/powershell/pull/4123) +- Fixed issue with `Get-PnPWebHeader` cmdlet not working properly in Group connected SharePoint sites. [#4147](https://github.com/pnp/powershell/pull/4147) +- Fixed issue with `Get-PnPTeamsChannelFilesFolder` cmdlet to work properly for channels having data more than 2 GB. [#4127](https://github.com/pnp/powershell/pull/4127) + +### Changed +- Fixed `Update-PnPTeamsUser` cmdlet to throw a better error message when after a user is removed from a Team but is still in the connected M365 group, for the few seconds that the 2 are out of sync. [#4068](https://github.com/pnp/powershell/pull/4068) +- Changed `-FileUrl` on `Get-PnPFileSharingLink` to become obsolete. Please switch to using `-Identity` instead, passing in the same value [#4093](https://github.com/pnp/powershell/pull/4093) + +### Removed + +### Contributors + +- Dan Cecil [danielcecil] +- Reshmee Auckloo [reshmee011] +- Giacomo Pozzoni [jackpoz] +- Koen Zomers [koenzomers] + +## [2.5.0] + +### Added + - Added `New-PnPLibraryFileVersionBatchDeleteJob` and `New-PnPSiteFileVersionBatchDeleteJob` cmdlets to queue a job for deleting the file versions based on age. [#3799](https://github.com/pnp/powershell/pull/3799) - Added `New-PnPLibraryFileVersionExpirationReportJob` and `New-PnPSiteFileVersionExpirationReportJob` cmdlets to queue a job for generating a file version expiration report for all files in a document library or site. [#3799](https://github.com/pnp/powershell/pull/3799) - Added `Remove-PnPLibraryFileVersionBatchDeleteJob` and `Remove-PnPSiteFileVersionBatchDeleteJob` cmdlets to cancel the job for deleting file versions based on age. [#3799](https://github.com/pnp/powershell/pull/3799) @@ -34,6 +129,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - Added `-IncludeSensitivityLabels` parameter to `Get-PnPMicrosoft365Group` cmdlet to retrieve sensitivity labels assigned to M365 Groups. [#3991](https://github.com/pnp/powershell/pull/3991) - Added `Get-PnPFileSensitivityLabelInfo` cmdlet to retrieve sensitivity label information about a file in a SharePoint site. [#3994](https://github.com/pnp/powershell/pull/3994) - Added `Get-PnPTenantRestrictedSearchAllowedList` cmdlet to retrieve existing list of URLs in the allowed list. [#3997](https://github.com/pnp/powershell/pull/3997) +- Added `-IsSharePointAddInsDisabled` to the `Set-PnPTenant` cmdlet which allows disabling SharePoint Add-ins [#4032](https://github.com/pnp/powershell/pull/4032) +- Added `-RestrictContentOrgWideSearch`, `-ReadOnlyForUnmanagedDevices` and `-InheritVersionPolicyFromTenant` parameters to `Set-PnPTenantSite` cmdlet. [#4024](https://github.com/pnp/powershell/pull/4024) ### Fixed @@ -45,6 +142,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - Fixed the dev build process on Mac OS devices. [#3907](https://github.com/pnp/powershell/pull/3907) - Fixed `Get-PnPContainer` cmdlet to also handle pagination in case of large no. of containers in a tenant. [#3990](https://github.com/pnp/powershell/pull/3990) - Fixed `New-PnPTeamsTeam` cmdlet to better handle error specifically such as `Conflict (409): Team already exists`. [#3992](https://github.com/pnp/powershell/pull/3992) +- Fixed `Remove-PnPTeamsChannel` issue where it was throwing incorrect exception. [#4036](https://github.com/pnp/powershell/pull/4036) ### Changed - Renamed `Get-PnPSiteFileVersionExpirationReportJobProgress` to `Get-PnPSiteFileVersionExpirationReportJobStatus` [#3828](https://github.com/pnp/powershell/pull/3828) @@ -53,6 +151,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - Changed `Set-PnPTenantCdnPolicy` cmdlet to allow PolicyValue parameter to be an empty string or $null, while still being mandatory. [#3937](https://github.com/pnp/powershell/pull/3937) - Marked `UserVoiceForFeedbackEnabled` as obsolete in `Set-PnPTenant` cmdlet as Microsoft doesn't support this. [#3985](https://github.com/pnp/powershell/pull/3985) - `Get-PnPTenantSite` cmdlet now returns additional properties like `ArchiveStatus`, `EnableAutoExpirationVersionTrim` and many more. [#3987](https://github.com/pnp/powershell/pull/3987) +- `Add-PnPListFoldersToSiteTemplate` cmdlet now wont export RoleBindings which are `Limited Access`. It caused issues while applying the template. [#3918](https://github.com/pnp/powershell/pull/3918) ### Removed @@ -60,6 +159,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Contributors +- Maxime Hazebroucq [mhazebroucq] - Paolo Pialorsi [PaoloPia] - Marc Studer [Studermarc] - Mark Gort [markgort86] diff --git a/README.md b/README.md index a593e4065..16ae67008 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Both (1.x and 2.x) can be installed in the same machine with no conflict. ## Supportability and SLA -This library is open-source and community provided library with active community providing support for it. This is not Microsoft provided module so there's no SLA or direct support for this open-source component from Microsoft. Please report any issues using the [issues list](https://github.com/pnp/powershell/issues). +This library is open-source and community provided library with active community providing support for it. This is not Microsoft provided module so there's no SLA or direct support for this open-source component from Microsoft. For more information about the PnP initiative, check out the official website: [Microsoft 365 & Power Platform Community](https://pnp.github.io). --- This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. diff --git a/build/Build-Nightly.ps1 b/build/Build-Nightly.ps1 index c5de5bd71..2e9b23de8 100644 --- a/build/Build-Nightly.ps1 +++ b/build/Build-Nightly.ps1 @@ -84,7 +84,10 @@ if ($runPublish -eq $true) { } $corePath = "$destinationFolder/Core" - $commonPath = "$destinationFolder/Common" + $commonPath = "$destinationFolder/Common" + $coreRuntimePathWin64 = "$destinationFolder/Core/runtimes/win-x64/native" + $coreRuntimePathArm64 = "$destinationFolder/Core/runtimes/win-arm64/native" + $coreRuntimePathx86 = "$destinationFolder/Core/runtimes/win-x86/native" $assemblyExceptions = @("System.Memory.dll"); @@ -98,6 +101,10 @@ if ($runPublish -eq $true) { Write-Host "Creating target folders: $destinationFolder" -ForegroundColor Yellow New-Item -Path $destinationFolder -ItemType Directory -Force | Out-Null New-Item -Path "$destinationFolder\Core" -ItemType Directory -Force | Out-Null + New-Item -Path "$destinationFolder\Core\runtimes" -ItemType Directory -Force | Out-Null + New-Item -Path "$destinationFolder\Core\runtimes\win-x64\native" -ItemType Directory -Force | Out-Null + New-Item -Path "$destinationFolder\Core\runtimes\win-arm64\native" -ItemType Directory -Force | Out-Null + New-Item -Path "$destinationFolder\Core\runtimes\win-x86\native" -ItemType Directory -Force | Out-Null New-Item -Path "$destinationFolder\Common" -ItemType Directory -Force | Out-Null Write-Host "Copying files to $destinationFolder" -ForegroundColor Yellow @@ -105,7 +112,10 @@ if ($runPublish -eq $true) { $commonFiles = [System.Collections.Generic.Hashset[string]]::new() Copy-Item -Path "$PSscriptRoot/../resources/*.ps1xml" -Destination "$destinationFolder" Get-ChildItem -Path "$PSScriptRoot/../src/ALC/bin/Release/net6.0" | Where-Object { $_.Extension -in '.dll', '.pdb' } | Foreach-Object { if (!$assemblyExceptions.Contains($_.Name)) { [void]$commonFiles.Add($_.Name) }; Copy-Item -LiteralPath $_.FullName -Destination $commonPath } - Get-ChildItem -Path "$PSScriptRoot/../src/Commands/bin/Release/net6.0-windows" | Where-Object { $_.Extension -in '.dll', '.pdb' -and -not $commonFiles.Contains($_.Name) } | Foreach-Object { Copy-Item -LiteralPath $_.FullName -Destination $corePath } + Get-ChildItem -Path "$PSScriptRoot/../src/Commands/bin/Release/net6.0-windows" | Where-Object { $_.Extension -in '.dll', '.pdb' -and -not $commonFiles.Contains($_.Name) } | Foreach-Object { Copy-Item -LiteralPath $_.FullName -Destination $corePath } + Get-ChildItem -Path "$PSScriptRoot/../src/Commands/bin/Release/net6.0-windows/runtimes/win-x64/native" -Recurse | Where-Object { $_.Extension -in '.dll', '.pdb' -and -not $commonFiles.Contains($_.Name) } | Foreach-Object { Copy-Item -LiteralPath $_.FullName -Destination $coreRuntimePathWin64 } + Get-ChildItem -Path "$PSScriptRoot/../src/Commands/bin/Release/net6.0-windows/runtimes/win-arm64/native" -Recurse | Where-Object { $_.Extension -in '.dll', '.pdb' -and -not $commonFiles.Contains($_.Name) } | Foreach-Object { Copy-Item -LiteralPath $_.FullName -Destination $coreRuntimePathArm64 } + Get-ChildItem -Path "$PSScriptRoot/../src/Commands/bin/Release/net6.0-windows/runtimes/win-x86/native" -Recurse | Where-Object { $_.Extension -in '.dll', '.pdb' -and -not $commonFiles.Contains($_.Name) } | Foreach-Object { Copy-Item -LiteralPath $_.FullName -Destination $coreRuntimePathx86 } } Catch { Write-Host "Error: Cannot copy files to $destinationFolder. Maybe a PowerShell session is still using the module?" diff --git a/build/Unlist-Nightly.ps1 b/build/Unlist-Nightly.ps1 index 2886a2d69..f695b7413 100644 --- a/build/Unlist-Nightly.ps1 +++ b/build/Unlist-Nightly.ps1 @@ -2,30 +2,30 @@ $ErrorActionPreference = "Stop" Set-StrictMode -Version 2.0 function CleanPackage { - param([string] $Package , [int] $VersionsToKeep, [string] $key) - + param([string] $Package) + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13 $xml = Invoke-WebRequest -Uri "https://www.powershellgallery.com/api/v2/Search()?`$orderby=Id&`$skip=0&`$top=50&searchTerm='$Package'&targetFramework=''&includePrerelease=true" $result = [xml] $xml - - $entries = $result.feed.entry | Where-Object{$_.properties.Id -eq "PnP.PowerShell"} # There are other packages not owned by us that contain this string. - + + # There are other packages not owned by us that contain this string. + $entries = $result.feed.entry | Where-Object{$_.properties.Id -eq "PnP.PowerShell"} + $sortedEntries = $entries | Sort-Object -Property @{Expression = {[System.Management.Automation.SemanticVersion]::Parse($_.properties.version)}; Descending=$false} | Where-Object {[System.Management.Automation.SemanticVersion]::Parse($_.properties.version).PreReleaseLabel -eq "nightly"} - $releasedEntries = $entries.Where({[System.Management.Automation.SemanticVersion]::Parse($_.properties.version).PreReleaseLabel -ne "nightly"} ); - + $releasedEntries = $entries.Where({[System.Management.Automation.SemanticVersion]::Parse($_.properties.version).PreReleaseLabel -ne "nightly"} ); # keep last 10 $entriesToKeep = ($sortedEntries | Select-Object -Last 10) + $releasedEntries + $key = $("$env:POWERSHELLGALLERY_API_KEY") foreach($entry in $entries) - { + { if(!$entriesToKeep.Contains($entry)) { - Write-Host "Removing version $($entry.properties.Version)" + Write-host "Entry to be deleted - $($entry.properties.Version)" nuget delete "package/$($entry.properties.Id)" $entry.properties.Version -ApiKey $key -Source https://www.powershellgallery.com/api/v2 -NonInteractive } } } -$ApiKey = $("$env:POWERSHELLGALLERY_API_KEY") - -CleanPackage "PnP.PowerShell" 10 $ApiKey \ No newline at end of file +Write-host "Starting cleanup old nightlies job" +CleanPackage "PnP.PowerShell" diff --git a/documentation/Add-PnPDocumentSet.md b/documentation/Add-PnPDocumentSet.md index ae5386e44..cd48326e0 100644 --- a/documentation/Add-PnPDocumentSet.md +++ b/documentation/Add-PnPDocumentSet.md @@ -15,7 +15,7 @@ Creates a new document set in a library. ## SYNTAX ```powershell -Add-PnPDocumentSet -List -Name -ContentType +Add-PnPDocumentSet [-List] [-Name] [-ContentType ] [-Folder ] [-Connection ] ``` @@ -29,7 +29,12 @@ Allows to add new document set to library. Add-PnPDocumentSet -List "Documents" -ContentType "Test Document Set" -Name "Test" ``` -This will add a new document set based upon the 'Test Document Set' content type to a list called 'Documents'. The document set will be named 'Test' +### EXAMPLE 2 +```powershell +Add-PnPDocumentSet -List "Documents" -ContentType "Test Document Set" -Name "Test" -Folder "Projects/Europe" +``` + +This will add a new document set based upon the 'Test Document Set' content type to a list called 'Documents'. The document set will be named 'Test' and will be added to the 'Europe' folder which is located in the 'Projects' folder. Folders will be created if needed. ## PARAMETERS @@ -61,6 +66,20 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -Folder +The folder in the site/list where the document set needs to be created. + +```yaml +Type: FolderPipeBind +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -List The name of the list, its ID or an actual list object from where the document set needs to be added diff --git a/documentation/Add-PnPListFoldersToSiteTemplate.md b/documentation/Add-PnPListFoldersToSiteTemplate.md index db7f22d2c..5bcb9d474 100644 --- a/documentation/Add-PnPListFoldersToSiteTemplate.md +++ b/documentation/Add-PnPListFoldersToSiteTemplate.md @@ -111,6 +111,7 @@ A switch parameter to include all folders in the list, or just top level folders ```yaml Type: SwitchParameter Parameter Sets: (All) +Aliases: Recurse Required: False Position: 4 diff --git a/documentation/Add-PnPPlannerTask.md b/documentation/Add-PnPPlannerTask.md index 78562acfa..72f990b8c 100644 --- a/documentation/Add-PnPPlannerTask.md +++ b/documentation/Add-PnPPlannerTask.md @@ -23,7 +23,7 @@ Adds a new task to a planner bucket ```powershell Add-PnPPlannerTask -Group -Plan -Bucket -Title [-PercentComplete ] [-DueDateTime ] [-StartDateTime ] - [-AssignedTo ] [-Description ] + [-AssignedTo ] [-Description ] [-OutputTask] ``` @@ -31,7 +31,7 @@ Add-PnPPlannerTask -Group -Plan -Bu ```powershell Add-PnPPlannerTask -Bucket -PlanId -Title [-PercentComplete ] [-DueDateTime ] [-StartDateTime ] - [-AssignedTo ] [-Description ] + [-AssignedTo ] [-Description ] [-OutputTask] ``` @@ -61,6 +61,12 @@ Add-PnPPlannerTask -Group "Marketing" -Plan "Conference Plan" -Bucket "Todos" -T This cmdlet adds a new task and assigns to user@contoso.com and manager@contoso.com +### Example 4 +```powershell +$task = Add-PnPPlannerTask -Group "Marketing" -Plan "Conference Plan" -Bucket "Todos" -Title "Design booth layout" -AssignedTo "user@contoso.com","manager@contoso.com" -OutputTask +``` + +This returns the task as an object to inspect specific values ## PARAMETERS @@ -233,6 +239,21 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -OutputTask +Returns the just created task as an object to inspect values + +```yaml +Type: SwitchParameter +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + + ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). diff --git a/documentation/Connect-PnPOnline.md b/documentation/Connect-PnPOnline.md index beadb9e00..af58501a4 100644 --- a/documentation/Connect-PnPOnline.md +++ b/documentation/Connect-PnPOnline.md @@ -56,13 +56,6 @@ Connect-PnPOnline [-ReturnConnection] [-Url] [-CreateDrive] [-DriveName [-AzureADLoginEndPoint ] [-Connection ] ``` -### Web Login for Multi Factor Authentication -```powershell -Connect-PnPOnline [-ReturnConnection] [-Url] [-CreateDrive] [-DriveName ] - [-TenantAdminUrl ] [-UseWebLogin] [-ForceAuthentication] - [-ValidateConnection] -``` - ### Interactive for Multi Factor Authentication ```powershell Connect-PnPOnline -Interactive [-ReturnConnection] -Url [-CreateDrive] [-DriveName ] [-LaunchBrowser] @@ -119,6 +112,12 @@ Connect-PnPOnline [-ReturnConnection] [-ValidateConnection] [-Url] [-AzureADWorkloadIdentity] [-Connection ] ``` +### OS login +```powershell +Connect-PnPOnline -OSLogin [-ReturnConnection] [-Url] [-CreateDrive] [-DriveName ] + [-ClientId ] [-AzureEnvironment ] [-TenantAdminUrl ] [-ForceAuthentication] [-ValidateConnection] [-MicrosoftGraphEndPoint ] [-AzureADLoginEndPoint ] [-Connection ] +``` + ## DESCRIPTION Connects to a SharePoint site or another API and creates a context that is required for the other PnP Cmdlets. See https://pnp.github.io/powershell/articles/connecting.html for more information on the options to connect. @@ -127,46 +126,46 @@ See https://pnp.github.io/powershell/articles/connecting.html for more informati ### EXAMPLE 1 ```powershell -Connect-PnPOnline -Url "contoso.sharepoint.com" +Connect-PnPOnline -Url "https://contoso.sharepoint.com" ``` Connect to SharePoint prompting for the username and password. -When a generic credential is added to the Windows Credential Manager with https://contoso.sharepoint.com, PowerShell will not prompt for username and password and use those stored credentials instead. +When a generic credential is added to the Windows Credential Manager with https://contoso.sharepoint.com, PowerShell will not prompt for username and password and use those stored credentials instead. You will have to register your own App first, by means of `Register-PnPEntraIDApp` to use this method. You will also have to provide the `-ClientId` parameter starting September 9, 2024. Alternatively, create an environment variable, call it `ENTRAID_APP_ID` or `ENTRAID_CLIENT_ID` and set the value to the app id you created ### EXAMPLE 2 ```powershell -Connect-PnPOnline -Url "contoso.sharepoint.com" -Credentials (Get-Credential) +Connect-PnPOnline -Url "https://contoso.sharepoint.com" -Credentials (Get-Credential) ``` -Connect to SharePoint prompting for the username and password to use to authenticate +Connect to SharePoint prompting for the username and password to use to authenticate. ### EXAMPLE 3 ```powershell -Connect-PnPOnline -Url "contoso.sharepoint.de" -ClientId 344b8aab-389c-4e4a-8fa1-4c1ae2c0a60d -ClientSecret $clientSecret +Connect-PnPOnline -Url "https://contoso.sharepoint.de" -ClientId 344b8aab-389c-4e4a-8fa1-4c1ae2c0a60d -ClientSecret $clientSecret ``` This will authenticate you to the site using Legacy ACS authentication ### EXAMPLE 4 ```powershell -Connect-PnPOnline -Url "contoso.sharepoint.com" -DeviceLogin +Connect-PnPOnline -Url "https://contoso.sharepoint.com" -DeviceLogin ``` This will authenticate you using the PnP Management Shell Multi-Tenant application. -A browser window will have to be opened where you have to enter a code that is shown in your PowerShell window. +A browser window will have to be opened where you have to enter a code that is shown in your PowerShell window. Alternatively, create an environment variable, call it `ENTRAID_APP_ID` or `ENTRAID_CLIENT_ID` and set the value to the app id you created and we will use that value and authenticate using that Entra ID app. ### EXAMPLE 5 ```powershell -Connect-PnPOnline -Url "contoso.sharepoint.com" -DeviceLogin -LaunchBrowser +Connect-PnPOnline -Url "https://contoso.sharepoint.com" -DeviceLogin -LaunchBrowser ``` -This will authenticate you using the PnP Management Shell Multi-Tenant application. -A browser window will automatically open and the code you need to enter will be automatically copied to your clipboard. +This will authenticate you using the PnP Management Shell Multi-Tenant application. Alternatively, create an environment variable, call it `ENTRAID_APP_ID` or `ENTRAID_CLIENT_ID` and set the value to the app id you created. +A browser window will automatically open and the code you need to enter will be automatically copied to your clipboard. ### EXAMPLE 6 ```powershell $password = (ConvertTo-SecureString -AsPlainText 'myprivatekeypassword' -Force) -Connect-PnPOnline -Url "contoso.sharepoint.com" -ClientId 6c5c98c7-e05a-4a0f-bcfa-0cfc65aa1f28 -CertificatePath 'c:\mycertificate.pfx' -CertificatePassword $password -Tenant 'contoso.onmicrosoft.com' +Connect-PnPOnline -Url "https://contoso.sharepoint.com" -ClientId 6c5c98c7-e05a-4a0f-bcfa-0cfc65aa1f28 -CertificatePath 'c:\mycertificate.pfx' -CertificatePassword $password -Tenant 'contoso.onmicrosoft.com' ``` Connects using an Azure Active Directory registered application using a locally available certificate containing a private key. @@ -174,7 +173,7 @@ See https://learn.microsoft.com/sharepoint/dev/solution-guidance/security-apponl ### EXAMPLE 7 ```powershell -Connect-PnPOnline -Url "contoso.sharepoint.com" -ClientId 6c5c98c7-e05a-4a0f-bcfa-0cfc65aa1f28 -Tenant 'contoso.onmicrosoft.com' -Thumbprint 34CFAA860E5FB8C44335A38A097C1E41EEA206AA +Connect-PnPOnline -Url "https://contoso.sharepoint.com" -ClientId 6c5c98c7-e05a-4a0f-bcfa-0cfc65aa1f28 -Tenant 'contoso.onmicrosoft.com' -Thumbprint 34CFAA860E5FB8C44335A38A097C1E41EEA206AA ``` Connects to SharePoint using app-only tokens via an app's declared permission scopes. @@ -183,37 +182,23 @@ Ensure you have imported the private key certificate, typically the .pfx file, i ### EXAMPLE 8 ```powershell -Connect-PnPOnline -Url "contoso.sharepoint.com" -ClientId 6c5c98c7-e05a-4a0f-bcfa-0cfc65aa1f28 -CertificateBase64Encoded $base64encodedstring -Tenant 'contoso.onmicrosoft.com' +Connect-PnPOnline -Url "https://contoso.sharepoint.com" -ClientId 6c5c98c7-e05a-4a0f-bcfa-0cfc65aa1f28 -CertificateBase64Encoded $base64encodedstring -Tenant 'contoso.onmicrosoft.com' ``` Connects using an Azure Active Directory registered application using a certificate with a private key that has been base64 encoded. See https://learn.microsoft.com/sharepoint/dev/solution-guidance/security-apponly-azuread for a sample on how to get started. + ### EXAMPLE 9 ```powershell -Connect-PnPOnline -Url "contoso.sharepoint.com" -UseWebLogin +Connect-PnPOnline -Url "https://contoso.sharepoint.com" -Interactive -ClientId 6c5c98c7-e05a-4a0f-bcfa-0cfc65aa1f28 ``` -Note: See Example 10 as this is a preferred option over using -UseWebLogin. +Connects to the Azure AD, acquires an access token and allows PnP PowerShell to access both SharePoint and the Microsoft Graph. Notice that you will have to register your own App first, by means of `Register-PnPEntraIDApp` to use this method. You will also have to provide the `-ClientId` parameter starting September 9, 2024. Alternatively, create an environment variable, call it `ENTRAID_APP_ID` or `ENTRAID_CLIENT_ID` and set the value to the app id you created. If you use -Interactive and this environment variable is present you will not have to use -ClientId. -Connects to SharePoint using legacy cookie based authentication. -Notice this type of authentication is limited in its functionality. -We will for instance not be able to acquire an access token for the Graph, and as a result none of the Graph related cmdlets will work. -Also some of the functionality of the provisioning engine (Get-PnPSiteTemplate, Get-PnPTenantTemplate, Invoke-PnPSiteTemplate, Invoke-PnPTenantTemplate) will not work because of this reason. -The cookies will in general expire within a few days and if you use -UseWebLogin within that time popup window will appear that will disappear immediately, this is expected. -Use -ForceAuthentication to reset the authentication cookies and force a new login. -See example 10 for a full support for interactive logins using MFA and the ability to acquire Graph tokens. ### EXAMPLE 10 ```powershell -Connect-PnPOnline -Url "contoso.sharepoint.com" -Interactive -``` - -Connects to the Azure AD, acquires an access token and allows PnP PowerShell to access both SharePoint and the Microsoft Graph. -By default it will use the PnP Management Shell multi-tenant application behind the scenes, so make sure to run \`Register-PnPManagementShellAccess\` first. - -### EXAMPLE 11 -```powershell Connect-PnPOnline -Url "https://portal.contoso.com" -TransformationOnPrem -CurrentCredential ``` @@ -222,43 +207,47 @@ This option is only supported for being able to transform on-premises classic wi Although other PnP cmdlets might work as well, they're officially not supported for being used in an on-premises context. See http://aka.ms/sharepoint/modernization/pages for more details on page transformation. -### EXAMPLE 12 +### EXAMPLE 11 ```powershell -Connect-PnPOnline -Url contoso.sharepoint.com -ManagedIdentity +Connect-PnPOnline -Url "https://contoso.sharepoint.com" -ManagedIdentity Get-PnPTeamsTeam ``` Connects using a system assigned managed identity to Microsoft Graph. Using this way of connecting only works with environments that support managed identities: Azure Functions, Azure Automation Runbooks and the Azure Cloud Shell. Read up on [this article](https://pnp.github.io/powershell/articles/azurefunctions.html#by-using-a-managed-identity) how it can be used. -### EXAMPLE 13 +### EXAMPLE 12 ```powershell -Connect-PnPOnline -Url contoso.sharepoint.com -ManagedIdentity -UserAssignedManagedIdentityObjectId 363c1b31-6872-47fd-a616-574d3aec2a51 +Connect-PnPOnline -Url "https://contoso.sharepoint.com" -ManagedIdentity -UserAssignedManagedIdentityObjectId 363c1b31-6872-47fd-a616-574d3aec2a51 Get-PnPList ``` Connects using an user assigned managed identity with object/principal ID 363c1b31-6872-47fd-a616-574d3aec2a51 to SharePoint Online. Using this way of connecting only works with environments that support managed identities: Azure Functions, Azure Automation Runbooks and the Azure Cloud Shell. Read up on [this article](https://pnp.github.io/powershell/articles/azurefunctions.html#by-using-a-managed-identity) how it can be used. -### EXAMPLE 14 +### EXAMPLE 13 ```powershell -Connect-PnPOnline -Url contoso.sharepoint.com -AccessToken $token +Connect-PnPOnline -Url "https://contoso.sharepoint.com" -AccessToken $token ``` This method assumes you have acquired a valid OAuth2 access token from Azure AD with the correct audience and permissions set. Using this method PnP PowerShell will not acquire tokens dynamically and if the token expires (typically after 1 hour) cmdlets will fail to work using this method. -### EXAMPLE 15 +### EXAMPLE 14 ```powershell Connect-PnPOnline -Url contoso.sharepoint.com -EnvironmentVariable -Tenant 'contoso.onmicrosoft.com' ``` This example uses the `AZURE_CLIENT_CERTIFICATE_PATH` and `AZURE_CLIENT_CERTIFICATE_PASSWORD` environment variable values to authenticate. The `AZURE_CLIENT_ID` environment variable must be present and `Tenant` parameter value must be provided. -### EXAMPLE 16 +If these environment variables are not present, it will try to find `ENTRAID_APP_CERTIFICATE_PATH` or `ENTRAID_CLIENT_CERTIFICATE_PATH` and for certificate password use `ENTRAID_APP_CERTIFICATE_PASSWORD` or `ENTRAID_CLIENT_CERTIFICATE_PASSWORD` as fallback. + +### EXAMPLE 15 ```powershell Connect-PnPOnline -Url contoso.sharepoint.com -EnvironmentVariable ``` -This example uses the `AZURE_USERNAME` and `AZURE_PASSWORD` environment variables as credentials to authenticate. If `AZURE_CLIENT_ID` is not present, then it will try to use the default `PnP Management Shell Azure AD app` as fallback and attempt to authenticate. +This example uses the `AZURE_USERNAME` and `AZURE_PASSWORD` environment variables as credentials to authenticate. If these environment variables are not available, it will use `ENTRAID_USERNAME` and `ENTRAID_PASSWORD` environment variables as fallback. + +If `AZURE_CLIENT_ID` is not present, then it will try to use the default `PnP Management Shell Azure AD app` as fallback and attempt to authenticate. Starting from 9th Sept 2024, it will try to use `ENTRAID_APP_ID` or `ENTRAID_CLIENT_ID` environment variables as fallback. This method assumes you have the necessary environment variables available. For more information about the required environment variables, please refer to this article, [Azure.Identity Environment Variables](https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/identity/Azure.Identity#environment-variables) here. @@ -266,22 +255,33 @@ So, when using `-EnvironmentVariable` method for authenticating, we will require If `AZURE_USERNAME`, `AZURE_PASSWORD` and `AZURE_CLIENT_ID`, we will use these environment variables and authenticate using credentials flow. +If `ENTRAID_USERNAME`, `ENTRAID_PASSWORD` and `ENTRAID_APP_ID` , we will use these environment variables and authenticate using credentials flow. + We support only Service principal with certificate and Username with password mode for authentication. Configuration will be attempted in that order. For example, if values for a certificate and username+password are both present, the client certificate method will be used. -### EXAMPLE 17 +### EXAMPLE 16 ``` Connect-PnPOnline -Url contoso.sharepoint.com -AzureEnvironment Custom -MicrosoftGraphEndPoint "custom.graph.microsoft.com" -AzureADLoginEndPoint "https://custom.login.microsoftonline.com" ``` Use this method to connect to a custom Azure Environment. You can also specify the `MicrosoftGraphEndPoint` and `AzureADLoginEndPoint` parameters if applicable. If specified, then these values will be used to make requests to Graph and to retrieve access token. -### EXAMPLE 18 +### EXAMPLE 17 ```powershell Connect-PnPOnline -Url contoso.sharepoint.com -AzureADWorkloadIdentity ``` This example uses Azure AD Workload Identity to retrieve access tokens. For more information about this, please refer to this article, [Azure AD Workload Identity](https://azure.github.io/azure-workload-identity/docs/introduction.html). We are following the guidance mentioned in [this sample](https://github.com/Azure/azure-workload-identity/blob/main/examples/msal-net/akvdotnet/TokenCredential.cs) to retrieve the access tokens. +### EXAMPLE 18 +```powershell +Connect-PnPOnline -Url "https://contoso.sharepoint.com" -ClientId 6c5c98c7-e05a-4a0f-bcfa-0cfc65aa1f28 -OSLogin +``` + +Connects to the Azure AD with WAM (aka native Windows authentication prompt), acquires an access token and allows PnP PowerShell to access both SharePoint and the Microsoft Graph. Notice that you will have to register your own App first, by means of Register-PnPEntraIDAdd to use this method. You will also have to provide the -ClientId parameter starting September 9, 2024. Alternatively, create an environment variable, call it `ENTRAID_APP_ID` or `ENTRAID_CLIENT_ID` and set the value to the app id you created. + +WAM is a more secure & faster way of authenticating in Windows OS. It supports Windows Hello, FIDO keys , conditional access policies and more. + ## PARAMETERS ### -AccessToken @@ -307,7 +307,7 @@ The Azure environment to use for authentication, the defaults to 'Production' wh ```yaml Type: AzureEnvironment -Parameter Sets: Credentials, SharePoint ACS (Legacy) App Only, App-Only with Azure Active Directory, App-Only with Azure Active Directory using a certificate from the Windows Certificate Management Store by thumbprint, PnP Management Shell / DeviceLogin, Interactive, Access Token, Environment Variable +Parameter Sets: Credentials, SharePoint ACS (Legacy) App Only, App-Only with Azure Active Directory, App-Only with Azure Active Directory using a certificate from the Windows Certificate Management Store by thumbprint, PnP Management Shell / DeviceLogin, Interactive, Access Token, Environment Variable, Managed Identity Aliases: Accepted values: Production, PPE, China, Germany, USGovernment, USGovernmentHigh, USGovernmentDoD, Custom @@ -681,7 +681,7 @@ Accept wildcard characters: False ``` ### -Interactive -Connects to the Azure AD using interactive login, allowing you to authenticate using multi-factor authentication. +Connects to the Entra ID (Azure AD) using interactive login, allowing you to authenticate using multi-factor authentication. This parameter has preference over \`-UseWebLogin\`. ```yaml @@ -860,6 +860,22 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -OSLogin + +Connects using Web Account Manager (WAM). This works only on Windows machines, on other OS will open browser. Use this to open the native Windows authentication prompt. It supports Windows Hello, conditional access policies, FIDO keys and other OS integration auth options. Requires that the Entra ID app registration have `ms-appx-web://microsoft.aad.brokerplugin/{client_id}` as a redirect URI. For more information, visit this [link](https://learn.microsoft.com/en-us/entra/msal/dotnet/acquiring-tokens/desktop-mobile/wam). + +```yaml +Type: SwitchParameter +Parameter Sets: OS login +Aliases: + +Required: True +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + ## RELATED LINKS [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) diff --git a/documentation/Copy-PnPFile.md b/documentation/Copy-PnPFile.md index a0be44094..6d66f2eed 100644 --- a/documentation/Copy-PnPFile.md +++ b/documentation/Copy-PnPFile.md @@ -21,7 +21,7 @@ Copy-PnPFile [-SourceUrl] [-TargetUrl] [-Overwrite] [-Force] [ ## DESCRIPTION -Copies a file or folder to a different location. This location can be within the same document library, same site, same site collection or even to another site collection on the same tenant. Notice that if copying between sites or to a subsite you cannot specify a target filename, only a folder name. It is currently not possible to copy files between a OneDrive for Business site to SharePoint or vice versa. +Copies a file or folder to a different location. This location can be within the same document library, same site, same site collection or even to another site collection on the same tenant. Notice that if copying between sites or to a subsite you cannot specify a target filename, only a folder name. Copying files and folders is bound to some restrictions. You can find more on it here: https://learn.microsoft.com/office365/servicedescriptions/sharepoint-online-service-description/sharepoint-online-limits#moving-and-copying-across-sites diff --git a/documentation/Get-PnPApplicationCustomizer.md b/documentation/Get-PnPApplicationCustomizer.md index aeb0379be..12d35a23b 100644 --- a/documentation/Get-PnPApplicationCustomizer.md +++ b/documentation/Get-PnPApplicationCustomizer.md @@ -127,6 +127,20 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -Includes +Optionally allows properties to be retrieved for the returned application customizer which are not included in the response by default + +```yaml +Type: String[] +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -WhatIf diff --git a/documentation/Get-PnPAvailableLanguage.md b/documentation/Get-PnPAvailableLanguage.md index 6c37a07d1..6b8f1bf34 100644 --- a/documentation/Get-PnPAvailableLanguage.md +++ b/documentation/Get-PnPAvailableLanguage.md @@ -62,6 +62,20 @@ Accept pipeline input: True (ByValue) Accept wildcard characters: False ``` +### -Includes +Optionally allows properties to be retrieved for the returned web language which are not included in the response by default + +```yaml +Type: String[] +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ## RELATED LINKS [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) diff --git a/documentation/Get-PnPCustomAction.md b/documentation/Get-PnPCustomAction.md index 35ba11451..cbc85226d 100644 --- a/documentation/Get-PnPCustomAction.md +++ b/documentation/Get-PnPCustomAction.md @@ -105,6 +105,19 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -Includes +Optionally allows properties to be retrieved for the returned custom action which are not included in the response by default + +```yaml +Type: String[] +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` ## RELATED LINKS diff --git a/documentation/Get-PnPDocumentSetTemplate.md b/documentation/Get-PnPDocumentSetTemplate.md index 7bc47fc07..c1a3316cb 100644 --- a/documentation/Get-PnPDocumentSetTemplate.md +++ b/documentation/Get-PnPDocumentSetTemplate.md @@ -69,7 +69,19 @@ Accept pipeline input: True (ByValue) Accept wildcard characters: False ``` +### -Includes +Optionally allows properties to be retrieved for the returned document set template which are not included in the response by default +```yaml +Type: String[] +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` ## RELATED LINKS diff --git a/documentation/Get-PnPEventReceiver.md b/documentation/Get-PnPEventReceiver.md index 70d1bd2e2..f4f55268d 100644 --- a/documentation/Get-PnPEventReceiver.md +++ b/documentation/Get-PnPEventReceiver.md @@ -146,6 +146,20 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -Includes +Optionally allows properties to be retrieved for the returned event receiver which are not included in the response by default + +```yaml +Type: String[] +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ## RELATED LINKS [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) diff --git a/documentation/Get-PnPFeature.md b/documentation/Get-PnPFeature.md index 15147da74..7129e5738 100644 --- a/documentation/Get-PnPFeature.md +++ b/documentation/Get-PnPFeature.md @@ -97,6 +97,20 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -Includes +Optionally allows properties to be retrieved for the returned feature which are not included in the response by default + +```yaml +Type: String[] +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ## RELATED LINKS diff --git a/documentation/Get-PnPField.md b/documentation/Get-PnPField.md index 5859dcca5..431971b67 100644 --- a/documentation/Get-PnPField.md +++ b/documentation/Get-PnPField.md @@ -125,6 +125,20 @@ Accept pipeline input: True (ByValue) Accept wildcard characters: False ``` +### -Includes +Optionally allows properties to be retrieved for the returned field which are not included in the response by default + +```yaml +Type: String[] +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ## RELATED LINKS [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) diff --git a/documentation/Get-PnPFileInFolder.md b/documentation/Get-PnPFileInFolder.md index f10843ba3..fd5c9babe 100644 --- a/documentation/Get-PnPFileInFolder.md +++ b/documentation/Get-PnPFileInFolder.md @@ -16,12 +16,12 @@ List files in a folder ### Folder via url ```powershell -Get-PnPFileInFolder [-FolderSiteRelativeUrl ] [-ItemName ] [-Recurse] [-Includes ] [-Verbose] [-Connection ] +Get-PnPFileInFolder [-FolderSiteRelativeUrl ] [-ItemName ] [-Recurse] [-Includes ] [-ExcludeSystemFolders] [-Verbose] [-Connection ] ``` ### Folder via pipebind ```powershell -Get-PnPFileInFolder [-Identity ] [-ItemName ] [-Recurse] [-Includes ] [-Verbose] [-Connection ] +Get-PnPFileInFolder [-Identity ] [-ItemName ] [-Recurse] [-Includes ] [-ExcludeSystemFolders] [-Verbose] [-Connection ] ``` ## DESCRIPTION @@ -195,4 +195,4 @@ Accept wildcard characters: False ## RELATED LINKS -[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) \ No newline at end of file +[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) diff --git a/documentation/Get-PnPFileSharingLink.md b/documentation/Get-PnPFileSharingLink.md index f277acc74..4be26d674 100644 --- a/documentation/Get-PnPFileSharingLink.md +++ b/documentation/Get-PnPFileSharingLink.md @@ -10,26 +10,76 @@ title: Get-PnPFileSharingLink # Get-PnPFileSharingLink ## SYNOPSIS -Retrieves sharing links to associated with the file. +Retrieves sharing links to associated with the file or list item. ## SYNTAX ```powershell -Get-PnPFileSharingLink -FileUrl [-Connection ] +Get-PnPFileSharingLink -Identity [-Verbose] [-Connection ] ``` ## DESCRIPTION -Retrieves sharing links for a file. +Retrieves sharing links for a file or list item. ## EXAMPLES ### EXAMPLE 1 ```powershell -Get-PnPFileSharingLink -FileUrl "/sites/demo/Shared Documents/Test.docx" +Get-PnPFileSharingLink -Identity "/sites/demo/Shared Documents/Test.docx" ``` -This will fetch sharing links for `Test.docx` file in the `Shared Documents` library. +This will fetch sharing links for `Test.docx` file in the `Shared Documents` library based on the server relative url. + +### EXAMPLE 2 +```powershell +Get-PnPFileSharingLink -Identity eff4c8ca-7b92-4aa2-9744-855611c6ccf2 +``` + +This will fetch sharing links for the file in the site with the provided unique identifier, regardless of where it is located. + +### EXAMPLE 3 +```powershell +Get-PnPListItem -List "Documents" | Get-PnPFileSharingLink +``` + +This will fetch sharing links for all files in the `Documents` library. + +### EXAMPLE 4 + +```powershell +Get-PnPListItem -List "Documents" -Id 1 | Get-PnPFileSharingLink +``` + +This will fetch sharing links for the file in the `Documents` library with Id 1. + +### EXAMPLE 5 +```powershell +Get-PnPFile -Url "/sites/demo/Shared Documents/Test.docx" | Get-PnPFileSharingLink +``` + +This will fetch sharing links for the passed in file. + +### EXAMPLE 6 +```powershell +Get-PnPFileInFolder -Recurse -ExcludeSystemFolders -FolderSiteRelativeUrl "Shared Documents" | Get-PnPFileSharingLink +``` + +This will fetch sharing links for all files in the `Shared Documents` library, including the files in subfolders, excluding the ones in hidden internal system folders. + +### EXAMPLE 7 +```powershell +Get-PnPFileInFolder -Recurse -ExcludeSystemFolders -FolderSiteRelativeUrl "Shared Documents" | Get-PnPFileSharingLink | ? ExpirationDateTime -eq $null +``` + +This will fetch sharing links for all files in the `Shared Documents` library, including the files in subfolders, excluding the ones in hidden internal system folders where no expiration has been set on the sharing of the file. + +### EXAMPLE 8 +```powershell +Get-PnPFileSharingLink -Identity /sites/demo/Lists/Issue tracker/1_.000 +``` + +This will fetch sharing links for the list item with id `1` from list `Issue Tracker` ## PARAMETERS @@ -47,11 +97,11 @@ Accept pipeline input: False Accept wildcard characters: False ``` -### -FileUrl -The file in the site +### -Identity +The server relative path to the file, the unique identifier of the file, the listitem representing the file, or the file object itself to retrieve the sharing links for. ```yaml -Type: String +Type: FilePipeBind Parameter Sets: (All) Required: True @@ -61,6 +111,20 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -Verbose +When provided, additional debug statements will be shown while executing the cmdlet. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ## RELATED LINKS [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) diff --git a/documentation/Get-PnPFolder.md b/documentation/Get-PnPFolder.md index 51f6a2764..091982179 100644 --- a/documentation/Get-PnPFolder.md +++ b/documentation/Get-PnPFolder.md @@ -26,12 +26,12 @@ Get-PnPFolder -CurrentWebRootFolder [-Includes ] [-Connection [-Includes ] [-Connection ] [-Verbose] +Get-PnPFolder -Url [-Includes ] [-AsListItem ] [-Connection ] [-Verbose] ``` ### Root folder of a list ```powershell -Get-PnPFolder -ListRootFolder [-Includes ] [-Connection ] [-Verbose] +Get-PnPFolder -ListRootFolder [-Includes ] [-AsListItem ] [-Connection ] [-Verbose] ``` ### Folders In List @@ -89,7 +89,14 @@ Returns the root folder of the list called 'Shared Documents' Get-PnPFolder -List "Shared Documents" ``` -Returns the folders inside the root folder of the list called 'Shared Documents'. Please use Get-PnPFolder -ListRootFolder | Get-PnPFolderInFolder instead. +Returns the folders inside the root folder of the list called 'Shared Documents'. Please use Get-PnPFolder -ListRootFolder \ | Get-PnPFolderInFolder instead. + +### EXAMPLE 7 +```powershell +Get-PnPFolder -Url "/sites/demo/Shared Documents/Test" -AsListItem +``` + +Returns the folder called 'Test' which is located in the root of the site collection located at '/sites/demo' inside 'Shared Documents' document library as a SharePoint list item. ## PARAMETERS @@ -164,6 +171,20 @@ Accept pipeline input: True (ByValue) Accept wildcard characters: False ``` +### -AsListItem +Returns the folder as a listitem showing all its properties + +```yaml +Type: SwitchParameter +Parameter Sets: Folder by url, Root folder of a list + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -Verbose When provided, additional debug statements will be shown while executing the cmdlet. @@ -178,6 +199,20 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -Includes +Optionally allows properties to be retrieved for the returned folders which are not included in the response by default + +```yaml +Type: String[] +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ## RELATED LINKS -[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) \ No newline at end of file +[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) diff --git a/documentation/Get-PnPFolderItem.md b/documentation/Get-PnPFolderItem.md index 18b5947ac..c49e72714 100644 --- a/documentation/Get-PnPFolderItem.md +++ b/documentation/Get-PnPFolderItem.md @@ -69,7 +69,7 @@ Returns all subfolders of the folder SitePages which is located in the root of t ### EXAMPLE 6 ```powershell -Get-PnPFolder -Identity "Shared Documents" | Get-PnPFolderItem -ItemType File +Get-PnPFolder -Url "Shared Documents" | Get-PnPFolderItem -ItemType File ``` Returns all files in the "Shared Documents" folder which is located in the root of the current web @@ -160,6 +160,7 @@ A switch parameter to include contents of all subfolders in the specified folder ```yaml Type: SwitchParameter Parameter Sets: (All) +Aliases: Recurse Required: False Position: 4 diff --git a/documentation/Get-PnPGroup.md b/documentation/Get-PnPGroup.md index 59e9da76c..cc83ee9a4 100644 --- a/documentation/Get-PnPGroup.md +++ b/documentation/Get-PnPGroup.md @@ -141,6 +141,20 @@ Accept pipeline input: True (ByValue) Accept wildcard characters: False ``` +### -Includes +Optionally allows properties to be retrieved for the returned SharePoint security group which are not included in the response by default + +```yaml +Type: String[] +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ## RELATED LINKS [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) \ No newline at end of file diff --git a/documentation/Get-PnPRecycleBinItem.md b/documentation/Get-PnPRecycleBinItem.md index 67baa6155..168df7272 100644 --- a/documentation/Get-PnPRecycleBinItem.md +++ b/documentation/Get-PnPRecycleBinItem.md @@ -155,6 +155,20 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -Includes +Optionally allows properties to be retrieved for the returned recycle bin items which are not included in the response by default + +```yaml +Type: String[] +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ## RELATED LINKS [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) diff --git a/documentation/Get-PnPSearchExternalConnection.md b/documentation/Get-PnPSearchExternalConnection.md new file mode 100644 index 000000000..6a8111df6 --- /dev/null +++ b/documentation/Get-PnPSearchExternalConnection.md @@ -0,0 +1,90 @@ +--- +Module Name: PnP.PowerShell +schema: 2.0.0 +applicable: SharePoint Online +online version: https://pnp.github.io/powershell/cmdlets/Get-PnPSearchExternalConnection.html +external help file: PnP.PowerShell.dll-Help.xml +title: Get-PnPSearchExternalConnection +--- + +# Get-PnPSearchExternalConnection + +## SYNOPSIS + +**Required Permissions** + + * Microsoft Graph API : One of ExternalConnection.ReadWrite.OwnedBy, ExternalConnection.Read.All, ExternalConnection.ReadWrite.All + +Retrieves all connections to external datasources belonging to Microsoft Search + +## SYNTAX + +```powershell +Get-PnPSearchExternalConnection [-Identity ] [-Verbose] [-Connection ] +``` + +## DESCRIPTION + +This cmdlet can be used to retrieve all connections to external datasources that are being indexed into Microsoft Search through a custom connector. Use [Set-PnPSearchExternalItem](Set-PnPSearchExternalItem.md) to add items to the index for a connector. + +## EXAMPLES + +### EXAMPLE 1 +```powershell +Get-PnPSearchExternalConnection +``` + +This will return all connections to external datasources that are being indexed into Microsoft Search that exist within the tenant. + +### EXAMPLE 2 +```powershell +Get-PnPSearchExternalConnection -Identity "pnppowershell" +``` + +This will return the connection to the external datasource with the specified identity that is being indexed into Microsoft Search. + +## PARAMETERS + +### -Connection +Optional connection to be used by the cmdlet. Retrieve the value for this parameter by either specifying -ReturnConnection on Connect-PnPOnline or by executing [Get-PnPConnection](Get-PnPConnection.md). + +```yaml +Type: PnPConnection +Parameter Sets: (All) +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Identity +Unique identifier of the external connection in Microsoft Search. If not provided, all connections will be returned. + +```yaml +Type: String +Parameter Sets: (All) +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Verbose +When provided, additional debug statements will be shown while executing the cmdlet. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +## RELATED LINKS + +[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) \ No newline at end of file diff --git a/documentation/Get-PnPSearchExternalSchema.md b/documentation/Get-PnPSearchExternalSchema.md new file mode 100644 index 000000000..ac8701b37 --- /dev/null +++ b/documentation/Get-PnPSearchExternalSchema.md @@ -0,0 +1,83 @@ +--- +Module Name: PnP.PowerShell +schema: 2.0.0 +applicable: SharePoint Online +online version: https://pnp.github.io/powershell/cmdlets/Get-PnPSearchExternalSchema.html +external help file: PnP.PowerShell.dll-Help.xml +title: Get-PnPSearchExternalSchema +--- + +# Get-PnPSearchExternalSchema + +## SYNOPSIS + +**Required Permissions** + + * Microsoft Graph API : One of ExternalConnection.ReadWrite.OwnedBy, ExternalConnection.Read.All, ExternalConnection.ReadWrite.All + +Retrieves the schema set on a connection to an external datasource belonging to Microsoft Search + +## SYNTAX + +```powershell +Get-PnPSearchExternalSchema -ConnectionId [-Verbose] [-Connection ] +``` + +## DESCRIPTION + +This cmdlet can be used to retrieve the current schema set on a connection to an external datasource that is being indexed into Microsoft Search through a custom connector. + +## EXAMPLES + +### EXAMPLE 1 +```powershell +Get-PnPSearchExternalSchema -ConnectionId "pnppowershell" +``` + +This will return the current schema being used on the external Microsoft Search connection with the specified identity. + +## PARAMETERS + +### -Connection +Optional connection to be used by the cmdlet. Retrieve the value for this parameter by either specifying -ReturnConnection on Connect-PnPOnline or by executing [Get-PnPConnection](Get-PnPConnection.md). + +```yaml +Type: PnPConnection +Parameter Sets: (All) +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ConnectionId +Unique identifier or instance of the external connection in Microsoft Search to retrieve the schema for + +```yaml +Type: String +Parameter Sets: (All) +Required: True +Position: Named +Default value: None +Accept pipeline input: True +Accept wildcard characters: False +``` + +### -Verbose +When provided, additional debug statements will be shown while executing the cmdlet. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +## RELATED LINKS + +[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) \ No newline at end of file diff --git a/documentation/Get-PnPSite.md b/documentation/Get-PnPSite.md index 1a6391626..5fb9497b8 100644 --- a/documentation/Get-PnPSite.md +++ b/documentation/Get-PnPSite.md @@ -54,6 +54,20 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -Includes +Optionally allows properties to be retrieved for the returned site which are not included in the response by default + +```yaml +Type: String[] +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ## RELATED LINKS [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) diff --git a/documentation/Get-PnPSubWeb.md b/documentation/Get-PnPSubWeb.md index 2a850f920..79d2a2dab 100644 --- a/documentation/Get-PnPSubWeb.md +++ b/documentation/Get-PnPSubWeb.md @@ -118,6 +118,19 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -Includes +Optionally allows properties to be retrieved for the returned sub web which are not included in the response by default + +```yaml +Type: String[] +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` ## RELATED LINKS diff --git a/documentation/Get-PnPTerm.md b/documentation/Get-PnPTerm.md index abd29f627..788fb5586 100644 --- a/documentation/Get-PnPTerm.md +++ b/documentation/Get-PnPTerm.md @@ -195,6 +195,20 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -Includes +Optionally allows properties to be retrieved for the returned terms which are not included in the response by default + +```yaml +Type: String[] +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ## RELATED LINKS [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) diff --git a/documentation/Get-PnPTermGroup.md b/documentation/Get-PnPTermGroup.md index 31faf0a0e..ab542e1a1 100644 --- a/documentation/Get-PnPTermGroup.md +++ b/documentation/Get-PnPTermGroup.md @@ -80,6 +80,20 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -Includes +Optionally allows properties to be retrieved for the returned term group(s) which are not included in the response by default + +```yaml +Type: String[] +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ## RELATED LINKS [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) diff --git a/documentation/Get-PnPTermSet.md b/documentation/Get-PnPTermSet.md index 70658ee4d..0a258d587 100644 --- a/documentation/Get-PnPTermSet.md +++ b/documentation/Get-PnPTermSet.md @@ -108,6 +108,20 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -Includes +Optionally allows properties to be retrieved for the returned term set which are not included in the response by default + +```yaml +Type: String[] +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). diff --git a/documentation/Get-PnPView.md b/documentation/Get-PnPView.md index 830103299..27b2b3035 100644 --- a/documentation/Get-PnPView.md +++ b/documentation/Get-PnPView.md @@ -90,6 +90,19 @@ Accept pipeline input: True (ByValue) Accept wildcard characters: False ``` +### -Includes +Optionally allows properties to be retrieved for the returned list view which are not included in the response by default + +```yaml +Type: String[] +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` ## RELATED LINKS diff --git a/documentation/Get-PnPWeb.md b/documentation/Get-PnPWeb.md index 516494bc2..0101eea89 100644 --- a/documentation/Get-PnPWeb.md +++ b/documentation/Get-PnPWeb.md @@ -62,6 +62,20 @@ Accept pipeline input: True (ByValue) Accept wildcard characters: False ``` +### -Includes +Optionally allows properties to be retrieved for the returned web which are not included in the response by default + +```yaml +Type: String[] +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ## RELATED LINKS [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) diff --git a/documentation/Invoke-PnPGraphMethod.md b/documentation/Invoke-PnPGraphMethod.md index 9761922dd..3b2a405fc 100644 --- a/documentation/Invoke-PnPGraphMethod.md +++ b/documentation/Invoke-PnPGraphMethod.md @@ -17,7 +17,7 @@ Invokes a REST request towards the Microsoft Graph API ### Out to console (Default) ```powershell Invoke-PnPGraphMethod -Url - [-AdditionalHeaders ] + [-AdditionalHeaders GraphAdditionalHeadersPipeBind] [[-Method] ] [-Content ] [-ContentType ] @@ -31,7 +31,7 @@ Invoke-PnPGraphMethod -Url ### Out to file ```powershell Invoke-PnPGraphMethod -Url - [-AdditionalHeaders ] + [-AdditionalHeaders GraphAdditionalHeadersPipeBind] [[-Method] ] [-Content ] [-ContentType ] @@ -44,7 +44,7 @@ Invoke-PnPGraphMethod -Url ### Out to stream ```powershell Invoke-PnPGraphMethod -Url - [-AdditionalHeaders ] + [-AdditionalHeaders GraphAdditionalHeadersPipeBind] [[-Method] ] [-Content ] [-ContentType ] @@ -90,32 +90,43 @@ Get users with advanced query capabilities. Use of -ConsistencyLevelEventual. ### Example 5 ```powershell -Invoke-PnPGraphMethod "https://graph.microsoft.com/v1.0/users" +Invoke-PnPGraphMethod -Url "https://graph.microsoft.com/v1.0/users" ``` Performs a GET request to retrieve users from the Microsoft Graph API using the full URL. ### Example 6 ```powershell -Invoke-PnPGraphMethod "https://graph.microsoft.com/v1.0/users/user@contoso.com/photo/`$value" -OutFile c:\temp\photo.jpg +Invoke-PnPGraphMethod -Url "https://graph.microsoft.com/v1.0/users/user@contoso.com/photo/`$value" -OutFile c:\temp\photo.jpg ``` Downloads the user profile photo of the specified user to the specified file. ### Example 7 ```powershell -Invoke-PnPGraphMethod "https://graph.microsoft.com/v1.0/users/user@contoso.com/photo/`$value" -OutStream | Add-PnPFile -FileName user.jpg -Folder "Shared Documents" +Invoke-PnPGraphMethod -Url "https://graph.microsoft.com/v1.0/users/user@contoso.com/photo/`$value" -OutStream | Add-PnPFile -FileName user.jpg -Folder "Shared Documents" ``` Takes the user profile photo of the specified user and uploads it to the specified library in SharePoint Online. +### Example 8 +```powershell +$task = Invoke-PnPGraphMethod -Url "https://graph.microsoft.com/v1.0/planner/tasks/23fasefxcvzvsdf32e" # retrieve the task so we can figure out the etag which is needed to update the task +$etag = $task.'@odata.etag' +$headers = @{"If-Match"=$etag} +$content = @{"title"="My new task title"} +Invoke-PnPGraphMethod -Url "https://graph.microsoft.com/v1.0/planner/tasks/23fasefxcvzvsdf32e" -Method PATCH -Content $content -AdditionalHeaders $headers +``` + +This example retrieves a Planner task to find the etag value which is required to update the task. In order to update the task through call to the Microsoft Graph API we need to include an If-Match header with the value of the etag. It then creates the content to update, in this case the title of the task, and calls the PATCH method on the Graph end-point to update the specific task. + ## PARAMETERS ### -AdditionalHeaders -Additional request headers +Additional request headers, either by providing a Dictionary or a Hastable, .e.g -AdditionalHeaders @{"If-Match"="234567tysfssdvsadf"} ```yaml -Type: System.Collections.Generic.IDictionary`2[System.String,System.String] +Type: GraphAdditionalHeaderPipeBind Parameter Sets: (All) Aliases: diff --git a/documentation/Measure-PnPList.md b/documentation/Measure-PnPList.md index 0ef67031a..a786c7e85 100644 --- a/documentation/Measure-PnPList.md +++ b/documentation/Measure-PnPList.md @@ -96,6 +96,19 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -Includes +Optionally allows properties to be retrieved for the returned list which are not included in the response by default + +```yaml +Type: String[] +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` ## RELATED LINKS diff --git a/documentation/Measure-PnPWeb.md b/documentation/Measure-PnPWeb.md index a03d93fd1..c13a9c65c 100644 --- a/documentation/Measure-PnPWeb.md +++ b/documentation/Measure-PnPWeb.md @@ -88,6 +88,7 @@ Iterate all sub webs recursively ```yaml Type: SwitchParameter Parameter Sets: (All) +Aliases: Recurse Required: False Position: Named diff --git a/documentation/New-PnPLibraryFileVersionBatchDeleteJob.md b/documentation/New-PnPLibraryFileVersionBatchDeleteJob.md index d9ca6b4a9..a31291679 100644 --- a/documentation/New-PnPLibraryFileVersionBatchDeleteJob.md +++ b/documentation/New-PnPLibraryFileVersionBatchDeleteJob.md @@ -16,7 +16,7 @@ Starts a file version batch trim job for a document library. ## SYNTAX ```powershell -New-PnPLibraryFileVersionBatchDeleteJob -Identity -DeleteBeforeDays [-Force] +New-PnPLibraryFileVersionBatchDeleteJob -Identity [-DeleteBeforeDays ] [-MajorVersionLimit ] [-MajorWithMinorVersionsLimit ][Automatic][-Force] ``` ## DESCRIPTION @@ -41,14 +41,14 @@ Starts a file version batch trim job that will delete all file versions that are ### EXAMPLE 3 ```powershell -New-PnPLibraryFileVersionBatchDeleteJob -Automatic +New-PnPLibraryFileVersionBatchDeleteJob -Identity "Documents" -Automatic ``` -Starts a file version batch trim job that will delete file versions that expiread and set version expiration time for the ones not expired in the document library based on the backend algorithm. +Starts a file version batch trim job that will delete file versions that expired and set version expiration time for the ones not expired in the document library based on the backend algorithm. ### EXAMPLE 4 ```powershell -New-PnPLibraryFileVersionBatchDeleteJob -MajorVersionLimit 30 -MajorWithMinorVersionsLimit 10 +New-PnPLibraryFileVersionBatchDeleteJob -Identity "Documents" -MajorVersionLimit 30 -MajorWithMinorVersionsLimit 10 ``` Starts a file version batch trim job that will delete file versions in the document library based on the version count limits. @@ -76,7 +76,7 @@ The minimum age of file versions to trim. In other words, all file versions that Type: int Parameter Sets: DeleteOlderThanDays -Required: True +Required: False Position: Named Default value: None Accept pipeline input: False diff --git a/documentation/New-PnPMicrosoft365Group.md b/documentation/New-PnPMicrosoft365Group.md index 9ea4b32cb..be9503f51 100644 --- a/documentation/New-PnPMicrosoft365Group.md +++ b/documentation/New-PnPMicrosoft365Group.md @@ -302,7 +302,7 @@ Accept wildcard characters: False ``` ### -SensitivityLabels -The Sensitivity label to be set to the Microsoft 365 Group. To retrieve the sensitivity label you need to use the Graph API mentioned [here](https://learn.microsoft.com/en-us/graph/api/informationprotectionlabel-get?view=graph-rest-beta&tabs=http). +The Sensitivity label to be set to the Microsoft 365 Group. To retrieve the sensitivity label Ids you can use [Get-PnPAvailableSensitivityLabel](Get-PnPAvailableSensitivityLabel.md). ```yaml Type: GUID[] @@ -317,4 +317,4 @@ Accept wildcard characters: False ## RELATED LINKS [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) -[Microsoft Graph documentation](https://learn.microsoft.com/graph/api/group-post-groups) \ No newline at end of file +[Microsoft Graph documentation](https://learn.microsoft.com/graph/api/group-post-groups) diff --git a/documentation/New-PnPSearchExternalConnection.md b/documentation/New-PnPSearchExternalConnection.md new file mode 100644 index 000000000..c1169a288 --- /dev/null +++ b/documentation/New-PnPSearchExternalConnection.md @@ -0,0 +1,128 @@ +--- +Module Name: PnP.PowerShell +schema: 2.0.0 +applicable: SharePoint Online +online version: https://pnp.github.io/powershell/cmdlets/New-PnPSearchExternalConnection.html +external help file: PnP.PowerShell.dll-Help.xml +title: New-PnPSearchExternalConnection +--- + +# New-PnPSearchExternalConnection + +## SYNOPSIS + +**Required Permissions** + + * Microsoft Graph API : One of ExternalConnection.ReadWrite.OwnedBy, ExternalConnection.ReadWrite.All + +Creates a new connection to an external datasource for Microsoft Search + +## SYNTAX + +```powershell +New-PnPSearchExternalConnection -Identity -Name -Description [-AuthorizedAppIds ] [-Verbose] [-Connection ] +``` + +## DESCRIPTION + +This cmdlet can be used to create a new connection to an external datasource that needs to be indexed into Microsoft Search through a custom connector. Use [Set-PnPSearchExternalItem](Set-PnPSearchExternalItem.md) to add items to the index for this connector. + +## EXAMPLES + +### EXAMPLE 1 +```powershell +New-PnPSearchExternalConnection -Identity "pnppowershell" -Name "PnP PowerShell" -Description "External content ingested using PnP PowerShell" +``` + +This will create a new external connection with the provided name and description. Any application registration with the proper permissions can add items to the index for this connection. + +### EXAMPLE 2 +```powershell +New-PnPSearchExternalConnection -Identity "pnppowershell" -Name "PnP PowerShell" -Description "External content ingested using PnP PowerShell" -AuthorizedAppIds "00000000-0000-0000-0000-000000000000","11111111-1111-1111-1111-111111111111" +``` + +This will create a new external connection with the provided name and description. Only the application registrations of which the client Ids have been provided can add items to the index for this connection. + +## PARAMETERS + +### -Connection +Optional connection to be used by the cmdlet. Retrieve the value for this parameter by either specifying -ReturnConnection on Connect-PnPOnline or by executing [Get-PnPConnection](Get-PnPConnection.md). + +```yaml +Type: PnPConnection +Parameter Sets: (All) +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Identity +Unique identifier of the external connection in Microsoft Search. Must be unique within the tenant. Must be between 3 and 32 characters in length. Must only contain alphanumeric characters. Cannot begin with Microsoft or be one of the following values: None, Directory, Exchange, ExchangeArchive, LinkedIn, Mailbox, OneDriveBusiness, SharePoint, Teams, Yammer, Connectors, TaskFabric, PowerBI, Assistant, TopicEngine, MSFT_All_Connectors. + +```yaml +Type: String +Parameter Sets: (All) +Required: True +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Name +The display name of the connection to be displayed in the Microsoft 365 admin center. Maximum length of 128 characters. + +```yaml +Type: String +Parameter Sets: (All) +Required: True +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Description +Description of the connection displayed in the Microsoft 365 admin center + +```yaml +Type: String +Parameter Sets: (All) +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -AuthorizedAppIds +The client Ids of the application registrations that are allowed to add items to the index for this connection. If not provided, any application registration with the proper permissions can add items to the index for this connection. + +```yaml +Type: String[] +Parameter Sets: (All) +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Verbose +When provided, additional debug statements will be shown while executing the cmdlet. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +## RELATED LINKS + +[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) \ No newline at end of file diff --git a/documentation/Register-PnPAzureADApp.md b/documentation/Register-PnPAzureADApp.md index 4ac60c78c..7078dc8d0 100644 --- a/documentation/Register-PnPAzureADApp.md +++ b/documentation/Register-PnPAzureADApp.md @@ -38,6 +38,8 @@ Register-PnPAzureADApp -ApplicationName [-CertificatePassword ] [-NoPopup] [-LogoFilePath ] + [-MicrosoftGraphEndPoint ] + [-EntraIDLoginEndPoint ] ``` ### Existing Certificate @@ -67,31 +69,30 @@ Note: if you want to use the newly created app to authenticate with username/pas ### EXAMPLE 1 ```powershell -Register-PnPAzureADApp -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -Store CurrentUser -Username "yourname@domain.com" -Password (Read-Host -AsSecureString -Prompt "Enter Password") +Register-PnPAzureADApp -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -Store CurrentUser -Interactive ``` -Creates a new Azure AD Application registration, creates a new self signed certificate, and adds it to the local certificate store. It will upload the certificate to the azure app registration and it will request the following permissions: Sites.FullControl.All, Group.ReadWrite.All, User.Read.All +Creates a new Azure AD Application registration, creates a new self signed certificate, and adds it to the local certificate store. It will upload the certificate to the azure app registration and it will request the following permissions: Sites.FullControl.All, Group.ReadWrite.All, User.Read.All. A browser window will be shown allowing you to authenticate. ### EXAMPLE 2 ```powershell -Register-PnPAzureADApp -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -CertificatePath c:\certificate.pfx -CertificatePassword (ConvertTo-SecureString -String "password" -AsPlainText -Force) -Username "yourname@domain.com" -Password (Read-Host -AsSecureString -Prompt "Enter password") +Register-PnPAzureADApp -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -CertificatePath c:\certificate.pfx -CertificatePassword (ConvertTo-SecureString -String "password" -AsPlainText -Force) -Interactive ``` -Creates a new Azure AD Application registration which will use the existing private key certificate at the provided path to allow access. It will upload the provided private key certificate to the azure app registration and it will request the following permissions: Sites.FullControl.All, Group.ReadWrite.All, User.Read.All - +Creates a new Azure AD Application registration which will use the existing private key certificate at the provided path to allow access. It will upload the provided private key certificate to the azure app registration and it will request the following permissions: Sites.FullControl.All, Group.ReadWrite.All, User.Read.All. A browser window will be shown allowing you to authenticate. ### EXAMPLE 3 ```powershell -Register-PnPAzureADApp -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -Store CurrentUser -GraphApplicationPermissions "User.Read.All" -SharePointApplicationPermissions "Sites.Read.All" -Username "yourname@domain.com" -Password (Read-Host -AsSecureString -Prompt "Enter Password") +Register-PnPAzureADApp -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -Store CurrentUser -GraphApplicationPermissions "User.Read.All" -SharePointApplicationPermissions "Sites.Read.All" -Interactive ``` -Creates a new Azure AD Application registration, creates a new self signed certificate, and adds it to the local certificate store. It will upload the certificate to the azure app registration and it will request the following permissions: Sites.Read.All, User.Read.All +Creates a new Azure AD Application registration, creates a new self signed certificate, and adds it to the local certificate store. It will upload the certificate to the azure app registration and it will request the following permissions: Sites.Read.All, User.Read.All. A browser window will be shown allowing you to authenticate. ### EXAMPLE 4 ```powershell -Register-PnPAzureADApp -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -OutPath c:\ -CertificatePassword (ConvertTo-SecureString -String "password" -AsPlainText -Force) -Username "yourname@domain.com" -Password (Read-Host -AsSecureString -Prompt "Enter Password") +Register-PnPAzureADApp -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -OutPath c:\ -CertificatePassword (ConvertTo-SecureString -String "password" -AsPlainText -Force) -Interactive ``` -Creates a new Azure AD Application registration, creates a new self signed certificate, and stores the public and private key certificates in c:\. The private key certificate will be locked with the password "password". It will upload the certificate to the azure app registration and it will request the following permissions: Sites.FullControl.All, Group.ReadWrite.All, User.Read.All +Creates a new Azure AD Application registration, creates a new self signed certificate, and stores the public and private key certificates in c:\. The private key certificate will be locked with the password "password". It will upload the certificate to the azure app registration and it will request the following permissions: Sites.FullControl.All, Group.ReadWrite.All, User.Read.All. A browser window will be shown allowing you to authenticate. ### EXAMPLE 5 ```powershell @@ -109,13 +110,25 @@ Creates a new Azure AD Application registration and asks you to authenticate usi ### EXAMPLE 7 ```powershell -Register-PnPAzureADApp -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -CertificatePath c:\certificate.pfx -CertificatePassword (ConvertTo-SecureString -String "password" -AsPlainText -Force) -Username "yourname@domain.com" -Password (Read-Host -AsSecureString -Prompt "Enter password") -LogoFilePath c:\logo.png +Register-PnPAzureADApp -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -CertificatePath c:\certificate.pfx -CertificatePassword (ConvertTo-SecureString -String "password" -AsPlainText -Force) -Interactive -LogoFilePath c:\logo.png ``` Creates a new Azure AD Application registration which will use the existing private key certificate at the provided path to allow access. It will upload the provided private key certificate to the azure app registration and it will request the following permissions: Sites.FullControl.All, Group.ReadWrite.All, User.Read.All. It will also set the `logo.png` file as the logo for the Azure AD app. ## PARAMETERS +### -Interactive +If specified, an interactive authentication flow will be started, allowing your to authenticate with username, password and an optional second factor from your phone or other device. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) + +Required: False +Position: Named +Accept pipeline input: False +``` + ### -Username The username to use when logging into the Microsoft Graph. Notice that this user account needs to have write access to the Azure AD. @@ -383,6 +396,32 @@ Position: Named Accept pipeline input: False ``` +### -EntraIDLoginEndPoint + +Sets the EntraID login endpoint to be used for creation of the app. This only works if Azure Environment parameter is set to `Custom` + +```yaml +Type: String +Parameter Sets: (All) + +Required: False +Position: Named +Accept pipeline input: False +``` + +### -MicrosoftGraphEndPoint + +Sets the Microsoft Graph endpoint to be used for creation of the app. This only works if Azure Environment parameter is set to `Custom` + +```yaml +Type: String +Parameter Sets: (All) + +Required: False +Position: Named +Accept pipeline input: False +``` + ## RELATED LINKS [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) diff --git a/documentation/Register-PnPEntraIDAppForInteractiveLogin.md b/documentation/Register-PnPEntraIDAppForInteractiveLogin.md new file mode 100644 index 000000000..76db31468 --- /dev/null +++ b/documentation/Register-PnPEntraIDAppForInteractiveLogin.md @@ -0,0 +1,218 @@ +--- +Module Name: PnP.PowerShell +schema: 2.0.0 +applicable: SharePoint Online +online version: https://pnp.github.io/powershell/cmdlets/Register-PnPEntraIDAppForInteractiveLogin.html +external help file: PnP.PowerShell.dll-Help.xml +title: Register-PnPEntraIDAppForInteractiveLogin +--- + +# Register-PnPEntraIDAppForInteractiveLogin + +## SYNOPSIS +Registers an Entra ID App for use with Interactive login + +## SYNTAX + +### Generate App using Interactive Login +```powershell +Register-PnPEntraIDAppForInteractiveLogin -ApplicationName + -Tenant + -Interactive] + [-GraphApplicationPermissions ] + [-GraphDelegatePermissions ] + [-SharePointApplicationPermissions ] + [-SharePointDelegatePermissions ] + [-NoPopup] + [-LogoFilePath ] + [-MicrosoftGraphEndPoint ] + [-EntraIDLoginEndPoint ] +``` + +### Generate App using Device Login +```powershell +Register-PnPEntraIDAppForInteractiveLogin -ApplicationName + -Tenant + -DeviceLogin + [-GraphApplicationPermissions ] + [-GraphDelegatePermissions ] + [-SharePointApplicationPermissions ] + [-SharePointDelegatePermissions ] + [-NoPopup] + [-LogoFilePath ] +``` + +## DESCRIPTION +Registers an Entra ID App for use with the interactive login on Connect-PnPOnline. You will have to specify either -Interactive or -DeviceLogin to authenticate. + +## EXAMPLES + +### EXAMPLE 1 +```powershell +Register-PnPEntraIDAppForInteractiveLogin -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -Interactive +``` + +Creates a new Entra ID Application registration. The application will be setup with the following delegate permissions to consent: AllSites.FullControl, Group.ReadWrite.All, User.ReadWrite.All, TermStore.ReadWrite.All. A browser window will be shown allowing you to authenticate. + +### EXAMPLE 2 +```powershell +Register-PnPEntraIDAppForInteractiveLogin -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -GraphDelegatePermissions "Group.Read.All" -SharePointDelegatePermissions "AllSites.FullControl" -Interactive +``` + +Creates a new Entra ID Application registration. The application will be setup with the following delegate permissions to consent: Group.Read.All, AllSites.FullControl. A browser window will be shown allowing you to authenticate. + +## PARAMETERS + +### -Interactive +If specified, an interactive authentication flow will be started, allowing your to authenticate with username, password and an optional second factor from your phone or other device. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) + +Required: False +Position: Named +Accept pipeline input: False +``` + +### -DeviceLogin +If specified, a device login flow, supporting Multi-Factor Authentication will be used to authenticate towards the Microsoft Graph. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) + +Required: False +Position: Named +Accept pipeline input: False +``` + +### -ApplicationName +The name of the Azure AD Application to create. + +```yaml +Type: String +Parameter Sets: (All) + +Required: True +Position: Named +Accept pipeline input: False +``` + +### -GraphApplicationPermissions +Specify which Microsoft Graph Application permissions to request. + +```yaml +Type: Permission[] +Parameter Sets: Generate Certificate + +Required: False +Position: 0 +Accept pipeline input: False +``` + +### -GraphDelegatePermissions +Specify which Microsoft Graph Delegate permissions to request. + +```yaml +Type: Permission[] +Parameter Sets: Generate Certificate + +Required: False +Position: 0 +Accept pipeline input: False +``` + +### -SharePointApplicationPermissions +Specify which Microsoft SharePoint Application permissions to request. + +```yaml +Type: Permission[] +Parameter Sets: Generate Certificate + +Required: False +Position: 0 +Accept pipeline input: False +``` + +### -SharePointDelegatePermissions +Specify which Microsoft SharePoint Delegate permissions to request. + +```yaml +Type: Permission[] +Parameter Sets: Generate Certificate + +Required: False +Position: 0 +Accept pipeline input: False +``` + +### -Tenant +The identifier of your tenant, e.g. mytenant.onmicrosoft.com + +```yaml +Type: String +Parameter Sets: (All) + +Required: True +Position: Named +Accept pipeline input: False +``` + +### -NoPopup +This switch only applies to Windows and has no effect on Linux and MacOS. + +If not specified and running on Windows, all authentication and consent steps will be presented in a popup. If you want to open the URLs manually in a browser, specify this switch. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) + +Required: False +Position: Named +Accept pipeline input: False +``` + +### -LogoFilePath + +Sets the logo for the Azure AD application. Provide a full path to a local image file on your disk which you want to use as the logo. + +```yaml +Type: String +Parameter Sets: (All) + +Required: False +Position: Named +Accept pipeline input: False +``` + +### -EntraIDLoginEndPoint + +Sets the EntraID login endpoint to be used for creation of the app. This only works if Azure Environment parameter is set to `Custom` + +```yaml +Type: String +Parameter Sets: (All) + +Required: False +Position: Named +Accept pipeline input: False +``` + +### -MicrosoftGraphEndPoint + +Sets the Microsoft Graph endpoint to be used for creation of the app. This only works if Azure Environment parameter is set to `Custom` + +```yaml +Type: String +Parameter Sets: (All) + +Required: False +Position: Named +Accept pipeline input: False +``` + +## RELATED LINKS + +[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) + diff --git a/documentation/Remove-PnPAzureADUser.md b/documentation/Remove-PnPAzureADUser.md new file mode 100644 index 000000000..2078cd298 --- /dev/null +++ b/documentation/Remove-PnPAzureADUser.md @@ -0,0 +1,121 @@ +--- +Module Name: PnP.PowerShell +schema: 2.0.0 +applicable: SharePoint Online +online version: https://pnp.github.io/powershell/cmdlets/Remove-PnPAzureADUser.html +external help file: PnP.PowerShell.dll-Help.xml +title: Remove-PnPAzureADUser +--- + +# Remove-PnPAzureADUser + +## SYNOPSIS + +**Required Permissions** + + * Microsoft Graph API: User.ReadWrite.All + +Removes a user from Azure Active Directory / Microsoft Entra ID. + +## SYNTAX + +```powershell +Remove-PnPAzureADUser -Identity [-WhatIf] [-Connection ] [-Verbose] +``` + +## DESCRIPTION + +Allows a user to be removed from Azure Active Directory / Microsoft Entra ID. When the user is deleted, the user will be moved to the recycle bin and can be restored within 30 days. After 30 days the user will be permanently deleted. + +## EXAMPLES + +### EXAMPLE 1 +```powershell +Remove-PnPAzureADUser -Identity johndoe@contoso.onmicrosoft.com +``` + +The user with the provided UPN will be removed from Azure Active Directory. + +### EXAMPLE 2 +```powershell +Remove-PnPAzureADUser -Identity 5a4c547a-1440-4f64-9952-a0c6f1c9e7ea +``` + +The user with the provided guid will be removed from Azure Active Directory. + +### EXAMPLE 3 +```powershell +Get-PnPEntraIDUser | Where-Object { $_.OfficeLocation -eq "London" } | Remove-PnPAzureADUser +``` + +Removes all users that have their OfficeLocation set to London from Azure Active Directory. + +### EXAMPLE 4 +```powershell +Get-PnPEntraIDUser -Filter "accountEnabled eq false" | Remove-PnPAzureADUser +``` + +Removes all disabled user accounts from Azure Active Directory. + +## PARAMETERS + +### -Connection +Optional connection to be used by the cmdlet. Retrieve the value for this parameter by either specifying -ReturnConnection on Connect-PnPOnline or by executing Get-PnPConnection. + +```yaml +Type: PnPConnection +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Identity +The identity of the user to remove. This can be the UPN, the GUID or an instance of the user. + +```yaml +Type: AzureADUserPipeBind +Parameter Sets: (All) + +Required: True +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Verbose +When provided, additional debug statements will be shown while executing the cmdlet. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -WhatIf +When used in combination with -Verbose, it will show what would happen if the cmdlet runs. The user will not be deleted. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: wi + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +## RELATED LINKS + +[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) \ No newline at end of file diff --git a/documentation/Remove-PnPSearchExternalConnection.md b/documentation/Remove-PnPSearchExternalConnection.md new file mode 100644 index 000000000..a111ddb55 --- /dev/null +++ b/documentation/Remove-PnPSearchExternalConnection.md @@ -0,0 +1,83 @@ +--- +Module Name: PnP.PowerShell +schema: 2.0.0 +applicable: SharePoint Online +online version: https://pnp.github.io/powershell/cmdlets/Remove-PnPSearchExternalConnection.html +external help file: PnP.PowerShell.dll-Help.xml +title: Remove-PnPSearchExternalConnection +--- + +# Remove-PnPSearchExternalConnection + +## SYNOPSIS + +**Required Permissions** + + * Microsoft Graph API : One of ExternalConnection.ReadWrite.OwnedBy, ExternalConnection.ReadWrite.All + +Removes a specific connection to external datasources belonging to Microsoft Search + +## SYNTAX + +```powershell +Remove-PnPSearchExternalConnection -Identity [-Verbose] [-Connection ] +``` + +## DESCRIPTION + +This cmdlet can be used to remove a connection to an external datasource that is being indexed into Microsoft Search through a custom connector. + +## EXAMPLES + +### EXAMPLE 1 +```powershell +Remove-PnPSearchExternalConnection -Identity "pnppowershell" +``` + +This will remove the connection to the external datasource with the specified identity from Microsoft Search. + +## PARAMETERS + +### -Connection +Optional connection to be used by the cmdlet. Retrieve the value for this parameter by either specifying -ReturnConnection on Connect-PnPOnline or by executing [Get-PnPConnection](Get-PnPConnection.md). + +```yaml +Type: PnPConnection +Parameter Sets: (All) +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Identity +Unique identifier or an instance of the external connection in Microsoft Search that needs to be removed. + +```yaml +Type: SearchExternalConnectionPipeBind +Parameter Sets: (All) +Required: True +Position: Named +Default value: None +Accept pipeline input: True +Accept wildcard characters: False +``` + +### -Verbose +When provided, additional debug statements will be shown while executing the cmdlet. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +## RELATED LINKS + +[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) \ No newline at end of file diff --git a/documentation/Resolve-PnPFolder.md b/documentation/Resolve-PnPFolder.md index f1b88d515..ff30a162e 100644 --- a/documentation/Resolve-PnPFolder.md +++ b/documentation/Resolve-PnPFolder.md @@ -61,6 +61,20 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -Includes +Optionally allows properties to be retrieved for the folder which are not included in the response by default + +```yaml +Type: String[] +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ## RELATED LINKS diff --git a/documentation/Set-PnPBuiltInDesignPackageVisibility.md b/documentation/Set-PnPBuiltInDesignPackageVisibility.md index b28eded60..305e06667 100644 --- a/documentation/Set-PnPBuiltInDesignPackageVisibility.md +++ b/documentation/Set-PnPBuiltInDesignPackageVisibility.md @@ -15,7 +15,7 @@ Sets the visibility of the available built-in Design Packages at the moment of s ## SYNTAX ```powershell -Set-PnPBuiltInDesignPackageVisibility [-IsVisible] [-DesignPackage] +Set-PnPBuiltInDesignPackageVisibility [-IsVisible] [-DesignPackage] [-Connection ] ``` @@ -40,6 +40,20 @@ This example sets the visibility state of TeamSite design package to true. ## PARAMETERS +### -Connection +Optional connection to be used by the cmdlet. Retrieve the value for this parameter by either specifying -ReturnConnection on Connect-PnPOnline or by executing Get-PnPConnection. + +```yaml +Type: PnPConnection +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -DesignPackage Name of the design package, available names are diff --git a/documentation/Set-PnPFolderPermission.md b/documentation/Set-PnPFolderPermission.md index d01855674..ea70316b3 100644 --- a/documentation/Set-PnPFolderPermission.md +++ b/documentation/Set-PnPFolderPermission.md @@ -35,7 +35,7 @@ Set-PnPFolderPermission [-List] -Identity [-Inhe ``` ## DESCRIPTION -Sets or clears permissions on folders within SharePoint Online. When adding permissions, so when not using -InheritPermissions, it will apply unique permissions to the library, inheriting the ones from its parent. Use Get-PnPRoleDefinition to retrieve all available roles you can add or remove using this cmdlet. +Sets or clears permissions on folders within SharePoint Online. When adding permissions, if you don't use -InheritPermissions, the library will get unique permissions that initially match those of its parent. Use `Get-PnPRoleDefinition` to retrieve all available roles you can add or remove using this cmdlet. ## EXAMPLES diff --git a/documentation/Set-PnPFooter.md b/documentation/Set-PnPFooter.md index 8729432c9..6d8db6c04 100644 --- a/documentation/Set-PnPFooter.md +++ b/documentation/Set-PnPFooter.md @@ -10,7 +10,7 @@ online version: https://pnp.github.io/powershell/cmdlets/Set-PnPFooter.html # Set-PnPFooter ## SYNOPSIS -Configures the footer of the current web +Configures the footer of the current web. ## SYNTAX @@ -29,33 +29,33 @@ Allows the footer to be enabled or disabled and fine tuned in the current web. F Set-PnPFooter -Enabled:$true ``` -Enables the footer to be shown on the current web +Enables the footer to be shown on the current web. ### EXAMPLE 2 ```powershell Set-PnPFooter -Enabled:$true -Layout Extended -BackgroundTheme Neutral ``` -Enables the footer to be shown on the current web with the extended layout using a neutral background +Enables the footer to be shown on the current web with the extended layout using a neutral background. ### EXAMPLE 3 ```powershell Set-PnPFooter -Title "Contoso Inc." -LogoUrl "/sites/communication/Shared Documents/logo.png" ``` -Sets the title and logo shown in the footer +Sets the title and logo shown in the footer. ### EXAMPLE 4 ```powershell Set-PnPFooter -LogoUrl "" ``` -Removes the current logo shown in the footer +Removes the current logo shown in the footer. ## PARAMETERS ### -BackgroundTheme -Defines the background emphasis of the content in the footer +Defines the background emphasis of the content in the footer. ```yaml Type: FooterVariantThemeType @@ -84,7 +84,7 @@ Accept wildcard characters: False ``` ### -Enabled -Indicates if the footer should be shown on the current web ($true) or if it should be hidden ($false) +Indicates if the footer should be shown on the current web ($true) or if it should be hidden ($false). ```yaml Type: SwitchParameter @@ -98,7 +98,7 @@ Accept wildcard characters: False ``` ### -Layout -Defines how the footer should look like +Defines how the footer should look like. ```yaml Type: FooterLayoutType @@ -127,7 +127,7 @@ Accept wildcard characters: False ``` ### -Title -Defines the title displayed in the footer +Defines the title displayed in the footer. ```yaml Type: String diff --git a/documentation/Set-PnPGraphSubscription.md b/documentation/Set-PnPGraphSubscription.md index 31c1ff415..09423043e 100644 --- a/documentation/Set-PnPGraphSubscription.md +++ b/documentation/Set-PnPGraphSubscription.md @@ -15,7 +15,7 @@ Updates an existing Microsoft Graph subscription. Required Azure Active Director ## SYNTAX ```powershell -Set-PnPGraphSubscription -Identity -ExpirationDate +Set-PnPGraphSubscription -Identity -ExpirationDate [-Connection ] ``` @@ -30,10 +30,24 @@ Allows to update an existing Microsoft Graph subscription. Set-PnPGraphSubscription -Identity bc204397-1128-4911-9d70-1d8bceee39da -ExpirationDate "2020-11-22T18:23:45.9356913Z" ``` -Updates the Microsoft Graph subscription with the id 'bc204397-1128-4911-9d70-1d8bceee39da' to expire at the mentioned date +Updates the Microsoft Graph subscription with the id 'bc204397-1128-4911-9d70-1d8bceee39da' to expire at the mentioned date. ## PARAMETERS +### -Connection +Optional connection to be used by the cmdlet. Retrieve the value for this parameter by either specifying -ReturnConnection on Connect-PnPOnline or by executing Get-PnPConnection. + +```yaml +Type: PnPConnection +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -ExpirationDate Date and time to set the expiration to. Take notice of the maximum allowed lifetime of the subscription endpoints as documented at https://learn.microsoft.com/graph/api/resources/subscription#maximum-length-of-subscription-per-resource-type @@ -49,7 +63,7 @@ Accept wildcard characters: False ``` ### -Identity -The unique id or an instance of a Microsoft Graph Subscription +The unique id or an instance of a Microsoft Graph Subscription. ```yaml Type: GraphSubscriptionPipeBind diff --git a/documentation/Set-PnPGroupPermissions.md b/documentation/Set-PnPGroupPermissions.md index 9f6668dba..0a871d1b7 100644 --- a/documentation/Set-PnPGroupPermissions.md +++ b/documentation/Set-PnPGroupPermissions.md @@ -36,7 +36,7 @@ Adds the 'Contribute' permission to the SharePoint group with the name 'My Site Set-PnPGroupPermissions -Identity 'My Site Members' -RemoveRole 'Full Control' -AddRole 'Read' ``` -Removes the 'Full Control' from and adds the 'Contribute' permissions to the SharePoint group with the name 'My Site Members'. +Removes the 'Full Control' from and adds the 'Read' permissions to the SharePoint group with the name 'My Site Members'. ### EXAMPLE 3 ```powershell diff --git a/documentation/Set-PnPHomePage.md b/documentation/Set-PnPHomePage.md index d77c73338..c0a07586e 100644 --- a/documentation/Set-PnPHomePage.md +++ b/documentation/Set-PnPHomePage.md @@ -29,14 +29,14 @@ Allows to set the home page of the current site. Set-PnPHomePage -RootFolderRelativeUrl SitePages/Home.aspx ``` -Sets the home page to the home.aspx file which resides in the SitePages library +Sets the home page to the home.aspx file which resides in the SitePages library. ### EXAMPLE 2 ```powershell Set-PnPHomePage -RootFolderRelativeUrl Lists/Sample/AllItems.aspx ``` -Sets the home page to be the Sample list +Sets the home page to be the Sample list. ## PARAMETERS diff --git a/documentation/Set-PnPHomeSite.md b/documentation/Set-PnPHomeSite.md index b00ef17e8..dadea8974 100644 --- a/documentation/Set-PnPHomeSite.md +++ b/documentation/Set-PnPHomeSite.md @@ -34,7 +34,7 @@ Allows to set the home site of the current tenant. Set-PnPHomeSite -HomeSiteUrl "https://yourtenant.sharepoint.com/sites/myhome" ``` -Sets the home site to the provided site collection url +Sets the home site to the provided site collection url. ### EXAMPLE 2 ```powershell @@ -67,7 +67,7 @@ Accept wildcard characters: False ``` ### -HomeSiteUrl -The url of the site to set as the home site +The url of the site to set as the home site. ```yaml Type: String @@ -94,7 +94,7 @@ Accept wildcard characters: False ``` ### -DraftMode -When set to $true, the DraftMode parameter will keep the Viva Connections landing experience to the SharePoint home site in draf mode. +When set to $true, the DraftMode parameter will keep the Viva Connections landing experience to the SharePoint home site in draft mode. ```yaml Type: SwitchParameter @@ -107,7 +107,7 @@ Accept wildcard characters: False ``` ### -Force -Use the -Force flag to bypass the confirmation question +Use the -Force flag to bypass the confirmation question. ```yaml Type: SwitchParameter diff --git a/documentation/Set-PnPImageListItemColumn.md b/documentation/Set-PnPImageListItemColumn.md index 659924489..593829f16 100644 --- a/documentation/Set-PnPImageListItemColumn.md +++ b/documentation/Set-PnPImageListItemColumn.md @@ -11,7 +11,7 @@ online version: https://pnp.github.io/powershell/cmdlets/Set-PnPImageListItemCol ## SYNOPSIS -Updates the image column value of a list item +Updates the image column value of a list item. ## SYNTAX @@ -70,7 +70,7 @@ Accept wildcard characters: False ### -Identity -The ID of the listitem, or actual ListItem object +The ID of the list item, or actual ListItem object. ```yaml Type: ListItemPipeBind @@ -130,7 +130,7 @@ Accept wildcard characters: False ### -Path -Use the path from the local file system +Use the path from the local file system. ```yaml Type: String diff --git a/documentation/Set-PnPInPlaceRecordsManagement.md b/documentation/Set-PnPInPlaceRecordsManagement.md index 29f36f0f6..e0064bb51 100644 --- a/documentation/Set-PnPInPlaceRecordsManagement.md +++ b/documentation/Set-PnPInPlaceRecordsManagement.md @@ -29,14 +29,14 @@ Activates or deactivates in place records management feature in the site collect Set-PnPInPlaceRecordsManagement -Enabled $true ``` -Activates In Place Records Management. +Activates in place records management. ### EXAMPLE 2 ```powershell Set-PnPInPlaceRecordsManagement -Enabled $false ``` -Deactivates In Place Records Management. +Deactivates in place records management. ## PARAMETERS diff --git a/documentation/Set-PnPKnowledgeHubSite.md b/documentation/Set-PnPKnowledgeHubSite.md index ea4643604..1ee1d1ba1 100644 --- a/documentation/Set-PnPKnowledgeHubSite.md +++ b/documentation/Set-PnPKnowledgeHubSite.md @@ -15,7 +15,7 @@ online version: https://pnp.github.io/powershell/cmdlets/Set-PnPKnowledgeHubSite * SharePoint: Access to the SharePoint Tenant Administration site -Sets the Knowledge Hub Site for your tenant +Sets the Knowledge Hub Site for your tenant. ## SYNTAX @@ -34,7 +34,7 @@ Allows to set Knowledge Hub Site of the current tenant. Set-PnPKnowledgeHubSite -KnowledgeHubSiteUrl "https://yoursite.sharepoint.com/sites/knowledge" ``` -Sets the Knowledge Hub Site for your tenant +Sets the Knowledge Hub Site for your tenant. ## PARAMETERS @@ -53,6 +53,7 @@ Accept wildcard characters: False ``` ### -KnowledgeHubSiteUrl +Specifies the URL of the site to be set as the Knowledge Hub Site. ```yaml Type: String diff --git a/documentation/Set-PnPList.md b/documentation/Set-PnPList.md index c09f96db0..122d0f24e 100644 --- a/documentation/Set-PnPList.md +++ b/documentation/Set-PnPList.md @@ -10,7 +10,7 @@ online version: https://pnp.github.io/powershell/cmdlets/Set-PnPList.html # Set-PnPList ## SYNOPSIS -Updates list settings +Updates list settings. ## SYNTAX @@ -36,7 +36,7 @@ Allows the configuration of a specific SharePoint Online list to be set. Set-PnPList -Identity "Demo List" -EnableContentTypes $true ``` -Switches the Enable Content Type switch on the list +Switches the Enable Content Type switch on the list. ### EXAMPLE 2 ```powershell @@ -50,56 +50,56 @@ Hides the list from the SharePoint UI. Set-PnPList -Identity "Demo List" -EnableVersioning $true ``` -Turns on major versions on a list +Turns on major versions on a list. ### EXAMPLE 4 ```powershell Set-PnPList -Identity "Demo List" -EnableVersioning $true -MajorVersions 20 ``` -Turns on major versions on a list and sets the maximum number of Major Versions to keep to 20. +Turns on major versions on a list and sets the maximum number of major versions to keep at 20. ### EXAMPLE 5 ```powershell Set-PnPList -Identity "Demo Library" -EnableVersioning $true -EnableMinorVersions $true -MajorVersions 20 -MinorVersions 5 ``` -Turns on major versions on a document library and sets the maximum number of Major versions to keep to 20 and sets the maximum of Minor versions to 5. +Turns on major versions on a document library, sets the maximum number of major versions to keep at 20, and sets the maximum number of minor versions to 5. ### EXAMPLE 6 ```powershell Set-PnPList -Identity "Demo List" -EnableAttachments $true ``` -Turns on attachments on a list +Turns on attachments for a list. ### EXAMPLE 7 ```powershell Set-PnPList -Identity "Demo List" -Title "Demo List 2" -Path "Lists/DemoList2" ``` -Rename a list, including its' URL. +Renames a list, including its URL. ### EXAMPLE 8 ```powershell Set-PnPList -Identity "Demo List" -EnableAutoExpirationVersionTrim $true ``` -Enable AutoExpiration file version trim mode on a document library. +Enables AutoExpiration file version trim mode on a document library. ### EXAMPLE 9 ```powershell Set-PnPList -Identity "Demo List" -EnableAutoExpirationVersionTrim $false -ExpireVersionsAfterDays 30 -MajorVersions 500 ``` -Enable ExpireAfter file version trim mode on a document library. MinorVersions is also needed when minor version is enabled. +Enables ExpireAfter file version trim mode on a document library. MinorVersions parameter is also needed when minor version is enabled. ### EXAMPLE 10 ```powershell Set-PnPList -Identity "Demo List" -EnableAutoExpirationVersionTrim $false -ExpireVersionsAfterDays 0 -MajorVersions 500 ``` -Enable NoExpiration file version trim mode on a document library. MinorVersions is also needed when minor version is enabled. +Enables NoExpiration file version trim mode on a document library. MinorVersions parameter is also needed when minor version is enabled. ### EXAMPLE 11 ```powershell @@ -111,7 +111,7 @@ Sets the default sensitivity label for a document library to Confidential. ## PARAMETERS ### -BreakRoleInheritance -If used the security inheritance is broken for this list from its parent, the web in which it resides. Permissions can be added using [Set-PnPListPermission](Set-PnPListPermission.md). +If used, the security inheritance is broken for this list from its parent, the web in which it resides. Permissions can be added using [Set-PnPListPermission](Set-PnPListPermission.md). ```yaml Type: SwitchParameter @@ -125,7 +125,7 @@ Accept wildcard characters: False ``` ### -ResetRoleInheritance -If used the security inheritance is reset for this list meaning it will not copy the permissions from its parent, but will start with an empty list of permissions. Permissions can be added using [Set-PnPListPermission](Set-PnPListPermission.md). +If used, the security inheritance is reset for this list, meaning it will not copy the permissions from its parent but will start with an empty list of permissions. Permissions can be added using [Set-PnPListPermission](Set-PnPListPermission.md). ```yaml Type: SwitchParameter @@ -139,7 +139,7 @@ Accept wildcard characters: False ``` ### -ClearSubScopes -If used the unique permissions are cleared from child objects and they can inherit role assignments from this object +If used, the unique permissions are cleared from child objects and they can inherit role assignments from this object. ```yaml Type: SwitchParameter @@ -167,7 +167,7 @@ Accept wildcard characters: False ``` ### -CopyRoleAssignments -If used the roles are copied from the parent web +If used, the role assignments are copied from the parent web. ```yaml Type: SwitchParameter @@ -181,7 +181,7 @@ Accept wildcard characters: False ``` ### -Description -The description of the list +The description of the list. ```yaml Type: String @@ -223,7 +223,7 @@ Accept wildcard characters: False ``` ### -EnableContentTypes -Set to $true to enable content types, set to $false to disable content types +Set to $true to enable content types, set to $false to disable content types. ```yaml Type: Boolean @@ -378,7 +378,7 @@ Accept wildcard characters: False ``` ### -MajorVersions -Maximum major versions to keep +Maximum major versions to keep. ```yaml Type: UInt32 @@ -392,7 +392,7 @@ Accept wildcard characters: False ``` ### -MinorVersions -Maximum major versions for which to keep minor versions +Maximum major versions for which to keep minor versions. ```yaml Type: UInt32 @@ -406,7 +406,7 @@ Accept wildcard characters: False ``` ### -OpenDocumentsMode -Allows configuring the opening documents in the browser advanced setting on document libraries. Set to ClientApplication to have documents being opened in the locally installed Word, PowerPoint or Excel client or set to Browser to have documents being opened in the browser. It is not possible to set it to "Use the server default mode". +Allows configuring the "Opening Documents in the Browser" advanced setting on document libraries. Set to `ClientApplication` to have documents opened in the locally installed Word, PowerPoint, or Excel client, or set to `Browser` to have documents opened in the browser. It is not possible to set it to "Use the server default mode". ```yaml Type: DocumentLibraryOpenDocumentsInMode @@ -421,7 +421,7 @@ Accept wildcard characters: False ``` ### -ReadSecurity -Sets the read security for the list +Sets the read security for the list. ```yaml Type: ListReadSecurity @@ -435,7 +435,7 @@ Accept wildcard characters: False ``` ### -WriteSecurity -Sets the write security for the list +Sets the write security for the list. ```yaml Type: ListWriteSecurity @@ -449,7 +449,7 @@ Accept wildcard characters: False ``` ### -Title -The title of the list +The title of the list. ```yaml Type: String @@ -463,7 +463,7 @@ Accept wildcard characters: False ``` ### -NoCrawl -Switch parameter if this list should be indexed in search. +Switch parameter to specify whether this list should be excluded from search indexing. ```yaml Type: SwitchParameter @@ -552,7 +552,7 @@ Accept wildcard characters: False ``` ### -ExpireVersionsAfterDays -Work with parameter EnableAutoExpirationVersionTrim. Please see description in EnableAutoExpirationVersionTrim. +Works with parameter EnableAutoExpirationVersionTrim. Please see description in EnableAutoExpirationVersionTrim. ```yaml Type: UInt32 diff --git a/documentation/Set-PnPListInformationRightsManagement.md b/documentation/Set-PnPListInformationRightsManagement.md index d3688541b..17d8a4a52 100644 --- a/documentation/Set-PnPListInformationRightsManagement.md +++ b/documentation/Set-PnPListInformationRightsManagement.md @@ -313,6 +313,7 @@ Accept wildcard characters: False ``` ### -TemplateId +Specifies the predefined IRM (Information Rights Management) template. ```yaml Type: String diff --git a/documentation/Set-PnPListItem.md b/documentation/Set-PnPListItem.md index 288ab9907..948cda49f 100644 --- a/documentation/Set-PnPListItem.md +++ b/documentation/Set-PnPListItem.md @@ -11,7 +11,7 @@ online version: https://pnp.github.io/powershell/cmdlets/Set-PnPListItem.html ## SYNOPSIS -Updates a list item +Updates a list item. Supports Batching @@ -125,7 +125,7 @@ Accept wildcard characters: False ### -ContentType -Specify either the name, ID or an actual content type +Specify either the name, ID or an actual content type. ```yaml Type: ContentTypePipeBind @@ -140,7 +140,7 @@ Accept wildcard characters: False ### -Identity -The ID of the listitem, or actual ListItem object +The ID of the listitem, or actual ListItem object. ```yaml Type: ListItemPipeBind @@ -188,7 +188,7 @@ Accept wildcard characters: False Specifies the update type to use when updating the listitem. Possible values are "Update", "SystemUpdate", "UpdateOverwriteVersion". * **Update**: Sets field values and creates a new version if versioning is enabled for the list. The "Modified By" and "Modified" fields will be updated to reflect the time of the update and the user who made the change. -* **SystemUpdate**: Sets field values and does not create a new version. Any events on the list will trigger. The "Modified By" and "Modified" fields not updated and can not be set. +* **SystemUpdate**: Sets field values and does not create a new version. Any events on the list will trigger. The "Modified By" and "Modified" fields are not updated and can not be set. * **UpdateOverwriteVersion**: Sets field values and does not create a new version. No events on the list will trigger. The "Modified By" and "Modified" fields are not updated but can be set by passing the field values in the update. HINT: use 'Editor' to set the "Modified By" field. ```yaml diff --git a/documentation/Set-PnPListItemPermission.md b/documentation/Set-PnPListItemPermission.md index 075d734c7..d24a6e17e 100644 --- a/documentation/Set-PnPListItemPermission.md +++ b/documentation/Set-PnPListItemPermission.md @@ -11,9 +11,6 @@ online version: https://pnp.github.io/powershell/cmdlets/Set-PnPListItemPermissi ## SYNOPSIS Sets list item permissions. -Use Get-PnPRoleDefinition to retrieve all available roles you can add or remove using this cmdlet. -Use Get-PnPGroup to retrieve all groups available that you can add or remove using this cmdlet when using the -group parameter. - ## SYNTAX @@ -40,6 +37,8 @@ Set-PnPListItemPermission [-List] -Identity [- ## DESCRIPTION Allows to modify list item permissions. +Use Get-PnPRoleDefinition to retrieve all available roles you can add or remove using this cmdlet. +Use Get-PnPGroup to retrieve all groups available that you can add or remove using this cmdlet when using the -group parameter. ## EXAMPLES @@ -48,41 +47,41 @@ Allows to modify list item permissions. Set-PnPListItemPermission -List 'Documents' -Identity 1 -User 'user@contoso.com' -AddRole 'Contribute' ``` -Adds the 'Contribute' permission to the user 'user@contoso.com' for listitem with id 1 in the list 'Documents' +Adds the 'Contribute' permission to the user 'user@contoso.com' for listitem with id 1 in the list 'Documents'. ### EXAMPLE 2 ```powershell Set-PnPListItemPermission -List 'Documents' -Identity 1 -User 'user@contoso.com' -RemoveRole 'Contribute' ``` -Removes the 'Contribute' permission to the user 'user@contoso.com' for listitem with id 1 in the list 'Documents' +Removes the 'Contribute' permission from the user 'user@contoso.com' for listitem with id 1 in the list 'Documents'. ### EXAMPLE 3 ```powershell Set-PnPListItemPermission -List 'Documents' -Identity 1 -User 'user@contoso.com' -AddRole 'Contribute' -ClearExisting ``` -Adds the 'Contribute' permission to the user 'user@contoso.com' for listitem with id 1 in the list 'Documents' and removes all other permissions +Adds the 'Contribute' permission to the user 'user@contoso.com' for listitem with id 1 in the list 'Documents' and removes all other permissions. ### EXAMPLE 4 ```powershell Set-PnPListItemPermission -List 'Documents' -Identity 1 -InheritPermissions ``` -Resets permissions for listitem with id 1 to inherit permissions from the list 'Documents' +Resets permissions for listitem with id 1 to inherit permissions from the list 'Documents'. ### EXAMPLE 5 ```powershell Set-PnPListItemPermission -List 'Documents' -Identity 1 -AddRole 'Read' -RemoveRole 'Contribute' -Group "Site collection Visitors" ``` -Adds the 'Read' permission to the group of Site collection Visitors while removing the 'Contribute' permissions +Adds the 'Read' permission to the group of Site collection Visitors while removing the 'Contribute' permissions. ## PARAMETERS ### -AddRole -The role that must be assigned to the group or user +The role that must be assigned to the group or user. ```yaml Type: RoleDefinitionPipeBind @@ -96,7 +95,7 @@ Accept wildcard characters: False ``` ### -ClearExisting -Clear all existing permissions +Clear all existing permissions. ```yaml Type: SwitchParameter @@ -138,7 +137,7 @@ Accept wildcard characters: False ``` ### -Identity -The ID of the listitem, or actual ListItem object +The ID of the listitem, or actual ListItem object. ```yaml Type: ListItemPipeBind @@ -152,7 +151,7 @@ Accept wildcard characters: False ``` ### -InheritPermissions -Inherit permissions from the list, removing unique permissions +Inherit permissions from the list, removing unique permissions. ```yaml Type: SwitchParameter @@ -180,7 +179,7 @@ Accept wildcard characters: False ``` ### -RemoveRole -The role that must be removed from the group or user +The role that must be removed from the group or user. ```yaml Type: RoleDefinitionPipeBind diff --git a/documentation/Set-PnPListPermission.md b/documentation/Set-PnPListPermission.md index aa3d72c97..20a1ca863 100644 --- a/documentation/Set-PnPListPermission.md +++ b/documentation/Set-PnPListPermission.md @@ -28,6 +28,7 @@ Set-PnPListPermission -Identity -User [-AddRole ## DESCRIPTION Allows changing permissions on a SharePoint list. In case you would like to break the permission inheritance on a list from its parent, you can use [Set-PnPList -BreakRoleInheritance](Set-PnPList.md#-breakroleinheritance). +Use Get-PnPRoleDefinition to retrieve all available roles you can add or remove using this cmdlet. ## EXAMPLES @@ -43,7 +44,7 @@ Adds the 'Contribute' permission to the user 'user@contoso.com' for the list 'Do Set-PnPListPermission -Identity 'Documents' -User 'user@contoso.com' -RemoveRole 'Contribute' ``` -Removes the 'Contribute' permission to the user 'user@contoso.com' for the list 'Documents'. +Removes the 'Contribute' permission from the user 'user@contoso.com' for the list 'Documents'. ## PARAMETERS diff --git a/documentation/Set-PnPMasterPage.md b/documentation/Set-PnPMasterPage.md index 41ae61616..c396fe096 100644 --- a/documentation/Set-PnPMasterPage.md +++ b/documentation/Set-PnPMasterPage.md @@ -10,7 +10,7 @@ online version: https://pnp.github.io/powershell/cmdlets/Set-PnPMasterPage.html # Set-PnPMasterPage ## SYNOPSIS -Set the masterpage +Set the masterpage. ## SYNTAX @@ -36,28 +36,28 @@ Sets the default master page of the current web. Set-PnPMasterPage -MasterPageServerRelativeUrl /sites/projects/_catalogs/masterpage/oslo.master ``` -Sets the master page based on a server relative URL +Sets the master page based on a server relative URL. ### EXAMPLE 2 ```powershell Set-PnPMasterPage -MasterPageServerRelativeUrl /sites/projects/_catalogs/masterpage/oslo.master -CustomMasterPageServerRelativeUrl /sites/projects/_catalogs/masterpage/oslo.master ``` -Sets the master page and custom master page based on a server relative URL +Sets the master page and custom master page based on a server relative URL. ### EXAMPLE 3 ```powershell Set-PnPMasterPage -MasterPageSiteRelativeUrl _catalogs/masterpage/oslo.master ``` -Sets the master page based on a site relative URL +Sets the master page based on a site relative URL. ### EXAMPLE 4 ```powershell Set-PnPMasterPage -MasterPageSiteRelativeUrl _catalogs/masterpage/oslo.master -CustomMasterPageSiteRelativeUrl _catalogs/masterpage/oslo.master ``` -Sets the master page and custom master page based on a site relative URL +Sets the master page and custom master page based on a site relative URL. ## PARAMETERS @@ -76,7 +76,7 @@ Accept wildcard characters: False ``` ### -CustomMasterPageServerRelativeUrl -Specifies the custom Master page URL based on the server relative URL +Specifies the custom Master page URL based on the server relative URL. ```yaml Type: String @@ -91,7 +91,7 @@ Accept wildcard characters: False ``` ### -CustomMasterPageSiteRelativeUrl -Specifies the custom Master page URL based on the site relative URL +Specifies the custom Master page URL based on the site relative URL. ```yaml Type: String @@ -105,7 +105,7 @@ Accept wildcard characters: False ``` ### -MasterPageServerRelativeUrl -Specifies the Master page URL based on the server relative URL +Specifies the Master page URL based on the server relative URL. ```yaml Type: String @@ -120,7 +120,7 @@ Accept wildcard characters: False ``` ### -MasterPageSiteRelativeUrl -Specifies the Master page URL based on the site relative URL +Specifies the Master page URL based on the site relative URL. ```yaml Type: String diff --git a/documentation/Set-PnPMessageCenterAnnouncementAsArchived.md b/documentation/Set-PnPMessageCenterAnnouncementAsArchived.md index 3d14709a5..a643f9b40 100644 --- a/documentation/Set-PnPMessageCenterAnnouncementAsArchived.md +++ b/documentation/Set-PnPMessageCenterAnnouncementAsArchived.md @@ -15,12 +15,12 @@ online version: https://pnp.github.io/powershell/cmdlets/Set-PnPMessageCenterAnn * Microsoft Graph API : ServiceMessageViewpoint.Write (delegated) -Marks one or multiple message center announcements of the Office 365 Services as archived +Marks one or multiple message center announcements of the Office 365 Services as archived. ## SYNTAX ```powershell -Set-PnPMessageCenterAnnouncementAsArchived [-Identity ] +Set-PnPMessageCenterAnnouncementAsArchived [-Identity ] [-Connection ] ``` ## DESCRIPTION @@ -34,26 +34,40 @@ Allows to mark message center announcements as archived. Set-PnPMessageCenterAnnouncementAsArchived -Identity "MC123456" ``` -Marks message center announcement MC123456 as archived for the current user +Marks message center announcement MC123456 as archived for the current user. ### EXAMPLE 2 ```powershell Set-PnPMessageCenterAnnouncementAsArchived -Identity "MC123456", "MC234567" ``` -Marks message center announcements MC123456 and MC234567 as archived for the current user +Marks message center announcements MC123456 and MC234567 as archived for the current user. ### EXAMPLE 3 ```powershell Set-PnPMessageCenterAnnouncementAsArchived ``` -Marks all message center announcements as archived for the current user +Marks all message center announcements as archived for the current user. ## PARAMETERS +### -Connection +Optional connection to be used by the cmdlet. Retrieve the value for this parameter by either specifying -ReturnConnection on Connect-PnPOnline or by executing Get-PnPConnection. + +```yaml +Type: PnPConnection +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -Identity -Marks the message center announcement or announcements with the provided Ids as archived +Marks the message center announcement or announcements with the provided Ids as archived. ```yaml Type: String[] diff --git a/documentation/Set-PnPMessageCenterAnnouncementAsFavorite.md b/documentation/Set-PnPMessageCenterAnnouncementAsFavorite.md index 76bb2eafd..0fec0345a 100644 --- a/documentation/Set-PnPMessageCenterAnnouncementAsFavorite.md +++ b/documentation/Set-PnPMessageCenterAnnouncementAsFavorite.md @@ -15,12 +15,12 @@ online version: https://pnp.github.io/powershell/cmdlets/Set-PnPMessageCenterAnn * Microsoft Graph API : ServiceMessageViewpoint.Write (delegated) -Marks one or multiple message center announcements of the Office 365 Services as favorite +Marks one or multiple message center announcements of the Office 365 Services as favorite$. ## SYNTAX ```powershell -Set-PnPMessageCenterAnnouncementAsFavorite [-Identity ] +Set-PnPMessageCenterAnnouncementAsFavorite [-Identity ] [-Connection ] ``` ## DESCRIPTION @@ -34,26 +34,40 @@ Allows to mark message center announcements as favorite. Set-PnPMessageCenterAnnouncementAsFavorite -Identity "MC123456" ``` -Marks message center announcement MC123456 as favorite for the current user +Marks message center announcement MC123456 as favorite for the current user. ### EXAMPLE 2 ```powershell Set-PnPMessageCenterAnnouncementAsFavorite -Identity "MC123456", "MC234567" ``` -Marks message center announcements MC123456 and MC234567 as favorite for the current user +Marks message center announcements MC123456 and MC234567 as favorite for the current user. ### EXAMPLE 3 ```powershell Set-PnPMessageCenterAnnouncementAsFavorite ``` -Marks all message center announcements as favorite for the current user +Marks all message center announcements as favorite for the current user. ## PARAMETERS +### -Connection +Optional connection to be used by the cmdlet. Retrieve the value for this parameter by either specifying -ReturnConnection on Connect-PnPOnline or by executing Get-PnPConnection. + +```yaml +Type: PnPConnection +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -Identity -Marks a particular message center announcement or announcements with the provided Ids as favorite +Marks a particular message center announcement or announcements with the provided Ids as favorite. ```yaml Type: String[] Parameter Sets: None diff --git a/documentation/Set-PnPMessageCenterAnnouncementAsNotArchived.md b/documentation/Set-PnPMessageCenterAnnouncementAsNotArchived.md index 7302add4a..cdd1f735e 100644 --- a/documentation/Set-PnPMessageCenterAnnouncementAsNotArchived.md +++ b/documentation/Set-PnPMessageCenterAnnouncementAsNotArchived.md @@ -15,12 +15,12 @@ online version: https://pnp.github.io/powershell/cmdlets/Set-PnPMessageCenterAnn * Microsoft Graph API : ServiceMessageViewpoint.Write (delegated) -Marks one or multiple message center announcements of the Office 365 Services as not archived +Marks one or multiple message center announcements of the Office 365 Services as not archived. ## SYNTAX ```powershell -Set-PnPMessageCenterAnnouncementAsNotArchived [-Identity ] +Set-PnPMessageCenterAnnouncementAsNotArchived [-Identity ] [-Connection ] ``` ## DESCRIPTION @@ -34,26 +34,40 @@ Allows to mark message center announcements as not archived. Set-PnPMessageCenterAnnouncementAsNotArchived -Identity "MC123456" ``` -Marks message center announcement MC123456 as not archived for the current user +Marks message center announcement MC123456 as not archived for the current user. ### EXAMPLE 2 ```powershell Set-PnPMessageCenterAnnouncementAsNotArchived -Identity "MC123456", "MC234567" ``` -Marks message center announcements MC123456 and MC234567 as not archived for the current user +Marks message center announcements MC123456 and MC234567 as not archived for the current user. ### EXAMPLE 3 ```powershell Set-PnPMessageCenterAnnouncementAsNotArchived ``` -Marks all message center announcements as not archived for the current user +Marks all message center announcements as not archived for the current user. ## PARAMETERS +### -Connection +Optional connection to be used by the cmdlet. Retrieve the value for this parameter by either specifying -ReturnConnection on Connect-PnPOnline or by executing Get-PnPConnection. + +```yaml +Type: PnPConnection +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -Identity -Marks a particular message center announcement or announcements with the provided Ids as not archived +Marks a particular message center announcement or announcements with the provided Ids as not archived. ```yaml Type: String[] Parameter Sets: None diff --git a/documentation/Set-PnPMessageCenterAnnouncementAsNotFavorite.md b/documentation/Set-PnPMessageCenterAnnouncementAsNotFavorite.md index 789776efa..2d0bded11 100644 --- a/documentation/Set-PnPMessageCenterAnnouncementAsNotFavorite.md +++ b/documentation/Set-PnPMessageCenterAnnouncementAsNotFavorite.md @@ -15,12 +15,12 @@ online version: https://pnp.github.io/powershell/cmdlets/Set-PnPMessageCenterAnn * Microsoft Graph API : ServiceMessageViewpoint.Write (delegated) -Marks one or multiple message center announcements of the Office 365 Services as not favorite +Marks one or multiple message center announcements of the Office 365 Services as not favorite. ## SYNTAX ```powershell -Set-PnPMessageCenterAnnouncementAsNotFavorite [-Identity ] +Set-PnPMessageCenterAnnouncementAsNotFavorite [-Identity ] [-Connection ] ``` ## DESCRIPTION @@ -34,26 +34,40 @@ Allows to mark message center announcements as not favorite. Set-PnPMessageCenterAnnouncementAsNotFavorite -Identity "MC123456" ``` -Marks message center announcement MC123456 as not favorite for the current user +Marks message center announcement MC123456 as not favorite for the current user. ### EXAMPLE 2 ```powershell Set-PnPMessageCenterAnnouncementAsNotFavorite -Identity "MC123456", "MC234567" ``` -Marks message center announcements MC123456 and MC234567 as not favorite for the current user +Marks message center announcements MC123456 and MC234567 as not favorite for the current user. ### EXAMPLE 3 ```powershell Set-PnPMessageCenterAnnouncementAsNotFavorite ``` -Marks all message center announcements as not favorite for the current user +Marks all message center announcements as not favorite for the current user. ## PARAMETERS +### -Connection +Optional connection to be used by the cmdlet. Retrieve the value for this parameter by either specifying -ReturnConnection on Connect-PnPOnline or by executing Get-PnPConnection. + +```yaml +Type: PnPConnection +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -Identity -Marks the message center announcement or announcements with the provided Ids as not favorite +Marks the message center announcement or announcements with the provided Ids as not favorite. ```yaml Type: String[] Parameter Sets: None diff --git a/documentation/Set-PnPMessageCenterAnnouncementAsRead.md b/documentation/Set-PnPMessageCenterAnnouncementAsRead.md index 9b09fbfbf..1bcd75682 100644 --- a/documentation/Set-PnPMessageCenterAnnouncementAsRead.md +++ b/documentation/Set-PnPMessageCenterAnnouncementAsRead.md @@ -15,12 +15,12 @@ online version: https://pnp.github.io/powershell/cmdlets/Set-PnPMessageCenterAnn * Microsoft Graph API : ServiceMessageViewpoint.Write (delegated) -Marks one or multiple message center announcements of the Office 365 Services as read +Marks one or multiple message center announcements of the Office 365 Services as read. ## SYNTAX ```powershell -Set-PnPMessageCenterAnnouncementAsRead [-Identity ] +Set-PnPMessageCenterAnnouncementAsRead [-Identity ] [-Connection ] ``` ## DESCRIPTION @@ -34,26 +34,40 @@ Allows to mark message center announcements as read. Set-PnPMessageCenterAnnouncementAsRead -Identity "MC123456" ``` -Marks message center announcement MC123456 as read for the current user +Marks message center announcement MC123456 as read for the current user. ### EXAMPLE 2 ```powershell Set-PnPMessageCenterAnnouncementAsRead -Identity "MC123456", "MC234567" ``` -Marks message center announcements MC123456 and MC234567 as read for the current user +Marks message center announcements MC123456 and MC234567 as read for the current user. ### EXAMPLE 3 ```powershell Set-PnPMessageCenterAnnouncementAsRead ``` -Marks all message center announcements as read for the current user +Marks all message center announcements as read for the current user. ## PARAMETERS +### -Connection +Optional connection to be used by the cmdlet. Retrieve the value for this parameter by either specifying -ReturnConnection on Connect-PnPOnline or by executing Get-PnPConnection. + +```yaml +Type: PnPConnection +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -Identity -Marks the message center announcement or announcements with the provided Ids as read +Marks the message center announcement or announcements with the provided Ids as read. ```yaml Type: String[] Parameter Sets: None diff --git a/documentation/Set-PnPMicrosoft365Group.md b/documentation/Set-PnPMicrosoft365Group.md index db0556187..8a75ab97b 100644 --- a/documentation/Set-PnPMicrosoft365Group.md +++ b/documentation/Set-PnPMicrosoft365Group.md @@ -15,7 +15,7 @@ online version: https://pnp.github.io/powershell/cmdlets/Set-PnPMicrosoft365Grou * Microsoft Graph API: Group.ReadWrite.All -Sets Microsoft 365 Group properties +Sets Microsoft 365 Group properties. ## SYNTAX @@ -34,42 +34,42 @@ Allows to modify Microsoft 365 Group. Set-PnPMicrosoft365Group -Identity $group -DisplayName "My DisplayName" ``` -Sets the display name of the group where $group is a Group entity +Sets the display name of the group where $group is a Group entity. ### EXAMPLE 2 ```powershell -Set-PnPMicrosoft365Group -Identity $groupId -Descriptions "My Description" -DisplayName "My DisplayName" +Set-PnPMicrosoft365Group -Identity $groupId -Description "My Description" -DisplayName "My DisplayName" ``` -Sets the display name and description of a group based upon its ID +Sets the display name and description of a group based upon its ID. ### EXAMPLE 3 ```powershell Set-PnPMicrosoft365Group -Identity $group -GroupLogoPath ".\MyLogo.png" ``` -Sets a specific Microsoft 365 Group logo +Sets a specific Microsoft 365 Group logo. ### EXAMPLE 4 ```powershell Set-PnPMicrosoft365Group -Identity $group -IsPrivate:$false ``` -Sets a group to be Public if previously Private +Sets a group to be Public if previously Private. ### EXAMPLE 5 ```powershell Set-PnPMicrosoft365Group -Identity $group -Owners demo@contoso.com ``` -Sets demo@contoso.com as owner of the group +Sets demo@contoso.com as owner of the group. ### EXAMPLE 6 ```powershell Set-PnPMicrosoft365Group -Identity $group -SensitivityLabels "bc98af29-59eb-4869-baaa-9a8dff631aa4" ``` -Sets the sensitivity label of the group +Sets the sensitivity label of the group. ## PARAMETERS @@ -112,7 +112,7 @@ Accept wildcard characters: False ``` ### -CreateTeam -Creates a Microsoft Teams team associated with created group +Creates a Microsoft Teams team associated with the created group. ```yaml Type: SwitchParameter @@ -126,7 +126,7 @@ Accept wildcard characters: False ``` ### -Description -The Description of the group to set +The Description of the group to set. ```yaml Type: String @@ -140,7 +140,7 @@ Accept wildcard characters: False ``` ### -DisplayName -The DisplayName of the group to set +The DisplayName of the group to set. ```yaml Type: String @@ -153,11 +153,11 @@ Accept pipeline input: False Accept wildcard characters: False ``` -### -LogoPath -The path to the logo file of to set. Logo must be at least 48 pixels wide and may be at most 4 MB in size. Requires Site.ReadWrite.All permissions. +### -HideFromAddressLists +Controls whether the group is hidden or shown in the Global Address List (GAL). ```yaml -Type: String +Type: Boolean Parameter Sets: (All) Required: False @@ -167,8 +167,8 @@ Accept pipeline input: False Accept wildcard characters: False ``` -### -HideFromAddressLists -Controls whether the group is hidden or shown in the Global Address List (GAL). +### -HideFromOutlookClients +Controls whether the group shows in the Outlook left-hand navigation. ```yaml Type: Boolean @@ -181,25 +181,25 @@ Accept pipeline input: False Accept wildcard characters: False ``` -### -HideFromOutlookClients -Controls whether the group shows in the Outlook left-hand navigation. +### -Identity +The Identity of the Microsoft 365 Group. ```yaml -Type: Boolean +Type: Microsoft365GroupPipeBind Parameter Sets: (All) -Required: False +Required: True Position: Named Default value: None -Accept pipeline input: False +Accept pipeline input: True (ByValue) Accept wildcard characters: False ``` -### -MailNickname -The mail alias for the group, unique for Microsoft 365 groups in the organization. Maximum length is 64 characters. This property can contain only characters in the ASCII character set 0 - 127 except the following: @ () \ [] " ; : . <> , SPACE +### -IsPrivate +Makes the group private when selected. ```yaml -Type: String +Type: SwitchParameter Parameter Sets: (All) Required: False @@ -209,25 +209,25 @@ Accept pipeline input: False Accept wildcard characters: False ``` -### -Identity -The Identity of the Microsoft 365 Group +### -LogoPath +The path to the logo file of to set. Logo must be at least 48 pixels wide and may be at most 4 MB in size. Requires Site.ReadWrite.All permissions. ```yaml -Type: Microsoft365GroupPipeBind +Type: String Parameter Sets: (All) -Required: True +Required: False Position: Named Default value: None -Accept pipeline input: True (ByValue) +Accept pipeline input: False Accept wildcard characters: False ``` -### -IsPrivate -Makes the group private when selected +### -MailNickname +The mail alias for the group, unique for Microsoft 365 groups in the organization. Maximum length is 64 characters. This property can contain only characters in the ASCII character set 0 - 127 except the following: @ () \ [] " ; : . <> , SPACE ```yaml -Type: SwitchParameter +Type: String Parameter Sets: (All) Required: False @@ -295,4 +295,4 @@ Accept wildcard characters: False ## RELATED LINKS [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) -[Microsoft Graph documentation](https://learn.microsoft.com/graph/api/group-update) \ No newline at end of file +[Microsoft Graph documentation](https://learn.microsoft.com/graph/api/group-update) diff --git a/documentation/Set-PnPSearchExternalConnection.md b/documentation/Set-PnPSearchExternalConnection.md new file mode 100644 index 000000000..3a6ed1421 --- /dev/null +++ b/documentation/Set-PnPSearchExternalConnection.md @@ -0,0 +1,135 @@ +--- +Module Name: PnP.PowerShell +schema: 2.0.0 +applicable: SharePoint Online +online version: https://pnp.github.io/powershell/cmdlets/Set-PnPSearchExternalConnection.html +external help file: PnP.PowerShell.dll-Help.xml +title: Set-PnPSearchExternalConnection +--- + +# Set-PnPSearchExternalConnection + +## SYNOPSIS + +**Required Permissions** + + * Microsoft Graph API : One of ExternalConnection.ReadWrite.OwnedBy, ExternalConnection.ReadWrite.All + +Updates a connection to an external datasource for Microsoft Search + +## SYNTAX + +```powershell +Set-PnPSearchExternalConnection -Identity [-Name ] [-Description ] [-AuthorizedAppIds ] [-Verbose] [-Connection ] +``` + +## DESCRIPTION + +This cmdlet can be used to update an external datasource connection that is being indexed into Microsoft Search through a custom connector. Use [New-PnPSearchExternalConnection](New-PnPSearchExternalConnection.md) to create a new connector. + +## EXAMPLES + +### EXAMPLE 1 +```powershell +Set-PnPSearchExternalConnection -Identity "pnppowershell" -Name "PnP PowerShell Rocks" +``` + +This will update just the name of the external connection with the provided identity to the value provided. The description will remain unchanged. + +### EXAMPLE 2 +```powershell +Set-PnPSearchExternalConnection -Identity "pnppowershell" -Name "PnP PowerShell Rocks" -Description "External content ingested using PnP PowerShell which rocks" +``` + +This will update the name and description of the external connection with the provided identity to the values provided. + +### EXAMPLE 3 +```powershell +Set-PnPSearchExternalConnection -Identity "pnppowershell" -AuthorizedAppIds "00000000-0000-0000-0000-000000000000","11111111-1111-1111-1111-111111111111" +``` + +This will replace the application registration identifiers of which the client Ids have been provided that can add items to the index for this connection. + +## PARAMETERS + +### -Connection +Optional connection to be used by the cmdlet. Retrieve the value for this parameter by either specifying -ReturnConnection on Connect-PnPOnline or by executing [Get-PnPConnection](Get-PnPConnection.md). + +```yaml +Type: PnPConnection +Parameter Sets: (All) +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Identity +Unique identifier or an instance of the external connection in Microsoft Search that needs to be updated. + +```yaml +Type: SearchExternalConnectionPipeBind +Parameter Sets: (All) +Required: True +Position: Named +Default value: None +Accept pipeline input: True +Accept wildcard characters: False +``` + +### -Name +The display name of the connection to be displayed in the Microsoft 365 admin center. Maximum length of 128 characters. Only provide when it needs to change. + +```yaml +Type: String +Parameter Sets: (All) +Required: False +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Description +Description of the connection displayed in the Microsoft 365 admin center. Only provide when it needs to change. + +```yaml +Type: String +Parameter Sets: (All) +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -AuthorizedAppIds +The client Ids of the application registrations that are allowed to add items to the index for this connection. Only provide when it needs to change. + +```yaml +Type: String[] +Parameter Sets: (All) +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Verbose +When provided, additional debug statements will be shown while executing the cmdlet. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +## RELATED LINKS + +[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) \ No newline at end of file diff --git a/documentation/Set-PnPSearchExternalItem.md b/documentation/Set-PnPSearchExternalItem.md index 67cb4f542..9c7e165f0 100644 --- a/documentation/Set-PnPSearchExternalItem.md +++ b/documentation/Set-PnPSearchExternalItem.md @@ -20,7 +20,7 @@ Adds or updates an external item in Microsoft Search ## SYNTAX ```powershell -Set-PnPSearchExternalItem -ItemId -ConnectionId -Properties [-ContentValue ] [-ContentType ] [-GrantUsers ] [-GrantGroups ] [-DenyUsers ] [-DenyGroups ] [-GrantExternalGroups ] [-DenyExternalGroups ] [-GrantEveryone ] [-Verbose] [-Connection ] +Set-PnPSearchExternalItem -ItemId -ConnectionId -Properties [-ContentValue ] [-ContentType ] [-GrantUsers ] [-GrantGroups ] [-DenyUsers ] [-DenyGroups ] [-GrantExternalGroups ] [-DenyExternalGroups ] [-GrantEveryone ] [-Verbose] [-Connection ] ``` ## DESCRIPTION @@ -72,14 +72,14 @@ Accept wildcard characters: False ``` ### -ConnectionId -The Connection ID of the custom connector to use. This is the ID that was entered when registering the custom connector and will indicate for which custom connector this external item is being added to the Microsoft Search index. +The Connection ID or connection instance of the custom connector to use. This is the ID that was entered when registering the custom connector and will indicate for which custom connector this external item is being added to the Microsoft Search index. ```yaml -Type: String +Type: SearchExternalConnectionPipeBind Parameter Sets: (All) Required: True Default value: None -Accept pipeline input: False +Accept pipeline input: True Accept wildcard characters: False ``` diff --git a/documentation/Set-PnPSearchExternalSchema.md b/documentation/Set-PnPSearchExternalSchema.md new file mode 100644 index 000000000..8888a4211 --- /dev/null +++ b/documentation/Set-PnPSearchExternalSchema.md @@ -0,0 +1,150 @@ +--- +Module Name: PnP.PowerShell +schema: 2.0.0 +applicable: SharePoint Online +online version: https://pnp.github.io/powershell/cmdlets/Set-PnPSearchExternalSchema.html +external help file: PnP.PowerShell.dll-Help.xml +title: Set-PnPSearchExternalSchema +--- + +# Set-PnPSearchExternalSchema + +## SYNOPSIS + +**Required Permissions** + + * Microsoft Graph API : One of ExternalConnection.ReadWrite.OwnedBy, ExternalConnection.ReadWrite.All + +Updates the schema set on a connection to an external datasource belonging to Microsoft Search + +## SYNTAX + +### By textual schema + +```powershell +Set-PnPSearchExternalSchema -ConnectionId -SchemaAsText [-Verbose] [-Connection ] +``` + +### By schema instance + +```powershell +Set-PnPSearchExternalSchema -ConnectionId -Schema [-Verbose] [-Connection ] +``` + +## DESCRIPTION + +This cmdlet can be used to initially set or update the current schema set on a connection to an external datasource that is being indexed into Microsoft Search through a custom connector. The URL returned can be queried in Microsoft Graph to check on the status of the schema update. + +## EXAMPLES + +### EXAMPLE 1 +```powershell +Set-PnPSearchExternalSchema -ConnectionId "pnppowershell" -SchemaAsText '{ + "baseType": "microsoft.graph.externalItem", + "properties": [ + { + "name": "ticketTitle", + "type": "String", + "isSearchable": "true", + "isRetrievable": "true", + "labels": [ + "title" + ] + }, + { + "name": "priority", + "type": "String", + "isQueryable": "true", + "isRetrievable": "true", + "isSearchable": "false" + }, + { + "name": "assignee", + "type": "String", + "isRetrievable": "true" + } + ] + }' +``` + +This will set the provided JSON schema to be used for the external search connection with the provided name + +### EXAMPLE 2 +```powershell +$schema = Get-PnPSearchExternalSchema -ConnectionId "pnppowershell1" +Set-PnPSearchExternalSchema -ConnectionId "pnppowershell2" -Schema $schema +``` + +This will take the current schema set on the external search connection named 'pnppowershell1' and sets the same schema on the external search connection named 'pnppowershell2' + +## PARAMETERS + +### -Connection +Optional connection to be used by the cmdlet. Retrieve the value for this parameter by either specifying -ReturnConnection on Connect-PnPOnline or by executing [Get-PnPConnection](Get-PnPConnection.md). + +```yaml +Type: PnPConnection +Parameter Sets: (All) +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ConnectionId +Unique identifier or instance of the external connection in Microsoft Search to set the schema for + +```yaml +Type: String +Parameter Sets: (All) +Required: True +Position: Named +Default value: None +Accept pipeline input: True +Accept wildcard characters: False +``` + +### -SchemaAsText +The textual representation of the schema to set on the external connection + +```yaml +Type: String +Parameter Sets: By textual schema +Required: True +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Schema +An instance of a schema to set on the external connection + +```yaml +Type: String +Parameter Sets: By schema instance +Required: True +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Verbose +When provided, additional debug statements will be shown while executing the cmdlet. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +## RELATED LINKS + +[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) \ No newline at end of file diff --git a/documentation/Set-PnPSiteSensitivityLabel.md b/documentation/Set-PnPSiteSensitivityLabel.md index 04caae5bb..4706d9203 100644 --- a/documentation/Set-PnPSiteSensitivityLabel.md +++ b/documentation/Set-PnPSiteSensitivityLabel.md @@ -24,11 +24,11 @@ Set-PnPSiteSensitivityLabel -Identity [-Connection ] [-V ``` ## DESCRIPTION -This cmdlet allows for setting a Microsoft Purview sensitivity label on the currently connected to site. If the site has a Microsoft 365 Group behind it, the label will be placed on the Microsoft 365 Group and will require either Group.ReadWrite.All or Directory.ReadWrite.All delegate permissions on Microsoft Graph. This currently cannot be done using App Only permissions due to a limitation in Microsoft Graph. If it does not have a Microsoft 365 Group behind it, it will set the label on the SharePoint Online site and will not require Microsoft Graph permissions and will work with both delegate as well as app only logins. +This cmdlet allows for setting a Microsoft Purview sensitivity label on the currently connected to site. If the site has a Microsoft 365 Group behind it, the label will be placed on the Microsoft 365 Group and will require either Group.ReadWrite.All or Directory.ReadWrite.All delegate permissions on Microsoft Graph. This currently cannot be done using App Only permissions due to a limitation in Microsoft Graph. If it does not have a Microsoft 365 Group behind it, it will set the label on the SharePoint Online site and will not require Microsoft Graph permissions and will work with both delegate as well as app only logins. If you're looking to set a sensitivity label on a Microsoft 365 Group backed site in an App Only context, you can use [Set-PnPTenantSite -SensitivityLabel](Set-PnPTenantSite.md#-sensitivitylabel) instead to do so. -It may take up to a few minutes for a change to the sensitivity label to become visible in SharePoint Online and Azure Active Directory. +It may take up to a few minutes for a change to the sensitivity label to become visible in SharePoint Online and Entra ID / Azure Active Directory. -Use [Get-PnPAvailableSensitivityLabel](Get-PnPAvailableSensitivityLabel.md) to get an overview of the available Microsoft Purview sensitivity labels on the tenant. +Use [Get-PnPAvailableSensitivityLabel](Get-PnPAvailableSensitivityLabel.md) to get an overview of the available Microsoft Purview sensitivity labels on the tenant. For the classic classification labels, use [Set-PnPSiteClassification](Set-PnPSiteClassification.md) instead. @@ -95,4 +95,4 @@ Accept wildcard characters: False ## RELATED LINKS [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) -[Microsoft Graph documentation](https://learn.microsoft.com/graph/api/group-update?view=graph-rest-beta&tabs=http#example-2-apply-sensitivity-label-to-a-microsoft-365-group) \ No newline at end of file +[Microsoft Graph documentation](https://learn.microsoft.com/graph/api/group-update?view=graph-rest-beta&tabs=http#example-2-apply-sensitivity-label-to-a-microsoft-365-group) diff --git a/documentation/Set-PnPTenant.md b/documentation/Set-PnPTenant.md index 867623c10..5285e31ff 100644 --- a/documentation/Set-PnPTenant.md +++ b/documentation/Set-PnPTenant.md @@ -154,6 +154,11 @@ Set-PnPTenant [-SpecialCharactersStateInFileFolderNames [-OneDriveDefaultLinkToExistingAccess ] [-OneDriveBlockGuestsAsSiteAdmin ] [-RecycleBinRetentionPeriod ] + [-IsSharePointAddInsDisabled ] + [-CoreDefaultShareLinkScope ] + [-CoreDefaultShareLinkRole ] + [-GuestSharingGroupAllowListInTenantByPrincipalIdentity ] + [-OneDriveSharingCapability ] [-Force] [-Connection ] ``` @@ -193,6 +198,20 @@ Set-PnPTenant -UsePersistentCookiesForExplorerView $true This example enables the use of special persisted cookie for Open with Explorer. +### EXAMPLE 5 +```powershell +Set-PnPTenant -GuestSharingGroupAllowListInTenantByPrincipalIdentity {c:0o.c|federateddirectoryclaimprovider|ee0f40fc-b2f7-45c7-b62d-11b90dd2ea8e} +``` + +This example sets the guest sharing group allow list in the tenant to the specified principal identity. + +### EXAMPLE 6 +```powershell +Set-PnPTenant -GuestSharingGroupAllowListInTenantByPrincipalIdentity {} +``` + +This example clears the guest sharing group allow list in the tenant. + ## PARAMETERS ### -AllowDownloadingNonWebViewableFiles @@ -704,6 +723,24 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -IsSharePointAddInsDisabled +When the feature is enabled, all the add-ins features will be disabled. + +The valid values are: +- False (default) - All the add-ins features are supported. +- True - All the add-ins features will be disabled. + +```yaml +Type: Boolean +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -LegacyAuthProtocolsEnabled By default this value is set to $true. @@ -1134,8 +1171,11 @@ Accept wildcard characters: False Determines what level of sharing is available for the site. The valid values are: -ExternalUserAndGuestSharing (default) - External user sharing (share by email) and guest link sharing are both enabled. Disabled - External user sharing (share by email) and guest link sharing are both disabled. -ExternalUserSharingOnly - External user sharing (share by email) is enabled, but guest link sharing is disabled. + +- ExternalUserAndGuestSharing (default) : External user sharing (share by email) and guest link sharing are both enabled. +- Disabled : External user sharing (share by email) and guest link sharing are both disabled. +- ExternalUserSharingOnly : External user sharing (share by email) is enabled, but guest link sharing is disabled. +- ExistingExternalUserSharingOnly : Only guests already in your organization's directory. For more information about sharing, see Manage external sharing for your SharePoint online environment (https://learn.microsoft.com/sharepoint/turn-external-sharing-on-or-off). @@ -1715,14 +1755,15 @@ Gets or sets collaboration type for fluid on core partition The valid values are: -- Disabled -- ExternalUserSharingOnly -- ExternalUserAndGuestSharing -- ExistingExternalUserSharingOnly +- ExternalUserAndGuestSharing (default) : External user sharing (share by email) and guest link sharing are both enabled. +- Disabled : External user sharing (share by email) and guest link sharing are both disabled. +- ExternalUserSharingOnly : External user sharing (share by email) is enabled, but guest link sharing is disabled. +- ExistingExternalUserSharingOnly : Only guests already in your organization's directory. ```yaml Type: SharingCapabilities Parameter Sets: (All) +Accepted values: Disabled, ExternalUserSharingOnly, ExternalUserAndGuestSharing, ExistingExternalUserSharingOnly Required: False Position: Named @@ -1741,14 +1782,16 @@ If you have the external sharing for OneDrive for Business allowed, no further a The valid values are: -- Disabled -- ExternalUserSharingOnly -- ExternalUserAndGuestSharing -- ExistingExternalUserSharingOnly +- ExternalUserAndGuestSharing (default) : External user sharing (share by email) and guest link sharing are both enabled. +- Disabled : External user sharing (share by email) and guest link sharing are both disabled. +- ExternalUserSharingOnly : External user sharing (share by email) is enabled, but guest link sharing is disabled. +- ExistingExternalUserSharingOnly : Only guests already in your organization's directory. + ```yaml Type: SharingCapabilities Parameter Sets: (All) +Accepted values: Disabled, ExternalUserSharingOnly, ExternalUserAndGuestSharing, ExistingExternalUserSharingOnly Required: False Position: Named @@ -2382,6 +2425,14 @@ Accept wildcard characters: False ### -CoreSharingCapability Sets what level of sharing is available for SharePoint sites (not including OneDrive sites). +The valid values are: + +- ExternalUserAndGuestSharing (default) : External user sharing (share by email) and guest link sharing are both enabled. +- Disabled : External user sharing (share by email) and guest link sharing are both disabled. +- ExternalUserSharingOnly : External user sharing (share by email) is enabled, but guest link sharing is disabled. +- ExistingExternalUserSharingOnly : Only guests already in your organization's directory. + + ```yaml Type: SharingCapabilities Parameter Sets: (All) @@ -2574,10 +2625,11 @@ Sets the default sharing link scope for OneDrive. The valid values are: -- Anyone -- Organization -- SpecificPeople -- Uninitialized +- Anyone : Anyone with the link can access the content. +- Organization : Only people within the organization can access the content. +- SpecificPeople : Only specific individuals (specified by the user) can access the content. +- Uninitialized : The default value, indicating that the default share link scope is not explicitly set + ```yaml Type: SharingScope @@ -2591,15 +2643,15 @@ Accept wildcard characters: False ### -OneDriveDefaultShareLinkRole -Sets the default sharing link role for OneDrive. +Sets the default sharing link role for OneDrive. It replaces the DefaultSharingLinkType. Valid values are : -- Edit -- None -- RestrictedView -- Review -- View +- None: No permissions granted. +- View: View-only permissions. +- Edit: Edit permissions. +- Review: Review permissions. +- RestrictedView: Restricted view permissions. ```yaml Type: Role @@ -2613,7 +2665,7 @@ Accept wildcard characters: False ### -OneDriveDefaultLinkToExistingAccess -Sets whether OneDrive default links should grant access to existing users. +Sets whether OneDrive default links should grant access to existing users. It replaces the DefaultLinkPermission. ```yaml Type: Boolean @@ -2661,6 +2713,88 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -CoreDefaultShareLinkScope + +Sets the default sharing link scope for SharePoint sites. It replaces the DefaultSharingLinkType. + +The valid values are: + +- Anyone : Anyone with the link can access the content. +- Organization : Only people within the organization can access the content. +- SpecificPeople : Only specific individuals (specified by the user) can access the content. +- Uninitialized : The default value, indicating that the default share link scope is not explicitly set + +```yaml +Type: SharingScope +Parameter Sets: (All) +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -CoreDefaultShareLinkRole + +Sets the default sharing link role for SharePoint sites. It replaces the DefaultLinkPermission. + +Valid values are : + +- None: No permissions granted. +- View: View-only permissions. +- Edit: Edit permissions. +- Review: Review permissions. +- RestrictedView: Restricted view permissions. + +```yaml +Type: Role +Parameter Sets: (All) +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -OneDriveSharingCapability + +Determines what level of sharing is available for OneDrive for Business. + +The valid values are: + +- ExternalUserAndGuestSharing (default) : External user sharing (share by email) and guest link sharing are both enabled. +- Disabled : External user sharing (share by email) and guest link sharing are both disabled. +- ExternalUserSharingOnly : External user sharing (share by email) is enabled, but guest link sharing is disabled. +- ExistingExternalUserSharingOnly : Only guests already in your organization's directory. + +For more information about sharing, see Manage external sharing for your SharePoint online environment (https://learn.microsoft.com/sharepoint/turn-external-sharing-on-or-off). + +```yaml +Type: SharingCapabilities +Parameter Sets: (All) +Accepted values: Disabled, ExternalUserSharingOnly, ExternalUserAndGuestSharing, ExistingExternalUserSharingOnly + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -GuestSharingGroupAllowListInTenantByPrincipalIdentity +Sets the guest sharing group allow list in the tenant by principal identity. + +```yaml +Type: String[] +Parameter Sets: (All) + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -Force If provided, no confirmation will be requested and the action will be performed diff --git a/documentation/Set-PnPTenantSite.md b/documentation/Set-PnPTenantSite.md index e57fd96a6..d819a825a 100644 --- a/documentation/Set-PnPTenantSite.md +++ b/documentation/Set-PnPTenantSite.md @@ -39,7 +39,10 @@ Set-PnPTenantSite [-Identity] [-Title ] [-LocaleId ] [- [-ListsShowHeaderAndNavigation ] [-DefaultLinkToExistingAccessReset ] [-DefaultShareLinkRole ] [-DefaultShareLinkScope ] [-LoopDefaultSharingLinkRole ] - [-LoopDefaultSharingLinkScope ] + [-LoopDefaultSharingLinkScope ] [-RestrictContentOrgWideSearch ] [-ReadOnlyForUnmanagedDevices ] + [-RequestFilesLinkExpirationInDays ] [-RequestFilesLinkEnabled ] [-OverrideSharingCapability ] + [-RestrictedAccessControl ] [-ClearRestrictedAccessControl ] [-RestrictedAccessControlGroups ] + [-AddRestrictedAccessControlGroups ] [-RemoveRestrictedAccessControlGroups ][-InheritVersionPolicyFromTenant ] [-Wait] [-Connection ] ``` @@ -896,6 +899,94 @@ Default value: None Accept pipeline input: False Accept wildcard characters: False ``` + +### -RestrictContentOrgWideSearch +To restrict content from being searchable organization-wide and Copilot. + +```yaml +Type: Boolean +Parameter Sets: Set Properties + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ReadOnlyForUnmanagedDevices +To set the site as read-only for unmanaged devices. + +```yaml +Type: Boolean +Parameter Sets: Set Properties + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -InheritVersionPolicyFromTenant +Clears the file version setting at site level. + +```yaml +Type: Boolean +Parameter Sets: Set Properties + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -RequestFilesLinkExpirationInDays +Specifies the number of days after which the request files link will expire. +The value can be from 0 to 730 days. + +```yaml +Type: Int32 +Parameter Sets: Set Properties + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + + +### -OverrideSharingCapability +Specifies whether to override the sharing capability for the site. + +```yaml +Type: Boolean +Parameter Sets: Set Properties + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -RequestFilesLinkEnabled +Enables or disables the Request Files link on the site. + +```yaml +Type: Boolean +Parameter Sets: Set Properties + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + + ### -Wait Wait for the operation to complete diff --git a/pages/articles/authentication.md b/pages/articles/authentication.md index 786aeca6a..96868bd3e 100644 --- a/pages/articles/authentication.md +++ b/pages/articles/authentication.md @@ -1,58 +1,114 @@ # Authentication -## Setting up Access +Before you can authenticate using PnP PowerShell, you need to ensure you have [created your own application registration](registerapplication.md) first and that you have [set the proper permissions](determinepermissions.md) on the application registration. -PnP PowerShell allows you to authenticate with credentials to your tenant. However, due to changes in the underlying SDKs we require you first to register a Azure AD Application which will allow you to authenticate. +PnP PowerShell offers many different ways to authenticate to your tenant. Based on what you would like to achieve, pick the method that best suits your needs below. -The easiest way to do this by using a built-in cmdlet: +Instead of having to provide `-ClientId` on every connect, you can also opt to [configure a default Client ID](defaultclientid.md) that will be used if `-ClientID` is not being specified in your `Connect-PnPOnline`. + +## Interactive Authentication + +This is the easiest method to authenticate, but it requires you to enter your credentials and go through multi factor authentication and conditional access policy steps, if applicable, each time you connect. This works perfectly well if your intend is to manually run scripts, but is not suitable to run unattended scripts at i.e. timed intervals. + +Connecting can be done using: ```powershell -Register-PnPManagementShellAccess +Connect-PnPOnline [yourtenant].sharepoint.com -Interactive -ClientId ``` -You'll notice that the cmdlet is not called `Register-PnPPowerShellAccess`. This is because both PnP PowerShell and the CLI for Microsoft 365 make use of this Azure AD application. +This will show a popup window which will allow to authenticate and step through the multi-factor authentication flow. Ensure you provide [the Client ID of your own Entra ID Application Registration](registerapplication.md) with the `-ClientId` parameter. -> [!Important] -> You need to run this cmdlet with an identity that has write access to the Azure AD. -> You are not creating a new application in the sense of something that runs in your Azure AD tenant. You're only adding a registration to your Azure AD, a so called 'consent' for people in your tenant to use that application. The access rights the application requires are delegate only, so you will always have to provide credentials or another way of identifying the user actually using that application. +## Authenticating from another device or specific browser + +In some scenarios it can happen that you need to authenticate to PnP PowerShell from a different device or through a specific browser. In these cases you can use the `-DeviceLogin` method to connect. A sample scenario could for example be when running PnP PowerShell scripts on a Raspberry Pi without a desktop environment installed on it. In this case there is no browser to authenticate through on the device itself. + +Connecting can be done using: + +```powershell +Connect-PnPOnline [yourtenant].sharepoint.com -DeviceLogin -Tenant .onmicrosoft.com -ClientId +``` + +When running this line, it will prompt in text to go to https://microsoft.com/devicelogin on any device and log in using a specific code which will be shown in the text. You can perform this step on any device. This does not have to be the same device as you're using PnP PowerShell on. After going to that website and entering the code shown in the text, you can complete the interactive login process as normal, including any multi factor authentication requirements that might have been set up for your account. Once the authentication completes, PnP PowerShell will automatically detect this and will be ready to be used. -During execution of the cmdlet you will be talked through the consent flow. This means that a browser window will open, you will be asked to authenticate, and you will be asked to consent to a number of permissions. After this permissions has been granted a new entry will show up if you navigate to `Enterprise Applications` in your Azure AD. If you want to revoke the consent you can simply remove the entry from the Enterprise Applications. +## Authenticating using Web Account Manager -## Setting up access to your own Azure AD App +Another option to authenticate is using Web Account Manager (WAM). WAM is a more secure & faster way of authenticating in Windows OS. It supports Windows Hello, FIDO keys, single sign on, conditional access policies, and more. It only works on Windows 10 (Version 1703 - Creators Update) and above, as well as Windows Server 2019 and above. -PnP PowerShell has a cmdlet that allows you to register a new Azure AD App, and optionally generate the certificates for you to use to login with that app. +Connecting can be done using: ```powershell -$result = Register-PnPAzureADApp -ApplicationName "PnP Rocks" -Tenant [yourtenant].onmicrosoft.com -OutPath c:\mycertificates -DeviceLogin -$result +Connect-PnPOnline [yourtenant].sharepoint.com -OSLogin -ClientId ``` -When you run the cmdlet above you will be asked to navigate to the shown url and enter the code shown. After that a new app will be registered in the Azure AD (make sure you have the rights to do this), and a certificate will be generated and uploaded to that app. After this a URL will be shown which you have to navigate to to provide consent for this application. By default a limited set of permissions scopes is added, but you can provide the one of the permission parameters (`GraphApplicationPermissions`, `GraphDelegatePermissions`, `SharePointApplicationPermissions`, `SharePointDelegatePermissions`) to provide your own permission scopes. +## Non interactive Authentication + +If your goal is to automatically connect to PnP PowerShell without user intervention of having to enter credentials or perform multi factor authentication steps, this is the method to go with. Ensure you have gone through the [steps to set up an App Only application registration](registerapplication.md#setting-up-access-to-your-own-entra-id-app-for-app-only-access) first. Your application registration needs to use a public/private key pair certificate to authenticate. A client secret is not supported. The public key (.cer) goes into your application registration in Entra ID, the private key (.pfx) will be used to connect using PnP PowerShell. + +Depending on how you have the certificate available, choose the section below that matches your scenario. -It also returns the private key certificate encoded in base64 encoding. As it spans multiple lines, it is recommended to assign the outcome of `Register-PnPAzureAdApp` to a variable so you have access to this value more easily. The Base64 encoded private key certificate can be used in your Connect-PnPOnline voiding the need to have access to the physical file: +### Non interactive Authentication using a certificate file + +If you have the private key certificate (.pfx) stored as a physical file on your machine, you can connecting using: ```powershell -Connect-PnPOnline [yourtenant].sharepoint.com -ClientId [clientid] -Tenant [yourtenant].onmicrosoft.com -CertificateBase64Encoded [pfx base64 encoded] +Connect-PnPOnline [yourtenant].sharepoint.com -ClientId -Tenant .onmicrosoft.com -CertificatePath ``` -The cmdlet will also save both the CER and PFX files to the location specified with the -Outpath parameter. The names of the files will be matching the -ApplicationName parameter, e.g. in the example above the files will be called `PnP Rocks.cer` and `PnP Rocks.pfx`. The output of the cmdlet will show the clientid. After all is set up and consent has been provided you can login using: +If your private key (.pfx) certificate has a password on it, add `-CertificatePassword (ConvertTo-SecureString -AsPlainText 'myprivatekeypassword' -Force)` to the parameters. + +### Non interactive Authentication using a certificate in the Windows Certificate Store + +If you have the private key certificate (.pfx) added to the Windows Certificate Store (certmgr. msc) in the Personal > Certificates branch on your machine, you can connecting using: + +```powershell +Connect-PnPOnline [yourtenant].sharepoint.com -ClientId -Tenant .onmicrosoft.com -Thumbprint +``` + +### Non interactive Authentication using a base64 representation of the certificate + +This scenario is typically used when having the private key certificate (.pfx) stored as base64. This can for example be the case when [using PnP PowerShell within Azure Functions](azurefunctions.md). In this case you can connect using: + +```powershell +Connect-PnPOnline [yourtenant].sharepoint.com -ClientId -Tenant .onmicrosoft.com -CertificateBase64Encoded +``` + +If your private key (.pfx) certificate has a password on it, add `-CertificatePassword (ConvertTo-SecureString -AsPlainText 'myprivatekeypassword' -Force)` to the parameters. + +If you wish to convert a private key certificate file to its Base64 encoded equivalent, you can use: + +```powershell +$bytes = Get-Content '.\PnPPowerShell.pfx' -AsByteStream +$encodedPfx = [System.Convert]::ToBase64String($bytes) +``` + +## Authenticating by providing an access token + +A really specific and limited scenario is where you provide the oAuth JWT access token yourself that needs to be used to access resources. You can only pass in one access token and you need to ensure the token is still within its validity period and has the proper audience and scopes for the cmdlets you are going to execute. I.e. if you pass in an access token for your SharePoint Online tenant, you can only execute cmdlets that will directly target your SharePoint Online environment. If you would use a cmdlet that communicates with Microsoft Graph behind the scenes, it will throw an access denied exception. + +Connecting can be done using: ```powershell -Connect-PnPOnline [yourtenant].sharepoint.com -ClientId [clientid] -Tenant [yourtenant].onmicrosoft.com -CertificatePath [certificate.pfx] +Connect-PnPOnline [yourtenant].sharepoint.com -AccessToken ``` ## Authenticating with Credentials -Enter +This method allows you to connect by just providing your username and password. It will not work with multi factor authentication. Therefore this method is less recommended. + +Connecting can be done using: ```powershell -Connect-PnPOnline [yourtenant].sharepoint.com -Credentials (Get-Credential) +Connect-PnPOnline [yourtenant].sharepoint.com -ClientId -Credentials (Get-Credential) ``` -and you will be prompted for credentials. Using this method you're required to have granted the PnP Management Shell multi-tenant application access rights. You can however register your own application using `Register-PnPAzureAzureApp` and then provide the `-ClientId` parameter with the client id/app id of your custom application. +and you will be prompted for credentials. Ensure you provide [the Client ID of your own Entra ID Application Registration](registerapplication.md) with the `-ClientId` parameter. ## Authenticating with pre-stored credentials using the Windows Credential Manager (Windows only) +This method can be used if you just intend to use PnP PowerShell on a Windows device, you want to use just a username and password for an account that does not require multi factor authentication, and you wish to store these credentials in the Windows Credential Manager so you don't have to enter them every time you connect. As this will not work with multi factor authentication, this method is less recommended. + +Adding your credentials to the Windows Credential Manager, which is a one time operation, can be done using: + ```powershell Add-PnPStoredCredential -Name "yourlabel" -Username youruser@domain.com ``` @@ -60,24 +116,33 @@ Add-PnPStoredCredential -Name "yourlabel" -Username youruser@domain.com You will be prompted to provide a password. After that you can login using: ```powershell -Connect-PnPOnline [yourtenant].sharepoint.com -Credentials "yourlabel" +Connect-PnPOnline [yourtenant].sharepoint.com -ClientId -Credentials "yourlabel" ``` -When you create the stored credentials (with Add-PnPStoredCredential or any other tool) if the Name you give it is the URL for your tenant you can omit the -Credentials parameter with Connect-PnPOnline. Using the example above create your stored credential with this command: + +When you create the stored credentials (with Add-PnPStoredCredential or any other tool) if the Name you give it is the URL for your tenant you can omit the `-Credentials` parameter with `Connect-PnPOnline`. Using the example above create your stored credential with this command: ```powershell Add-PnPStoredCredential -Name "https://[yourtenant].sharepoint.com" -Username youruser@contoso.com ``` + When connecting to https://yourtenant.sharepoint.com you can use this command: + ```powershell -Connect-PnPOnline [yourtenant].sharepoint.com +Connect-PnPOnline [yourtenant].sharepoint.com -ClientId ``` + Connect-PnPOnline will look through the Windows Credential Manager for a credential matching the URL. If it finds one it will use it. It will also match that credential with deeper connection URLs like https://yourtenant.sharepoint.com/sites/IT. You can create additional stored credentials for deeper sites if you routinely connect to them with different credentials. If you want to connect with a different set of credentials you can use the -Credentials parameter to specify them. A stored credential can be used for other URLs, like the Admin site: + ```powershell -Connect-PnPOnline [yourtenant]-admin.sharepoint.com -Credentials https://[yourtenant].sharepoint.com +Connect-PnPOnline [yourtenant]-admin.sharepoint.com -ClientId -Credentials https://[yourtenant].sharepoint.com ``` ## Authenticating with pre-stored credentials using the Secrets Management Module from Microsoft (Multi-Platform) +This method can be used if you just intend to use PnP PowerShell on a Windows, Linux or iOS device, you want to use just a username and password for an account that does not require multi factor authentication, and you wish to store these credentials in the a Credential Manager so you don't have to enter them every time you connect. As this will not work with multi factor authentication, this method is less recommended. + +Adding your credentials to the Credential Manager, which is a one time operation, can be done using: + ```powershell Install-Module -Name Microsoft.PowerShell.SecretManagement -AllowPrerelease Install-Module -Name Microsoft.PowerShell.SecretStore -AllowPrerelease @@ -93,72 +158,27 @@ Set-SecretStoreConfiguration -Authentication None For more information about these cmdlets, check out the github repositories: https://github.com/powershell/secretmanagement and https://github.com/powershell/secretstore. -After you set up the vault and you added a credential +After you set up the vault and you added a credential, you can connect using: ```powershell -Connect-PnPOnline [yourtenant].sharepoint.com -Credentials (Get-Secret -Name "yourlabel") +Connect-PnPOnline [yourtenant].sharepoint.com -ClientId -Credentials (Get-Secret -Name "yourlabel") ``` -## Authentication in case you have Multi-Factor authentication enabled - -```powershell -Connect-PnPOnline[yourtenant].sharepoint.com -Interactive -``` - -This will show a popup window which will allow to authenticate and step through the multi-factor authentication flow. - ## Authentication to GCC or National Cloud environments -In order to authentication to a GCC or a national cloud environment you have to take a few steps. Notice that this will work as of release 1.3.9-nightly or later. +In order to connect to a GCC or a national cloud environment, ensure you have followed the [specific steps for setting up the application registration for national clouds](#special-instructions-for-gcc-or-national-cloud-environments). -### Register your own Azure AD App -You are required to register your own Azure AD App in order to authentication +Connecting can be done using: -```powershell -Register-PnPAzureADApp -ApplicationName "PnP PowerShell" -Tenant [yourtenant].onmicrosoft.com -Interactive -AzureEnvironment [USGovernment|USGovernmentHigh|USGovernmentDoD|Germany|China] -SharePointDelegatePermissions AllSites.FullControl -SharePointApplicationPermissions Sites.FullControl.All -GraphApplicationPermissions Group.ReadWrite.All -GraphDelegatePermissions Group.ReadWrite.All -``` - -The AzureEnvironment parameter only allows one value. Select the correct one that matches your cloud deployment. - -The above statement grants a few permission scopes. You might want to add more if you want to. Alternatively, after registering the application, navigate to the Azure AD, locate the app registration, and grant more permissions and consent to them. - -### Optionally modify the manifest for the app -There is a limitation in the Azure AD for national cloud environments where you cannot select permission scopes for SharePoint Online. In order to add specific SharePoint rights you will have to manually add them to the manifest that you can edit in Azure AD: - -Locate the `requiredResourceAccess` section and add to or modify the existing entries. See the example below (notice, this is an example, do not copy and paste this as is as it will limit the permissions to only AllSites.FullControl): - -```json -"requiredResourceAccess": [ -{ - "resourceAppId": "00000003-0000-0ff1-ce00-000000000000", - "resourceAccess": [ - { - "id": "56680e0d-d2a3-4ae1-80d8-3c4f2100e3d0", - "type": "Scope" - } - ] -} -``` - -You can add more permissions by using the following values: - -The resourceAppId for SharePoint = "00000003-0000-0ff1-ce00-000000000000" - -Permission | Permission type | Id | Type -| -------| ----------- | ------ | ----- | -| Sites.FullControl.All | Application | 678536fe-1083-478a-9c59-b99265e6b0d3 | Role | -| AllSites.FullControl | Delegate | 56680e0d-d2a3-4ae1-80d8-3c4f2100e3d0 | Scope | - - -### Connect ```powershell Connect-PnPOnline [yourtenant].sharepoint.com -Interactive -ClientId [clientid] -Tenant [yourtenant].onmicrosoft.com -AzureEnvironment [USGovernment|USGovernmentHigh|USGovernmentDoD|Germany|China] ``` + The AzureEnvironment parameter only allows one value. Select the correct one that matches your cloud deployment. ## Silent Authentication with Credentials for running in Pipelines -For running `Connect-PnPOnline` with user credentials in Azure DevOps pipeline, you need to make sure that authentication in your Azure AD application is configured to allow public client. +For running `Connect-PnPOnline` with user credentials in Azure DevOps pipeline, you need to make sure that authentication in your Entra ID application is configured to allow public client. Public client can be configured from the Azure portal from the Authentication Blade in the application or by setting the `allowPublicClient` property in the application's manifest to true. ![image](../images/authentication/allowPublicClient.png) @@ -176,9 +196,9 @@ Public client can be configured from the Azure portal from the Authentication Bl For example, if your organization is located in the South East Asia region, you would map it to the format AzureCloud.SouthEastAsia. -### Create a named location in Azure AD conditional access +### Create a named location in Entra ID conditional access -- Go to Azure AD conditional access +- Go to Entra ID conditional access - Open named location blade, click on `+ IP Ranges Location` - Enter the IP ranges for Microsoft Hosted Agents, `Mark as trusted location` should be checked. ![image](../images/authentication/namedLocations.png) @@ -186,7 +206,7 @@ For example, if your organization is located in the South East Asia region, you ### Create a conditional access policy -- Go to Azure AD conditional access, click on `+New Policy`. +- Go to Entra ID conditional access, click on `+New Policy`. - Give a meaningful name, click on Users and Groups -> Include select users and groups, select the user with which you want to run your pipeline. - Include all cloud apps. - Under conditions -> locations include `any locations` and exclude the recently created named location. @@ -200,5 +220,5 @@ For example, if your organization is located in the South East Asia region, you ### Powershell script to be run in pipeline ```powershell $creds = New-Object System.Management.Automation.PSCredential -ArgumentList ($username, $password) -Connect-PnPOnline -Url -Credentials $creds -ClientId +Connect-PnPOnline -Url -Credentials $creds -ClientId ``` diff --git a/pages/articles/connecting.md b/pages/articles/connecting.md deleted file mode 100644 index c5262ddd2..000000000 --- a/pages/articles/connecting.md +++ /dev/null @@ -1,106 +0,0 @@ -# Connecting with PnP PowerShell - -PnP PowerShell offers many ways to connect to an environment. This page provides guidance on the various options you have and how they can be used against which environment(s). - - -## Connect using credentials - -In order to connect with credentials you have two options: -### Connect by using the PnP Management Shell Multi-Tenant Azure AD Application - -You will have to consent / register the PnP Management Shell Multi-Tenant Azure AD Application in your own tenant: - -```powershell -Register-PnPManagementShellAccess -``` - -This will launch a device login flow that will ask you to consent to the application. Notice that is only required -once- per tenant. You will need to have appropriate access rights to be able to consent applications in your Azure AD. - -After that you can authenticate using - -```powershell -Connect-PnPOnline [tenant].sharepoint.com -Credentials (Get-Credential) -``` - -or in case the account you would like to use has MFA or any other authentication provider configured for it, instead use: - -```powershell -Connect-PnPOnline [tenant].sharepoint.com -Interactive -``` - -### Connect by using your own Azure AD Application - -You will have to create your own Azure AD Application registration, or you can create one: - -```powershell -Register-PnPAzureADApp -ApplicationName "YourApplicationName" -Tenant [tenant].onmicrosoft.com -Interactive -``` - -This will launch an authentication dialog where you need to authenticate. After closing this window the cmdlet will continue to register a new application with a set of default permissions. By default a certificate will be generated and stored in the current folder, named after the application you want to create. You can specify your own certificate by using the `-CertificatePath` parameter and optional `-CertificatePassword` parameter. - -You can add permissions by using the `-GraphApplicationPermissions`, `-GraphDelegatePermissions`, `-SharePointApplicationPermissions` or `-SharePointDelegatePermissions` parameters. The cmdlet will output the Azure AppId/client id, the name and location of the certificates created (if any) and the thumbprint of the certificate. It is possible to add the certificate created to the certificate management store in Windows by adding the `-Store` parameter. - -Note if you are using Credential Based Authentication, you will need to make a change to the app registration manifest file. Go to the app registration, select Manifest under the Manage section, then change the "allowPublicClient" property to true and click save. - -```powershell -Connect-PnPOnline [tenant].sharepoint.com -Credentials (Get-Credential) -ClientId [clientid] -``` - -## Connect interactively using WebLogin supporting MFA - -One of the easiest methods to use. However, notice that this connection method will have its limitation as we will utility cookie based authentication. For instance, we will not be able to make calls to the Microsoft Graph behind the scenes. - -```powershell -Connect-PnPOnline [tenant].sharepoint.com -UseWebLogin -``` - -## Connect using a ClientId and PFX certificate stored on your local machine - -Allows using an Azure Active Directory app registration from your own Azure Active Directory with a certificate to connect. The private key certificate, typically the .pfx file, should be accessible on your local machine. - -The following will generate an Azure AD Application registration and create a certificate containing a public and private key. - -```powershell -Register-PnPAzureADApp -ApplicationName "PnPPowerShell" -Tenant [tenant].onmicrosoft.com -Password (ConvertTo-SecureString -String "password" -AsPlainText -Force) -``` - -You will be asked to authenticate. After that the cmdlet will generate two files, PnPPowerShell.pfx and PnPPowerShell.cer and a new Azure AD Application will be registered with the specified name. The public key/CER file will be uploaded and registered with the newly create application registration. You will have to use the .pfx file to connect. Notice that the `Register-PnPAzureADApp` cmdlet only have to be executed once per tenant/application. - -```powershell -Connect-PnPOnline [tenant].sharepoint.com -ClientId [clientid] -Tenant [tenant].onmicrosoft.com -CertificatePath '.\PnPPowerShell.pfx' -CertificatePassword (ConvertTo-SecureString -AsPlainText -Force "password") -``` - -## Connect using a ClientId and PFX certificate stored in the Windows Certificate Management Store - -Allows using an Azure Active Directory app registration from your own Azure Active Directory with a certificate to connect. The private key certificate, typically the .pfx file, should be accessible on your local machine in the Certificate Management Store. - -The following will generate an Azure AD Application registration and create a certificate containing a public and private key which will be stored for the current user in the Windows Certificate Management Store. -```powershell -$password = ConvertTo-SecureString -String "password" -AsPlainText -Force -Register-PnPAzureADApp -ApplicationName "PnPPowerShell" -Tenant [tenant].onmicrosoft.com -Store CurrentUser -``` - -You will be asked to authenticate. After that the cmdlet will generate a certificate and will store it in the Windows Certificate Management Store and a new Azure AD Application will be registered with the specified name. The public key of the certificate file will be uploaded and registered with the newly create application registration. Notice that the `Register-PnPAzureADApp` cmdlet only have to be executed once per tenant/application. The output of the cmdlet contains the thumbprint to use. - -```PowerShell -Connect-PnPOnline [tenant].sharepoint.com -ClientId [clientid] -Tenant [tenant].onmicrosoft.com -Thumbprint $thumbprint -``` - -## Connect using a ClientId and PFX certificate being Base64 encoded - -In some scenarios it might be easier to have the PFX file being encoded as a string using Base64 as opposed to having to store the physical PFX file somewhere. If you have the PFX encoded using Base64 encoding, you can connect using: - -```PowerShell -Connect-PnPOnline [tenant].sharepoint.com -ClientId [clientid] -Tenant [tenant].onmicrosoft.com -CertificateBase64Encoded $encodedPfx -``` - -If you wish to convert a PFX file to its Base64 encoded equivalent, you can use: - -```PowerShell -$bytes = Get-Content '.\PnPPowerShell.pfx' -AsByteStream -$encodedPfx = [System.Convert]::ToBase64String($bytes) -``` - -## Connect to a National Cloud Deployment (GCC/Germany/China) - -If you are on a National Cloud instance, read the [authentication](authentication.md) article for more information diff --git a/pages/articles/defaultclientid.md b/pages/articles/defaultclientid.md new file mode 100644 index 000000000..055c6ef86 --- /dev/null +++ b/pages/articles/defaultclientid.md @@ -0,0 +1,41 @@ +# Set a default Client ID + +As of September 9th, 2024, it is no longer possible to use PnP PowerShell with `-Interactive` without [providing your own Entra ID App Registration](registerapplication.md) by passing in `-ClientId` as well. To avoid having to add `-ClientId` on every connect, you can also perform the below task to set the default ClientId for your environment. This avoids you having to update all of your scripts to include `-ClientId` in the Connect-PnPonline statements. + +## By setting an environment variable + +You can set an environment variable on your machine or in your profile to default to the ClientId you configure in it. The name of the environment variable should be either: `ENTRAID_APP_ID`, or `ENTRAID_CLIENT_ID`, or `AZURE_CLIENT_ID`. You only need one of these, not all of them. They will be used in the order shown, i.e. if you set a value for `AZURE_CLIENT_ID` and another one for `ENTRAID_APP_ID`, the `ENTRAID_APP_ID` entry will be used and the other will be ignored. + +As the value for the environment variable, set the GUID of the Client Id / App Id from Entra ID of [your own App Registration](registerapplication.md). + +### Steps for Windows + +To create an environment variable on a Windows machine, follow the below steps. + +1. Right click on the Windows start icon on your Windows taskbar and click on _System_ + + ![image](../images/configuration/configuration_defaultclientid_windowsmenu_system.png) + +1. Click on _Advanced system settings_ + + ![image](../images/configuration/configuration_defaultclientid_windowsmenu_system_advancedsettings.png) + +1. Click on _Environment Variables_ + + ![image](../images/configuration/configuration_defaultclientid_windowsmenu_system_advancedsettings_envvariables.png) + +1. Under _User variables for \_, click the _New_ button. As the _Variable name_, enter: + + ENTRAID_CLIENT_ID + + As the _Variable value_ enter the Client ID of your Entra ID application registration which you would like to use as the default for all Connect-PnPOnline executions. + + Close all open dialog boxes by clicking on _OK_ + + ![image](../images/configuration/configuration_defaultclientid_windowsmenu_system_advancedsettings_envvariables_addentry.png) + +## Troubleshooting + +In case you want to validate which ClientID is being used to connect, simply add `-Verbose` to your `Connect-PnPOnline` statement to see which ClientID is used to make the connection. + +![image](../images/configuration/connecting_verbose_clientid.png) diff --git a/pages/articles/determinepermissions.md b/pages/articles/determinepermissions.md new file mode 100644 index 000000000..71a7d0710 --- /dev/null +++ b/pages/articles/determinepermissions.md @@ -0,0 +1,72 @@ +# How to determine which permissions you need + +As of September 9th, 2024, it is [required to use your own Entra ID Application Registration](https://pnp.github.io/blog/post/changes-pnp-management-shell-registration/) to use PnP PowerShell. This introduces the complexity of trying to determine the minimum set of permissions you will need to be able to execute your script. This article aims to help you in determining the permissions you need to set on your Entra ID Application Registration. + +## Creating an Entra ID Application Registration + +In case you're starting from the beginning and you do not have your own Entra ID Application Registration yet to use with PnP Powershell, which is mandatory, you can [follow these steps](registerapplication.md) to create your Entra ID Application Registration. + +## Starting with minimal permissions + +It is highly recommended to keep the permissions on your Entra ID Application Registration to a minimum to avoid risks when access through your application registration would somehow fall in the wrong hands. As PnP PowerShell always starts with connecting to SharePoint Online, you will at least need permissions to access SharePoint Online, regardless of whatever else you plan on doing with PnP PowerShell. + +### When using a delegate login + +A delegate login means you will be interactively logging in to your tenant using PnP PowerShell by providing your credentials. There are [several ways](authentication.md) of connecting in this way. Always remember that in this scenario, regardless of which permissions you assign to your Entra ID Application Registration, the user logging in through PnP PowerShell _must_ also have the permissions for whatever the user is trying to do. I.e. if you would assign `AllSites.FullControl` permissions on your application registration, the user still can only access those SharePoint Online sites to which the user has been granted permissions directly to that site as well and will only have those permissions assigned to it (i.e. read or write). + +The lowest permission you can set on a delegate login will be `AllSites.Read` on the delegate scope of SharePoint: + +![image](../images/determinepermissions/entraid_permissions_delegate_minimal.png) + +### When using an app only context + +An app only context is being used when your intend is to run a script that does not require any user intervention to connect and authenticate to your tenant. There are [several ways](authentication.md) of connecting in this way. In this scenario, exactly those permissions you assign to your Entra ID Application Registration are the ones the script that runs will have. Therefore, be extra careful in this scenario not to set too high permissions. + +The lowest permission you can set on an app only scenario will be `Sites.Selected` on the application scope of SharePoint: + +![image](../images/determinepermissions/entraid_permissions_apponly_minimal.png) + +When using the `Sites.Selected` permission, you still must assign permissions to one or more sites where the script will have access to. Ensure you will assign at least `Read` permissions on the site of which you will use the URL in your `Connect-PnPOnline ` statement in your script. You can easily do so by utilizing the PnP PowerShell cmdlet [Grant-PnPAzureADAppSitePermission](../cmdlets/Grant-PnPAzureADAppSitePermission.md) as shown here: + +```powershell +Grant-PnPAzureADAppSitePermission -AppId "" -DisplayName "PnP PowerShell" -Permissions Read -Site +``` + +In order to be able to run this cmdlet, you will need to connect to PnP PowerShell using preferably another Entra ID application registration which will have the `AllSites.FullControl` permission on the delegate scope on SharePoint set to it and being logged on with a Global Administrator or SharePoint Administrator priviledged account. + +## Adding additional permissions as needed + +Once you've se the minimum permissions as described above, you can go ahead and test using your Entra ID application registration to connect to SharePoint Online using [one of the available connect options](authentication.md). You can add `-ValidateConnection -Verbose` to your `Connect-PnPOnline` cmdlet to instruct it to test the connection once established. + +Now you likely want to perform more than just a simple read using PnP PowerShell. Read on below to find out what you can do to find out about the additional permissions your application registration might need to operate correctly. + +### When using a delegate login + +When planning to use your app registration for delegates, you could opt for simply starting to use it. Once you execute a cmdlet that requires more permissions, a dialog will pop up asking you to consent to these additional permissions being assigned to the application registration. An example of this is shown on the following screenshot: + +![image](../images/determinepermissions/entraid_permissions_delegate_requestadditionalpermissions.png) + +What technically happens here when you provide consent through this dialog is that in the Entra ID Enterprise Application connected to your Entra ID application registration, the permission gets added. This means that on subsequent requests of this cmdlet using this client id, even in new sessions, these permissions will then be granted already. You can visualize this by going to [Entra ID](https://entra.microsoft.com) > Identity > Applications > Enterprise applications and looking for the registration with the same name as your Entra ID application registration. Once found, open it, in the menu click on _Permissions_, go to the _User consent_ tab and look at the assigned permissions: + +![image](../images/determinepermissions/entraid_permissions_delegate_enterprisepermissionadded.png) + +### When using an app only context + +For an app only scenario, you will have to follow a different approach, as there is no way for it to interactively request for more permissions. If you try to execute a cmdlet for which the Entra ID application registration does not have permissions, it will return you an access denied notice. + +What you could try if you run into this, is to add `-Verbose` to your cmdlet. For many, but unfortunately not all, cmdlets, this will reveal which permissions it receives through the application registration and which permissions it actually needs to be able to execute properly. See the following example: + +![image](../images/determinepermissions/entraid_permissions_accessdenied_verbose.png) + +In this scenario, you now know you need to add `Group.Read.All` on the applications scope of Microsoft Graph in your application registration in order to give it sufficient rights to execute this cmdlet. + +## Help, I can't figure out which permissions I need + +As mentioned above, unfortunately, not for all cmdlets it will be clear which exact (minimum) permissions will be needed. Not even when using `-Verbose`. To give some guidance which permissions you could try for a minimum permissions approach, follow the table below. + +What are you trying to do | Permission type | Permission(s) likely needed from least to most priviledged +| ------------------------| --------------- | -------------------------- | +| Interact with SharePoint | Delegate | AllSites.Read / AllSites.Write / AllSites.Manage / AllSites.FullControl | +| Interact with SharePoint | App Only | Sites.Selected / Sites.Read.All / Sites.ReadWrite.All / Sites.Manage.All / Sites.FullControl .All | +| Interact with Microsoft Graph | Delegate \ App Only | Use `-Verbose` or look at [the documentation](../cmdlets/index.md) to find the permissions needed | +| Interact with Power Platform | Delegate | `Azure Service Management\user_impersonation` AND `Dynamics CRM\user_impersonation` AND `PowerApps Service\User` (the last one you can find on the second tab: APIs that my organization uses) | diff --git a/pages/articles/microsoftsearch.md b/pages/articles/microsoftsearch.md new file mode 100644 index 000000000..4fe0f2cef --- /dev/null +++ b/pages/articles/microsoftsearch.md @@ -0,0 +1,3 @@ +# Using PnP PowerShell with Microsoft Search + +TODO diff --git a/pages/articles/registerapplication.md b/pages/articles/registerapplication.md new file mode 100644 index 000000000..06b61a95c --- /dev/null +++ b/pages/articles/registerapplication.md @@ -0,0 +1,177 @@ +# Register an Entra ID Application to use with PnP PowerShell + +It has always been a recommended practise to register your own Entra ID Application to use with PnP PowerShell. As of September 9th, 2024, [this has become mandatory step](https://pnp.github.io/blog/post/changes-pnp-management-shell-registration/). This article will guide you through how to do so. + +The first decission you will have to make is whether you are going to interactively log on through PnP PowerShell to your tenant by providing your credentials, [Interactive Login](#setting-up-access-to-your-own-entra-id-app-for-interactive-login), or if you are aiming to write a script that will log on without requiring any user intervention, [App Only Access](#setting-up-access-to-your-own-entra-id-app-for-app-only-access). Depending on your scenario, continue reading in the appropriate section below. + +## Setting up access to your own Entra ID App for Interactive Login + +In this scenario, you will be creating an application registration in Entra ID which will allow you to interactively log on to your tenant using PnP PowerShell. This means that each time you use PnP PowerShell, you will need to enter your credentials and comply with any multi factor authentication and conditional access policies that may have been set up on your tenant. + +There are two methods to create your application registration for this scenario: creating it [automatically](#automatically-create-an-app-registration-for-interactive-login) (easiest) or creating it [manually](#manually-create-an-app-registration-for-interactive-login). Both will require you to have at least the [Application Developer permission role](https://learn.microsoft.com/entra/identity/role-based-access-control/permissions-reference#application-developer) or the [Global Administrator permission role](https://learn.microsoft.com/en-us/entra/identity/role-based-access-control/permissions-reference#global-administrator). The first should be enough to create the application registration in Entra ID, whenever this has been disabled for normal users, but Global Administrator permissions might be needed after this to set the desired permissions on the application registration. See [determining which permissions you need](determinepermissions.md) for more information. + +Proceed in the section below which matches with your desired option for creating the application registration, [automatically](#automatically-create-an-app-registration-for-interactive-login) or [manually](#manually-create-an-app-registration-for-interactive-login). + +### Automatically create an app registration for interactive login + +PnP PowerShell has a cmdlet that allows you to register a new Entra ID Application specifically for interactive login. Notice that you need to be able to create App registrations in your Entra ID. + +```PowerShell +Register-PnPEntraIDAppForInteractiveLogin -ApplicationName "PnP Rocks" -Tenant [yourtenant].onmicrosoft.com -Interactive +``` + +When you run the cmdlet above you will be asked to authenticate with your username, password and an optional second factor. After that a new app will be registered in the Entra ID (make sure you have the rights to do this). By default a limited set of permissions scopes is added, but you can provide the one of the permission parameters (`GraphApplicationPermissions`, `GraphDelegatePermissions`, `SharePointApplicationPermissions`, `SharePointDelegatePermissions`) to provide your own permission scopes. + +After the app has been registered you will be asked to provide consent for the application. Alternatively you can ask someone with the appropriate access rights to navigate to the app registration in the Entra ID portal to add them for you. See [determining which permissions you need](determinepermissions.md) for more information. + +### Manually create an app registration for interactive login + +Another option is to manually create the application registration in Entra ID. While the automatic method above is by far the easiest and quickest, for those that like to fully understand each step of the process, can follow this steps in this paragraph in order to create it manually. + +1. [Navigate to the Entra ID portal](https://entra.microsoft.com) and authenticate with an account that has permissions to create application registrations + +1. Using the menu on the left, go to _Identity_ > _Applications_ > _App registrations_ + + ![image](../images/registerapplication/entraid_navigate_to_app_registrations.png) + +1. At the top, click on _New registration_ + + ![image](../images/registerapplication/entraid_new_app_registration.png) + +1. In the _Name_ field, enter any name you would like which indicates to you what the purpose of this script is. Leave the rest of the fields as they are and click on _Register_ at the bottom of the page. + + ![image](../images/registerapplication/entraid_new_app_registration_enter_name.png) + +1. Take note of the _Application (client) ID_ value, as you will use this to connect to PnP PowerShell using the application registration you have just created + + ![image](../images/registerapplication/entraid_new_app_clientid.png) + +1. In the menu, look for _Manage_ and click on _Authentication_ + + ![image](../images/registerapplication/entraid_new_app_authentication_menu.png) + +1. Under _Platform configurations_ on the page, click on _Add a platform_ + + ![image](../images/registerapplication/entraid_new_app_authentication_add_platform.png) + +1. In the panel that shows up on the right, click on _Mobile and desktop applications_ + + ![image](../images/registerapplication/entraid_new_app_authentication_add_platform_desktop.png) + +1. Leave the three boxes shown in the panel on the right unchecked and in the _Custom redirect URIs_ field, enter: + + http://localhost + + Note that this should really be http and not https + + Click on _Configure_ at the bottom + + ![image](../images/registerapplication/entraid_new_app_authentication_add_platform_desktop_redirecturis.png) + +1. Under _Manage_ go to _API permissions_ + + ![image](../images/registerapplication/entraid_new_app_apipermissions_menu.png) + +1. In the _Configured permissions_ section, click on the three dots in the line that reads _Microsoft Graph (1)_ and click on _Remove all permissions_ and click on _Yes, remove_ in the confirmation dialog that will show up. + + ![image](../images/registerapplication/entraid_new_app_apipermissions_removedefault.png) + +1. In the _Configured permissions_ section, click on _Add a permission_ + + ![image](../images/registerapplication/entraid_new_app_apipermissions_addpermission.png) + +1. In the panel on the right, stay in the _Microsoft APIs_ category and scroll down to _SharePoint_ and click on it + + ![image](../images/registerapplication/entraid_new_app_apipermissions_addpermission_sharepoint.png) + +1. Click on _Delegated permissions_ + + ![image](../images/registerapplication/entraid_new_app_apipermissions_addpermission_sharepoint_delegated.png) + +1. Expand _AllSites_ and check the box for _AllSites.Read_ or any other permission you wish to use with your application registration and click on _Add permissions_ at the bottom + + ![image](../images/registerapplication/entraid_new_app_apipermissions_addpermission_sharepoint_delegated_allsites_read.png) + +1. Under _Configured permissions_ click on _Grant admin consent for -organization name-_ + + If this button is greyed out, it means you do not have the proper permissions to provide the consent. Log in using an account or ask someone having the Global Administrator role to perform this step for you if this is the case. + + ![image](../images/registerapplication/entraid_new_app_apipermissions_addpermission_grant_admin_consent.png) + +1. In the panel on the right, select _No, remove other granted permissions_ and click on _Grant admin consent_ at the bottom. In the confirmation dialog that appears, click _Yes_. + + ![image](../images/registerapplication/entraid_new_app_apipermissions_addpermission_grant_admin_consent_remove_other.png) + +1. The _Configured permissions_ section should now look similar to the screenshot below. You can now use this application to [connect to PnP PowerShell](connecting.md) or [add additional permissions](determinepermissions.md) to this application registration as necessary. + + ![image](../images/registerapplication/entraid_new_app_apipermissions_minimal.png ) + +## Setting up access to your own Entra ID App for App Only Access + +If you're looking to register an application in Entra ID to use PnP PowerShell with a script that will run without requiring user interaction, App Only described in this section is what you want to go with. + +PnP PowerShell has a cmdlet that allows you to register a new Entra ID App, and optionally generate the certificates for you to use to login with that app. + +```PowerShell +$result = Register-PnPEntraIDApp -ApplicationName "PnP Rocks" -Tenant [yourtenant].onmicrosoft.com -OutPath c:\mycertificates -DeviceLogin +$result +``` + +When you run the cmdlet above you will be asked to navigate to the shown url and enter the code shown. After that a new app will be registered in the Entra ID (make sure you have the rights to do this), and a certificate will be generated and uploaded to that app. After this a URL will be shown which you have to navigate to to provide consent for this application. By default a limited set of permissions scopes is added, but you can provide the one of the permission parameters (`GraphApplicationPermissions`, `GraphDelegatePermissions`, `SharePointApplicationPermissions`, `SharePointDelegatePermissions`) to provide your own permission scopes. + +It also returns the private key certificate encoded in base64 encoding. As it spans multiple lines, it is recommended to assign the outcome of `Register-PnPAzureAdApp` to a variable so you have access to this value more easily. The Base64 encoded private key certificate can be used in your Connect-PnPOnline voiding the need to have access to the physical file: + +```PowerShell +Connect-PnPOnline [yourtenant].sharepoint.com -ClientId [clientid] -Tenant [yourtenant].onmicrosoft.com -CertificateBase64Encoded [pfx base64 encoded] +``` + +The cmdlet will also save both the CER and PFX files to the location specified with the -Outpath parameter. The names of the files will be matching the -ApplicationName parameter, e.g. in the example above the files will be called `PnP Rocks.cer` and `PnP Rocks.pfx`. The output of the cmdlet will show the clientid. After all is set up and consent has been provided you can login using: + +```PowerShell +Connect-PnPOnline [yourtenant].sharepoint.com -ClientId [clientid] -Tenant [yourtenant].onmicrosoft.com -CertificatePath [certificate.pfx] +``` +## Special instructions for GCC or National Cloud environments + +In order to set up your application registration on a GCC or a national cloud environment, you will have to take a few extra steps. In the two methods described above for [interactive login](#automatically-create-an-app-registration-for-interactive-login) and [App Only access](#setting-up-access-to-your-own-entra-id-app-for-app-only-access), you will have to add `-AzureEnvironment [USGovernment|USGovernmentHigh|USGovernmentDoD|Germany|China]` to the cmdlet picking the one that applies to your environment to register your application in Entra ID. + +I.e. for an application registration meand for interactive login, use: + +```PowerShell +Register-PnPEntraIDAppForInteractiveLogin -ApplicationName "PnP Rocks" -Tenant [yourtenant].onmicrosoft.com -Interactive -AzureEnvironment [USGovernment|USGovernmentHigh|USGovernmentDoD|Germany|China] +``` + +And for an App Only application registration, use: + +```PowerShell +$result = Register-PnPEntraIDApp -ApplicationName "PnP Rocks" -Tenant [yourtenant].onmicrosoft.com -OutPath c:\mycertificates -DeviceLogin -AzureEnvironment [USGovernment|USGovernmentHigh|USGovernmentDoD|Germany|China] +$result +``` + +The above statement grants a few permission scopes. You might want to add more if you want to. Alternatively, after registering the application, navigate to Entra ID, locate the app registration, and grant more permissions and consent to them. + +### Optionally modify the manifest for the app +There is a limitation in the Entra ID for national cloud environments where you cannot select permission scopes for SharePoint Online. In order to add specific SharePoint rights you will have to manually add them to the manifest that you can edit in Entra ID: + +Locate the `requiredResourceAccess` section and add to or modify the existing entries. See the example below (notice, this is an example, do not copy and paste this as is as it will limit the permissions to only AllSites.FullControl): + +```json +"requiredResourceAccess": [ +{ + "resourceAppId": "00000003-0000-0ff1-ce00-000000000000", + "resourceAccess": [ + { + "id": "56680e0d-d2a3-4ae1-80d8-3c4f2100e3d0", + "type": "Scope" + } + ] +} +``` + +You can add more permissions by using the following values: + +The resourceAppId for SharePoint = "00000003-0000-0ff1-ce00-000000000000" + +Permission | Permission type | Id | Type +| -------| ----------- | ------ | ----- | +| Sites.FullControl.All | Application | 678536fe-1083-478a-9c59-b99265e6b0d3 | Role | +| AllSites.FullControl | Delegate | 56680e0d-d2a3-4ae1-80d8-3c4f2100e3d0 | Scope | diff --git a/pages/articles/toc.yml b/pages/articles/toc.yml index b0f2bff6b..3a0a357f4 100644 --- a/pages/articles/toc.yml +++ b/pages/articles/toc.yml @@ -1,21 +1,21 @@ -- name: Installation - href: installation.md -- name: Authentication - href: authentication.md -- name: Credential Management - href: credentialmanagement.md -- name: Connecting - href: connecting.md -- name: Batching in PnP PowerShell - href: batching.md -- name: Upgrading from the Legacy version - href: upgrading.md +- name: Getting started + items: + - name: Installation + href: installation.md + - name: Register your application + href: registerapplication.md + - name: Determine permissions + href: determinepermissions.md + - name: Connecting and authenticating + href: authentication.md - name: Configure PnP PowerShell items: - name: Telemetry href: telemetry.md - name: Version checks href: updatenotifications.md + - name: Default Client Id + href: defaultclientid.md - name: Using PnP PowerShell in Azure items: - name: Introduction @@ -32,6 +32,16 @@ href: docker.md - name: Visual Studio Development Containers href: dev-containers.md +- name: Advanced topics + items: + - name: Using Microsoft Search with PnP PowerShell + href: microsoftsearch.md + - name: Batching in PnP PowerShell + href: batching.md + - name: Upgrading from the Legacy version + href: upgrading.md + - name: Credential Management + href: credentialmanagement.md - name: How to contribute items: - name: Getting started @@ -49,4 +59,4 @@ - name: PnP PowerShell predictor href: powershellpredictor.md - name: Visual Studio Code extension - href: vscodeextension.md \ No newline at end of file + href: vscodeextension.md diff --git a/pages/images/configuration/README.md b/pages/images/configuration/README.md new file mode 100644 index 000000000..b25382597 --- /dev/null +++ b/pages/images/configuration/README.md @@ -0,0 +1 @@ +This folder contains images used in Configuration articles diff --git a/pages/images/configuration/configuration_defaultclientid_windowsmenu_system.png b/pages/images/configuration/configuration_defaultclientid_windowsmenu_system.png new file mode 100644 index 000000000..b9d09334b Binary files /dev/null and b/pages/images/configuration/configuration_defaultclientid_windowsmenu_system.png differ diff --git a/pages/images/configuration/configuration_defaultclientid_windowsmenu_system_advancedsettings.png b/pages/images/configuration/configuration_defaultclientid_windowsmenu_system_advancedsettings.png new file mode 100644 index 000000000..67dd8c4aa Binary files /dev/null and b/pages/images/configuration/configuration_defaultclientid_windowsmenu_system_advancedsettings.png differ diff --git a/pages/images/configuration/configuration_defaultclientid_windowsmenu_system_advancedsettings_envvariables.png b/pages/images/configuration/configuration_defaultclientid_windowsmenu_system_advancedsettings_envvariables.png new file mode 100644 index 000000000..ac9e7f384 Binary files /dev/null and b/pages/images/configuration/configuration_defaultclientid_windowsmenu_system_advancedsettings_envvariables.png differ diff --git a/pages/images/configuration/configuration_defaultclientid_windowsmenu_system_advancedsettings_envvariables_addentry.png b/pages/images/configuration/configuration_defaultclientid_windowsmenu_system_advancedsettings_envvariables_addentry.png new file mode 100644 index 000000000..db3fc6e6d Binary files /dev/null and b/pages/images/configuration/configuration_defaultclientid_windowsmenu_system_advancedsettings_envvariables_addentry.png differ diff --git a/pages/images/configuration/connecting_verbose_clientid.png b/pages/images/configuration/connecting_verbose_clientid.png new file mode 100644 index 000000000..33f1e8b1b Binary files /dev/null and b/pages/images/configuration/connecting_verbose_clientid.png differ diff --git a/pages/images/determinepermissions/README.md b/pages/images/determinepermissions/README.md new file mode 100644 index 000000000..b9d212884 --- /dev/null +++ b/pages/images/determinepermissions/README.md @@ -0,0 +1 @@ +This folder contains images used in the determine permissions article diff --git a/pages/images/determinepermissions/entraid_permissions_accessdenied_verbose.png b/pages/images/determinepermissions/entraid_permissions_accessdenied_verbose.png new file mode 100644 index 000000000..5ce7d720c Binary files /dev/null and b/pages/images/determinepermissions/entraid_permissions_accessdenied_verbose.png differ diff --git a/pages/images/determinepermissions/entraid_permissions_apponly_minimal.png b/pages/images/determinepermissions/entraid_permissions_apponly_minimal.png new file mode 100644 index 000000000..41be86bdd Binary files /dev/null and b/pages/images/determinepermissions/entraid_permissions_apponly_minimal.png differ diff --git a/pages/images/determinepermissions/entraid_permissions_delegate_enterprisepermissionadded.png b/pages/images/determinepermissions/entraid_permissions_delegate_enterprisepermissionadded.png new file mode 100644 index 000000000..880cfe884 Binary files /dev/null and b/pages/images/determinepermissions/entraid_permissions_delegate_enterprisepermissionadded.png differ diff --git a/pages/images/determinepermissions/entraid_permissions_delegate_minimal.png b/pages/images/determinepermissions/entraid_permissions_delegate_minimal.png new file mode 100644 index 000000000..b5740ae0d Binary files /dev/null and b/pages/images/determinepermissions/entraid_permissions_delegate_minimal.png differ diff --git a/pages/images/determinepermissions/entraid_permissions_delegate_requestadditionalpermissions.png b/pages/images/determinepermissions/entraid_permissions_delegate_requestadditionalpermissions.png new file mode 100644 index 000000000..0ef092dee Binary files /dev/null and b/pages/images/determinepermissions/entraid_permissions_delegate_requestadditionalpermissions.png differ diff --git a/pages/images/registerapplication/README.md b/pages/images/registerapplication/README.md new file mode 100644 index 000000000..fcc661d3c --- /dev/null +++ b/pages/images/registerapplication/README.md @@ -0,0 +1 @@ +This folder contains images used in the registerapplication article diff --git a/pages/images/registerapplication/entraid_navigate_to_app_registrations.png b/pages/images/registerapplication/entraid_navigate_to_app_registrations.png new file mode 100644 index 000000000..dc5797089 Binary files /dev/null and b/pages/images/registerapplication/entraid_navigate_to_app_registrations.png differ diff --git a/pages/images/registerapplication/entraid_new_app_apipermissions_addpermission.png b/pages/images/registerapplication/entraid_new_app_apipermissions_addpermission.png new file mode 100644 index 000000000..154c053e9 Binary files /dev/null and b/pages/images/registerapplication/entraid_new_app_apipermissions_addpermission.png differ diff --git a/pages/images/registerapplication/entraid_new_app_apipermissions_addpermission_grant_admin_consent.png b/pages/images/registerapplication/entraid_new_app_apipermissions_addpermission_grant_admin_consent.png new file mode 100644 index 000000000..bf3d14131 Binary files /dev/null and b/pages/images/registerapplication/entraid_new_app_apipermissions_addpermission_grant_admin_consent.png differ diff --git a/pages/images/registerapplication/entraid_new_app_apipermissions_addpermission_grant_admin_consent_remove_other.png b/pages/images/registerapplication/entraid_new_app_apipermissions_addpermission_grant_admin_consent_remove_other.png new file mode 100644 index 000000000..8578a9f89 Binary files /dev/null and b/pages/images/registerapplication/entraid_new_app_apipermissions_addpermission_grant_admin_consent_remove_other.png differ diff --git a/pages/images/registerapplication/entraid_new_app_apipermissions_addpermission_sharepoint.png b/pages/images/registerapplication/entraid_new_app_apipermissions_addpermission_sharepoint.png new file mode 100644 index 000000000..3cb2c773d Binary files /dev/null and b/pages/images/registerapplication/entraid_new_app_apipermissions_addpermission_sharepoint.png differ diff --git a/pages/images/registerapplication/entraid_new_app_apipermissions_addpermission_sharepoint_delegated.png b/pages/images/registerapplication/entraid_new_app_apipermissions_addpermission_sharepoint_delegated.png new file mode 100644 index 000000000..63d2d0d09 Binary files /dev/null and b/pages/images/registerapplication/entraid_new_app_apipermissions_addpermission_sharepoint_delegated.png differ diff --git a/pages/images/registerapplication/entraid_new_app_apipermissions_addpermission_sharepoint_delegated_allsites_read.png b/pages/images/registerapplication/entraid_new_app_apipermissions_addpermission_sharepoint_delegated_allsites_read.png new file mode 100644 index 000000000..8f187161d Binary files /dev/null and b/pages/images/registerapplication/entraid_new_app_apipermissions_addpermission_sharepoint_delegated_allsites_read.png differ diff --git a/pages/images/registerapplication/entraid_new_app_apipermissions_menu.png b/pages/images/registerapplication/entraid_new_app_apipermissions_menu.png new file mode 100644 index 000000000..d264252ca Binary files /dev/null and b/pages/images/registerapplication/entraid_new_app_apipermissions_menu.png differ diff --git a/pages/images/registerapplication/entraid_new_app_apipermissions_minimal.png b/pages/images/registerapplication/entraid_new_app_apipermissions_minimal.png new file mode 100644 index 000000000..179a51942 Binary files /dev/null and b/pages/images/registerapplication/entraid_new_app_apipermissions_minimal.png differ diff --git a/pages/images/registerapplication/entraid_new_app_apipermissions_removedefault.png b/pages/images/registerapplication/entraid_new_app_apipermissions_removedefault.png new file mode 100644 index 000000000..de8029d9b Binary files /dev/null and b/pages/images/registerapplication/entraid_new_app_apipermissions_removedefault.png differ diff --git a/pages/images/registerapplication/entraid_new_app_authentication_add_platform.png b/pages/images/registerapplication/entraid_new_app_authentication_add_platform.png new file mode 100644 index 000000000..4fb77cce2 Binary files /dev/null and b/pages/images/registerapplication/entraid_new_app_authentication_add_platform.png differ diff --git a/pages/images/registerapplication/entraid_new_app_authentication_add_platform_desktop.png b/pages/images/registerapplication/entraid_new_app_authentication_add_platform_desktop.png new file mode 100644 index 000000000..186bf0721 Binary files /dev/null and b/pages/images/registerapplication/entraid_new_app_authentication_add_platform_desktop.png differ diff --git a/pages/images/registerapplication/entraid_new_app_authentication_add_platform_desktop_redirecturis.png b/pages/images/registerapplication/entraid_new_app_authentication_add_platform_desktop_redirecturis.png new file mode 100644 index 000000000..17c9d1122 Binary files /dev/null and b/pages/images/registerapplication/entraid_new_app_authentication_add_platform_desktop_redirecturis.png differ diff --git a/pages/images/registerapplication/entraid_new_app_authentication_add_platform_web.png b/pages/images/registerapplication/entraid_new_app_authentication_add_platform_web.png new file mode 100644 index 000000000..1e02a45bb Binary files /dev/null and b/pages/images/registerapplication/entraid_new_app_authentication_add_platform_web.png differ diff --git a/pages/images/registerapplication/entraid_new_app_authentication_add_platform_web_enterurl.png b/pages/images/registerapplication/entraid_new_app_authentication_add_platform_web_enterurl.png new file mode 100644 index 000000000..c9b8bcad8 Binary files /dev/null and b/pages/images/registerapplication/entraid_new_app_authentication_add_platform_web_enterurl.png differ diff --git a/pages/images/registerapplication/entraid_new_app_authentication_menu.png b/pages/images/registerapplication/entraid_new_app_authentication_menu.png new file mode 100644 index 000000000..e27b7c500 Binary files /dev/null and b/pages/images/registerapplication/entraid_new_app_authentication_menu.png differ diff --git a/pages/images/registerapplication/entraid_new_app_clientid.png b/pages/images/registerapplication/entraid_new_app_clientid.png new file mode 100644 index 000000000..7be22fe75 Binary files /dev/null and b/pages/images/registerapplication/entraid_new_app_clientid.png differ diff --git a/pages/images/registerapplication/entraid_new_app_registration.png b/pages/images/registerapplication/entraid_new_app_registration.png new file mode 100644 index 000000000..1410e9795 Binary files /dev/null and b/pages/images/registerapplication/entraid_new_app_registration.png differ diff --git a/pages/images/registerapplication/entraid_new_app_registration_enter_name.png b/pages/images/registerapplication/entraid_new_app_registration_enter_name.png new file mode 100644 index 000000000..11e69b719 Binary files /dev/null and b/pages/images/registerapplication/entraid_new_app_registration_enter_name.png differ diff --git a/pages/index.md b/pages/index.md index 6b157ec33..dd8093cc5 100644 --- a/pages/index.md +++ b/pages/index.md @@ -1,5 +1,5 @@ # PnP PowerShell -PnP PowerShell is a cross-platform PowerShell Module providing over 650 cmdlets that work with Microsoft 365 environments and products such as SharePoint Online, Microsoft Teams, Microsoft Planner, Microsoft Flow and more. It runs on Windows, Linux and MacOS. +PnP PowerShell is a cross-platform PowerShell Module providing over 700 cmdlets that work with Microsoft 365 environments and products such as SharePoint Online, Microsoft Teams, Microsoft Planner, Microsoft Flow and more. It runs on Windows, Linux and MacOS. ## Getting up and running diff --git a/pnpcoresdk_hash.txt b/pnpcoresdk_hash.txt index ce70a05ec..7697dfd40 100644 --- a/pnpcoresdk_hash.txt +++ b/pnpcoresdk_hash.txt @@ -1 +1 @@ -47de48eb3458bfeb429d5bce8cdb4ef124942a7c \ No newline at end of file +d79b4b7306bc5ece9e5554a952ecc4dc8fcd982b \ No newline at end of file diff --git a/pnpframework_hash.txt b/pnpframework_hash.txt index 54107f807..97aa7c73c 100644 --- a/pnpframework_hash.txt +++ b/pnpframework_hash.txt @@ -1 +1 @@ -b933e7b1b4e296a920d2df47857c8b4283cc8475 \ No newline at end of file +1908fda86a457d7568482b572323c5f60ca0bf1d \ No newline at end of file diff --git a/pnppowershell_hash.txt b/pnppowershell_hash.txt index 1320ac3e1..e68f1e89f 100644 --- a/pnppowershell_hash.txt +++ b/pnppowershell_hash.txt @@ -1 +1 @@ -83a839208ba24b991ed5a727db600661c547fa26 \ No newline at end of file +14480ebda00baf0cc67ec93367eae154b2cce800 \ No newline at end of file diff --git a/resources/predictor/PnP.PowerShell.Suggestions.nightly.json b/resources/predictor/PnP.PowerShell.Suggestions.nightly.json index b686f5822..314c83f38 100644 --- a/resources/predictor/PnP.PowerShell.Suggestions.nightly.json +++ b/resources/predictor/PnP.PowerShell.Suggestions.nightly.json @@ -1,9998 +1,10124 @@ [ { + "CommandName": "Add-PnPAlert", "Command": "Add-PnPAlert -List \"Demo List\"", "Id": 1, - "CommandName": "Add-PnPAlert", "Rank": 1 }, { + "CommandName": "Add-PnPAlert", "Command": "Add-PnPAlert -Title \"Daily summary\" -List \"Demo List\" -Frequency Daily -ChangeType All -Time (Get-Date -Hour 11 -Minute 00 -Second 00)", "Id": 2, - "CommandName": "Add-PnPAlert", "Rank": 2 }, { + "CommandName": "Add-PnPAlert", "Command": "Add-PnPAlert -Title \"Alert for user\" -List \"Demo List\" -User \"i:0#.f|membership|Alice@contoso.onmicrosoft.com\"", "Id": 3, - "CommandName": "Add-PnPAlert", "Rank": 3 }, { + "CommandName": "Add-PnPAlert", "Command": "Add-PnPAlert -Title \"Alert for user\" -List \"Demo List\" -User \"i:0#.f|membership|Alice@contoso.onmicrosoft.com\" -Frequency Daily -Time ((Get-Date).AddDays(1))", "Id": 4, - "CommandName": "Add-PnPAlert", "Rank": 4 }, { + "CommandName": "Add-PnPApp", "Command": "Add-PnPApp -Path ./myapp.sppkg", "Id": 5, - "CommandName": "Add-PnPApp", "Rank": 1 }, { + "CommandName": "Add-PnPApp", "Command": "Add-PnPApp -Path ./myapp.sppkg -Publish", "Id": 6, - "CommandName": "Add-PnPApp", "Rank": 2 }, { + "CommandName": "Add-PnPApp", "Command": "Add-PnPApp -Path ./myapp.sppkg -Scope Site -Publish", "Id": 7, - "CommandName": "Add-PnPApp", "Rank": 3 }, { + "CommandName": "Add-PnPApp", "Command": "Add-PnPApp -Path ./myapp.sppkg -Publish -SkipFeatureDeployment", "Id": 8, - "CommandName": "Add-PnPApp", "Rank": 4 }, { + "CommandName": "Add-PnPApplicationCustomizer", "Command": "Add-PnPApplicationCustomizer -Title \"CollabFooter\" -ClientSideComponentId c0ab3b94-8609-40cf-861e-2a1759170b43 -ClientSideComponentProperties \"{`\"sourceTermSet`\":`\"PnP-CollabFooter-SharedLinks`\",`\"personalItemsStorageProperty`\":`\"PnP-CollabFooter-MyLinks`\"}", "Id": 9, - "CommandName": "Add-PnPApplicationCustomizer", "Rank": 1 }, { + "CommandName": "Add-PnPAvailableSiteClassification", "Command": "Add-PnPAvailableSiteClassification -Classifications \"Top Secret\"", "Id": 10, - "CommandName": "Add-PnPAvailableSiteClassification", "Rank": 1 }, { + "CommandName": "Add-PnPAvailableSiteClassification", "Command": "Add-PnPAvailableSiteClassification -Classifications \"Top Secret\",\"HBI\"", "Id": 11, - "CommandName": "Add-PnPAvailableSiteClassification", "Rank": 2 }, { + "CommandName": "Add-PnPAzureADGroupMember", "Command": "Add-PnPAzureADGroupMember -Identity \"Project Team\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\"", "Id": 12, - "CommandName": "Add-PnPAzureADGroupMember", "Rank": 1 }, { + "CommandName": "Add-PnPAzureADGroupMember", "Command": "Add-PnPAzureADGroupMember -Identity \"Project Team\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\" -RemoveExisting", "Id": 13, - "CommandName": "Add-PnPAzureADGroupMember", "Rank": 2 }, { + "CommandName": "Add-PnPAzureADGroupMember", "Command": "Add-PnPAzureADGroupMember -Identity \"Project Team\" -Users \"125eaa87-7b54-41fd-b30f-2adfa68c4afe\"", "Id": 14, - "CommandName": "Add-PnPAzureADGroupMember", "Rank": 3 }, { + "CommandName": "Add-PnPAzureADGroupOwner", "Command": "Add-PnPAzureADGroupOwner -Identity \"Project Team\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\"", "Id": 15, - "CommandName": "Add-PnPAzureADGroupOwner", "Rank": 1 }, { + "CommandName": "Add-PnPAzureADGroupOwner", "Command": "Add-PnPAzureADGroupOwner -Identity \"Project Team\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\" -RemoveExisting", "Id": 16, - "CommandName": "Add-PnPAzureADGroupOwner", "Rank": 2 }, { + "CommandName": "Add-PnPAzureADGroupOwner", "Command": "Add-PnPAzureADGroupOwner -Identity \"Project Team\" -Users \"125eaa87-7b54-41fd-b30f-2adfa68c4afe\"", "Id": 17, - "CommandName": "Add-PnPAzureADGroupOwner", "Rank": 3 }, { + "CommandName": "Add-PnPAzureADServicePrincipalAppRole", "Command": "Add-PnPAzureADServicePrincipalAppRole -Principal \"62614f96-cb78-4534-bf12-1f6693e8237c\" -AppRole \"Directory.Read.All\" -BuiltInType MicrosoftGraph", "Id": 18, - "CommandName": "Add-PnPAzureADServicePrincipalAppRole", "Rank": 1 }, { + "CommandName": "Add-PnPAzureADServicePrincipalAppRole", "Command": "Add-PnPAzureADServicePrincipalAppRole -Principal \"62614f96-cb78-4534-bf12-1f6693e8237c\" -AppRole \"MyApplication.Read\" -Resource \"b8c2a8aa-33a0-43f4-a9d3-fe2851c5293e\"", "Id": 19, - "CommandName": "Add-PnPAzureADServicePrincipalAppRole", "Rank": 2 }, { + "CommandName": "Add-PnPContentType", "Command": "Add-PnPContentType -Name \"Project Document\" -Description \"Use for Contoso projects\" -Group \"Contoso Content Types\" -ParentContentType $ct", "Id": 20, - "CommandName": "Add-PnPContentType", "Rank": 1 }, { + "CommandName": "Add-PnPContentType", "Command": "Add-PnPContentType -Name \"Project Document\" -Description \"Use for Contoso projects\" -Group \"Contoso Content Types\" -ParentContentType (Get-PnPContentType -Identity 0x0101) -DocumentTemplate \"/_cts/Project Document/template.docx\"", "Id": 21, - "CommandName": "Add-PnPContentType", "Rank": 2 }, { + "CommandName": "Add-PnPContentType", "Command": "Add-PnPContentType -Name \"Project Item\" -Description \"Use for Contoso projects\" -Group \"Contoso Content Types\"", "Id": 22, - "CommandName": "Add-PnPContentType", "Rank": 3 }, { + "CommandName": "Add-PnPContentType", "Command": "Add-PnPContentType -Name \"Project Item\"", "Id": 23, - "CommandName": "Add-PnPContentType", "Rank": 4 }, { + "CommandName": "Add-PnPContentType", "Command": "Add-PnPContentType -Name \"Project Document\" -Description \"Use for Contoso projects\" -Group \"Contoso Content Types\" -ContentTypeId 0x010100CD5BDB7DDE03324794E155CE37E4B6BB", "Id": 24, - "CommandName": "Add-PnPContentType", "Rank": 5 }, { + "CommandName": "Add-PnPContentTypesFromContentTypeHub", "Command": "Add-PnPContentTypesFromContentTypeHub -ContentTypes \"0x0101\", \"0x01\"", "Id": 25, - "CommandName": "Add-PnPContentTypesFromContentTypeHub", "Rank": 1 }, { + "CommandName": "Add-PnPContentTypesFromContentTypeHub", "Command": "Add-PnPContentTypesFromContentTypeHub -ContentTypes \"0x010057C83E557396744783531D80144BD08D\" -Site https://tenant.sharepoint.com/sites/HR", "Id": 26, - "CommandName": "Add-PnPContentTypesFromContentTypeHub", "Rank": 2 }, { + "CommandName": "Add-PnPContentTypeToDocumentSet", "Command": "Add-PnPContentTypeToDocumentSet -ContentType \"Test CT\" -DocumentSet \"Test Document Set\"", "Id": 27, - "CommandName": "Add-PnPContentTypeToDocumentSet", "Rank": 1 }, { + "CommandName": "Add-PnPContentTypeToDocumentSet", "Command": "Add-PnPContentTypeToDocumentSet -ContentType 0x0101001F1CEFF1D4126E4CAD10F00B6137E969 -DocumentSet 0x0120D520005DB65D094035A241BAC9AF083F825F3B", "Id": 28, - "CommandName": "Add-PnPContentTypeToDocumentSet", "Rank": 2 }, { + "CommandName": "Add-PnPContentTypeToList", "Command": "Add-PnPContentTypeToList -List \"Documents\" -ContentType \"Project Document\" -DefaultContentType", "Id": 29, - "CommandName": "Add-PnPContentTypeToList", "Rank": 1 }, { + "CommandName": "Add-PnPCustomAction", "Command": "Add-PnPCustomAction -Title \"CollabFooter\" -Name \"CollabFooter\" -Location \"ClientSideExtension.ApplicationCustomizer\" -ClientSideComponentId c0ab3b94-8609-40cf-861e-2a1759170b43 -ClientSideComponentProperties \"{`\"sourceTermSet`\":`\"PnP-CollabFooter-SharedLinks`\",`\"personalItemsStorageProperty`\":`\"PnP-CollabFooter-MyLinks`\"}\"", "Id": 30, - "CommandName": "Add-PnPCustomAction", "Rank": 1 }, { + "CommandName": "Add-PnPDataRowsToSiteTemplate", "Command": "Add-PnPDataRowsToSiteTemplate -Path template.pnp -List 'PnPTestList' -Fields 'Title','Choice'", "Id": 31, - "CommandName": "Add-PnPDataRowsToSiteTemplate", "Rank": 1 }, { + "CommandName": "Add-PnPDataRowsToSiteTemplate", "Command": "Add-PnPDataRowsToSiteTemplate -Path template.pnp -List 'PnPTestList' -Query '' -Fields 'Title','Choice' -IncludeSecurity", "Id": 32, - "CommandName": "Add-PnPDataRowsToSiteTemplate", "Rank": 2 }, { + "CommandName": "Add-PnPDocumentSet", "Command": "Add-PnPDocumentSet -List \"Documents\" -ContentType \"Test Document Set\" -Name \"Test\"", "Id": 33, - "CommandName": "Add-PnPDocumentSet", "Rank": 1 }, { - "Command": "Add-PnPEventReceiver -List \"ProjectList\" -Name \"TestEventReceiver\" -Url https://yourserver.azurewebsites.net/eventreceiver.svc -EventReceiverType ItemAdded -Synchronization Asynchronous", + "CommandName": "Add-PnPDocumentSet", + "Command": "Add-PnPDocumentSet -List \"Documents\" -ContentType \"Test Document Set\" -Name \"Test\" -Folder \"Projects/Europe\"", "Id": 34, + "Rank": 2 + }, + { "CommandName": "Add-PnPEventReceiver", + "Command": "Add-PnPEventReceiver -List \"ProjectList\" -Name \"TestEventReceiver\" -Url https://yourserver.azurewebsites.net/eventreceiver.svc -EventReceiverType ItemAdded -Synchronization Asynchronous", + "Id": 35, "Rank": 1 }, { - "Command": "Add-PnPEventReceiver -Name \"TestEventReceiver\" -Url https://yourserver.azurewebsites.net/eventreceiver.svc -EventReceiverType WebAdding -Synchronization Synchronous", - "Id": 35, "CommandName": "Add-PnPEventReceiver", + "Command": "Add-PnPEventReceiver -Name \"TestEventReceiver\" -Url https://yourserver.azurewebsites.net/eventreceiver.svc -EventReceiverType WebAdding -Synchronization Synchronous", + "Id": 36, "Rank": 2 }, { - "Command": "Add-PnPEventReceiver -Name \"TestEventReceiver\" -Url https://yourserver.azurewebsites.net/eventreceiver.svc -EventReceiverType ListAdding -Synchronization Synchronous -Scope Site", - "Id": 36, "CommandName": "Add-PnPEventReceiver", + "Command": "Add-PnPEventReceiver -Name \"TestEventReceiver\" -Url https://yourserver.azurewebsites.net/eventreceiver.svc -EventReceiverType ListAdding -Synchronization Synchronous -Scope Site", + "Id": 37, "Rank": 3 }, { - "Command": "Add-PnPEventReceiver -Name \"TestEventReceiver\" -Url https://yourserver.azurewebsites.net/eventreceiver.svc -EventReceiverType ListDeleted -Synchronization Asynchronous -Scope Web", - "Id": 37, "CommandName": "Add-PnPEventReceiver", + "Command": "Add-PnPEventReceiver -Name \"TestEventReceiver\" -Url https://yourserver.azurewebsites.net/eventreceiver.svc -EventReceiverType ListDeleted -Synchronization Asynchronous -Scope Web", + "Id": 38, "Rank": 4 }, { - "Command": "Add-PnPField -Type Calculated -InternalName \"C1\" -DisplayName \"C1\" -Formula \"=[Title]\"", - "Id": 38, "CommandName": "Add-PnPField", + "Command": "Add-PnPField -Type Calculated -InternalName \"C1\" -DisplayName \"C1\" -Formula \"=[Title]\"", + "Id": 39, "Rank": 1 }, { - "Command": "Add-PnPField -List \"Demo list\" -DisplayName \"Location\" -InternalName \"SPSLocation\" -Type Choice -Group \"Demo Group\" -AddToDefaultView -Choices \"Stockholm\",\"Helsinki\",\"Oslo\"", - "Id": 39, "CommandName": "Add-PnPField", + "Command": "Add-PnPField -List \"Demo list\" -DisplayName \"Location\" -InternalName \"SPSLocation\" -Type Choice -Group \"Demo Group\" -AddToDefaultView -Choices \"Stockholm\",\"Helsinki\",\"Oslo\"", + "Id": 40, "Rank": 2 }, { - "Command": "Add-PnPField -List \"Demo list\" -DisplayName \"Speakers\" -InternalName \"SPSSpeakers\" -Type MultiChoice -Group \"Demo Group\" -AddToDefaultView -Choices \"Obiwan Kenobi\",\"Darth Vader\", \"Anakin Skywalker\"", - "Id": 40, "CommandName": "Add-PnPField", + "Command": "Add-PnPField -List \"Demo list\" -DisplayName \"Speakers\" -InternalName \"SPSSpeakers\" -Type MultiChoice -Group \"Demo Group\" -AddToDefaultView -Choices \"Obiwan Kenobi\",\"Darth Vader\", \"Anakin Skywalker\"", + "Id": 41, "Rank": 3 }, { - "Command": "Add-PnPField -List \"Demo List\" -Field \"MyTestCol\"", - "Id": 41, "CommandName": "Add-PnPField", + "Command": "Add-PnPField -List \"Demo List\" -Field \"MyTestCol\"", + "Id": 42, "Rank": 4 }, { - "Command": "Add-PnPField -Type Choice -Choices \"PnP\",\"Parker\",\"Sharing Is Caring\" -DisplayName \"My Test Column\" -InternalName \"MyTestCol\"", - "Id": 42, "CommandName": "Add-PnPField", + "Command": "Add-PnPField -Type Choice -Choices \"PnP\",\"Parker\",\"Sharing Is Caring\" -DisplayName \"My Test Column\" -InternalName \"MyTestCol\"", + "Id": 43, "Rank": 5 }, { - "Command": "Add-PnPField -Type Calculated -ResultType Number -DisplayName \"My Calculated Column\" -InternalName \"MyCalcCol\" -Formula \"=Today()\"", - "Id": 43, "CommandName": "Add-PnPField", + "Command": "Add-PnPField -Type Calculated -ResultType Number -DisplayName \"My Calculated Column\" -InternalName \"MyCalcCol\" -Formula \"=Today()\"", + "Id": 44, "Rank": 6 }, { - "Command": "Add-PnPFieldToContentType -Field \"Project_Name\" -ContentType \"Project Document\"", - "Id": 44, "CommandName": "Add-PnPFieldToContentType", + "Command": "Add-PnPFieldToContentType -Field \"Project_Name\" -ContentType \"Project Document\"", + "Id": 45, "Rank": 1 }, { - "Command": "Add-PnPFile -Path c:\\temp\\company.master -Folder \"_catalogs/masterpage\"", - "Id": 45, "CommandName": "Add-PnPFile", + "Command": "Add-PnPFile -Path c:\\temp\\company.master -Folder \"_catalogs/masterpage\"", + "Id": 46, "Rank": 1 }, { - "Command": "Add-PnPFile -Path .\\displaytemplate.html -Folder \"_catalogs/masterpage/display templates/test\"", - "Id": 46, "CommandName": "Add-PnPFile", + "Command": "Add-PnPFile -Path .\\displaytemplate.html -Folder \"_catalogs/masterpage/display templates/test\"", + "Id": 47, "Rank": 2 }, { - "Command": "Add-PnPFile -Path .\\sample.doc -Folder \"Shared Documents\" -Values @{Modified=\"12/28/2023\"}", - "Id": 47, "CommandName": "Add-PnPFile", + "Command": "Add-PnPFile -Path .\\sample.doc -Folder \"Shared Documents\" -Values @{Modified=\"12/28/2023\"}", + "Id": 48, "Rank": 3 }, { - "Command": "Add-PnPFile -FileName sample.doc -Folder \"Shared Documents\" -Stream $fileStream -Values @{Modified=\"12/28/2023\"}", - "Id": 48, "CommandName": "Add-PnPFile", + "Command": "Add-PnPFile -FileName sample.doc -Folder \"Shared Documents\" -Stream $fileStream -Values @{Modified=\"12/28/2023\"}", + "Id": 49, "Rank": 4 }, { - "Command": "Add-PnPFile -Path sample.doc -Folder \"Shared Documents\" -ContentType \"Document\" -Values @{Modified=\"12/28/2023\"}", - "Id": 49, "CommandName": "Add-PnPFile", + "Command": "Add-PnPFile -Path sample.doc -Folder \"Shared Documents\" -ContentType \"Document\" -Values @{Modified=\"12/28/2023\"}", + "Id": 50, "Rank": 5 }, { - "Command": "Add-PnPFile -Path sample.docx -Folder \"Documents\" -Values @{Modified=\"12/28/2016\"; Created=\"12/28/2023\"; Editor=23}", - "Id": 50, "CommandName": "Add-PnPFile", + "Command": "Add-PnPFile -Path sample.docx -Folder \"Documents\" -Values @{Modified=\"12/28/2016\"; Created=\"12/28/2023\"; Editor=23}", + "Id": 51, "Rank": 6 }, { - "Command": "Add-PnPFile -Path sample.docx -Folder \"Documents\" -NewFileName \"differentname.docx\"", - "Id": 51, "CommandName": "Add-PnPFile", + "Command": "Add-PnPFile -Path sample.docx -Folder \"Documents\" -NewFileName \"differentname.docx\"", + "Id": 52, "Rank": 7 }, { - "Command": "Add-PnPFile -FileName sample.txt -Folder \"Shared Documents\" -Content '{ \"Test\": \"Value\" }'", - "Id": 52, "CommandName": "Add-PnPFile", + "Command": "Add-PnPFile -FileName sample.txt -Folder \"Shared Documents\" -Content '{ \"Test\": \"Value\" }'", + "Id": 53, "Rank": 8 }, { - "Command": "Add-PnPFileAnonymousSharingLink -FileUrl \"/sites/demo/Shared Documents/Test.docx\"", - "Id": 53, "CommandName": "Add-PnPFileAnonymousSharingLink", + "Command": "Add-PnPFileAnonymousSharingLink -FileUrl \"/sites/demo/Shared Documents/Test.docx\"", + "Id": 54, "Rank": 1 }, { - "Command": "Add-PnPFileAnonymousSharingLink -FileUrl \"/sites/demo/Shared Documents/Test.docx\" -Type Edit -Password \"PnPRocks!\"", - "Id": 54, "CommandName": "Add-PnPFileAnonymousSharingLink", + "Command": "Add-PnPFileAnonymousSharingLink -FileUrl \"/sites/demo/Shared Documents/Test.docx\" -Type Edit -Password \"PnPRocks!\"", + "Id": 55, "Rank": 2 }, { - "Command": "Add-PnPFileAnonymousSharingLink -FileUrl \"/sites/demo/Shared Documents/Test.docx\" -Type View -ExpirationDateTime (Get-Date).AddDays(15)", - "Id": 55, "CommandName": "Add-PnPFileAnonymousSharingLink", + "Command": "Add-PnPFileAnonymousSharingLink -FileUrl \"/sites/demo/Shared Documents/Test.docx\" -Type View -ExpirationDateTime (Get-Date).AddDays(15)", + "Id": 56, "Rank": 3 }, { - "Command": "Add-PnPFileOrganizationalSharingLink -FileUrl \"/sites/demo/Shared Documents/Test.docx\"", - "Id": 56, "CommandName": "Add-PnPFileOrganizationalSharingLink", + "Command": "Add-PnPFileOrganizationalSharingLink -FileUrl \"/sites/demo/Shared Documents/Test.docx\"", + "Id": 57, "Rank": 1 }, { - "Command": "Add-PnPFileOrganizationalSharingLink -FileUrl \"/sites/demo/Shared Documents/Test.docx\" -Type Edit", - "Id": 57, "CommandName": "Add-PnPFileOrganizationalSharingLink", + "Command": "Add-PnPFileOrganizationalSharingLink -FileUrl \"/sites/demo/Shared Documents/Test.docx\" -Type Edit", + "Id": 58, "Rank": 2 }, { - "Command": "Add-PnPFileSharingInvite -FileUrl \"/sites/demo/Shared Documents/Test.docx\" -Users \"john@contoso.onmicrosoft.com\" -RequireSignIn", - "Id": 58, "CommandName": "Add-PnPFileSharingInvite", + "Command": "Add-PnPFileSharingInvite -FileUrl \"/sites/demo/Shared Documents/Test.docx\" -Users \"john@contoso.onmicrosoft.com\" -RequireSignIn", + "Id": 59, "Rank": 1 }, { - "Command": "Add-PnPFileSharingInvite -FileUrl \"/sites/demo/Shared Documents/Test.docx\" -Users \"john@contoso.onmicrosoft.com\" -RequireSignIn -SendInvitation -Role Owner", - "Id": 59, "CommandName": "Add-PnPFileSharingInvite", + "Command": "Add-PnPFileSharingInvite -FileUrl \"/sites/demo/Shared Documents/Test.docx\" -Users \"john@contoso.onmicrosoft.com\" -RequireSignIn -SendInvitation -Role Owner", + "Id": 60, "Rank": 2 }, { - "Command": "Add-PnPFileSharingInvite -FileUrl \"/sites/demo/Shared Documents/Test.docx\" -Users \"john@contoso.onmicrosoft.com\" -RequireSignIn -ExpirationDate (Get-Date).AddDays(15)", - "Id": 60, "CommandName": "Add-PnPFileSharingInvite", + "Command": "Add-PnPFileSharingInvite -FileUrl \"/sites/demo/Shared Documents/Test.docx\" -Users \"john@contoso.onmicrosoft.com\" -RequireSignIn -ExpirationDate (Get-Date).AddDays(15)", + "Id": 61, "Rank": 3 }, { - "Command": "Add-PnPFileToSiteTemplate -Path template.pnp -Source \"Instructions.docx\" -Folder \"Shared Documents\"", - "Id": 61, "CommandName": "Add-PnPFileToSiteTemplate", + "Command": "Add-PnPFileToSiteTemplate -Path template.pnp -Source \"Instructions.docx\" -Folder \"Shared Documents\"", + "Id": 62, "Rank": 1 }, { - "Command": "Add-PnPFileToSiteTemplate -Path c:\\temp\\template.pnp -Source \"c:\\temp\\Sample.pptx\" -Folder \"Shared Documents\\Samples\"", - "Id": 62, "CommandName": "Add-PnPFileToSiteTemplate", + "Command": "Add-PnPFileToSiteTemplate -Path c:\\temp\\template.pnp -Source \"c:\\temp\\Sample.pptx\" -Folder \"Shared Documents\\Samples\"", + "Id": 63, "Rank": 2 }, { - "Command": "Add-PnPFileToSiteTemplate -Path template.pnp -Source \"./myfile.png\" -Folder \"folderinsite\" -FileLevel Published -FileOverwrite:$false", - "Id": 63, "CommandName": "Add-PnPFileToSiteTemplate", + "Command": "Add-PnPFileToSiteTemplate -Path template.pnp -Source \"./myfile.png\" -Folder \"folderinsite\" -FileLevel Published -FileOverwrite:$false", + "Id": 64, "Rank": 3 }, { - "Command": "Add-PnPFileToSiteTemplate -Path template.pnp -Source $sourceFilePath -Folder $targetFolder -Container $container", - "Id": 64, "CommandName": "Add-PnPFileToSiteTemplate", + "Command": "Add-PnPFileToSiteTemplate -Path template.pnp -Source $sourceFilePath -Folder $targetFolder -Container $container", + "Id": 65, "Rank": 4 }, { - "Command": "Add-PnPFileToSiteTemplate -Path template.pnp -SourceUrl \"Shared%20Documents/ProjectStatus.docx\"", - "Id": 65, "CommandName": "Add-PnPFileToSiteTemplate", + "Command": "Add-PnPFileToSiteTemplate -Path template.pnp -SourceUrl \"Shared%20Documents/ProjectStatus.docx\"", + "Id": 66, "Rank": 5 }, { - "Command": "Add-PnPFileUserSharingLink -FileUrl \"/sites/demo/Shared Documents/Test.docx\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\"", - "Id": 66, "CommandName": "Add-PnPFileUserSharingLink", + "Command": "Add-PnPFileUserSharingLink -FileUrl \"/sites/demo/Shared Documents/Test.docx\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\"", + "Id": 67, "Rank": 1 }, { - "Command": "Add-PnPFileUserSharingLink -FileUrl \"/sites/demo/Shared Documents/Test.docx\" -Type Edit -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\"", - "Id": 67, "CommandName": "Add-PnPFileUserSharingLink", + "Command": "Add-PnPFileUserSharingLink -FileUrl \"/sites/demo/Shared Documents/Test.docx\" -Type Edit -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\"", + "Id": 68, "Rank": 2 }, { - "Command": "Add-PnPFlowOwner -Environment (Get-PnPPowerPlatformEnvironment -IsDefault) -Identity f07c34a9-a586-4e58-91fb-e7ea19741b61 -User username@tenant.onmicrosoft.com -Role CanEdit", - "Id": 68, "CommandName": "Add-PnPFlowOwner", + "Command": "Add-PnPFlowOwner -Environment (Get-PnPPowerPlatformEnvironment -IsDefault) -Identity f07c34a9-a586-4e58-91fb-e7ea19741b61 -User username@tenant.onmicrosoft.com -Role CanEdit", + "Id": 69, "Rank": 1 }, { - "Command": "Add-PnPFlowOwner -Environment (Get-PnPPowerPlatformEnvironment -IsDefault) -Identity f07c34a9-a586-4e58-91fb-e7ea19741b61 -User 6844c04a-8ee7-40ad-af66-28f6e948cd04 -Role CanView", - "Id": 69, "CommandName": "Add-PnPFlowOwner", + "Command": "Add-PnPFlowOwner -Environment (Get-PnPPowerPlatformEnvironment -IsDefault) -Identity f07c34a9-a586-4e58-91fb-e7ea19741b61 -User 6844c04a-8ee7-40ad-af66-28f6e948cd04 -Role CanView", + "Id": 70, "Rank": 2 }, { - "Command": "Add-PnPFlowOwner -Environment (Get-PnPPowerPlatformEnvironment -IsDefault) -Identity f07c34a9-a586-4e58-91fb-e7ea19741b61 -User 6844c04a-8ee7-40ad-af66-28f6e948cd04 -Role CanViewWithShare", - "Id": 70, "CommandName": "Add-PnPFlowOwner", + "Command": "Add-PnPFlowOwner -Environment (Get-PnPPowerPlatformEnvironment -IsDefault) -Identity f07c34a9-a586-4e58-91fb-e7ea19741b61 -User 6844c04a-8ee7-40ad-af66-28f6e948cd04 -Role CanViewWithShare", + "Id": 71, "Rank": 3 }, { - "Command": "Add-PnPFlowOwner -Environment (Get-PnPPowerPlatformEnvironment -IsDefault) -Identity f07c34a9-a586-4e58-91fb-e7ea19741b61 -User username@tenant.onmicrosoft.com -AsAdmin -Role CanEdit", - "Id": 71, "CommandName": "Add-PnPFlowOwner", + "Command": "Add-PnPFlowOwner -Environment (Get-PnPPowerPlatformEnvironment -IsDefault) -Identity f07c34a9-a586-4e58-91fb-e7ea19741b61 -User username@tenant.onmicrosoft.com -AsAdmin -Role CanEdit", + "Id": 72, "Rank": 4 }, { - "Command": "Add-PnPFolder -Name NewFolder -Folder _catalogs/masterpage", - "Id": 72, "CommandName": "Add-PnPFolder", + "Command": "Add-PnPFolder -Name NewFolder -Folder _catalogs/masterpage", + "Id": 73, "Rank": 1 }, { - "Command": "Add-PnPFolder -Name NewFolder -Folder \"Shared Documents\"", - "Id": 73, "CommandName": "Add-PnPFolder", + "Command": "Add-PnPFolder -Name NewFolder -Folder \"Shared Documents\"", + "Id": 74, "Rank": 2 }, { - "Command": "Add-PnPFolder -Name NewFolder -Folder \"Shared Documents/Folder\"", - "Id": 74, "CommandName": "Add-PnPFolder", + "Command": "Add-PnPFolder -Name NewFolder -Folder \"Shared Documents/Folder\"", + "Id": 75, "Rank": 3 }, { - "Command": "Add-PnPFolderAnonymousSharingLink -Folder \"/sites/demo/Shared Documents/Test\"", - "Id": 75, "CommandName": "Add-PnPFolderAnonymousSharingLink", + "Command": "Add-PnPFolderAnonymousSharingLink -Folder \"/sites/demo/Shared Documents/Test\"", + "Id": 76, "Rank": 1 }, { - "Command": "Add-PnPFolderAnonymousSharingLink -Folder \"/sites/demo/Shared Documents/Test\" -Type Edit -Password \"PnPRocks!\"", - "Id": 76, "CommandName": "Add-PnPFolderAnonymousSharingLink", + "Command": "Add-PnPFolderAnonymousSharingLink -Folder \"/sites/demo/Shared Documents/Test\" -Type Edit -Password \"PnPRocks!\"", + "Id": 77, "Rank": 2 }, { - "Command": "Add-PnPFolderAnonymousSharingLink -Folder \"/sites/demo/Shared Documents/Test\" -Type Edit -Password \"PnPRocks!\" -ExpirationDateTime (Get-Date).AddDays(15)", - "Id": 77, "CommandName": "Add-PnPFolderAnonymousSharingLink", + "Command": "Add-PnPFolderAnonymousSharingLink -Folder \"/sites/demo/Shared Documents/Test\" -Type Edit -Password \"PnPRocks!\" -ExpirationDateTime (Get-Date).AddDays(15)", + "Id": 78, "Rank": 3 }, { - "Command": "Add-PnPFolderOrganizationalSharingLink -Folder \"/sites/demo/Shared Documents/Test\"", - "Id": 78, "CommandName": "Add-PnPFolderOrganizationalSharingLink", + "Command": "Add-PnPFolderOrganizationalSharingLink -Folder \"/sites/demo/Shared Documents/Test\"", + "Id": 79, "Rank": 1 }, { - "Command": "Add-PnPFolderOrganizationalSharingLink -Folder \"/sites/demo/Shared Documents/Test\" -Type Edit", - "Id": 79, "CommandName": "Add-PnPFolderOrganizationalSharingLink", + "Command": "Add-PnPFolderOrganizationalSharingLink -Folder \"/sites/demo/Shared Documents/Test\" -Type Edit", + "Id": 80, "Rank": 2 }, { - "Command": "Add-PnPFolderSharingInvite -Folder \"/sites/demo/Shared Documents/Test\" -Users \"john@contoso.onmicrosoft.com\" -RequireSignIn", - "Id": 80, "CommandName": "Add-PnPFolderSharingInvite", - "Rank": 1 + "Command": "Add-PnPFolderSharingInvite -Folder \"/sites/demo/Shared Documents/Test\" -Users \"john@contoso.onmicrosoft.com\" -RequireSignIn", + "Id": 81, + "Rank": 1 }, { - "Command": "Add-PnPFolderSharingInvite -Folder \"/sites/demo/Shared Documents/Test\" -Users \"john@contoso.onmicrosoft.com\" -RequireSignIn -SendInvitation -Role Owner", - "Id": 81, "CommandName": "Add-PnPFolderSharingInvite", + "Command": "Add-PnPFolderSharingInvite -Folder \"/sites/demo/Shared Documents/Test\" -Users \"john@contoso.onmicrosoft.com\" -RequireSignIn -SendInvitation -Role Owner", + "Id": 82, "Rank": 2 }, { - "Command": "Add-PnPFolderSharingInvite -Folder \"/sites/demo/Shared Documents/Test\" -Users \"john@contoso.onmicrosoft.com\" -RequireSignIn -ExpirationDate (Get-Date).AddDays(15)", - "Id": 82, "CommandName": "Add-PnPFolderSharingInvite", + "Command": "Add-PnPFolderSharingInvite -Folder \"/sites/demo/Shared Documents/Test\" -Users \"john@contoso.onmicrosoft.com\" -RequireSignIn -ExpirationDate (Get-Date).AddDays(15)", + "Id": 83, "Rank": 3 }, { - "Command": "Add-PnPFolderUserSharingLink -Folder \"/sites/demo/Shared Documents/Test\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\"", - "Id": 83, "CommandName": "Add-PnPFolderUserSharingLink", + "Command": "Add-PnPFolderUserSharingLink -Folder \"/sites/demo/Shared Documents/Test\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\"", + "Id": 84, "Rank": 1 }, { - "Command": "Add-PnPFolderUserSharingLink -Folder \"/sites/demo/Shared Documents/Test\" -ShareType Edit -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\"", - "Id": 84, "CommandName": "Add-PnPFolderUserSharingLink", + "Command": "Add-PnPFolderUserSharingLink -Folder \"/sites/demo/Shared Documents/Test\" -ShareType Edit -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\"", + "Id": 85, "Rank": 2 }, { - "Command": "Add-PnPGroupMember -LoginName user@company.com -Group 'Marketing Site Members'", - "Id": 85, "CommandName": "Add-PnPGroupMember", + "Command": "Add-PnPGroupMember -LoginName user@company.com -Group 'Marketing Site Members'", + "Id": 86, "Rank": 1 }, { - "Command": "Add-PnPGroupMember -LoginName user@company.com -Group 5", - "Id": 86, "CommandName": "Add-PnPGroupMember", + "Command": "Add-PnPGroupMember -LoginName user@company.com -Group 5", + "Id": 87, "Rank": 2 }, { - "Command": "Add-PnPHomeSite -HomeSiteUrl \"https://yourtenant.sharepoint.com/sites/myhome\"", - "Id": 87, "CommandName": "Add-PnPHomeSite", + "Command": "Add-PnPHomeSite -HomeSiteUrl \"https://yourtenant.sharepoint.com/sites/myhome\"", + "Id": 88, "Rank": 1 }, { - "Command": "Add-PnPHtmlPublishingPageLayout -Title 'Our custom page layout' -SourceFilePath 'customlayout.aspx' -Description 'A custom page layout' -AssociatedContentTypeID 0x01010901", - "Id": 88, "CommandName": "Add-PnPHtmlPublishingPageLayout", + "Command": "Add-PnPHtmlPublishingPageLayout -Title 'Our custom page layout' -SourceFilePath 'customlayout.aspx' -Description 'A custom page layout' -AssociatedContentTypeID 0x01010901", + "Id": 89, "Rank": 1 }, { - "Command": "Add-PnPHubSiteAssociation -Site \"https://tenant.sharepoint.com/sites/mysite\" -HubSite \"https://tenant.sharepoint.com/sites/hubsite\"", - "Id": 89, "CommandName": "Add-PnPHubSiteAssociation", + "Command": "Add-PnPHubSiteAssociation -Site \"https://tenant.sharepoint.com/sites/mysite\" -HubSite \"https://tenant.sharepoint.com/sites/hubsite\"", + "Id": 90, "Rank": 1 }, { - "Command": "Add-PnPHubToHubAssociation -Source 6638bd4c-d88d-447c-9eb2-c84f28ba8b15 -Target 0b70f9de-2b98-46e9-862f-ba5700aa2443", - "Id": 90, "CommandName": "Add-PnPHubToHubAssociation", + "Command": "Add-PnPHubToHubAssociation -Source 6638bd4c-d88d-447c-9eb2-c84f28ba8b15 -Target 0b70f9de-2b98-46e9-862f-ba5700aa2443", + "Id": 91, "Rank": 1 }, { - "Command": "Add-PnPHubToHubAssociation -SourceUrl \"https://yourtenant.sharepoint.com/sites/sourcehub\" -TargetUrl \"https://yourtenant.sharepoint.com/sites/targethub\"", - "Id": 91, "CommandName": "Add-PnPHubToHubAssociation", + "Command": "Add-PnPHubToHubAssociation -SourceUrl \"https://yourtenant.sharepoint.com/sites/sourcehub\" -TargetUrl \"https://yourtenant.sharepoint.com/sites/targethub\"", + "Id": 92, "Rank": 2 }, { - "Command": "Add-PnPHubToHubAssociation -SourceUrl \"https://yourtenant.sharepoint.com/sites/secondlevelhub\" -TargetUrl \"https://yourtenant.sharepoint.com/sites/toplevelhub\"\r ; Add-PnPHubToHubAssociation -SourceUrl \"https://yourtenant.sharepoint.com/sites/thirdlevelhub\" -TargetUrl \"https://yourtenant.sharepoint.com/sites/secondlevelhub\"", - "Id": 92, "CommandName": "Add-PnPHubToHubAssociation", + "Command": "Add-PnPHubToHubAssociation -SourceUrl \"https://yourtenant.sharepoint.com/sites/secondlevelhub\" -TargetUrl \"https://yourtenant.sharepoint.com/sites/toplevelhub\"\r ; Add-PnPHubToHubAssociation -SourceUrl \"https://yourtenant.sharepoint.com/sites/thirdlevelhub\" -TargetUrl \"https://yourtenant.sharepoint.com/sites/secondlevelhub\"", + "Id": 93, "Rank": 3 }, { - "Command": "Add-PnPJavaScriptBlock -Name myAction -script '' -Sequence 9999 -Scope Site", - "Id": 93, "CommandName": "Add-PnPJavaScriptBlock", + "Command": "Add-PnPJavaScriptBlock -Name myAction -script '' -Sequence 9999 -Scope Site", + "Id": 94, "Rank": 1 }, { - "Command": "Add-PnPJavaScriptBlock -Name myAction -script ''", - "Id": 94, "CommandName": "Add-PnPJavaScriptBlock", + "Command": "Add-PnPJavaScriptBlock -Name myAction -script ''", + "Id": 95, "Rank": 2 }, { - "Command": "Add-PnPJavaScriptLink -Name jQuery -Url https://code.jquery.com/jquery.min.js -Sequence 9999 -Scope Site", - "Id": 95, "CommandName": "Add-PnPJavaScriptLink", + "Command": "Add-PnPJavaScriptLink -Name jQuery -Url https://code.jquery.com/jquery.min.js -Sequence 9999 -Scope Site", + "Id": 96, "Rank": 1 }, { - "Command": "Add-PnPJavaScriptLink -Name jQuery -Url https://code.jquery.com/jquery.min.js", - "Id": 96, "CommandName": "Add-PnPJavaScriptLink", + "Command": "Add-PnPJavaScriptLink -Name jQuery -Url https://code.jquery.com/jquery.min.js", + "Id": 97, "Rank": 2 }, { - "Command": "Add-PnPListDesign -Title \"My Custom List\" -SiteScriptIds \"e84dcb46-3ab9-4456-a136-66fc6ae3d3c5\"", - "Id": 97, "CommandName": "Add-PnPListDesign", + "Command": "Add-PnPListDesign -Title \"My Custom List\" -SiteScriptIds \"e84dcb46-3ab9-4456-a136-66fc6ae3d3c5\"", + "Id": 98, "Rank": 1 }, { - "Command": "Add-PnPListDesign -Title \"My Company Design\" -SiteScriptIds \"6def687f-0e08-4f1e-999c-791f3af9a600\" -Description \"My description\" -ListColor Orange -ListIcon BullseyeTarget -ThumbnailUrl \"https://contoso.sharepoint.com/SiteAssets/site-thumbnail.png\"", - "Id": 98, "CommandName": "Add-PnPListDesign", + "Command": "Add-PnPListDesign -Title \"My Company Design\" -SiteScriptIds \"6def687f-0e08-4f1e-999c-791f3af9a600\" -Description \"My description\" -ListColor Orange -ListIcon BullseyeTarget -ThumbnailUrl \"https://contoso.sharepoint.com/SiteAssets/site-thumbnail.png\"", + "Id": 99, "Rank": 2 }, { - "Command": "Add-PnPListFoldersToSiteTemplate -Path template.pnp -List 'PnPTestList'", - "Id": 99, "CommandName": "Add-PnPListFoldersToSiteTemplate", + "Command": "Add-PnPListFoldersToSiteTemplate -Path template.pnp -List 'PnPTestList'", + "Id": 100, "Rank": 1 }, { - "Command": "Add-PnPListFoldersToSiteTemplate -Path template.pnp -List 'PnPTestList' -Recursive", - "Id": 100, "CommandName": "Add-PnPListFoldersToSiteTemplate", + "Command": "Add-PnPListFoldersToSiteTemplate -Path template.pnp -List 'PnPTestList' -Recursive", + "Id": 101, "Rank": 2 }, { - "Command": "Add-PnPListFoldersToSiteTemplate -Path template.pnp -List 'PnPTestList' -Recursive -IncludeSecurity", - "Id": 101, "CommandName": "Add-PnPListFoldersToSiteTemplate", + "Command": "Add-PnPListFoldersToSiteTemplate -Path template.pnp -List 'PnPTestList' -Recursive -IncludeSecurity", + "Id": 102, "Rank": 3 }, { - "Command": "Add-PnPListItem -List \"Demo List\" -Values @{\"Title\" = \"Test Title\"; \"Category\"=\"Test Category\"}", - "Id": 102, "CommandName": "Add-PnPListItem", + "Command": "Add-PnPListItem -List \"Demo List\" -Values @{\"Title\" = \"Test Title\"; \"Category\"=\"Test Category\"}", + "Id": 103, "Rank": 1 }, { - "Command": "Add-PnPListItem -List \"Demo List\" -ContentType \"Company\" -Values @{\"Title\" = \"Test Title\"; \"Category\"=\"Test Category\"}", - "Id": 103, "CommandName": "Add-PnPListItem", + "Command": "Add-PnPListItem -List \"Demo List\" -ContentType \"Company\" -Values @{\"Title\" = \"Test Title\"; \"Category\"=\"Test Category\"}", + "Id": 104, "Rank": 2 }, { - "Command": "Add-PnPListItem -List \"Demo List\" -Values @{\"MultiUserField\"=\"user1@domain.com\",\"user2@domain.com\"}", - "Id": 104, "CommandName": "Add-PnPListItem", + "Command": "Add-PnPListItem -List \"Demo List\" -Values @{\"MultiUserField\"=\"user1@domain.com\",\"user2@domain.com\"}", + "Id": 105, "Rank": 3 }, { - "Command": "Add-PnPListItem -List \"Demo List\" -Values @{\"Title\"=\"Sales Report\"} -Folder \"projects/europe\"", - "Id": 105, "CommandName": "Add-PnPListItem", + "Command": "Add-PnPListItem -List \"Demo List\" -Values @{\"Title\"=\"Sales Report\"} -Folder \"projects/europe\"", + "Id": 106, "Rank": 4 }, { - "Command": "Add-PnPListItem -List \"Demo List\" -Values @{\"Title\"=\"Sales Report\"} -Label \"Public\"", - "Id": 106, "CommandName": "Add-PnPListItem", + "Command": "Add-PnPListItem -List \"Demo List\" -Values @{\"Title\"=\"Sales Report\"} -Label \"Public\"", + "Id": 107, "Rank": 5 }, { - "Command": "Add-PnPListItemAttachment -List \"Demo List\" -Identity 1 -Path c:\\temp\\test.mp4", - "Id": 107, "CommandName": "Add-PnPListItemAttachment", + "Command": "Add-PnPListItemAttachment -List \"Demo List\" -Identity 1 -Path c:\\temp\\test.mp4", + "Id": 108, "Rank": 1 }, { - "Command": "Add-PnPListItemAttachment -List \"Demo List\" -Identity 1 -FileName \"test.txt\" -Content '{ \"Test\": \"Value\" }'", - "Id": 108, "CommandName": "Add-PnPListItemAttachment", + "Command": "Add-PnPListItemAttachment -List \"Demo List\" -Identity 1 -FileName \"test.txt\" -Content '{ \"Test\": \"Value\" }'", + "Id": 109, "Rank": 2 }, { - "Command": "Add-PnPListItemAttachment -List \"Demo List\" -Identity 1 -FileName \"test.mp4\" -Stream $fileStream", - "Id": 109, "CommandName": "Add-PnPListItemAttachment", + "Command": "Add-PnPListItemAttachment -List \"Demo List\" -Identity 1 -FileName \"test.mp4\" -Stream $fileStream", + "Id": 110, "Rank": 3 }, { - "Command": "Add-PnPListItemComment -List \"Demo List\" -Identity \"1\" -Text \"Hello world\"", - "Id": 110, "CommandName": "Add-PnPListItemComment", + "Command": "Add-PnPListItemComment -List \"Demo List\" -Identity \"1\" -Text \"Hello world\"", + "Id": 111, "Rank": 1 }, { - "Command": "Add-PnPMasterPage -SourceFilePath \"page.master\" -Title \"MasterPage\" -Description \"MasterPage for Web\" -DestinationFolderHierarchy \"SubFolder\"", - "Id": 111, "CommandName": "Add-PnPMasterPage", + "Command": "Add-PnPMasterPage -SourceFilePath \"page.master\" -Title \"MasterPage\" -Description \"MasterPage for Web\" -DestinationFolderHierarchy \"SubFolder\"", + "Id": 112, "Rank": 1 }, { - "Command": "Add-PnPMicrosoft365GroupMember -Identity \"Project Team\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\"", - "Id": 112, "CommandName": "Add-PnPMicrosoft365GroupMember", + "Command": "Add-PnPMicrosoft365GroupMember -Identity \"Project Team\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\"", + "Id": 113, "Rank": 1 }, { - "Command": "Add-PnPMicrosoft365GroupMember -Identity \"Project Team\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\" -RemoveExisting", - "Id": 113, "CommandName": "Add-PnPMicrosoft365GroupMember", + "Command": "Add-PnPMicrosoft365GroupMember -Identity \"Project Team\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\" -RemoveExisting", + "Id": 114, "Rank": 2 }, { - "Command": "Add-PnPMicrosoft365GroupOwner -Identity \"Project Team\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\"", - "Id": 114, "CommandName": "Add-PnPMicrosoft365GroupOwner", + "Command": "Add-PnPMicrosoft365GroupOwner -Identity \"Project Team\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\"", + "Id": 115, "Rank": 1 }, { - "Command": "Add-PnPMicrosoft365GroupOwner -Identity \"Project Team\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\" -RemoveExisting", - "Id": 115, "CommandName": "Add-PnPMicrosoft365GroupOwner", + "Command": "Add-PnPMicrosoft365GroupOwner -Identity \"Project Team\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\" -RemoveExisting", + "Id": 116, "Rank": 2 }, { - "Command": "Add-PnPMicrosoft365GroupToSite -Url \"https://contoso.sharepoint.com/sites/FinanceTeamsite\" -Alias \"FinanceTeamsite\" -DisplayName \"My finance team site group\"", - "Id": 116, "CommandName": "Add-PnPMicrosoft365GroupToSite", + "Command": "Add-PnPMicrosoft365GroupToSite -Url \"https://contoso.sharepoint.com/sites/FinanceTeamsite\" -Alias \"FinanceTeamsite\" -DisplayName \"My finance team site group\"", + "Id": 117, "Rank": 1 }, { - "Command": "Add-PnPMicrosoft365GroupToSite -Alias \"HRTeamsite\" -DisplayName \"My HR team site group\"", - "Id": 117, "CommandName": "Add-PnPMicrosoft365GroupToSite", + "Command": "Add-PnPMicrosoft365GroupToSite -Alias \"HRTeamsite\" -DisplayName \"My HR team site group\"", + "Id": 118, "Rank": 2 }, { - "Command": "Add-PnPMicrosoft365GroupToSite -Url $SiteURL -Alias $GroupAlias -DisplayName $GroupName -IsPublic -KeepOldHomePage", - "Id": 118, "CommandName": "Add-PnPMicrosoft365GroupToSite", + "Command": "Add-PnPMicrosoft365GroupToSite -Url $SiteURL -Alias $GroupAlias -DisplayName $GroupName -IsPublic -KeepOldHomePage", + "Id": 119, "Rank": 3 }, { - "Command": "Add-PnPNavigationNode -Title \"Contoso\" -Url \"http://contoso.sharepoint.com/sites/contoso/\" -Location \"QuickLaunch\"", - "Id": 119, "CommandName": "Add-PnPNavigationNode", + "Command": "Add-PnPNavigationNode -Title \"Contoso\" -Url \"http://contoso.sharepoint.com/sites/contoso/\" -Location \"QuickLaunch\"", + "Id": 120, "Rank": 1 }, { - "Command": "Add-PnPNavigationNode -Title \"Contoso USA\" -Url \"http://contoso.sharepoint.com/sites/contoso/usa/\" -Location \"QuickLaunch\" -Parent 2012", - "Id": 120, "CommandName": "Add-PnPNavigationNode", + "Command": "Add-PnPNavigationNode -Title \"Contoso USA\" -Url \"http://contoso.sharepoint.com/sites/contoso/usa/\" -Location \"QuickLaunch\" -Parent 2012", + "Id": 121, "Rank": 2 }, { - "Command": "Add-PnPNavigationNode -Title \"Contoso\" -Url \"http://contoso.sharepoint.com/sites/contoso/\" -Location \"QuickLaunch\" -First", - "Id": 121, "CommandName": "Add-PnPNavigationNode", + "Command": "Add-PnPNavigationNode -Title \"Contoso\" -Url \"http://contoso.sharepoint.com/sites/contoso/\" -Location \"QuickLaunch\" -First", + "Id": 122, "Rank": 3 }, { - "Command": "Add-PnPNavigationNode -Title \"Contoso Pharmaceuticals\" -Url \"http://contoso.sharepoint.com/sites/contosopharma/\" -Location \"QuickLaunch\" -External", - "Id": 122, "CommandName": "Add-PnPNavigationNode", + "Command": "Add-PnPNavigationNode -Title \"Contoso Pharmaceuticals\" -Url \"http://contoso.sharepoint.com/sites/contosopharma/\" -Location \"QuickLaunch\" -External", + "Id": 123, "Rank": 4 }, { - "Command": "Add-PnPNavigationNode -Title \"Wiki\" -Location \"QuickLaunch\" -Url \"wiki/\"", - "Id": 123, "CommandName": "Add-PnPNavigationNode", + "Command": "Add-PnPNavigationNode -Title \"Wiki\" -Location \"QuickLaunch\" -Url \"wiki/\"", + "Id": 124, "Rank": 5 }, { - "Command": "Add-PnPNavigationNode -Title \"Label\" -Location \"TopNavigationBar\" -Url \"http://linkless.header/\"", - "Id": 124, "CommandName": "Add-PnPNavigationNode", + "Command": "Add-PnPNavigationNode -Title \"Label\" -Location \"TopNavigationBar\" -Url \"http://linkless.header/\"", + "Id": 125, "Rank": 6 }, { - "Command": "Add-PnPNavigationNode -Title \"Wiki\" -Location \"QuickLaunch\" -Url \"wiki/\" -PreviousNode 2012", - "Id": 125, "CommandName": "Add-PnPNavigationNode", + "Command": "Add-PnPNavigationNode -Title \"Wiki\" -Location \"QuickLaunch\" -Url \"wiki/\" -PreviousNode 2012", + "Id": 126, "Rank": 7 }, { - "Command": "Add-PnPNavigationNode -Title \"Contoso\" -Url \"http://contoso.sharepoint.com/sites/contoso/\" -Location \"QuickLaunch\" -OpenInNewTab", - "Id": 126, "CommandName": "Add-PnPNavigationNode", + "Command": "Add-PnPNavigationNode -Title \"Contoso\" -Url \"http://contoso.sharepoint.com/sites/contoso/\" -Location \"QuickLaunch\" -OpenInNewTab", + "Id": 127, "Rank": 8 }, { - "Command": "Add-PnPOrgAssetsLibrary -LibraryUrl \"https://yourtenant.sharepoint.com/sites/branding/logos\"", - "Id": 127, "CommandName": "Add-PnPOrgAssetsLibrary", + "Command": "Add-PnPOrgAssetsLibrary -LibraryUrl \"https://yourtenant.sharepoint.com/sites/branding/logos\"", + "Id": 128, "Rank": 1 }, { - "Command": "Add-PnPOrgAssetsLibrary -LibraryUrl \"https://yourtenant.sharepoint.com/sites/branding/logos\" -ThumbnailUrl \"https://yourtenant.sharepoint.com/sites/branding/logos/thumbnail.jpg\"", - "Id": 128, "CommandName": "Add-PnPOrgAssetsLibrary", + "Command": "Add-PnPOrgAssetsLibrary -LibraryUrl \"https://yourtenant.sharepoint.com/sites/branding/logos\" -ThumbnailUrl \"https://yourtenant.sharepoint.com/sites/branding/logos/thumbnail.jpg\"", + "Id": 129, "Rank": 2 }, { - "Command": "Add-PnPOrgAssetsLibrary -LibraryUrl \"https://yourtenant.sharepoint.com/sites/branding/logos\" -CdnType Private", - "Id": 129, "CommandName": "Add-PnPOrgAssetsLibrary", + "Command": "Add-PnPOrgAssetsLibrary -LibraryUrl \"https://yourtenant.sharepoint.com/sites/branding/logos\" -CdnType Private", + "Id": 130, "Rank": 3 }, { - "Command": "Add-PnPOrgNewsSite -OrgNewsSiteUrl \"https://yourtenant.sharepoint.com/sites/news\"", - "Id": 130, "CommandName": "Add-PnPOrgNewsSite", + "Command": "Add-PnPOrgNewsSite -OrgNewsSiteUrl \"https://yourtenant.sharepoint.com/sites/news\"", + "Id": 131, "Rank": 1 }, { - "Command": "Add-PnPPage -Name \"NewPage\"", - "Id": 131, "CommandName": "Add-PnPPage", + "Command": "Add-PnPPage -Name \"NewPage\"", + "Id": 132, "Rank": 1 }, { - "Command": "Add-PnPPage -Name \"NewPage\" -Title \"Welcome to my page\"", - "Id": 132, "CommandName": "Add-PnPPage", + "Command": "Add-PnPPage -Name \"NewPage\" -Title \"Welcome to my page\"", + "Id": 133, "Rank": 2 }, { - "Command": "Add-PnPPage -Name \"NewPage\" -ContentType \"MyPageContentType\"", - "Id": 133, "CommandName": "Add-PnPPage", + "Command": "Add-PnPPage -Name \"NewPage\" -ContentType \"MyPageContentType\"", + "Id": 134, "Rank": 3 }, { - "Command": "Add-PnPPage -Name \"NewPageTemplate\" -PromoteAs Template", - "Id": 134, "CommandName": "Add-PnPPage", + "Command": "Add-PnPPage -Name \"NewPageTemplate\" -PromoteAs Template", + "Id": 135, "Rank": 4 }, { - "Command": "Add-PnPPage -Name \"Folder/NewPage\"", - "Id": 135, "CommandName": "Add-PnPPage", + "Command": "Add-PnPPage -Name \"Folder/NewPage\"", + "Id": 136, "Rank": 5 }, { - "Command": "Add-PnPPage -Name \"NewPage\" -HeaderLayoutType ColorBlock", - "Id": 136, "CommandName": "Add-PnPPage", + "Command": "Add-PnPPage -Name \"NewPage\" -HeaderLayoutType ColorBlock", + "Id": 137, "Rank": 6 }, { - "Command": "Add-PnPPage -Name \"NewPage\" Article -ScheduledPublishDate (Get-Date).AddHours(1)", - "Id": 137, "CommandName": "Add-PnPPage", + "Command": "Add-PnPPage -Name \"NewPage\" Article -ScheduledPublishDate (Get-Date).AddHours(1)", + "Id": 138, "Rank": 7 }, { - "Command": "Add-PnPPage -Name \"NewPage\" -Translate", - "Id": 138, "CommandName": "Add-PnPPage", + "Command": "Add-PnPPage -Name \"NewPage\" -Translate", + "Id": 139, "Rank": 8 }, { - "Command": "Add-PnPPage -Name \"NewPage\" -Translate -TranslationLanguageCodes 1043", - "Id": 139, "CommandName": "Add-PnPPage", + "Command": "Add-PnPPage -Name \"NewPage\" -Translate -TranslationLanguageCodes 1043", + "Id": 140, "Rank": 9 }, { - "Command": "Add-PnPPage -Name \"NewPage\" -Translate -TranslationLanguageCodes 1043,1035", - "Id": 140, "CommandName": "Add-PnPPage", + "Command": "Add-PnPPage -Name \"NewPage\" -Translate -TranslationLanguageCodes 1043,1035", + "Id": 141, "Rank": 10 }, { - "Command": "Add-PnPPageImageWebPart -Page \"MyPage\" -ImageUrl \"/sites/contoso/siteassets/test.png\"", - "Id": 141, "CommandName": "Add-PnPPageImageWebPart", + "Command": "Add-PnPPageImageWebPart -Page \"MyPage\" -ImageUrl \"/sites/contoso/siteassets/test.png\"", + "Id": 142, "Rank": 1 }, { - "Command": "Add-PnPPageImageWebPart -Page \"MyPage\" -ImageUrl \"/sites/contoso/SiteAssets/test.png\" -ImageWidth 400 -ImageHeight 200 -Caption \"Caption text\" -AlternativeText \"Alt text\" -Link \"https://pnp.github.io\"", - "Id": 142, "CommandName": "Add-PnPPageImageWebPart", + "Command": "Add-PnPPageImageWebPart -Page \"MyPage\" -ImageUrl \"/sites/contoso/SiteAssets/test.png\" -ImageWidth 400 -ImageHeight 200 -Caption \"Caption text\" -AlternativeText \"Alt text\" -Link \"https://pnp.github.io\"", + "Id": 143, "Rank": 2 }, { - "Command": "Add-PnPPageSection -Page \"MyPage\" -SectionTemplate OneColumn", - "Id": 143, "CommandName": "Add-PnPPageSection", + "Command": "Add-PnPPageSection -Page \"MyPage\" -SectionTemplate OneColumn", + "Id": 144, "Rank": 1 }, { + "CommandName": "Add-PnPPageSection", "Command": "Add-PnPPageSection -Page \"MyPage\" -SectionTemplate ThreeColumn -Order 10", - "Id": 144, - "CommandName": "Add-PnPPageSection", + "Id": 145, "Rank": 2 }, { - "Command": "Add-PnPPageTextPart -Page \"MyPage\" -Text \"Hello World!\"", - "Id": 145, "CommandName": "Add-PnPPageTextPart", + "Command": "Add-PnPPageTextPart -Page \"MyPage\" -Text \"Hello World!\"", + "Id": 146, "Rank": 1 }, { - "Command": "Add-PnPPageTextPart -Page \"MyPage\" -Text \"Hello World!\" -ImageUrl \"/sites/contoso/SiteAssets/test.png\"", - "Id": 146, "CommandName": "Add-PnPPageTextPart", + "Command": "Add-PnPPageTextPart -Page \"MyPage\" -Text \"Hello World!\" -ImageUrl \"/sites/contoso/SiteAssets/test.png\"", + "Id": 147, "Rank": 2 }, { - "Command": "Add-PnPPageTextPart -Page \"MyPage\" -Text \"Hello World!\" -ImageUrl \"/sites/contoso/SiteAssets/test.png\" -TextBeforeImage \"Text before\" -TextAfterImage \"Text after\"", - "Id": 147, "CommandName": "Add-PnPPageTextPart", + "Command": "Add-PnPPageTextPart -Page \"MyPage\" -Text \"Hello World!\" -ImageUrl \"/sites/contoso/SiteAssets/test.png\" -TextBeforeImage \"Text before\" -TextAfterImage \"Text after\"", + "Id": 148, "Rank": 3 }, { - "Command": "Add-PnPPageWebPart -Page \"MyPage\" -DefaultWebPartType BingMap", - "Id": 148, "CommandName": "Add-PnPPageWebPart", + "Command": "Add-PnPPageWebPart -Page \"MyPage\" -DefaultWebPartType BingMap", + "Id": 149, "Rank": 1 }, { - "Command": "Add-PnPPageWebPart -Page \"MyPage\" -Component \"HelloWorld\"", - "Id": 149, "CommandName": "Add-PnPPageWebPart", + "Command": "Add-PnPPageWebPart -Page \"MyPage\" -Component \"HelloWorld\"", + "Id": 150, "Rank": 2 }, { - "Command": "Add-PnPPageWebPart -Page \"MyPage\" -Component \"HelloWorld\" -Section 1 -Column 2", - "Id": 150, "CommandName": "Add-PnPPageWebPart", + "Command": "Add-PnPPageWebPart -Page \"MyPage\" -Component \"HelloWorld\" -Section 1 -Column 2", + "Id": 151, "Rank": 3 }, { - "Command": "Add-PnPPlannerBucket -Group \"My Group\" -Plan \"My Plan\" -Name \"Project Todos\"", - "Id": 151, "CommandName": "Add-PnPPlannerBucket", + "Command": "Add-PnPPlannerBucket -Group \"My Group\" -Plan \"My Plan\" -Name \"Project Todos\"", + "Id": 152, "Rank": 1 }, { - "Command": "Add-PnPPlannerBucket -PlanId \"QvfkTd1mc02gwxHjHC_43JYABhAy\" -Name \"Project Todos\"", - "Id": 152, "CommandName": "Add-PnPPlannerBucket", + "Command": "Add-PnPPlannerBucket -PlanId \"QvfkTd1mc02gwxHjHC_43JYABhAy\" -Name \"Project Todos\"", + "Id": 153, "Rank": 2 }, { - "Command": "Add-PnPPlannerRoster", - "Id": 153, "CommandName": "Add-PnPPlannerRoster", + "Command": "Add-PnPPlannerRoster", + "Id": 154, "Rank": 1 }, { - "Command": "Add-PnPPlannerRosterMember -Identity \"6519868f-868f-6519-8f86-19658f861965\" -User \"johndoe@contoso.onmicrosoft.com\"", - "Id": 154, "CommandName": "Add-PnPPlannerRosterMember", + "Command": "Add-PnPPlannerRosterMember -Identity \"6519868f-868f-6519-8f86-19658f861965\" -User \"johndoe@contoso.onmicrosoft.com\"", + "Id": 155, "Rank": 1 }, { - "Command": "Add-PnPPlannerTask -Group \"Marketing\" -Plan \"Conference Plan\" -Bucket \"Todos\" -Title \"Design booth layout\"", - "Id": 155, "CommandName": "Add-PnPPlannerTask", + "Command": "Add-PnPPlannerTask -Group \"Marketing\" -Plan \"Conference Plan\" -Bucket \"Todos\" -Title \"Design booth layout\"", + "Id": 156, "Rank": 1 }, { - "Command": "Add-PnPPlannerTask -PlanId \"QvfkTd1mc02gwxHjHC_43JYABhAy\" -Bucket \"Todos\" -Title \"Design booth layout\"", - "Id": 156, "CommandName": "Add-PnPPlannerTask", + "Command": "Add-PnPPlannerTask -PlanId \"QvfkTd1mc02gwxHjHC_43JYABhAy\" -Bucket \"Todos\" -Title \"Design booth layout\"", + "Id": 157, "Rank": 2 }, { - "Command": "Add-PnPPlannerTask -Group \"Marketing\" -Plan \"Conference Plan\" -Bucket \"Todos\" -Title \"Design booth layout\" -AssignedTo \"user@contoso.com\",\"manager@contoso.com\"", - "Id": 157, "CommandName": "Add-PnPPlannerTask", + "Command": "Add-PnPPlannerTask -Group \"Marketing\" -Plan \"Conference Plan\" -Bucket \"Todos\" -Title \"Design booth layout\" -AssignedTo \"user@contoso.com\",\"manager@contoso.com\"", + "Id": 158, "Rank": 3 }, { - "Command": "Add-PnPPublishingImageRendition -Name \"MyImageRendition\" -Width 800 -Height 600", - "Id": 158, "CommandName": "Add-PnPPublishingImageRendition", + "Command": "Add-PnPPublishingImageRendition -Name \"MyImageRendition\" -Width 800 -Height 600", + "Id": 159, "Rank": 1 }, { - "Command": "Add-PnPPublishingPage -PageName 'OurNewPage' -Title 'Our new page' -PageTemplateName 'ArticleLeft'", - "Id": 159, "CommandName": "Add-PnPPublishingPage", + "Command": "Add-PnPPublishingPage -PageName 'OurNewPage' -Title 'Our new page' -PageTemplateName 'ArticleLeft'", + "Id": 160, "Rank": 1 }, { - "Command": "Add-PnPPublishingPage -PageName 'OurNewPage' -Title 'Our new page' -PageTemplateName 'ArticleLeft' -Folder '/Pages/folder'", - "Id": 160, "CommandName": "Add-PnPPublishingPage", + "Command": "Add-PnPPublishingPage -PageName 'OurNewPage' -Title 'Our new page' -PageTemplateName 'ArticleLeft' -Folder '/Pages/folder'", + "Id": 161, "Rank": 2 }, { - "Command": "Add-PnPPublishingPageLayout -Title 'Our custom page layout' -SourceFilePath 'customlayout.aspx' -Description 'A custom page layout' -AssociatedContentTypeID 0x01010901", - "Id": 161, "CommandName": "Add-PnPPublishingPageLayout", + "Command": "Add-PnPPublishingPageLayout -Title 'Our custom page layout' -SourceFilePath 'customlayout.aspx' -Description 'A custom page layout' -AssociatedContentTypeID 0x01010901", + "Id": 162, "Rank": 1 }, { - "Command": "Add-PnPRoleDefinition -RoleName \"CustomPerm\"", - "Id": 162, "CommandName": "Add-PnPRoleDefinition", + "Command": "Add-PnPRoleDefinition -RoleName \"CustomPerm\"", + "Id": 163, "Rank": 1 }, { - "Command": "Add-PnPRoleDefinition -RoleName \"NoDelete\" -Clone \"Contribute\" -Exclude DeleteListItems", - "Id": 163, "CommandName": "Add-PnPRoleDefinition", + "Command": "Add-PnPRoleDefinition -RoleName \"NoDelete\" -Clone \"Contribute\" -Exclude DeleteListItems", + "Id": 164, "Rank": 2 }, { - "Command": "Add-PnPRoleDefinition -RoleName \"AddOnly\" -Clone \"Contribute\" -Exclude DeleteListItems, EditListItems", - "Id": 164, "CommandName": "Add-PnPRoleDefinition", + "Command": "Add-PnPRoleDefinition -RoleName \"AddOnly\" -Clone \"Contribute\" -Exclude DeleteListItems, EditListItems", + "Id": 165, "Rank": 3 }, { - "Command": "Add-PnPSiteCollectionAdmin -Owners \"user@contoso.onmicrosoft.com\"", - "Id": 165, "CommandName": "Add-PnPSiteCollectionAdmin", + "Command": "Add-PnPSiteCollectionAdmin -Owners \"user@contoso.onmicrosoft.com\"", + "Id": 166, "Rank": 1 }, { - "Command": "Add-PnPSiteCollectionAdmin -Owners @(\"user1@contoso.onmicrosoft.com\", \"user2@contoso.onmicrosoft.com\")", - "Id": 166, "CommandName": "Add-PnPSiteCollectionAdmin", + "Command": "Add-PnPSiteCollectionAdmin -Owners @(\"user1@contoso.onmicrosoft.com\", \"user2@contoso.onmicrosoft.com\")", + "Id": 167, "Rank": 2 }, { - "Command": "Add-PnPSiteCollectionAdmin -PrimarySiteCollectionAdmin \"user@contoso.onmicrosoft.com\"", - "Id": 167, "CommandName": "Add-PnPSiteCollectionAdmin", + "Command": "Add-PnPSiteCollectionAdmin -PrimarySiteCollectionAdmin \"user@contoso.onmicrosoft.com\"", + "Id": 168, "Rank": 3 }, { - "Command": "Add-PnPSiteCollectionAppCatalog", - "Id": 168, "CommandName": "Add-PnPSiteCollectionAppCatalog", + "Command": "Add-PnPSiteCollectionAppCatalog", + "Id": 169, "Rank": 1 }, { - "Command": "Add-PnPSiteCollectionAppCatalog -Site \"https://contoso.sharepoint.com/sites/FinanceTeamsite\"", - "Id": 169, "CommandName": "Add-PnPSiteCollectionAppCatalog", + "Command": "Add-PnPSiteCollectionAppCatalog -Site \"https://contoso.sharepoint.com/sites/FinanceTeamsite\"", + "Id": 170, "Rank": 2 }, { - "Command": "Add-PnPSiteDesign -Title \"My Company Design\" -SiteScriptIds \"e84dcb46-3ab9-4456-a136-66fc6ae3d3c5\",\"6def687f-0e08-4f1e-999c-791f3af9a600\" -Description \"My description\" -WebTemplate TeamSite", - "Id": 170, "CommandName": "Add-PnPSiteDesign", + "Command": "Add-PnPSiteDesign -Title \"My Company Design\" -SiteScriptIds \"e84dcb46-3ab9-4456-a136-66fc6ae3d3c5\",\"6def687f-0e08-4f1e-999c-791f3af9a600\" -Description \"My description\" -WebTemplate TeamSite", + "Id": 171, "Rank": 1 }, { - "Command": "Add-PnPSiteDesign -Title \"My Company Design\" -SiteScriptIds \"e84dcb46-3ab9-4456-a136-66fc6ae3d3c5\",\"6def687f-0e08-4f1e-999c-791f3af9a600\" -Description \"My description\" -WebTemplate TeamSite -ThumbnailUrl https://contoso.sharepoint.com/sites/templates/siteassets/logo.png", - "Id": 171, "CommandName": "Add-PnPSiteDesign", + "Command": "Add-PnPSiteDesign -Title \"My Company Design\" -SiteScriptIds \"e84dcb46-3ab9-4456-a136-66fc6ae3d3c5\",\"6def687f-0e08-4f1e-999c-791f3af9a600\" -Description \"My description\" -WebTemplate TeamSite -ThumbnailUrl https://contoso.sharepoint.com/sites/templates/siteassets/logo.png", + "Id": 172, "Rank": 2 }, { - "Command": "Add-PnPSiteDesign -Title \"My Company Design\" -SiteScriptIds \"e84dcb46-3ab9-4456-a136-66fc6ae3d3c5\",\"6def687f-0e08-4f1e-999c-791f3af9a600\" -Description \"My description\" -WebTemplate TeamSite -ThumbnailUrl \"https://contoso.sharepoint.com/sites/templates/my images/logo.png\"", - "Id": 172, "CommandName": "Add-PnPSiteDesign", + "Command": "Add-PnPSiteDesign -Title \"My Company Design\" -SiteScriptIds \"e84dcb46-3ab9-4456-a136-66fc6ae3d3c5\",\"6def687f-0e08-4f1e-999c-791f3af9a600\" -Description \"My description\" -WebTemplate TeamSite -ThumbnailUrl \"https://contoso.sharepoint.com/sites/templates/my images/logo.png\"", + "Id": 173, "Rank": 3 }, { - "Command": "Add-PnPSiteDesignFromWeb -Title \"My Company Design\" -Description \"My description\" -WebTemplate TeamSite -IncludeAll", - "Id": 173, "CommandName": "Add-PnPSiteDesignFromWeb", + "Command": "Add-PnPSiteDesignFromWeb -Title \"My Company Design\" -Description \"My description\" -WebTemplate TeamSite -IncludeAll", + "Id": 174, "Rank": 1 }, { - "Command": "Add-PnPSiteDesignFromWeb -Title \"My Company Design\" -Description \"My description\" -WebTemplate TeamSite -IncludeAll -Lists (\"/lists/Issue list\", \"Shared Documents)", - "Id": 174, "CommandName": "Add-PnPSiteDesignFromWeb", + "Command": "Add-PnPSiteDesignFromWeb -Title \"My Company Design\" -Description \"My description\" -WebTemplate TeamSite -IncludeAll -Lists (\"/lists/Issue list\", \"Shared Documents)", + "Id": 175, "Rank": 2 }, { - "Command": "Add-PnPSiteDesignFromWeb -Title \"My Company Design\" -Description \"My description\" -WebTemplate TeamSite -Lists \"/lists/Issue list\" -ThumbnailUrl https://contoso.sharepoint.com/SiteAssets/logo.png", - "Id": 175, "CommandName": "Add-PnPSiteDesignFromWeb", + "Command": "Add-PnPSiteDesignFromWeb -Title \"My Company Design\" -Description \"My description\" -WebTemplate TeamSite -Lists \"/lists/Issue list\" -ThumbnailUrl https://contoso.sharepoint.com/SiteAssets/logo.png", + "Id": 176, "Rank": 3 }, { - "Command": "Add-PnPSiteDesignTask -SiteDesignId 501z8c32-4147-44d4-8607-26c2f67cae82", - "Id": 176, "CommandName": "Add-PnPSiteDesignTask", + "Command": "Add-PnPSiteDesignTask -SiteDesignId 501z8c32-4147-44d4-8607-26c2f67cae82", + "Id": 177, "Rank": 1 }, { - "Command": "Add-PnPSiteDesignTask -SiteDesignId 501z8c32-4147-44d4-8607-26c2f67cae82 -WebUrl \"https://contoso.sharepoint.com/sites/project\"", - "Id": 177, "CommandName": "Add-PnPSiteDesignTask", + "Command": "Add-PnPSiteDesignTask -SiteDesignId 501z8c32-4147-44d4-8607-26c2f67cae82 -WebUrl \"https://contoso.sharepoint.com/sites/project\"", + "Id": 178, "Rank": 2 }, { - "Command": "Add-PnPSiteScript -Title \"My Site Script\" -Description \"A more detailed description\" -Content $script", - "Id": 178, "CommandName": "Add-PnPSiteScript", + "Command": "Add-PnPSiteScript -Title \"My Site Script\" -Description \"A more detailed description\" -Content $script", + "Id": 179, "Rank": 1 }, { - "Command": "Add-PnPSiteScriptPackage -Title \"My Site Script Package\" -Description \"A more detailed description\" -ContentPath \"c:\\package.zip\"", - "Id": 179, "CommandName": "Add-PnPSiteScriptPackage", + "Command": "Add-PnPSiteScriptPackage -Title \"My Site Script Package\" -Description \"A more detailed description\" -ContentPath \"c:\\package.zip\"", + "Id": 180, "Rank": 1 }, { - "Command": "Add-PnPSiteTemplate -TenantTemplate $tenanttemplate -SiteTemplate $sitetemplate", - "Id": 180, "CommandName": "Add-PnPSiteTemplate", + "Command": "Add-PnPSiteTemplate -TenantTemplate $tenanttemplate -SiteTemplate $sitetemplate", + "Id": 181, "Rank": 1 }, { - "Command": "Add-PnPStoredCredential -Name \"https://tenant.sharepoint.com\" -Username yourname@tenant.onmicrosoft.com", - "Id": 181, "CommandName": "Add-PnPStoredCredential", + "Command": "Add-PnPStoredCredential -Name \"https://tenant.sharepoint.com\" -Username yourname@tenant.onmicrosoft.com", + "Id": 182, "Rank": 1 }, { - "Command": "Add-PnPStoredCredential -Name \"https://tenant.sharepoint.com\" -Username yourname@tenant.onmicrosoft.com -Password (ConvertTo-SecureString -String \"YourPassword\" -AsPlainText -Force)", - "Id": 182, "CommandName": "Add-PnPStoredCredential", + "Command": "Add-PnPStoredCredential -Name \"https://tenant.sharepoint.com\" -Username yourname@tenant.onmicrosoft.com -Password (ConvertTo-SecureString -String \"YourPassword\" -AsPlainText -Force)", + "Id": 183, "Rank": 2 }, { - "Command": "Add-PnPStoredCredential -Name \"https://tenant.sharepoint.com\" -Username yourname@tenant.onmicrosoft.com -Password (ConvertTo-SecureString -String \"YourPassword\" -AsPlainText -Force)\r ; Connect-PnPOnline -Url \"https://tenant.sharepoint.com/sites/mydemosite\"", - "Id": 183, "CommandName": "Add-PnPStoredCredential", + "Command": "Add-PnPStoredCredential -Name \"https://tenant.sharepoint.com\" -Username yourname@tenant.onmicrosoft.com -Password (ConvertTo-SecureString -String \"YourPassword\" -AsPlainText -Force)\r ; Connect-PnPOnline -Url \"https://tenant.sharepoint.com/sites/mydemosite\"", + "Id": 184, "Rank": 3 }, { - "Command": "Add-PnPTaxonomyField -DisplayName \"Test\" -InternalName \"Test\" -TermSetPath \"TestTermGroup|TestTermSet\"", - "Id": 184, "CommandName": "Add-PnPTaxonomyField", + "Command": "Add-PnPTaxonomyField -DisplayName \"Test\" -InternalName \"Test\" -TermSetPath \"TestTermGroup|TestTermSet\"", + "Id": 185, "Rank": 1 }, { - "Command": "Add-PnPTaxonomyField -DisplayName \"Test\" -InternalName \"Test\" -TaxonomyItemId \"0e5fe3c6-3e6a-4d25-9f48-82a655f15992\"", - "Id": 185, "CommandName": "Add-PnPTaxonomyField", + "Command": "Add-PnPTaxonomyField -DisplayName \"Test\" -InternalName \"Test\" -TaxonomyItemId \"0e5fe3c6-3e6a-4d25-9f48-82a655f15992\"", + "Id": 186, "Rank": 2 }, { - "Command": "Add-PnPTeamsChannel -Team 4efdf392-8225-4763-9e7f-4edeb7f721aa -DisplayName \"My Channel\" -IsFavoriteByDefault $true", - "Id": 186, "CommandName": "Add-PnPTeamsChannel", + "Command": "Add-PnPTeamsChannel -Team 4efdf392-8225-4763-9e7f-4edeb7f721aa -DisplayName \"My Channel\" -IsFavoriteByDefault $true", + "Id": 187, "Rank": 1 }, { - "Command": "Add-PnPTeamsChannel -Team \"My Team\" -DisplayName \"My standard channel\"", - "Id": 187, "CommandName": "Add-PnPTeamsChannel", + "Command": "Add-PnPTeamsChannel -Team \"My Team\" -DisplayName \"My standard channel\"", + "Id": 188, "Rank": 2 }, { - "Command": "Add-PnPTeamsChannel -Team \"HR\" -DisplayName \"My private channel\" -ChannelType Private -OwnerUPN user1@domain.com", - "Id": 188, "CommandName": "Add-PnPTeamsChannel", + "Command": "Add-PnPTeamsChannel -Team \"HR\" -DisplayName \"My private channel\" -ChannelType Private -OwnerUPN user1@domain.com", + "Id": 189, "Rank": 3 }, { - "Command": "Add-PnPTeamsChannel -Team \"Logistical Department\" -DisplayName \"My shared channel\" -ChannelType Shared -OwnerUPN user1@domain.com", - "Id": 189, "CommandName": "Add-PnPTeamsChannel", + "Command": "Add-PnPTeamsChannel -Team \"Logistical Department\" -DisplayName \"My shared channel\" -ChannelType Shared -OwnerUPN user1@domain.com", + "Id": 190, "Rank": 4 }, { - "Command": "Add-PnPTeamsChannelUser -Team 4efdf392-8225-4763-9e7f-4edeb7f721aa -Channel \"19:796d063b63e34497aeaf092c8fb9b44e@thread.skype\" -User john@doe.com -Role Owner", - "Id": 190, "CommandName": "Add-PnpTeamsChannelUser", + "Command": "Add-PnPTeamsChannelUser -Team 4efdf392-8225-4763-9e7f-4edeb7f721aa -Channel \"19:796d063b63e34497aeaf092c8fb9b44e@thread.skype\" -User john@doe.com -Role Owner", + "Id": 191, "Rank": 1 }, { - "Command": "Add-PnPTeamsChannelUser -Team \"My Team\" -Channel \"My Private Channel\" -User john@doe.com -Role Member", - "Id": 191, "CommandName": "Add-PnpTeamsChannelUser", + "Command": "Add-PnPTeamsChannelUser -Team \"My Team\" -Channel \"My Private Channel\" -User john@doe.com -Role Member", + "Id": 192, "Rank": 2 }, { - "Command": "Add-PnPTeamsTab -Team \"My Team\" -Channel \"My Channel\" -DisplayName \"My Tab Name\" -Type WebSite -ContentUrl \"https://aka.ms/m365pnp\"", - "Id": 192, "CommandName": "Add-PnPTeamsTab", + "Command": "Add-PnPTeamsTab -Team \"My Team\" -Channel \"My Channel\" -DisplayName \"My Tab Name\" -Type WebSite -ContentUrl \"https://aka.ms/m365pnp\"", + "Id": 193, "Rank": 1 }, { - "Command": "Add-PnPTeamsTab -Team \"My Team\" -Channel \"My Channel\" -DisplayName \"My Tab Name\" -Type PDF -ContentUrl \"https://contoso.sharepoint.com/sites/Marketing/Shared Documents/General/MyFile.pdf\" -EntityId \"null\"", - "Id": 193, "CommandName": "Add-PnPTeamsTab", + "Command": "Add-PnPTeamsTab -Team \"My Team\" -Channel \"My Channel\" -DisplayName \"My Tab Name\" -Type PDF -ContentUrl \"https://contoso.sharepoint.com/sites/Marketing/Shared Documents/General/MyFile.pdf\" -EntityId \"null\"", + "Id": 194, "Rank": 2 }, { - "Command": "Add-PnPTeamsTab -Team \"My Team\" -Channel \"My Channel\" -DisplayName \"My Tab Name\" -Type SharePointPageAndList -WebSiteUrl \"https://contoso.sharepoint.com/sites/Marketing/SitePages/Home.aspx\"", - "Id": 194, "CommandName": "Add-PnPTeamsTab", + "Command": "Add-PnPTeamsTab -Team \"My Team\" -Channel \"My Channel\" -DisplayName \"My Tab Name\" -Type SharePointPageAndList -WebSiteUrl \"https://contoso.sharepoint.com/sites/Marketing/SitePages/Home.aspx\"", + "Id": 195, "Rank": 3 }, { - "Command": "Add-PnPTeamsTab -Team \"My Team\" -Channel \"My Channel\" -DisplayName \"My Excel Tab\" -Type Excel -ContentUrl \"https://contoso.sharepoint.com/sites/Marketing/Shared Documents/My Excel File.csv\" -EntityId 6", - "Id": 195, "CommandName": "Add-PnPTeamsTab", + "Command": "Add-PnPTeamsTab -Team \"My Team\" -Channel \"My Channel\" -DisplayName \"My Excel Tab\" -Type Excel -ContentUrl \"https://contoso.sharepoint.com/sites/Marketing/Shared Documents/My Excel File.csv\" -EntityId 6", + "Id": 196, "Rank": 4 }, { - "Command": "Add-PnPTeamsTeam", - "Id": 196, "CommandName": "Add-PnPTeamsTeam", + "Command": "Add-PnPTeamsTeam", + "Id": 197, "Rank": 1 }, { - "Command": "Add-PnPTeamsUser -Team MyTeam -User john@doe.com -Role Owner", - "Id": 197, "CommandName": "Add-PnPTeamsUser", + "Command": "Add-PnPTeamsUser -Team MyTeam -User john@doe.com -Role Owner", + "Id": 198, "Rank": 1 }, { - "Command": "Add-PnPTeamsUser -Team MyTeam -User john@doe.com -Role Member", - "Id": 198, "CommandName": "Add-PnPTeamsUser", + "Command": "Add-PnPTeamsUser -Team MyTeam -User john@doe.com -Role Member", + "Id": 199, "Rank": 2 }, { - "Command": "Add-PnPTeamsUser -Team MyTeam -Users \"john@doe.com\",\"jane@doe.com\" -Role Member", - "Id": 199, "CommandName": "Add-PnPTeamsUser", + "Command": "Add-PnPTeamsUser -Team MyTeam -Users \"john@doe.com\",\"jane@doe.com\" -Role Member", + "Id": 200, "Rank": 3 }, { - "Command": "Add-PnPTeamsUser -Team MyTeam -User \"jane@doe.com\" -Role Member -Channel Private", - "Id": 200, "CommandName": "Add-PnPTeamsUser", + "Command": "Add-PnPTeamsUser -Team MyTeam -User \"jane@doe.com\" -Role Member -Channel Private", + "Id": 201, "Rank": 4 }, { - "Command": "Add-PnPTenantCdnOrigin -OriginUrl /sites/site/subfolder -CdnType Public", - "Id": 201, "CommandName": "Add-PnPTenantCdnOrigin", + "Command": "Add-PnPTenantCdnOrigin -OriginUrl /sites/site/subfolder -CdnType Public", + "Id": 202, "Rank": 1 }, { - "Command": "Add-PnPTenantSequence -Template $mytemplate -Sequence $mysequence", - "Id": 202, "CommandName": "Add-PnPTenantSequence", + "Command": "Add-PnPTenantSequence -Template $mytemplate -Sequence $mysequence", + "Id": 203, "Rank": 1 }, { - "Command": "Add-PnPTenantSequenceSite -Site $myteamsite -Sequence $mysequence", - "Id": 203, "CommandName": "Add-PnPTenantSequenceSite", + "Command": "Add-PnPTenantSequenceSite -Site $myteamsite -Sequence $mysequence", + "Id": 204, "Rank": 1 }, { - "Command": "Add-PnPTenantSequenceSubSite -Site $mysite -SubSite $mysubsite", - "Id": 204, "CommandName": "Add-PnPTenantSequenceSubSite", + "Command": "Add-PnPTenantSequenceSubSite -Site $mysite -SubSite $mysubsite", + "Id": 205, "Rank": 1 }, { - "Command": "Add-PnPTermToTerm -ParentTermId 2d1f298b-804a-4a05-96dc-29b667adec62 -Name SubTerm -CustomProperties @{\"Department\"=\"Marketing\"}", - "Id": 205, "CommandName": "Add-PnPTermToTerm", + "Command": "Add-PnPTermToTerm -ParentTermId 2d1f298b-804a-4a05-96dc-29b667adec62 -Name SubTerm -CustomProperties @{\"Department\"=\"Marketing\"}", + "Id": 206, "Rank": 1 }, { - "Command": "Add-PnPView -List \"Demo List\" -Title \"Demo View\" -Fields \"Title\",\"Address\"", - "Id": 206, "CommandName": "Add-PnPView", + "Command": "Add-PnPView -List \"Demo List\" -Title \"Demo View\" -Fields \"Title\",\"Address\"", + "Id": 207, "Rank": 1 }, { - "Command": "Add-PnPView -List \"Demo List\" -Title \"Demo View\" -Fields \"Title\",\"Address\" -Paged -RowLimit 100", - "Id": 207, "CommandName": "Add-PnPView", + "Command": "Add-PnPView -List \"Demo List\" -Title \"Demo View\" -Fields \"Title\",\"Address\" -Paged -RowLimit 100", + "Id": 208, "Rank": 2 }, { + "CommandName": "Add-PnPView", "Command": "Add-PnPView -List \"Demo List\" -Title \"Demo View\" -Fields \"Title\",\"Address\" -Aggregations \"\"", - "Id": 208, - "CommandName": "Add-PnPView", + "Id": 209, "Rank": 3 }, { - "Command": "Add-PnPVivaConnectionsDashboardACE -Identity CardDesigner -Order 3 -Title \"Hello there\" -PropertiesJSON $myProperties -CardSize Large -Description \"ACE description\" -Iconproperty \"https://cdn.hubblecontent.osi.office.net/m365content/publish/002f8bf9-b8ee-4689-ae97-e411b756099d/691108002.jpg\"", - "Id": 209, "CommandName": "Add-PnPVivaConnectionsDashboardACE", + "Command": "Add-PnPVivaConnectionsDashboardACE -Identity CardDesigner -Order 3 -Title \"Hello there\" -PropertiesJSON $myProperties -CardSize Large -Description \"ACE description\" -Iconproperty \"https://cdn.hubblecontent.osi.office.net/m365content/publish/002f8bf9-b8ee-4689-ae97-e411b756099d/691108002.jpg\"", + "Id": 210, "Rank": 1 }, { - "Command": "Add-PnPVivaConnectionsDashboardACE -Identity ThirdPartyApp -Order 1 -Title \"Hello there\" -PropertiesJSON $myProperties -CardSize Medium -Description \"ACE with description\" -Iconproperty \"https://cdn.hubblecontent.osi.office.net/m365content/publish/002f8bf9-b8ee-4689-ae97-e411b756099d/691108002.jpg\"", - "Id": 210, "CommandName": "Add-PnPVivaConnectionsDashboardACE", + "Command": "Add-PnPVivaConnectionsDashboardACE -Identity ThirdPartyApp -Order 1 -Title \"Hello there\" -PropertiesJSON $myProperties -CardSize Medium -Description \"ACE with description\" -Iconproperty \"https://cdn.hubblecontent.osi.office.net/m365content/publish/002f8bf9-b8ee-4689-ae97-e411b756099d/691108002.jpg\"", + "Id": 211, "Rank": 2 }, { - "Command": "Add-PnPVivaConnectionsDashboardACE -Identity AssignedTasks -Order 2 -Title \"Tasks\" -PropertiesJSON $myProperties -CardSize Medium -Description \"My Assigned tasks\" -Iconproperty \"https://cdn.hubblecontent.osi.office.net/m365content/publish/002f8bf9-b8ee-4689-ae97-e411b756099d/691108002.jpg\"", - "Id": 211, "CommandName": "Add-PnPVivaConnectionsDashboardACE", + "Command": "Add-PnPVivaConnectionsDashboardACE -Identity AssignedTasks -Order 2 -Title \"Tasks\" -PropertiesJSON $myProperties -CardSize Medium -Description \"My Assigned tasks\" -Iconproperty \"https://cdn.hubblecontent.osi.office.net/m365content/publish/002f8bf9-b8ee-4689-ae97-e411b756099d/691108002.jpg\"", + "Id": 212, "Rank": 3 }, { - "Command": "Add-PnPWebhookSubscription -List MyList -NotificationUrl https://my-func.azurewebsites.net/webhook", - "Id": 212, "CommandName": "Add-PnPWebhookSubscription", + "Command": "Add-PnPWebhookSubscription -List MyList -NotificationUrl https://my-func.azurewebsites.net/webhook", + "Id": 213, "Rank": 1 }, { - "Command": "Add-PnPWebhookSubscription -List MyList -NotificationUrl https://my-func.azurewebsites.net/webhook -ExpirationDate \"2017-09-01\"", - "Id": 213, "CommandName": "Add-PnPWebhookSubscription", + "Command": "Add-PnPWebhookSubscription -List MyList -NotificationUrl https://my-func.azurewebsites.net/webhook -ExpirationDate \"2017-09-01\"", + "Id": 214, "Rank": 2 }, { - "Command": "Add-PnPWebhookSubscription -List MyList -NotificationUrl https://my-func.azurewebsites.net/webhook -ExpirationDate \"2017-09-01\" -ClientState \"Hello State!\"", - "Id": 214, "CommandName": "Add-PnPWebhookSubscription", + "Command": "Add-PnPWebhookSubscription -List MyList -NotificationUrl https://my-func.azurewebsites.net/webhook -ExpirationDate \"2017-09-01\" -ClientState \"Hello State!\"", + "Id": 215, "Rank": 3 }, { - "Command": "Add-PnPWebPartToWebPartPage -ServerRelativePageUrl \"/sites/demo/sitepages/home.aspx\" -Path \"c:\\myfiles\\listview.webpart\" -ZoneId \"Header\" -ZoneIndex 1", - "Id": 215, "CommandName": "Add-PnPWebPartToWebPartPage", + "Command": "Add-PnPWebPartToWebPartPage -ServerRelativePageUrl \"/sites/demo/sitepages/home.aspx\" -Path \"c:\\myfiles\\listview.webpart\" -ZoneId \"Header\" -ZoneIndex 1", + "Id": 216, "Rank": 1 }, { - "Command": "Add-PnPWebPartToWebPartPage -ServerRelativePageUrl \"/sites/demo/sitepages/home.aspx\" -XML $webpart -ZoneId \"Header\" -ZoneIndex 1", - "Id": 216, "CommandName": "Add-PnPWebPartToWebPartPage", + "Command": "Add-PnPWebPartToWebPartPage -ServerRelativePageUrl \"/sites/demo/sitepages/home.aspx\" -XML $webpart -ZoneId \"Header\" -ZoneIndex 1", + "Id": 217, "Rank": 2 }, { - "Command": "Add-PnPWebPartToWikiPage -ServerRelativePageUrl \"/sites/demo/sitepages/home.aspx\" -Path \"c:\\myfiles\\listview.webpart\" -Row 1 -Column 1", - "Id": 217, "CommandName": "Add-PnPWebPartToWikiPage", + "Command": "Add-PnPWebPartToWikiPage -ServerRelativePageUrl \"/sites/demo/sitepages/home.aspx\" -Path \"c:\\myfiles\\listview.webpart\" -Row 1 -Column 1", + "Id": 218, "Rank": 1 }, { - "Command": "Add-PnPWebPartToWikiPage -ServerRelativePageUrl \"/sites/demo/sitepages/home.aspx\" -XML $webpart -Row 1 -Column 1", - "Id": 218, "CommandName": "Add-PnPWebPartToWikiPage", + "Command": "Add-PnPWebPartToWikiPage -ServerRelativePageUrl \"/sites/demo/sitepages/home.aspx\" -XML $webpart -Row 1 -Column 1", + "Id": 219, "Rank": 2 }, { - "Command": "Add-PnPWikiPage -PageUrl '/sites/demo1/pages/wikipage.aspx' -Content 'New WikiPage'", - "Id": 219, "CommandName": "Add-PnPWikiPage", + "Command": "Add-PnPWikiPage -PageUrl '/sites/demo1/pages/wikipage.aspx' -Content 'New WikiPage'", + "Id": 220, "Rank": 1 }, { - "Command": "Clear-PnPAzureADGroupMember -Identity \"Project Team\"", - "Id": 220, "CommandName": "Clear-PnPAzureADGroupMember", + "Command": "Clear-PnPAzureADGroupMember -Identity \"Project Team\"", + "Id": 221, "Rank": 1 }, { - "Command": "Clear-PnPAzureADGroupOwner -Identity \"Project Team\"", - "Id": 221, "CommandName": "Clear-PnPAzureADGroupOwner", + "Command": "Clear-PnPAzureADGroupOwner -Identity \"Project Team\"", + "Id": 222, "Rank": 1 }, { - "Command": "Clear-PnPDefaultColumnValues -List Documents -Field MyField", - "Id": 222, "CommandName": "Clear-PnPDefaultColumnValues", + "Command": "Clear-PnPDefaultColumnValues -List Documents -Field MyField", + "Id": 223, "Rank": 1 }, { - "Command": "Clear-PnPDefaultColumnValues -List Documents -Field MyField -Folder A", - "Id": 223, "CommandName": "Clear-PnPDefaultColumnValues", + "Command": "Clear-PnPDefaultColumnValues -List Documents -Field MyField -Folder A", + "Id": 224, "Rank": 2 }, { - "Command": "Clear-PnPListItemAsRecord -List \"Documents\" -Identity 4", - "Id": 224, "CommandName": "Clear-PnPListItemAsRecord", + "Command": "Clear-PnPListItemAsRecord -List \"Documents\" -Identity 4", + "Id": 225, "Rank": 1 }, { - "Command": "Clear-PnPMicrosoft365GroupMember -Identity \"Project Team\"", - "Id": 225, "CommandName": "Clear-PnPMicrosoft365GroupMember", + "Command": "Clear-PnPMicrosoft365GroupMember -Identity \"Project Team\"", + "Id": 226, "Rank": 1 }, { - "Command": "Clear-PnPMicrosoft365GroupOwner -Identity \"Project Team\"", - "Id": 226, "CommandName": "Clear-PnPMicrosoft365GroupOwner", + "Command": "Clear-PnPMicrosoft365GroupOwner -Identity \"Project Team\"", + "Id": 227, "Rank": 1 }, { - "Command": "Clear-PnPRecycleBinItem -Identity 72e4d749-d750-4989-b727-523d6726e442", - "Id": 227, "CommandName": "Clear-PnpRecycleBinItem", + "Command": "Clear-PnPRecycleBinItem -Identity 72e4d749-d750-4989-b727-523d6726e442", + "Id": 228, "Rank": 1 }, { - "Command": "Clear-PnPRecycleBinItem -Identity $item -Force", - "Id": 228, "CommandName": "Clear-PnpRecycleBinItem", + "Command": "Clear-PnPRecycleBinItem -Identity $item -Force", + "Id": 229, "Rank": 2 }, { - "Command": "Clear-PnPRecycleBinItem -All -RowLimit 10000", - "Id": 229, "CommandName": "Clear-PnpRecycleBinItem", + "Command": "Clear-PnPRecycleBinItem -All -RowLimit 10000", + "Id": 230, "Rank": 3 }, { - "Command": "Clear-PnPTenantAppCatalogUrl", - "Id": 230, "CommandName": "Clear-PnPTenantAppCatalogUrl", + "Command": "Clear-PnPTenantAppCatalogUrl", + "Id": 231, "Rank": 1 }, { - "Command": "Clear-PnPTenantRecycleBinItem -Url \"https://tenant.sharepoint.com/sites/contoso\"", - "Id": 231, "CommandName": "Clear-PnPTenantRecycleBinItem", + "Command": "Clear-PnPTenantRecycleBinItem -Url \"https://tenant.sharepoint.com/sites/contoso\"", + "Id": 232, "Rank": 1 }, { - "Command": "Clear-PnPTenantRecycleBinItem -Url \"https://tenant.sharepoint.com/sites/contoso\" -Wait", - "Id": 232, "CommandName": "Clear-PnPTenantRecycleBinItem", + "Command": "Clear-PnPTenantRecycleBinItem -Url \"https://tenant.sharepoint.com/sites/contoso\" -Wait", + "Id": 233, "Rank": 2 }, { - "Command": "Connect-PnPOnline -Url contoso.sharepoint.com -AzureEnvironment Custom -MicrosoftGraphEndPoint \"custom.graph.microsoft.com\" -AzureADLoginEndPoint \"https://custom.login.microsoftonline.com\"", - "Id": 233, "CommandName": "Connect-PnPOnline", + "Command": "Connect-PnPOnline -Url contoso.sharepoint.com -AzureEnvironment Custom -MicrosoftGraphEndPoint \"custom.graph.microsoft.com\" -AzureADLoginEndPoint \"https://custom.login.microsoftonline.com\"", + "Id": 234, "Rank": 1 }, { - "Command": "Convert-PnPFile -Url \"/sites/demo/Shared Documents/Document.docx\" -AsMemoryStream", - "Id": 234, "CommandName": "Convert-PnPFile", + "Command": "Convert-PnPFile -Url \"/sites/demo/Shared Documents/Document.docx\" -AsMemoryStream", + "Id": 235, "Rank": 1 }, { - "Command": "Convert-PnPFile -Url \"/sites/demo/Shared Documents/Document.docx\"", - "Id": 235, "CommandName": "Convert-PnPFile", + "Command": "Convert-PnPFile -Url \"/sites/demo/Shared Documents/Document.docx\"", + "Id": 236, "Rank": 2 }, { - "Command": "Convert-PnPFile -Url \"/sites/demo/Shared Documents/Document.docx\" -Path \"C:\\Temp\"", - "Id": 236, "CommandName": "Convert-PnPFile", + "Command": "Convert-PnPFile -Url \"/sites/demo/Shared Documents/Document.docx\" -Path \"C:\\Temp\"", + "Id": 237, "Rank": 3 }, { - "Command": "Convert-PnPFile -Url \"/sites/demo/Shared Documents/Document.docx\" -Path \"C:\\Temp\" -Force", - "Id": 237, "CommandName": "Convert-PnPFile", + "Command": "Convert-PnPFile -Url \"/sites/demo/Shared Documents/Document.docx\" -Path \"C:\\Temp\" -Force", + "Id": 238, "Rank": 4 }, { - "Command": "Convert-PnPFile -Url \"/sites/demo/Shared Documents/Test/Book.xlsx\" -Folder \"/sites/demo/Shared Documents/Archive\"", - "Id": 238, "CommandName": "Convert-PnPFile", + "Command": "Convert-PnPFile -Url \"/sites/demo/Shared Documents/Test/Book.xlsx\" -Folder \"/sites/demo/Shared Documents/Archive\"", + "Id": 239, "Rank": 5 }, { - "Command": "Convert-PnPFile -Url \"/sites/demo/Shared Documents/Test/Book.png\" -ConvertToFormat Jpg -Folder \"/sites/demo/Shared Documents/Archive\"", - "Id": 239, "CommandName": "Convert-PnPFile", + "Command": "Convert-PnPFile -Url \"/sites/demo/Shared Documents/Test/Book.png\" -ConvertToFormat Jpg -Folder \"/sites/demo/Shared Documents/Archive\"", + "Id": 240, "Rank": 6 }, { - "Command": "Convert-PnPFolderToSiteTemplate -Out template.pnp", - "Id": 240, "CommandName": "Convert-PnPFolderToSiteTemplate", + "Command": "Convert-PnPFolderToSiteTemplate -Out template.pnp", + "Id": 241, "Rank": 1 }, { - "Command": "Convert-PnPFolderToSiteTemplate -Out template.pnp -Folder c:\\temp", - "Id": 241, "CommandName": "Convert-PnPFolderToSiteTemplate", + "Command": "Convert-PnPFolderToSiteTemplate -Out template.pnp -Folder c:\\temp", + "Id": 242, "Rank": 2 }, { - "Command": "Convert-PnPSiteTemplate -Path template.xml", - "Id": 242, "CommandName": "Convert-PnPSiteTemplate", + "Command": "Convert-PnPSiteTemplate -Path template.xml", + "Id": 243, "Rank": 1 }, { - "Command": "Convert-PnPSiteTemplate -Path template.xml -Out newtemplate.xml", - "Id": 243, "CommandName": "Convert-PnPSiteTemplate", + "Command": "Convert-PnPSiteTemplate -Path template.xml -Out newtemplate.xml", + "Id": 244, "Rank": 2 }, { - "Command": "Convert-PnPSiteTemplate -Path template.xml -Out newtemplate.xml -ToSchema V201512", - "Id": 244, "CommandName": "Convert-PnPSiteTemplate", + "Command": "Convert-PnPSiteTemplate -Path template.xml -Out newtemplate.xml -ToSchema V201512", + "Id": 245, "Rank": 3 }, { - "Command": "Convert-PnPSiteTemplateToMarkdown -TemplatePath ./mytemplate.xml", - "Id": 245, "CommandName": "Convert-PnPSiteTemplateToMarkdown", + "Command": "Convert-PnPSiteTemplateToMarkdown -TemplatePath ./mytemplate.xml", + "Id": 246, "Rank": 1 }, { - "Command": "Convert-PnPSiteTemplateToMarkdown -TemplatePath ./mytemplate.xml -Out ./myreport.md", - "Id": 246, "CommandName": "Convert-PnPSiteTemplateToMarkdown", + "Command": "Convert-PnPSiteTemplateToMarkdown -TemplatePath ./mytemplate.xml -Out ./myreport.md", + "Id": 247, "Rank": 2 }, { - "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -Overwrite", - "Id": 247, "CommandName": "ConvertTo-PnPPage", + "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -Overwrite", + "Id": 248, "Rank": 1 }, { - "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -Overwrite -WebPartMappingFile c:\\contoso\\webpartmapping.xml", - "Id": 248, "CommandName": "ConvertTo-PnPPage", + "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -Overwrite -WebPartMappingFile c:\\contoso\\webpartmapping.xml", + "Id": 249, "Rank": 2 }, { - "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -Overwrite -AddPageAcceptBanner", - "Id": 249, "CommandName": "ConvertTo-PnPPage", + "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -Overwrite -AddPageAcceptBanner", + "Id": 250, "Rank": 3 }, { - "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -Overwrite -CopyPageMetadata", - "Id": 250, "CommandName": "ConvertTo-PnPPage", + "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -Overwrite -CopyPageMetadata", + "Id": 251, "Rank": 4 }, { - "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -PublishingPage -Overwrite -TargetWebUrl \"https://contoso.sharepoint.com/sites/targetmodernsite\"", - "Id": 251, "CommandName": "ConvertTo-PnPPage", + "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -PublishingPage -Overwrite -TargetWebUrl \"https://contoso.sharepoint.com/sites/targetmodernsite\"", + "Id": 252, "Rank": 5 }, { - "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -PublishingPage -Overwrite -TargetConnection $target", - "Id": 252, "CommandName": "ConvertTo-PnPPage", + "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -PublishingPage -Overwrite -TargetConnection $target", + "Id": 253, "Rank": 6 }, { - "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -Library \"SiteAssets\" -Folder \"Folder1\" -Overwrite", - "Id": 253, "CommandName": "ConvertTo-PnPPage", + "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -Library \"SiteAssets\" -Folder \"Folder1\" -Overwrite", + "Id": 254, "Rank": 7 }, { - "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -Folder \"\" -Overwrite", - "Id": 254, "CommandName": "ConvertTo-PnPPage", + "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -Folder \"\" -Overwrite", + "Id": 255, "Rank": 8 }, { - "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -Overwrite -TargetWebUrl \"https://contoso.sharepoint.com/sites/targetmodernsite\"", - "Id": 255, "CommandName": "ConvertTo-PnPPage", + "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -Overwrite -TargetWebUrl \"https://contoso.sharepoint.com/sites/targetmodernsite\"", + "Id": 256, "Rank": 9 }, { - "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -LogType File -LogFolder c:\\temp -LogVerbose -Overwrite", - "Id": 256, "CommandName": "ConvertTo-PnPPage", + "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -LogType File -LogFolder c:\\temp -LogVerbose -Overwrite", + "Id": 257, "Rank": 10 }, { - "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -LogType SharePoint -LogSkipFlush", - "Id": 257, "CommandName": "ConvertTo-PnPPage", + "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -LogType SharePoint -LogSkipFlush", + "Id": 258, "Rank": 11 }, { - "Command": "ConvertTo-PnPPage -Identity \"My post title\" -BlogPage -LogType Console -Overwrite -TargetWebUrl \"https://contoso.sharepoint.com/sites/targetmodernsite\"", - "Id": 258, "CommandName": "ConvertTo-PnPPage", + "Command": "ConvertTo-PnPPage -Identity \"My post title\" -BlogPage -LogType Console -Overwrite -TargetWebUrl \"https://contoso.sharepoint.com/sites/targetmodernsite\"", + "Id": 259, "Rank": 12 }, { - "Command": "ConvertTo-PnPPage -Identity \"My post title\" -DelveBlogPage -LogType Console -Overwrite -TargetWebUrl \"https://contoso.sharepoint.com/sites/targetmodernsite\"", - "Id": 259, "CommandName": "ConvertTo-PnPPage", + "Command": "ConvertTo-PnPPage -Identity \"My post title\" -DelveBlogPage -LogType Console -Overwrite -TargetWebUrl \"https://contoso.sharepoint.com/sites/targetmodernsite\"", + "Id": 260, "Rank": 13 }, { - "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -PublishingPage -Overwrite -TargetConnection $target -UserMappingFile c:\\\\temp\\user_mapping_file.csv", - "Id": 260, "CommandName": "ConvertTo-PnPPage", + "Command": "ConvertTo-PnPPage -Identity \"somepage.aspx\" -PublishingPage -Overwrite -TargetConnection $target -UserMappingFile c:\\\\temp\\user_mapping_file.csv", + "Id": 261, "Rank": 14 }, { - "Command": "Copy-PnPFile -SourceUrl \"Shared Documents/MyProjectfiles\" -TargetUrl \"/sites/otherproject/Shared Documents\" -Overwrite", - "Id": 261, "CommandName": "Copy-PnPFile", + "Command": "Copy-PnPFile -SourceUrl \"Shared Documents/MyProjectfiles\" -TargetUrl \"/sites/otherproject/Shared Documents\" -Overwrite", + "Id": 262, "Rank": 1 }, { - "Command": "Copy-PnPFile -SourceUrl \"/sites/project/Shared Documents/company.docx\" -TargetUrl \"/sites/otherproject/Shared Documents\"", - "Id": 262, "CommandName": "Copy-PnPFile", + "Command": "Copy-PnPFile -SourceUrl \"/sites/project/Shared Documents/company.docx\" -TargetUrl \"/sites/otherproject/Shared Documents\"", + "Id": 263, "Rank": 2 }, { - "Command": "Copy-PnPFile -SourceUrl \"Shared Documents/company.docx\" -TargetUrl \"/sites/otherproject/Shared Documents\" -IgnoreVersionHistory", - "Id": 263, "CommandName": "Copy-PnPFile", + "Command": "Copy-PnPFile -SourceUrl \"Shared Documents/company.docx\" -TargetUrl \"/sites/otherproject/Shared Documents\" -IgnoreVersionHistory", + "Id": 264, "Rank": 3 }, { - "Command": "Copy-PnPFile -SourceUrl \"/sites/project/Shared Documents/Archive\" -TargetUrl \"/sites/otherproject/Shared Documents\" -Overwrite", - "Id": 264, "CommandName": "Copy-PnPFile", + "Command": "Copy-PnPFile -SourceUrl \"/sites/project/Shared Documents/Archive\" -TargetUrl \"/sites/otherproject/Shared Documents\" -Overwrite", + "Id": 265, "Rank": 4 }, { - "Command": "Copy-PnPFile -SourceUrl \"Documents/company.docx\" -TargetUrl \"Documents/company2.docx\"", - "Id": 265, "CommandName": "Copy-PnPFile", + "Command": "Copy-PnPFile -SourceUrl \"Documents/company.docx\" -TargetUrl \"Documents/company2.docx\"", + "Id": 266, "Rank": 5 }, { - "Command": "Copy-PnPFile -SourceUrl \"Shared Documents/company.docx\" -TargetUrl \"Shared Documents2/company.docx\"", - "Id": 266, "CommandName": "Copy-PnPFile", + "Command": "Copy-PnPFile -SourceUrl \"Shared Documents/company.docx\" -TargetUrl \"Shared Documents2/company.docx\"", + "Id": 267, "Rank": 6 }, { - "Command": "Copy-PnPFile -SourceUrl \"Shared DocuDocuments/company.docx\" -TargetUrl \"Subsite/Shared Documents\"", - "Id": 267, "CommandName": "Copy-PnPFile", + "Command": "Copy-PnPFile -SourceUrl \"Shared DocuDocuments/company.docx\" -TargetUrl \"Subsite/Shared Documents\"", + "Id": 268, "Rank": 7 }, { - "Command": "Copy-PnPFile -SourceUrl \"Shared Documents/company.docx\" -TargetUrl \"/sites/otherproject/Shared Documents\" -Overwrite", - "Id": 268, "CommandName": "Copy-PnPFile", + "Command": "Copy-PnPFile -SourceUrl \"Shared Documents/company.docx\" -TargetUrl \"/sites/otherproject/Shared Documents\" -Overwrite", + "Id": 269, "Rank": 8 }, { - "Command": "Copy-PnPFile -SourceUrl \"Shared Documents/MyDocs\" -TargetUrl \"/sites/otherproject/Documents\" -Overwrite", - "Id": 269, "CommandName": "Copy-PnPFile", + "Command": "Copy-PnPFile -SourceUrl \"Shared Documents/MyDocs\" -TargetUrl \"/sites/otherproject/Documents\" -Overwrite", + "Id": 270, "Rank": 9 }, { - "Command": "Copy-PnPFile -SourceUrl \"SubSite1/Documents/company.docx\" -TargetUrl \"SubSite2/Documents\"", - "Id": 270, "CommandName": "Copy-PnPFile", + "Command": "Copy-PnPFile -SourceUrl \"SubSite1/Documents/company.docx\" -TargetUrl \"SubSite2/Documents\"", + "Id": 271, "Rank": 10 }, { - "Command": "Copy-PnPFolder -SourceUrl \"Shared Documents/MyProjectfiles\" -TargetUrl \"/sites/otherproject/Shared Documents\" -Overwrite", - "Id": 271, "CommandName": "Copy-PnPFolder", + "Command": "Copy-PnPFolder -SourceUrl \"Shared Documents/MyProjectfiles\" -TargetUrl \"/sites/otherproject/Shared Documents\" -Overwrite", + "Id": 272, "Rank": 1 }, { + "CommandName": "Copy-PnPFolder", "Command": "Copy-PnPFolder -SourceUrl \"/sites/project/Shared Documents/company.docx\" -TargetUrl \"/sites/otherproject/Shared Documents\"", - "Id": 272, - "CommandName": "Copy-PnPFolder", + "Id": 273, "Rank": 2 }, { - "Command": "Copy-PnPFolder -SourceUrl \"Shared Documents/company.docx\" -TargetUrl \"/sites/otherproject/Shared Documents\" -IgnoreVersionHistory", - "Id": 273, "CommandName": "Copy-PnPFolder", + "Command": "Copy-PnPFolder -SourceUrl \"Shared Documents/company.docx\" -TargetUrl \"/sites/otherproject/Shared Documents\" -IgnoreVersionHistory", + "Id": 274, "Rank": 3 }, { - "Command": "Copy-PnPFolder -SourceUrl \"/sites/project/Shared Documents/Archive\" -TargetUrl \"/sites/otherproject/Shared Documents\" -Overwrite", - "Id": 274, "CommandName": "Copy-PnPFolder", + "Command": "Copy-PnPFolder -SourceUrl \"/sites/project/Shared Documents/Archive\" -TargetUrl \"/sites/otherproject/Shared Documents\" -Overwrite", + "Id": 275, "Rank": 4 }, { - "Command": "Copy-PnPFolder -SourceUrl \"Documents/company.docx\" -TargetUrl \"Documents/company2.docx\"", - "Id": 275, "CommandName": "Copy-PnPFolder", + "Command": "Copy-PnPFolder -SourceUrl \"Documents/company.docx\" -TargetUrl \"Documents/company2.docx\"", + "Id": 276, "Rank": 5 }, { - "Command": "Copy-PnPFolder -SourceUrl \"Shared Documents/company.docx\" -TargetUrl \"Shared Documents2/company.docx\"", - "Id": 276, "CommandName": "Copy-PnPFolder", + "Command": "Copy-PnPFolder -SourceUrl \"Shared Documents/company.docx\" -TargetUrl \"Shared Documents2/company.docx\"", + "Id": 277, "Rank": 6 }, { - "Command": "Copy-PnPFolder -SourceUrl \"Shared DocuDocuments/company.docx\" -TargetUrl \"Subsite/Shared Documents\"", - "Id": 277, "CommandName": "Copy-PnPFolder", + "Command": "Copy-PnPFolder -SourceUrl \"Shared DocuDocuments/company.docx\" -TargetUrl \"Subsite/Shared Documents\"", + "Id": 278, "Rank": 7 }, { - "Command": "Copy-PnPFolder -SourceUrl \"Shared Documents/company.docx\" -TargetUrl \"/sites/otherproject/Shared Documents\" -Overwrite", - "Id": 278, "CommandName": "Copy-PnPFolder", + "Command": "Copy-PnPFolder -SourceUrl \"Shared Documents/company.docx\" -TargetUrl \"/sites/otherproject/Shared Documents\" -Overwrite", + "Id": 279, "Rank": 8 }, { - "Command": "Copy-PnPFolder -SourceUrl \"Shared Documents/MyDocs\" -TargetUrl \"/sites/otherproject/Documents\" -Overwrite", - "Id": 279, "CommandName": "Copy-PnPFolder", + "Command": "Copy-PnPFolder -SourceUrl \"Shared Documents/MyDocs\" -TargetUrl \"/sites/otherproject/Documents\" -Overwrite", + "Id": 280, "Rank": 9 }, { - "Command": "Copy-PnPFolder -SourceUrl \"SubSite1/Documents/company.docx\" -TargetUrl \"SubSite2/Documents\"", - "Id": 280, "CommandName": "Copy-PnPFolder", + "Command": "Copy-PnPFolder -SourceUrl \"SubSite1/Documents/company.docx\" -TargetUrl \"SubSite2/Documents\"", + "Id": 281, "Rank": 10 }, { - "Command": "Copy-PnPFolder -LocalPath \"c:\\temp\" -TargetUrl \"Subsite1/Shared Documents\" -Recurse -Overwrite", - "Id": 281, "CommandName": "Copy-PnPFolder", + "Command": "Copy-PnPFolder -LocalPath \"c:\\temp\" -TargetUrl \"Subsite1/Shared Documents\" -Recurse -Overwrite", + "Id": 282, "Rank": 11 }, { - "Command": "Copy-PnPItemProxy \"C:\\Users\\Admin\\seattle.master\" -Destination \"C:\\Presentation\"", - "Id": 282, "CommandName": "Copy-PnPItemProxy", + "Command": "Copy-PnPItemProxy \"C:\\Users\\Admin\\seattle.master\" -Destination \"C:\\Presentation\"", + "Id": 283, "Rank": 1 }, { - "Command": "Copy-PnPList -Identity \"My List\" -Title \"Copy of My List\"", - "Id": 283, "CommandName": "Copy-PnPList", + "Command": "Copy-PnPList -Identity \"My List\" -Title \"Copy of My List\"", + "Id": 284, "Rank": 1 }, { - "Command": "Copy-PnPList -Identity \"My List\" -DestinationWebUrl https://contoso.sharepoint.com/sites/hrdepartment", - "Id": 284, "CommandName": "Copy-PnPList", + "Command": "Copy-PnPList -Identity \"My List\" -DestinationWebUrl https://contoso.sharepoint.com/sites/hrdepartment", + "Id": 285, "Rank": 2 }, { - "Command": "Copy-PnPList -Identity \"My List\" -DestinationWebUrl https://contoso.sharepoint.com/sites/hrdepartment -Title \"My copied list\"", - "Id": 285, "CommandName": "Copy-PnPList", + "Command": "Copy-PnPList -Identity \"My List\" -DestinationWebUrl https://contoso.sharepoint.com/sites/hrdepartment -Title \"My copied list\"", + "Id": 286, "Rank": 3 }, { - "Command": "Copy-PnPList -SourceListUrl https://contoso.sharepoint.com/sites/templates/lists/mylist -Verbose -DestinationWebUrl https://contoso.sharepoint.com/sites/hrdepartment\\", - "Id": 286, "CommandName": "Copy-PnPList", + "Command": "Copy-PnPList -SourceListUrl https://contoso.sharepoint.com/sites/templates/lists/mylist -Verbose -DestinationWebUrl https://contoso.sharepoint.com/sites/hrdepartment\\", + "Id": 287, "Rank": 4 }, { - "Command": "Copy-PnPTeamsTeam -Identity ee0f40fc-b2f7-45c7-b62d-11b90dd2ea8e -DisplayName \"Library Assist\" -PartsToClone apps,tabs,settings,channels,members", - "Id": 287, "CommandName": "Copy-PnPTeamsTeam", + "Command": "Copy-PnPTeamsTeam -Identity ee0f40fc-b2f7-45c7-b62d-11b90dd2ea8e -DisplayName \"Library Assist\" -PartsToClone apps,tabs,settings,channels,members", + "Id": 288, "Rank": 1 }, { - "Command": "Copy-PnPTeamsTeam -Identity \"Team 12\" -DisplayName \"Library Assist\"", - "Id": 288, "CommandName": "Copy-PnPTeamsTeam", + "Command": "Copy-PnPTeamsTeam -Identity \"Team 12\" -DisplayName \"Library Assist\"", + "Id": 289, "Rank": 2 }, { - "Command": "Copy-PnPTeamsTeam -Identity \"Team 12\" -DisplayName \"Library Assist\" -PartsToClone apps,tabs,settings,channels,members -Description \"Self help community for library\" -Classification \"Library\" -Visibility public", - "Id": 289, "CommandName": "Copy-PnPTeamsTeam", + "Command": "Copy-PnPTeamsTeam -Identity \"Team 12\" -DisplayName \"Library Assist\" -PartsToClone apps,tabs,settings,channels,members -Description \"Self help community for library\" -Classification \"Library\" -Visibility public", + "Id": 290, "Rank": 3 }, { - "Command": "Copy-PnPTeamsTeam -Identity \"Team 12\" -DisplayName \"Library Assist\" -PartsToClone settings,channels -Description \"Self help community for library\" -Classification \"Library\" -Visibility public", - "Id": 290, "CommandName": "Copy-PnPTeamsTeam", + "Command": "Copy-PnPTeamsTeam -Identity \"Team 12\" -DisplayName \"Library Assist\" -PartsToClone settings,channels -Description \"Self help community for library\" -Classification \"Library\" -Visibility public", + "Id": 291, "Rank": 4 }, { - "Command": "Disable-PnPFeature -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe", - "Id": 291, "CommandName": "Disable-PnPFeature", + "Command": "Disable-PnPFeature -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe", + "Id": 292, "Rank": 1 }, { - "Command": "Disable-PnPFeature -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe -Force", - "Id": 292, "CommandName": "Disable-PnPFeature", + "Command": "Disable-PnPFeature -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe -Force", + "Id": 293, "Rank": 2 }, { - "Command": "Disable-PnPFeature -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe -Scope Web", - "Id": 293, "CommandName": "Disable-PnPFeature", + "Command": "Disable-PnPFeature -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe -Scope Web", + "Id": 294, "Rank": 3 }, { - "Command": "Disable-PnPPageScheduling", - "Id": 294, "CommandName": "Disable-PnPPageScheduling", + "Command": "Disable-PnPPageScheduling", + "Id": 295, "Rank": 1 }, { - "Command": "Disable-PnPPowerShellTelemetry", - "Id": 295, "CommandName": "Disable-PnPPowerShellTelemetry", + "Command": "Disable-PnPPowerShellTelemetry", + "Id": 296, "Rank": 1 }, { - "Command": "Disable-PnPPowerShellTelemetry -Force", - "Id": 296, "CommandName": "Disable-PnPPowerShellTelemetry", + "Command": "Disable-PnPPowerShellTelemetry -Force", + "Id": 297, "Rank": 2 }, { - "Command": "Disable-PnPSharingForNonOwnersOfSite", - "Id": 297, "CommandName": "Disable-PnPSharingForNonOwnersOfSite", + "Command": "Disable-PnPSharingForNonOwnersOfSite", + "Id": 298, "Rank": 1 }, { - "Command": "Disable-PnPSiteClassification", - "Id": 298, "CommandName": "Disable-PnPSiteClassification", + "Command": "Disable-PnPSiteClassification", + "Id": 299, "Rank": 1 }, { - "Command": "Disconnect-PnPOnline", - "Id": 299, "CommandName": "Disconnect-PnPOnline", + "Command": "Disconnect-PnPOnline", + "Id": 300, "Rank": 1 }, { - "Command": "Enable-PnPCommSite", - "Id": 300, "CommandName": "Enable-PnPCommSite", + "Command": "Enable-PnPCommSite", + "Id": 301, "Rank": 1 }, { - "Command": "Enable-PnPCommSite -DesignPackageId 6142d2a0-63a5-4ba0-aede-d9fefca2c767", - "Id": 301, "CommandName": "Enable-PnPCommSite", + "Command": "Enable-PnPCommSite -DesignPackageId 6142d2a0-63a5-4ba0-aede-d9fefca2c767", + "Id": 302, "Rank": 2 }, { - "Command": "Enable-PnPFeature -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe", - "Id": 302, "CommandName": "Enable-PnPFeature", + "Command": "Enable-PnPFeature -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe", + "Id": 303, "Rank": 1 }, { - "Command": "Enable-PnPFeature -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe -Force", - "Id": 303, "CommandName": "Enable-PnPFeature", + "Command": "Enable-PnPFeature -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe -Force", + "Id": 304, "Rank": 2 }, { - "Command": "Enable-PnPFeature -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe -Scope Web", - "Id": 304, "CommandName": "Enable-PnPFeature", + "Command": "Enable-PnPFeature -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe -Scope Web", + "Id": 305, "Rank": 3 }, { - "Command": "Enable-PnPPageScheduling", - "Id": 305, "CommandName": "Enable-PnPPageScheduling", + "Command": "Enable-PnPPageScheduling", + "Id": 306, "Rank": 1 }, { - "Command": "Enable-PnPPowerShellTelemetry", - "Id": 306, "CommandName": "Enable-PnPPowerShellTelemetry", + "Command": "Enable-PnPPowerShellTelemetry", + "Id": 307, "Rank": 1 }, { - "Command": "Enable-PnPPowerShellTelemetry -Force", - "Id": 307, "CommandName": "Enable-PnPPowerShellTelemetry", + "Command": "Enable-PnPPowerShellTelemetry -Force", + "Id": 308, "Rank": 2 }, { - "Command": "Enable-PnPSiteClassification -Classifications \"HBI\",\"LBI\",\"Top Secret\" -DefaultClassification \"LBI\"", - "Id": 308, "CommandName": "Enable-PnPSiteClassification", + "Command": "Enable-PnPSiteClassification -Classifications \"HBI\",\"LBI\",\"Top Secret\" -DefaultClassification \"LBI\"", + "Id": 309, "Rank": 1 }, { - "Command": "Enable-PnPSiteClassification -Classifications \"HBI\",\"LBI\",\"Top Secret\" -UsageGuidelinesUrl https://aka.ms/m365pnp", - "Id": 309, "CommandName": "Enable-PnPSiteClassification", + "Command": "Enable-PnPSiteClassification -Classifications \"HBI\",\"LBI\",\"Top Secret\" -UsageGuidelinesUrl https://aka.ms/m365pnp", + "Id": 310, "Rank": 2 }, { - "Command": "Export-PnPListToSiteTemplate -Out template.xml -List \"Documents\"", - "Id": 310, "CommandName": "Export-PnPListToSiteTemplate", + "Command": "Export-PnPListToSiteTemplate -Out template.xml -List \"Documents\"", + "Id": 311, "Rank": 1 }, { - "Command": "Export-PnPListToSiteTemplate -Out template.pnp -List \"Documents\",\"Events\"", - "Id": 311, "CommandName": "Export-PnPListToSiteTemplate", + "Command": "Export-PnPListToSiteTemplate -Out template.pnp -List \"Documents\",\"Events\"", + "Id": 312, "Rank": 2 }, { - "Command": "Export-PnPPage -Identity Home.aspx", - "Id": 312, "CommandName": "Export-PnPPage", + "Command": "Export-PnPPage -Identity Home.aspx", + "Id": 313, "Rank": 1 }, { - "Command": "Export-PnPPage -Identity HR/Home.aspx -Out template.pnp", - "Id": 313, "CommandName": "Export-PnPPage", + "Command": "Export-PnPPage -Identity HR/Home.aspx -Out template.pnp", + "Id": 314, "Rank": 2 }, { - "Command": "Export-PnPPageMapping -BuiltInPageLayoutMapping -CustomPageLayoutMapping -Folder c:\\\\temp -Overwrite", - "Id": 314, "CommandName": "Export-PnPPageMapping", + "Command": "Export-PnPPageMapping -BuiltInPageLayoutMapping -CustomPageLayoutMapping -Folder c:\\\\temp -Overwrite", + "Id": 315, "Rank": 1 }, { - "Command": "Export-PnPPageMapping -CustomPageLayoutMapping -PublishingPage mypage.aspx -Folder c:\\\\temp -Overwrite", - "Id": 315, "CommandName": "Export-PnPPageMapping", + "Command": "Export-PnPPageMapping -CustomPageLayoutMapping -PublishingPage mypage.aspx -Folder c:\\\\temp -Overwrite", + "Id": 316, "Rank": 2 }, { - "Command": "Export-PnPPageMapping -BuiltInWebPartMapping -Folder c:\\\\temp -Overwrite", - "Id": 316, "CommandName": "Export-PnPPageMapping", + "Command": "Export-PnPPageMapping -BuiltInWebPartMapping -Folder c:\\\\temp -Overwrite", + "Id": 317, "Rank": 3 }, { - "Command": "Export-PnPTaxonomy", - "Id": 317, "CommandName": "Export-PnPTaxonomy", + "Command": "Export-PnPTaxonomy", + "Id": 318, "Rank": 1 }, { - "Command": "Export-PnPTaxonomy -Path c:\\output.txt", - "Id": 318, "CommandName": "Export-PnPTaxonomy", + "Command": "Export-PnPTaxonomy -Path c:\\output.txt", + "Id": 319, "Rank": 2 }, { - "Command": "Export-PnPTaxonomy -Path c:\\output.txt -TermSetId f6f43025-7242-4f7a-b739-41fa32847254", - "Id": 319, "CommandName": "Export-PnPTaxonomy", + "Command": "Export-PnPTaxonomy -Path c:\\output.txt -TermSetId f6f43025-7242-4f7a-b739-41fa32847254", + "Id": 320, "Rank": 3 }, { - "Command": "Export-PnPTaxonomy -Path c:\\output.txt -TermSetId f6f43025-7242-4f7a-b739-41fa32847254 -Lcid 1044", - "Id": 320, "CommandName": "Export-PnPTaxonomy", + "Command": "Export-PnPTaxonomy -Path c:\\output.txt -TermSetId f6f43025-7242-4f7a-b739-41fa32847254 -Lcid 1044", + "Id": 321, "Rank": 4 }, { - "Command": "Export-PnPTermGroupToXml", - "Id": 321, "CommandName": "Export-PnPTermGroupToXml", + "Command": "Export-PnPTermGroupToXml", + "Id": 322, "Rank": 1 }, { - "Command": "Export-PnPTermGroupToXml -Out output.xml", - "Id": 322, "CommandName": "Export-PnPTermGroupToXml", + "Command": "Export-PnPTermGroupToXml -Out output.xml", + "Id": 323, "Rank": 2 }, { - "Command": "Export-PnPTermGroupToXml -Out c:\\output.xml -Identity \"Test Group\"", - "Id": 323, "CommandName": "Export-PnPTermGroupToXml", + "Command": "Export-PnPTermGroupToXml -Out c:\\output.xml -Identity \"Test Group\"", + "Id": 324, "Rank": 3 }, { - "Command": "Export-PnPUserInfo -LoginName user@domain.com -Site \"https://yoursite.sharepoint.com/sites/team\"", - "Id": 324, "CommandName": "Export-PnPUserInfo", + "Command": "Export-PnPUserInfo -LoginName user@domain.com -Site \"https://yoursite.sharepoint.com/sites/team\"", + "Id": 325, "Rank": 1 }, { - "Command": "Export-PnPUserInfo -LoginName user@domain.com -Site \"https://yoursite.sharepoint.com/sites/team\" | ConvertTo-Csv | Out-File MyFile.csv", - "Id": 325, "CommandName": "Export-PnPUserInfo", + "Command": "Export-PnPUserInfo -LoginName user@domain.com -Site \"https://yoursite.sharepoint.com/sites/team\" | ConvertTo-Csv | Out-File MyFile.csv", + "Id": 326, "Rank": 2 }, { - "Command": "Export-PnPUserProfile -LoginName user@domain.com", - "Id": 326, "CommandName": "Export-PnPUserProfile", + "Command": "Export-PnPUserProfile -LoginName user@domain.com", + "Id": 327, "Rank": 1 }, { - "Command": "Export-PnPUserProfile -LoginName user@domain.com | ConvertTo-Csv | Out-File MyFile.csv", - "Id": 327, "CommandName": "Export-PnPUserProfile", + "Command": "Export-PnPUserProfile -LoginName user@domain.com | ConvertTo-Csv | Out-File MyFile.csv", + "Id": 328, "Rank": 2 }, { - "Command": "Find-PnPFile -Match *.master", - "Id": 328, "CommandName": "Find-PnPFile", + "Command": "Find-PnPFile -Match *.master", + "Id": 329, "Rank": 1 }, { - "Command": "Find-PnPFile -List \"Documents\" -Match *.pdf", - "Id": 329, "CommandName": "Find-PnPFile", + "Command": "Find-PnPFile -List \"Documents\" -Match *.pdf", + "Id": 330, "Rank": 2 }, { - "Command": "Find-PnPFile -Folder \"Shared Documents/Sub Folder\" -Match *.docx", - "Id": 330, "CommandName": "Find-PnPFile", + "Command": "Find-PnPFile -Folder \"Shared Documents/Sub Folder\" -Match *.docx", + "Id": 331, "Rank": 3 }, { - "Command": "Get-PnPAccessToken", - "Id": 331, "CommandName": "Get-PnPAccessToken", + "Command": "Get-PnPAccessToken", + "Id": 332, "Rank": 1 }, { - "Command": "Get-PnPAccessToken -Decoded", - "Id": 332, "CommandName": "Get-PnPAccessToken", + "Command": "Get-PnPAccessToken -Decoded", + "Id": 333, "Rank": 2 }, { - "Command": "Get-PnPAccessToken -ResourceTypeName SharePoint", - "Id": 333, "CommandName": "Get-PnPAccessToken", + "Command": "Get-PnPAccessToken -ResourceTypeName SharePoint", + "Id": 334, "Rank": 3 }, { - "Command": "Get-PnPAccessToken -ResourceTypeName ARM", - "Id": 334, "CommandName": "Get-PnPAccessToken", + "Command": "Get-PnPAccessToken -ResourceTypeName ARM", + "Id": 335, "Rank": 4 }, { - "Command": "Get-PnPAccessToken -ResourceUrl \"https://management.azure.com/.default\"", - "Id": 335, "CommandName": "Get-PnPAccessToken", + "Command": "Get-PnPAccessToken -ResourceUrl \"https://management.azure.com/.default\"", + "Id": 336, "Rank": 5 }, { + "CommandName": "Get-PnPAlert", "Command": "Get-PnPAlert", - "Id": 336, - "CommandName": "Get-PnPAlert", + "Id": 337, "Rank": 1 }, { - "Command": "Get-PnPAlert -List \"Demo List\"", - "Id": 337, "CommandName": "Get-PnPAlert", + "Command": "Get-PnPAlert -List \"Demo List\"", + "Id": 338, "Rank": 2 }, { - "Command": "Get-PnPAlert -List \"Demo List\" -User \"i:0#.f|membership|Alice@contoso.onmicrosoft.com\"", - "Id": 338, "CommandName": "Get-PnPAlert", + "Command": "Get-PnPAlert -List \"Demo List\" -User \"i:0#.f|membership|Alice@contoso.onmicrosoft.com\"", + "Id": 339, "Rank": 3 }, { - "Command": "Get-PnPAlert -Title \"Demo Alert\"", - "Id": 339, "CommandName": "Get-PnPAlert", + "Command": "Get-PnPAlert -Title \"Demo Alert\"", + "Id": 340, "Rank": 4 }, { - "Command": "Get-PnPAlert -AllUsers", - "Id": 340, "CommandName": "Get-PnPAlert", + "Command": "Get-PnPAlert -AllUsers", + "Id": 341, "Rank": 5 }, { - "Command": "Get-PnPAlert -List \"Demo List\" -AllUsers", - "Id": 341, "CommandName": "Get-PnPAlert", + "Command": "Get-PnPAlert -List \"Demo List\" -AllUsers", + "Id": 342, "Rank": 6 }, { - "Command": "Get-PnPApp", - "Id": 342, "CommandName": "Get-PnPApp", + "Command": "Get-PnPApp", + "Id": 343, "Rank": 1 }, { - "Command": "Get-PnPApp -Scope Site", - "Id": 343, "CommandName": "Get-PnPApp", + "Command": "Get-PnPApp -Scope Site", + "Id": 344, "Rank": 2 }, { - "Command": "Get-PnPApp -Identity 2646ccc3-6a2b-46ef-9273-81411cbbb60f", - "Id": 344, "CommandName": "Get-PnPApp", + "Command": "Get-PnPApp -Identity 2646ccc3-6a2b-46ef-9273-81411cbbb60f", + "Id": 345, "Rank": 3 }, { - "Command": "Get-PnPAppErrors -ProductId a2681b0c-84fe-41bf-9a8e-d480ab81ba7b", - "Id": 345, "CommandName": "Get-PnPAppErrors", + "Command": "Get-PnPAppErrors -ProductId a2681b0c-84fe-41bf-9a8e-d480ab81ba7b", + "Id": 346, "Rank": 1 }, { - "Command": "Get-PnPAppErrors -ProductId a2681b0c-84fe-41bf-9a8e-d480ab81ba7b -StartTimeInUtc (Get-Date).AddHours(-1).ToUniversalTime()", - "Id": 346, "CommandName": "Get-PnPAppErrors", + "Command": "Get-PnPAppErrors -ProductId a2681b0c-84fe-41bf-9a8e-d480ab81ba7b -StartTimeInUtc (Get-Date).AddHours(-1).ToUniversalTime()", + "Id": 347, "Rank": 2 }, { - "Command": "Get-PnPAppInfo -Name \"Excel Service\"", - "Id": 347, "CommandName": "Get-PnPAppInfo", + "Command": "Get-PnPAppInfo -Name \"Excel Service\"", + "Id": 348, "Rank": 1 }, { - "Command": "Get-PnPAppInfo -ProductId 2646ccc3-6a2b-46ef-9273-81411cbbb60f", - "Id": 348, "CommandName": "Get-PnPAppInfo", + "Command": "Get-PnPAppInfo -ProductId 2646ccc3-6a2b-46ef-9273-81411cbbb60f", + "Id": 349, "Rank": 2 }, { - "Command": "Get-PnPAppInfo -Name \" \" | Sort -Property Name", - "Id": 349, "CommandName": "Get-PnPAppInfo", + "Command": "Get-PnPAppInfo -Name \" \" | Sort -Property Name", + "Id": 350, "Rank": 3 }, { - "Command": "Get-PnPApplicationCustomizer", - "Id": 350, "CommandName": "Get-PnPApplicationCustomizer", + "Command": "Get-PnPApplicationCustomizer", + "Id": 351, "Rank": 1 }, { - "Command": "Get-PnPApplicationCustomizer -Identity aa66f67e-46c0-4474-8a82-42bf467d07f2", - "Id": 351, "CommandName": "Get-PnPApplicationCustomizer", + "Command": "Get-PnPApplicationCustomizer -Identity aa66f67e-46c0-4474-8a82-42bf467d07f2", + "Id": 352, "Rank": 2 }, { - "Command": "Get-PnPApplicationCustomizer -ClientSideComponentId aa66f67e-46c0-4474-8a82-42bf467d07f2 -Scope Web", - "Id": 352, "CommandName": "Get-PnPApplicationCustomizer", + "Command": "Get-PnPApplicationCustomizer -ClientSideComponentId aa66f67e-46c0-4474-8a82-42bf467d07f2 -Scope Web", + "Id": 353, "Rank": 3 }, { - "Command": "Get-PnPAuditing", - "Id": 353, "CommandName": "Get-PnPAuditing", + "Command": "Get-PnPAuditing", + "Id": 354, "Rank": 1 }, { - "Command": "Get-PnPAuthenticationRealm", - "Id": 354, "CommandName": "Get-PnPAuthenticationRealm", + "Command": "Get-PnPAuthenticationRealm", + "Id": 355, "Rank": 1 }, { - "Command": "Get-PnPAuthenticationRealm -Url \"https://contoso.sharepoint.com\"", - "Id": 355, "CommandName": "Get-PnPAuthenticationRealm", + "Command": "Get-PnPAuthenticationRealm -Url \"https://contoso.sharepoint.com\"", + "Id": 356, "Rank": 2 }, { - "Command": "Get-PnPAvailableLanguage", - "Id": 356, "CommandName": "Get-PnPAvailableLanguage", + "Command": "Get-PnPAvailableLanguage", + "Id": 357, "Rank": 1 }, { - "Command": "Get-PnPAvailableSensitivityLabel", - "Id": 357, "CommandName": "Get-PnPAvailableSensitivityLabel", + "Command": "Get-PnPAvailableSensitivityLabel", + "Id": 358, "Rank": 1 }, { - "Command": "Get-PnPAvailableSensitivityLabel -User johndoe@tenant.onmicrosoft.com", - "Id": 358, "CommandName": "Get-PnPAvailableSensitivityLabel", + "Command": "Get-PnPAvailableSensitivityLabel -User johndoe@tenant.onmicrosoft.com", + "Id": 359, "Rank": 2 }, { - "Command": "Get-PnPAvailableSensitivityLabel -Identity 47e66706-8627-4979-89f1-fa7afeba2884", - "Id": 359, "CommandName": "Get-PnPAvailableSensitivityLabel", + "Command": "Get-PnPAvailableSensitivityLabel -Identity 47e66706-8627-4979-89f1-fa7afeba2884", + "Id": 360, "Rank": 3 }, { - "Command": "Get-PnPAvailableSiteClassification", - "Id": 360, "CommandName": "Get-PnPAvailableSiteClassification", + "Command": "Get-PnPAvailableSiteClassification", + "Id": 361, "Rank": 1 }, { - "Command": "Get-PnPAzureACSPrincipal", - "Id": 361, "CommandName": "Get-PnPAzureACSPrincipal", + "Command": "Get-PnPAzureACSPrincipal", + "Id": 362, "Rank": 1 }, { - "Command": "Get-PnPAzureACSPrincipal -IncludeSubsites", - "Id": 362, "CommandName": "Get-PnPAzureACSPrincipal", + "Command": "Get-PnPAzureACSPrincipal -IncludeSubsites", + "Id": 363, "Rank": 2 }, { - "Command": "Get-PnPAzureACSPrincipal -Scope Tenant", - "Id": 363, "CommandName": "Get-PnPAzureACSPrincipal", + "Command": "Get-PnPAzureACSPrincipal -Scope Tenant", + "Id": 364, "Rank": 3 }, { - "Command": "Get-PnPAzureACSPrincipal -Scope All -IncludeSubsites", - "Id": 364, "CommandName": "Get-PnPAzureACSPrincipal", + "Command": "Get-PnPAzureACSPrincipal -Scope All -IncludeSubsites", + "Id": 365, "Rank": 4 }, { - "Command": "Get-PnPAzureADActivityReportDirectoryAudit", - "Id": 365, "CommandName": "Get-PnPAzureADActivityReportDirectoryAudit", + "Command": "Get-PnPAzureADActivityReportDirectoryAudit", + "Id": 366, "Rank": 1 }, { - "Command": "Get-PnPAzureADActivityReportDirectoryAudit -Identity \"Directory_c3b82411-5445-4620-aace-6a684a252673_02R72_362975819\"", - "Id": 366, "CommandName": "Get-PnPAzureADActivityReportDirectoryAudit", + "Command": "Get-PnPAzureADActivityReportDirectoryAudit -Identity \"Directory_c3b82411-5445-4620-aace-6a684a252673_02R72_362975819\"", + "Id": 367, "Rank": 2 }, { - "Command": "Get-PnPAzureADActivityReportDirectoryAudit -Filter \"activityDateTime le 2018-01-24\"", - "Id": 367, "CommandName": "Get-PnPAzureADActivityReportDirectoryAudit", + "Command": "Get-PnPAzureADActivityReportDirectoryAudit -Filter \"activityDateTime le 2018-01-24\"", + "Id": 368, "Rank": 3 }, { - "Command": "Get-PnPAzureADActivityReportSignIn", - "Id": 368, "CommandName": "Get-PnPAzureADActivityReportSignIn", + "Command": "Get-PnPAzureADActivityReportSignIn", + "Id": 369, "Rank": 1 }, { - "Command": "Get-PnPAzureADActivityReportSignIn -Identity \"da364266-533d-3186-a8b2-44ee1c21af11\"", - "Id": 369, "CommandName": "Get-PnPAzureADActivityReportSignIn", + "Command": "Get-PnPAzureADActivityReportSignIn -Identity \"da364266-533d-3186-a8b2-44ee1c21af11\"", + "Id": 370, "Rank": 2 }, { - "Command": "Get-PnPAzureADActivityReportSignIn -Filter \"startsWith(appDisplayName,'Graph')\"", - "Id": 370, "CommandName": "Get-PnPAzureADActivityReportSignIn", + "Command": "Get-PnPAzureADActivityReportSignIn -Filter \"startsWith(appDisplayName,'Graph')\"", + "Id": 371, "Rank": 3 }, { - "Command": "Get-PnPAzureADApp", - "Id": 371, "CommandName": "Get-PnPAzureADApp", + "Command": "Get-PnPAzureADApp", + "Id": 372, "Rank": 1 }, { - "Command": "Get-PnPAzureADApp -Identity MyApp", - "Id": 372, "CommandName": "Get-PnPAzureADApp", + "Command": "Get-PnPAzureADApp -Identity MyApp", + "Id": 373, "Rank": 2 }, { - "Command": "Get-PnPAzureADApp -Identity 93a9772d-d0af-4ed8-9821-17282b64690e", - "Id": 373, "CommandName": "Get-PnPAzureADApp", + "Command": "Get-PnPAzureADApp -Identity 93a9772d-d0af-4ed8-9821-17282b64690e", + "Id": 374, "Rank": 3 }, { - "Command": "Get-PnPAzureADApp -Filter \"startswith(description, 'contoso')\"", - "Id": 374, "CommandName": "Get-PnPAzureADApp", + "Command": "Get-PnPAzureADApp -Filter \"startswith(description, 'contoso')\"", + "Id": 375, "Rank": 4 }, { - "Command": "Get-PnPAzureADAppPermission", - "Id": 375, "CommandName": "Get-PnPAzureADAppPermission", + "Command": "Get-PnPAzureADAppPermission", + "Id": 376, "Rank": 1 }, { - "Command": "Get-PnPAzureADAppPermission -Identity MyApp", - "Id": 376, "CommandName": "Get-PnPAzureADAppPermission", + "Command": "Get-PnPAzureADAppPermission -Identity MyApp", + "Id": 377, "Rank": 2 }, { - "Command": "Get-PnPAzureADAppPermission -Identity 93a9772d-d0af-4ed8-9821-17282b64690e", - "Id": 377, "CommandName": "Get-PnPAzureADAppPermission", + "Command": "Get-PnPAzureADAppPermission -Identity 93a9772d-d0af-4ed8-9821-17282b64690e", + "Id": 378, "Rank": 3 }, { - "Command": "Get-PnPAzureADAppSitePermission", - "Id": 378, "CommandName": "Get-PnPAzureADAppSitePermission", + "Command": "Get-PnPAzureADAppSitePermission", + "Id": 379, "Rank": 1 }, { - "Command": "Get-PnPAzureADAppSitePermission -Site https://contoso.sharepoint.com/sites/projects", - "Id": 379, "CommandName": "Get-PnPAzureADAppSitePermission", + "Command": "Get-PnPAzureADAppSitePermission -Site https://contoso.sharepoint.com/sites/projects", + "Id": 380, "Rank": 2 }, { - "Command": "Get-PnPAzureADAppSitePermission -PermissionId TowaS50fG1zLnNwLmV4dHwxYxNmI0OTI1", - "Id": 380, "CommandName": "Get-PnPAzureADAppSitePermission", + "Command": "Get-PnPAzureADAppSitePermission -PermissionId TowaS50fG1zLnNwLmV4dHwxYxNmI0OTI1", + "Id": 381, "Rank": 3 }, { - "Command": "Get-PnPAzureADAppSitePermission -AppIdentity \"Test App\"", - "Id": 381, "CommandName": "Get-PnPAzureADAppSitePermission", + "Command": "Get-PnPAzureADAppSitePermission -AppIdentity \"Test App\"", + "Id": 382, "Rank": 4 }, { - "Command": "Get-PnPAzureADAppSitePermission -AppIdentity \"14effc36-dc8b-4f68-8919-f6beb7d847b3\"", - "Id": 382, "CommandName": "Get-PnPAzureADAppSitePermission", + "Command": "Get-PnPAzureADAppSitePermission -AppIdentity \"14effc36-dc8b-4f68-8919-f6beb7d847b3\"", + "Id": 383, "Rank": 5 }, { - "Command": "Get-PnPAzureADGroup", - "Id": 383, "CommandName": "Get-PnPAzureADGroup", + "Command": "Get-PnPAzureADGroup", + "Id": 384, "Rank": 1 }, { - "Command": "Get-PnPAzureADGroup -Identity $groupId", - "Id": 384, "CommandName": "Get-PnPAzureADGroup", + "Command": "Get-PnPAzureADGroup -Identity $groupId", + "Id": 385, "Rank": 2 }, { - "Command": "Get-PnPAzureADGroup -Identity $groupDisplayName", - "Id": 385, "CommandName": "Get-PnPAzureADGroup", + "Command": "Get-PnPAzureADGroup -Identity $groupDisplayName", + "Id": 386, "Rank": 3 }, { - "Command": "Get-PnPAzureADGroup -Identity $groupSiteMailNickName", - "Id": 386, "CommandName": "Get-PnPAzureADGroup", + "Command": "Get-PnPAzureADGroup -Identity $groupSiteMailNickName", + "Id": 387, "Rank": 4 }, { - "Command": "Get-PnPAzureADGroup -Identity $group", - "Id": 387, "CommandName": "Get-PnPAzureADGroup", + "Command": "Get-PnPAzureADGroup -Identity $group", + "Id": 388, "Rank": 5 }, { - "Command": "Get-PnPAzureADGroupMember -Identity $groupId", - "Id": 388, "CommandName": "Get-PnPAzureADGroupMember", + "Command": "Get-PnPAzureADGroupMember -Identity $groupId", + "Id": 389, "Rank": 1 }, { - "Command": "Get-PnPAzureADGroupMember -Identity $group", - "Id": 389, "CommandName": "Get-PnPAzureADGroupMember", + "Command": "Get-PnPAzureADGroupMember -Identity $group", + "Id": 390, "Rank": 2 }, { - "Command": "Get-PnPAzureADGroupOwner -Identity $groupId", - "Id": 390, "CommandName": "Get-PnPAzureADGroupOwner", + "Command": "Get-PnPAzureADGroupOwner -Identity $groupId", + "Id": 391, "Rank": 1 }, { - "Command": "Get-PnPAzureADGroupOwner -Identity $group", - "Id": 391, "CommandName": "Get-PnPAzureADGroupOwner", + "Command": "Get-PnPAzureADGroupOwner -Identity $group", + "Id": 392, "Rank": 2 }, { - "Command": "Get-PnPAzureADServicePrincipal", - "Id": 392, "CommandName": "Get-PnPAzureADServicePrincipal", + "Command": "Get-PnPAzureADServicePrincipal", + "Id": 393, "Rank": 1 }, { - "Command": "Get-PnPAzureADServicePrincipal -AppId b8c2a8aa-33a0-43f4-a9d3-fe2851c5293e", - "Id": 393, "CommandName": "Get-PnPAzureADServicePrincipal", + "Command": "Get-PnPAzureADServicePrincipal -AppId b8c2a8aa-33a0-43f4-a9d3-fe2851c5293e", + "Id": 394, "Rank": 2 }, { - "Command": "Get-PnPAzureADServicePrincipal -ObjectId 06ca9985-367a-41ba-9c44-b2ed88c19aec", - "Id": 394, "CommandName": "Get-PnPAzureADServicePrincipal", + "Command": "Get-PnPAzureADServicePrincipal -ObjectId 06ca9985-367a-41ba-9c44-b2ed88c19aec", + "Id": 395, "Rank": 3 }, { - "Command": "Get-PnPAzureADServicePrincipal -AppName \"My application\"", - "Id": 395, "CommandName": "Get-PnPAzureADServicePrincipal", + "Command": "Get-PnPAzureADServicePrincipal -AppName \"My application\"", + "Id": 396, "Rank": 4 }, { - "Command": "Get-PnPAzureADServicePrincipal -Filter \"startswith(description, 'contoso')\"", - "Id": 396, "CommandName": "Get-PnPAzureADServicePrincipal", + "Command": "Get-PnPAzureADServicePrincipal -Filter \"startswith(description, 'contoso')\"", + "Id": 397, "Rank": 5 }, { - "Command": "Get-PnPAzureADServicePrincipalAssignedAppRole -Principal 797ee8a7-a950-4eb8-945d-7f10cc68a933", - "Id": 397, "CommandName": "Get-PnPAzureADServicePrincipalAssignedAppRole", + "Command": "Get-PnPAzureADServicePrincipalAssignedAppRole -Principal 797ee8a7-a950-4eb8-945d-7f10cc68a933", + "Id": 398, "Rank": 1 }, { - "Command": "Get-PnPAzureADServicePrincipalAssignedAppRole -Principal \"My application\"", - "Id": 398, "CommandName": "Get-PnPAzureADServicePrincipalAssignedAppRole", + "Command": "Get-PnPAzureADServicePrincipalAssignedAppRole -Principal \"My application\"", + "Id": 399, "Rank": 2 }, { - "Command": "Get-PnPAzureADServicePrincipalAvailableAppRole -Principal 797ee8a7-a950-4eb8-945d-7f10cc68a933", - "Id": 399, "CommandName": "Get-PnPAzureADServicePrincipalAvailableAppRole", + "Command": "Get-PnPAzureADServicePrincipalAvailableAppRole -Principal 797ee8a7-a950-4eb8-945d-7f10cc68a933", + "Id": 400, "Rank": 1 }, { + "CommandName": "Get-PnPAzureADServicePrincipalAvailableAppRole", "Command": "Get-PnPAzureADServicePrincipalAvailableAppRole -Principal \"My application\"", - "Id": 400, - "CommandName": "Get-PnPAzureADServicePrincipalAvailableAppRole", + "Id": 401, "Rank": 2 }, { - "Command": "Get-PnPAzureADUser", - "Id": 401, "CommandName": "Get-PnPAzureADUser", + "Command": "Get-PnPAzureADUser", + "Id": 402, "Rank": 1 }, { - "Command": "Get-PnPAzureADUser -EndIndex 50", - "Id": 402, "CommandName": "Get-PnPAzureADUser", + "Command": "Get-PnPAzureADUser -EndIndex 50", + "Id": 403, "Rank": 2 }, { - "Command": "Get-PnPAzureADUser -Identity 328c7693-5524-44ac-a946-73e02d6b0f98", - "Id": 403, "CommandName": "Get-PnPAzureADUser", + "Command": "Get-PnPAzureADUser -Identity 328c7693-5524-44ac-a946-73e02d6b0f98", + "Id": 404, "Rank": 3 }, { - "Command": "Get-PnPAzureADUser -Identity john@contoso.com", - "Id": 404, "CommandName": "Get-PnPAzureADUser", + "Command": "Get-PnPAzureADUser -Identity john@contoso.com", + "Id": 405, "Rank": 4 }, { - "Command": "Get-PnPAzureADUser -Identity john@contoso.com -Select \"DisplayName\",\"extension_3721d05137db455ad81aa442e3c2d4f9_extensionAttribute1\"", - "Id": 405, "CommandName": "Get-PnPAzureADUser", + "Command": "Get-PnPAzureADUser -Identity john@contoso.com -Select \"DisplayName\",\"extension_3721d05137db455ad81aa442e3c2d4f9_extensionAttribute1\"", + "Id": 406, "Rank": 5 }, { - "Command": "Get-PnPAzureADUser -Filter \"accountEnabled eq false\"", - "Id": 406, "CommandName": "Get-PnPAzureADUser", + "Command": "Get-PnPAzureADUser -Filter \"accountEnabled eq false\"", + "Id": 407, "Rank": 6 }, { - "Command": "Get-PnPAzureADUser -Filter \"startswith(DisplayName, 'John')\" -OrderBy \"DisplayName\"", - "Id": 407, "CommandName": "Get-PnPAzureADUser", + "Command": "Get-PnPAzureADUser -Filter \"startswith(DisplayName, 'John')\" -OrderBy \"DisplayName\"", + "Id": 408, "Rank": 7 }, { - "Command": "Get-PnPAzureADUser -Delta", - "Id": 408, "CommandName": "Get-PnPAzureADUser", + "Command": "Get-PnPAzureADUser -Delta", + "Id": 409, "Rank": 8 }, { - "Command": "Get-PnPAzureADUser -Delta -DeltaToken abcdef", - "Id": 409, "CommandName": "Get-PnPAzureADUser", + "Command": "Get-PnPAzureADUser -Delta -DeltaToken abcdef", + "Id": 410, "Rank": 9 }, { - "Command": "Get-PnPAzureADUser -StartIndex 10 -EndIndex 20", - "Id": 410, "CommandName": "Get-PnPAzureADUser", + "Command": "Get-PnPAzureADUser -StartIndex 10 -EndIndex 20", + "Id": 411, "Rank": 10 }, { - "Command": "Get-PnPAzureCertificate -Path \"mycert.pfx\"", - "Id": 411, "CommandName": "Get-PnPAzureCertificate", + "Command": "Get-PnPAzureCertificate -Path \"mycert.pfx\"", + "Id": 412, "Rank": 1 }, { - "Command": "Get-PnPAzureCertificate -Path \"mycert.pfx\" -Password (ConvertTo-SecureString -String \"YourPassword\" -AsPlainText -Force)", - "Id": 412, "CommandName": "Get-PnPAzureCertificate", + "Command": "Get-PnPAzureCertificate -Path \"mycert.pfx\" -Password (ConvertTo-SecureString -String \"YourPassword\" -AsPlainText -Force)", + "Id": 413, "Rank": 2 }, { - "Command": "Get-PnPAzureCertificate -Path \"mycert.cer\" | clip", - "Id": 413, "CommandName": "Get-PnPAzureCertificate", + "Command": "Get-PnPAzureCertificate -Path \"mycert.cer\" | clip", + "Id": 414, "Rank": 3 }, { - "Command": "Get-PnPBrowserIdleSignout", - "Id": 414, "CommandName": "Get-PnPBrowserIdleSignout", + "Command": "Get-PnPBrowserIdleSignout", + "Id": 415, "Rank": 1 }, { - "Command": "Get-PnPBuiltInDesignPackageVisibility -DesignPackage Showcase", - "Id": 415, "CommandName": "Get-PnPBuiltInDesignPackageVisibility", + "Command": "Get-PnPBuiltInDesignPackageVisibility -DesignPackage Showcase", + "Id": 416, "Rank": 1 }, { - "Command": "Get-PnPBuiltInDesignPackageVisibility", - "Id": 416, "CommandName": "Get-PnPBuiltInDesignPackageVisibility", + "Command": "Get-PnPBuiltInDesignPackageVisibility", + "Id": 417, "Rank": 2 }, { - "Command": "Get-PnPBuiltInSiteTemplateSettings", - "Id": 417, "CommandName": "Get-PnPBuiltInSiteTemplateSettings", + "Command": "Get-PnPBuiltInSiteTemplateSettings", + "Id": 418, "Rank": 1 }, { - "Command": "Get-PnPBuiltInSiteTemplateSettings -Identity 9522236e-6802-4972-a10d-e98dc74b3344", - "Id": 418, "CommandName": "Get-PnPBuiltInSiteTemplateSettings", + "Command": "Get-PnPBuiltInSiteTemplateSettings -Identity 9522236e-6802-4972-a10d-e98dc74b3344", + "Id": 419, "Rank": 2 }, { - "Command": "Get-PnPBuiltInSiteTemplateSettings -Template CrisisManagement", - "Id": 419, "CommandName": "Get-PnPBuiltInSiteTemplateSettings", + "Command": "Get-PnPBuiltInSiteTemplateSettings -Template CrisisManagement", + "Id": 420, "Rank": 3 }, { - "Command": "Get-PnPBuiltInSiteTemplateSettings -Identity 00000000-0000-0000-0000-000000000000", - "Id": 420, "CommandName": "Get-PnPBuiltInSiteTemplateSettings", + "Command": "Get-PnPBuiltInSiteTemplateSettings -Identity 00000000-0000-0000-0000-000000000000", + "Id": 421, "Rank": 4 }, { - "Command": "Get-PnPBuiltInSiteTemplateSettings -Template All", - "Id": 421, "CommandName": "Get-PnPBuiltInSiteTemplateSettings", + "Command": "Get-PnPBuiltInSiteTemplateSettings -Template All", + "Id": 422, "Rank": 5 }, { - "Command": "Get-PnPChangeLog", - "Id": 422, "CommandName": "Get-PnPChangeLog", + "Command": "Get-PnPChangeLog", + "Id": 423, "Rank": 1 }, { - "Command": "Get-PnPChangeLog -Nightly", - "Id": 423, "CommandName": "Get-PnPChangeLog", + "Command": "Get-PnPChangeLog -Nightly", + "Id": 424, "Rank": 2 }, { - "Command": "Get-PnPCompatibleHubContentTypes -WebUrl 'https://contoso.sharepoint.com/web1'", - "Id": 424, "CommandName": "Get-PnPCompatibleHubContentTypes", + "Command": "Get-PnPCompatibleHubContentTypes -WebUrl 'https://contoso.sharepoint.com/web1'", + "Id": 425, "Rank": 1 }, { - "Command": "Get-PnPCompatibleHubContentTypes -WebUrl 'https://contoso.sharepoint.com/web1' -ListUrl 'https://contoso.sharepoint.com/web1/Shared Documents'", - "Id": 425, "CommandName": "Get-PnPCompatibleHubContentTypes", + "Command": "Get-PnPCompatibleHubContentTypes -WebUrl 'https://contoso.sharepoint.com/web1' -ListUrl 'https://contoso.sharepoint.com/web1/Shared Documents'", + "Id": 426, "Rank": 2 }, { - "Command": "Get-PnPContainer -OwningApplicationId a187e399-0c36-4b98-8f04-1edc167a0996", - "Id": 426, "CommandName": "Get-PnPContainer", + "Command": "Get-PnPContainer -OwningApplicationId a187e399-0c36-4b98-8f04-1edc167a0996", + "Id": 427, "Rank": 1 }, { - "Command": "Get-PnPContainer -OwningApplicationId a187e399-0c36-4b98-8f04-1edc167a0996 -Identity \"b!aBrXSxKDdUKZsaK3Djug6C5rF4MG3pRBomypnjOHiSrjkM_EBk_1S57U3gD7oW-1\"", - "Id": 427, "CommandName": "Get-PnPContainer", + "Command": "Get-PnPContainer -OwningApplicationId a187e399-0c36-4b98-8f04-1edc167a0996 -Identity \"b!aBrXSxKDdUKZsaK3Djug6C5rF4MG3pRBomypnjOHiSrjkM_EBk_1S57U3gD7oW-1\"", + "Id": 428, "Rank": 2 }, { - "Command": "Get-PnPContainer -Identity \"bc07d4b8-1c2f-4184-8cc2-a52dfd6fe0c4\" -Identity \"https://contoso.sharepoint.com/contentstorage/CSP_4bd71a68-8312-4275-99b1-a2b70e3ba0e8\"", - "Id": 428, "CommandName": "Get-PnPContainer", + "Command": "Get-PnPContainer -Identity \"bc07d4b8-1c2f-4184-8cc2-a52dfd6fe0c4\" -Identity \"https://contoso.sharepoint.com/contentstorage/CSP_4bd71a68-8312-4275-99b1-a2b70e3ba0e8\"", + "Id": 429, "Rank": 3 }, { - "Command": "Get-PnPContainerType", - "Id": 429, "CommandName": "Get-PnPContainerType", + "Command": "Get-PnPContainerType", + "Id": 430, "Rank": 1 }, { - "Command": "Get-PnPContainerTypeConfiguration -Identity a187e399-0c36-4b98-8f04-1edc167a0996", - "Id": 430, "CommandName": "Get-PnPContainerTypeConfiguration", + "Command": "Get-PnPContainerTypeConfiguration -Identity a187e399-0c36-4b98-8f04-1edc167a0996", + "Id": 431, "Rank": 1 }, { - "Command": "Get-PnPContentType", - "Id": 431, "CommandName": "Get-PnPContentType", + "Command": "Get-PnPContentType", + "Id": 432, "Rank": 1 }, { - "Command": "Get-PnPContentType -InSiteHierarchy", - "Id": 432, "CommandName": "Get-PnPContentType", + "Command": "Get-PnPContentType -InSiteHierarchy", + "Id": 433, "Rank": 2 }, { - "Command": "Get-PnPContentType -Identity \"Project Document\"", - "Id": 433, "CommandName": "Get-PnPContentType", + "Command": "Get-PnPContentType -Identity \"Project Document\"", + "Id": 434, "Rank": 3 }, { - "Command": "Get-PnPContentType -List \"Documents\"", - "Id": 434, "CommandName": "Get-PnPContentType", + "Command": "Get-PnPContentType -List \"Documents\"", + "Id": 435, "Rank": 4 }, { - "Command": "Get-PnPContentType -Includes \"SchemaXml\"", - "Id": 435, "CommandName": "Get-PnPContentType", + "Command": "Get-PnPContentType -Includes \"SchemaXml\"", + "Id": 436, "Rank": 5 }, { - "Command": "Get-PnPContentTypePublishingStatus -ContentType 0x0101", - "Id": 436, "CommandName": "Get-PnPContentTypePublishingStatus", + "Command": "Get-PnPContentTypePublishingStatus -ContentType 0x0101", + "Id": 437, "Rank": 1 }, { - "Command": "Get-PnPCustomAction", - "Id": 437, "CommandName": "Get-PnPCustomAction", + "Command": "Get-PnPCustomAction", + "Id": 438, "Rank": 1 }, { - "Command": "Get-PnPCustomAction -Identity aa66f67e-46c0-4474-8a82-42bf467d07f2", - "Id": 438, "CommandName": "Get-PnPCustomAction", + "Command": "Get-PnPCustomAction -Identity aa66f67e-46c0-4474-8a82-42bf467d07f2", + "Id": 439, "Rank": 2 }, { - "Command": "Get-PnPCustomAction -Scope web", - "Id": 439, "CommandName": "Get-PnPCustomAction", + "Command": "Get-PnPCustomAction -Scope web", + "Id": 440, "Rank": 3 }, { - "Command": "Get-PnPDeletedContainer", - "Id": 440, "CommandName": "Get-PnPDeletedContainer", + "Command": "Get-PnPDeletedContainer", + "Id": 441, "Rank": 1 }, { - "Command": "Get-PnPDeletedMicrosoft365Group", - "Id": 441, "CommandName": "Get-PnPDeletedMicrosoft365Group", + "Command": "Get-PnPDeletedMicrosoft365Group", + "Id": 442, "Rank": 1 }, { - "Command": "Get-PnPDeletedMicrosoft365Group -Identity 38b32e13-e900-4d95-b860-fb52bc07ca7f", - "Id": 442, "CommandName": "Get-PnPDeletedMicrosoft365Group", + "Command": "Get-PnPDeletedMicrosoft365Group -Identity 38b32e13-e900-4d95-b860-fb52bc07ca7f", + "Id": 443, "Rank": 2 }, { - "Command": "Get-PnPDeletedTeam", - "Id": 443, "CommandName": "Get-PnPDeletedTeam", + "Command": "Get-PnPDeletedTeam", + "Id": 444, "Rank": 1 }, { - "Command": "Get-PnPDiagnostics", - "Id": 444, "CommandName": "Get-PnPDiagnostics", + "Command": "Get-PnPDiagnostics", + "Id": 445, "Rank": 1 }, { - "Command": "Get-PnPDisableSpacesActivation", - "Id": 445, "CommandName": "Get-PnPDisableSpacesActivation", + "Command": "Get-PnPDisableSpacesActivation", + "Id": 446, "Rank": 1 }, { - "Command": "Get-PnPDocumentSetTemplate -Identity \"Test Document Set\"", - "Id": 446, "CommandName": "Get-PnPDocumentSetTemplate", + "Command": "Get-PnPDocumentSetTemplate -Identity \"Test Document Set\"", + "Id": 447, "Rank": 1 }, { - "Command": "Get-PnPDocumentSetTemplate -Identity \"0x0120D520005DB65D094035A241BAC9AF083F825F3B\"", - "Id": 447, "CommandName": "Get-PnPDocumentSetTemplate", + "Command": "Get-PnPDocumentSetTemplate -Identity \"0x0120D520005DB65D094035A241BAC9AF083F825F3B\"", + "Id": 448, "Rank": 2 }, { - "Command": "Get-PnPEventReceiver", - "Id": 448, "CommandName": "Get-PnPEventReceiver", + "Command": "Get-PnPEventReceiver", + "Id": 449, "Rank": 1 }, { - "Command": "Get-PnPEventReceiver -Identity fb689d0e-eb99-4f13-beb3-86692fd39f22", - "Id": 449, "CommandName": "Get-PnPEventReceiver", + "Command": "Get-PnPEventReceiver -Identity fb689d0e-eb99-4f13-beb3-86692fd39f22", + "Id": 450, "Rank": 2 }, { - "Command": "Get-PnPEventReceiver -Identity MyReceiver", - "Id": 450, "CommandName": "Get-PnPEventReceiver", + "Command": "Get-PnPEventReceiver -Identity MyReceiver", + "Id": 451, "Rank": 3 }, { - "Command": "Get-PnPEventReceiver -List \"ProjectList\"", - "Id": 451, "CommandName": "Get-PnPEventReceiver", + "Command": "Get-PnPEventReceiver -List \"ProjectList\"", + "Id": 452, "Rank": 4 }, { - "Command": "Get-PnPEventReceiver -List \"ProjectList\" -Identity fb689d0e-eb99-4f13-beb3-86692fd39f22", - "Id": 452, "CommandName": "Get-PnPEventReceiver", + "Command": "Get-PnPEventReceiver -List \"ProjectList\" -Identity fb689d0e-eb99-4f13-beb3-86692fd39f22", + "Id": 453, "Rank": 5 }, { - "Command": "Get-PnPEventReceiver -List \"ProjectList\" -Identity MyReceiver", - "Id": 453, "CommandName": "Get-PnPEventReceiver", + "Command": "Get-PnPEventReceiver -List \"ProjectList\" -Identity MyReceiver", + "Id": 454, "Rank": 6 }, { - "Command": "Get-PnPEventReceiver -Scope Site", - "Id": 454, "CommandName": "Get-PnPEventReceiver", + "Command": "Get-PnPEventReceiver -Scope Site", + "Id": 455, "Rank": 7 }, { - "Command": "Get-PnPEventReceiver -Scope Web", - "Id": 455, "CommandName": "Get-PnPEventReceiver", + "Command": "Get-PnPEventReceiver -Scope Web", + "Id": 456, "Rank": 8 }, { - "Command": "Get-PnPEventReceiver -Scope All", - "Id": 456, "CommandName": "Get-PnPEventReceiver", + "Command": "Get-PnPEventReceiver -Scope All", + "Id": 457, "Rank": 9 }, { - "Command": "Get-PnPException", - "Id": 457, "CommandName": "Get-PnPException", + "Command": "Get-PnPException", + "Id": 458, "Rank": 1 }, { - "Command": "Get-PnPException -All", - "Id": 458, "CommandName": "Get-PnPException", + "Command": "Get-PnPException -All", + "Id": 459, "Rank": 2 }, { - "Command": "Get-PnPExternalUser -Position 0 -PageSize 2", - "Id": 459, "CommandName": "Get-PnPExternalUser", + "Command": "Get-PnPExternalUser -Position 0 -PageSize 2", + "Id": 460, "Rank": 1 }, { - "Command": "Get-PnPExternalUser -Position 2 -PageSize 2", - "Id": 460, "CommandName": "Get-PnPExternalUser", + "Command": "Get-PnPExternalUser -Position 2 -PageSize 2", + "Id": 461, "Rank": 2 }, { - "Command": "Get-PnPFeature", - "Id": 461, "CommandName": "Get-PnPFeature", + "Command": "Get-PnPFeature", + "Id": 462, "Rank": 1 }, { - "Command": "Get-PnPFeature -Scope Site", - "Id": 462, "CommandName": "Get-PnPFeature", + "Command": "Get-PnPFeature -Scope Site", + "Id": 463, "Rank": 2 }, { - "Command": "Get-PnPFeature -Identity fb689d0e-eb99-4f13-beb3-86692fd39f22", - "Id": 463, "CommandName": "Get-PnPFeature", + "Command": "Get-PnPFeature -Identity fb689d0e-eb99-4f13-beb3-86692fd39f22", + "Id": 464, "Rank": 3 }, { + "CommandName": "Get-PnPFeature", "Command": "Get-PnPFeature -Identity fb689d0e-eb99-4f13-beb3-86692fd39f22 -Scope Site", - "Id": 464, - "CommandName": "Get-PnPFeature", + "Id": 465, "Rank": 4 }, { - "Command": "Get-PnPField", - "Id": 465, "CommandName": "Get-PnPField", + "Command": "Get-PnPField", + "Id": 466, "Rank": 1 }, { - "Command": "Get-PnPField -List \"Demo list\" -Identity \"Speakers\"", - "Id": 466, "CommandName": "Get-PnPField", + "Command": "Get-PnPField -List \"Demo list\" -Identity \"Speakers\"", + "Id": 467, "Rank": 2 }, { - "Command": "Get-PnPField -Group \"Custom Columns\"", - "Id": 467, "CommandName": "Get-PnPField", + "Command": "Get-PnPField -Group \"Custom Columns\"", + "Id": 468, "Rank": 3 }, { - "Command": "Get-PnPFile -Url \"/sites/project/Shared Documents/Document.docx\"", - "Id": 468, "CommandName": "Get-PnPFile", + "Command": "Get-PnPFile -Url \"/sites/project/Shared Documents/Document.docx\"", + "Id": 469, "Rank": 1 }, { - "Command": "Get-PnPFile -Url /sites/project/SiteAssets/image.jpg -Path c:\\temp -FileName image.jpg -AsFile", - "Id": 469, "CommandName": "Get-PnPFile", + "Command": "Get-PnPFile -Url /sites/project/SiteAssets/image.jpg -Path c:\\temp -FileName image.jpg -AsFile", + "Id": 470, "Rank": 2 }, { - "Command": "Get-PnPFile -Url /sites/project/_catalogs/themes/15/company.spcolor -AsString", - "Id": 470, "CommandName": "Get-PnPFile", + "Command": "Get-PnPFile -Url /sites/project/_catalogs/themes/15/company.spcolor -AsString", + "Id": 471, "Rank": 3 }, { - "Command": "Get-PnPFile -Url /sites/project/Shared Documents/Folder/Presentation.pptx -AsFileObject", - "Id": 471, "CommandName": "Get-PnPFile", + "Command": "Get-PnPFile -Url /sites/project/Shared Documents/Folder/Presentation.pptx -AsFileObject", + "Id": 472, "Rank": 4 }, { - "Command": "Get-PnPFile -Url /sites/project/_catalogs/themes/15/company.spcolor -AsListItem", - "Id": 472, "CommandName": "Get-PnPFile", + "Command": "Get-PnPFile -Url /sites/project/_catalogs/themes/15/company.spcolor -AsListItem", + "Id": 473, "Rank": 5 }, { - "Command": "Get-PnPFile -Url /personal/john_tenant_onmicrosoft_com/Documents/Sample.xlsx -Path c:\\temp -FileName Project.xlsx -AsFile", - "Id": 473, "CommandName": "Get-PnPFile", + "Command": "Get-PnPFile -Url /personal/john_tenant_onmicrosoft_com/Documents/Sample.xlsx -Path c:\\temp -FileName Project.xlsx -AsFile", + "Id": 474, "Rank": 6 }, { - "Command": "Get-PnPFile -Url \"/sites/templates/Shared Documents/HR Site.pnp\" -AsMemoryStream", - "Id": 474, "CommandName": "Get-PnPFile", + "Command": "Get-PnPFile -Url \"/sites/templates/Shared Documents/HR Site.pnp\" -AsMemoryStream", + "Id": 475, "Rank": 7 }, { - "Command": "Get-PnPFileAnalyticsData -Url \"/sites/project/Shared Documents/Document.docx\"", - "Id": 475, "CommandName": "Get-PnPFileAnalyticsData", + "Command": "Get-PnPFileAnalyticsData -Url \"/sites/project/Shared Documents/Document.docx\"", + "Id": 476, "Rank": 1 }, { - "Command": "Get-PnPFileAnalyticsData -Url \"/sites/project/Shared Documents/Document.docx\" -LastSevenDays", - "Id": 476, "CommandName": "Get-PnPFileAnalyticsData", + "Command": "Get-PnPFileAnalyticsData -Url \"/sites/project/Shared Documents/Document.docx\" -LastSevenDays", + "Id": 477, "Rank": 2 }, { - "Command": "Get-PnPFileAnalyticsData -Url \"/sites/project/Shared Documents/Document.docx\" -StartDate (Get-date).AddDays(-15) -EndDate (Get-date) -AnalyticsAggregationInterval Day", - "Id": 477, "CommandName": "Get-PnPFileAnalyticsData", + "Command": "Get-PnPFileAnalyticsData -Url \"/sites/project/Shared Documents/Document.docx\" -StartDate (Get-date).AddDays(-15) -EndDate (Get-date) -AnalyticsAggregationInterval Day", + "Id": 478, "Rank": 3 }, { - "Command": "Get-PnPFileInFolder", - "Id": 478, "CommandName": "Get-PnPFileInFolder", + "Command": "Get-PnPFileInFolder", + "Id": 479, "Rank": 1 }, { - "Command": "Get-PnPFileInFolder -Recurse", - "Id": 479, "CommandName": "Get-PnPFileInFolder", + "Command": "Get-PnPFileInFolder -Recurse", + "Id": 480, "Rank": 2 }, { - "Command": "Get-PnPFileInFolder -Identity \"Shared Documents\"", - "Id": 480, "CommandName": "Get-PnPFileInFolder", + "Command": "Get-PnPFileInFolder -Identity \"Shared Documents\"", + "Id": 481, "Rank": 3 }, { - "Command": "Get-PnPFileInFolder -FolderSiteRelativeUrl \"SitePages\" -ItemName \"Default.aspx\"", - "Id": 481, "CommandName": "Get-PnPFileInFolder", + "Command": "Get-PnPFileInFolder -FolderSiteRelativeUrl \"SitePages\" -ItemName \"Default.aspx\"", + "Id": 482, "Rank": 4 }, { - "Command": "Get-PnPFileInFolder -FolderSiteRelativeUrl \"SitePages\" -Recurse", - "Id": 482, "CommandName": "Get-PnPFileInFolder", + "Command": "Get-PnPFileInFolder -FolderSiteRelativeUrl \"SitePages\" -Recurse", + "Id": 483, "Rank": 5 }, { - "Command": "Get-PnPFileSensitivityLabelInfo -Url \"https://contoso.sharepoint.com/sites/Marketing/Shared Documents/Report.pdf\"", - "Id": 483, "CommandName": "Get-PnPFileSensitivityLabelInfo", + "Command": "Get-PnPFileSensitivityLabelInfo -Url \"https://contoso.sharepoint.com/sites/Marketing/Shared Documents/Report.pdf\"", + "Id": 484, "Rank": 1 }, { - "Command": "Get-PnPFileSharingLink -FileUrl \"/sites/demo/Shared Documents/Test.docx\"", - "Id": 484, "CommandName": "Get-PnPFileSharingLink", + "Command": "Get-PnPFileSharingLink -Identity \"/sites/demo/Shared Documents/Test.docx\"", + "Id": 485, "Rank": 1 }, { - "Command": "Get-PnPFileVersion -Url Documents/MyDocument.docx", - "Id": 485, + "CommandName": "Get-PnPFileSharingLink", + "Command": "Get-PnPFileSharingLink -Identity eff4c8ca-7b92-4aa2-9744-855611c6ccf2", + "Id": 486, + "Rank": 2 + }, + { + "CommandName": "Get-PnPFileSharingLink", + "Command": "Get-PnPFileSharingLink -Identity /sites/demo/Lists/Issue tracker/1_.000", + "Id": 487, + "Rank": 3 + }, + { "CommandName": "Get-PnPFileVersion", + "Command": "Get-PnPFileVersion -Url Documents/MyDocument.docx", + "Id": 488, "Rank": 1 }, { - "Command": "Get-PnPFileVersion -Url \"/sites/marketing/Shared Documents/MyDocument.docx\"", - "Id": 486, "CommandName": "Get-PnPFileVersion", + "Command": "Get-PnPFileVersion -Url \"/sites/marketing/Shared Documents/MyDocument.docx\"", + "Id": 489, "Rank": 2 }, { - "Command": "Get-PnPFileVersion -Url \"/sites/marketing/Shared Documents/MyDocument.docx\" -UseVersionExpirationReport", - "Id": 487, "CommandName": "Get-PnPFileVersion", + "Command": "Get-PnPFileVersion -Url \"/sites/marketing/Shared Documents/MyDocument.docx\" -UseVersionExpirationReport", + "Id": 490, "Rank": 3 }, { - "Command": "Get-PnPFlow -AsAdmin", - "Id": 488, "CommandName": "Get-PnPFlow", + "Command": "Get-PnPFlow -AsAdmin", + "Id": 491, "Rank": 1 }, { - "Command": "Get-PnPFlow -SharingStatus SharedWithMe", - "Id": 489, "CommandName": "Get-PnPFlow", + "Command": "Get-PnPFlow -SharingStatus SharedWithMe", + "Id": 492, "Rank": 2 }, { - "Command": "Get-PnPFlow -Identity fba63225-baf9-4d76-86a1-1b42c917a182", - "Id": 490, "CommandName": "Get-PnPFlow", + "Command": "Get-PnPFlow -Identity fba63225-baf9-4d76-86a1-1b42c917a182", + "Id": 493, "Rank": 3 }, { - "Command": "Get-PnPFlowOwner -Environment (Get-PnPPowerPlatformEnvironment -IsDefault) -Identity 33f78dac-7e93-45de-ab85-67cad0f6ee30", - "Id": 491, "CommandName": "Get-PnPFlowOwner", + "Command": "Get-PnPFlowOwner -Environment (Get-PnPPowerPlatformEnvironment -IsDefault) -Identity 33f78dac-7e93-45de-ab85-67cad0f6ee30", + "Id": 494, "Rank": 1 }, { - "Command": "Get-PnPFolder", - "Id": 492, "CommandName": "Get-PnPFolder", + "Command": "Get-PnPFolder", + "Id": 495, "Rank": 1 }, { - "Command": "Get-PnPFolder -CurrentWebRootFolder", - "Id": 493, "CommandName": "Get-PnPFolder", + "Command": "Get-PnPFolder -CurrentWebRootFolder", + "Id": 496, "Rank": 2 }, { - "Command": "Get-PnPFolder -Url \"Shared Documents\"", - "Id": 494, "CommandName": "Get-PnPFolder", + "Command": "Get-PnPFolder -Url \"Shared Documents\"", + "Id": 497, "Rank": 3 }, { - "Command": "Get-PnPFolder -Url \"/sites/demo/Shared Documents\"", - "Id": 495, "CommandName": "Get-PnPFolder", + "Command": "Get-PnPFolder -Url \"/sites/demo/Shared Documents\"", + "Id": 498, "Rank": 4 }, { - "Command": "Get-PnPFolder -ListRootFolder \"Shared Documents\"", - "Id": 496, "CommandName": "Get-PnPFolder", + "Command": "Get-PnPFolder -ListRootFolder \"Shared Documents\"", + "Id": 499, "Rank": 5 }, { - "Command": "Get-PnPFolder -List \"Shared Documents\"", - "Id": 497, "CommandName": "Get-PnPFolder", + "Command": "Get-PnPFolder -List \"Shared Documents\"", + "Id": 500, "Rank": 6 }, { - "Command": "Get-PnPFolderInFolder", - "Id": 498, + "CommandName": "Get-PnPFolder", + "Command": "Get-PnPFolder -Url \"/sites/demo/Shared Documents/Test\" -AsListItem", + "Id": 501, + "Rank": 7 + }, + { "CommandName": "Get-PnPFolderInFolder", + "Command": "Get-PnPFolderInFolder", + "Id": 502, "Rank": 1 }, { - "Command": "Get-PnPFolderInFolder -Recurse", - "Id": 499, "CommandName": "Get-PnPFolderInFolder", + "Command": "Get-PnPFolderInFolder -Recurse", + "Id": 503, "Rank": 2 }, { - "Command": "Get-PnPFolderInFolder -Identity \"Shared Documents\"", - "Id": 500, "CommandName": "Get-PnPFolderInFolder", + "Command": "Get-PnPFolderInFolder -Identity \"Shared Documents\"", + "Id": 504, "Rank": 3 }, { - "Command": "Get-PnPFolderInFolder -Identity \"Shared Documents\" -ExcludeSystemFolders", - "Id": 501, "CommandName": "Get-PnPFolderInFolder", + "Command": "Get-PnPFolderInFolder -Identity \"Shared Documents\" -ExcludeSystemFolders", + "Id": 505, "Rank": 4 }, { - "Command": "Get-PnPFolderInFolder -FolderSiteRelativeUrl \"Shared Documents\" -ItemName \"Templates\"", - "Id": 502, "CommandName": "Get-PnPFolderInFolder", + "Command": "Get-PnPFolderInFolder -FolderSiteRelativeUrl \"Shared Documents\" -ItemName \"Templates\"", + "Id": 506, "Rank": 5 }, { - "Command": "Get-PnPFolderInFolder -FolderSiteRelativeUrl \"SitePages\" -Recurse", - "Id": 503, "CommandName": "Get-PnPFolderInFolder", + "Command": "Get-PnPFolderInFolder -FolderSiteRelativeUrl \"SitePages\" -Recurse", + "Id": 507, "Rank": 6 }, { - "Command": "Get-PnPFolderItem", - "Id": 504, "CommandName": "Get-PnPFolderItem", + "Command": "Get-PnPFolderItem", + "Id": 508, "Rank": 1 }, { - "Command": "Get-PnPFolderItem -Recurse", - "Id": 505, "CommandName": "Get-PnPFolderItem", + "Command": "Get-PnPFolderItem -Recurse", + "Id": 509, "Rank": 2 }, { - "Command": "Get-PnPFolderItem -Identity \"Shared Documents\"", - "Id": 506, "CommandName": "Get-PnPFolderItem", + "Command": "Get-PnPFolderItem -Identity \"Shared Documents\"", + "Id": 510, "Rank": 3 }, { - "Command": "Get-PnPFolderItem -FolderSiteRelativeUrl \"SitePages\" -ItemName \"Default.aspx\"", - "Id": 507, "CommandName": "Get-PnPFolderItem", + "Command": "Get-PnPFolderItem -FolderSiteRelativeUrl \"SitePages\" -ItemName \"Default.aspx\"", + "Id": 511, "Rank": 4 }, { - "Command": "Get-PnPFolderItem -FolderSiteRelativeUrl \"SitePages\" -ItemType Folder", - "Id": 508, "CommandName": "Get-PnPFolderItem", + "Command": "Get-PnPFolderItem -FolderSiteRelativeUrl \"SitePages\" -ItemType Folder", + "Id": 512, "Rank": 5 }, { - "Command": "Get-PnPFolderItem -FolderSiteRelativeUrl \"SitePages\" -Recursive", - "Id": 509, "CommandName": "Get-PnPFolderItem", + "Command": "Get-PnPFolderItem -FolderSiteRelativeUrl \"SitePages\" -Recursive", + "Id": 513, "Rank": 6 }, { - "Command": "Get-PnPFolderSharingLink -Folder \"/sites/demo/Shared Documents/Test\"", - "Id": 510, "CommandName": "Get-PnPFolderSharingLink", + "Command": "Get-PnPFolderSharingLink -Folder \"/sites/demo/Shared Documents/Test\"", + "Id": 514, "Rank": 1 }, { - "Command": "Get-PnPFolderStorageMetric", - "Id": 511, "CommandName": "Get-PnPFolderStorageMetric", + "Command": "Get-PnPFolderStorageMetric", + "Id": 515, "Rank": 1 }, { - "Command": "Get-PnPFolderStorageMetric -List \"Documents\"", - "Id": 512, "CommandName": "Get-PnPFolderStorageMetric", + "Command": "Get-PnPFolderStorageMetric -List \"Documents\"", + "Id": 516, "Rank": 2 }, { - "Command": "Get-PnPFolderStorageMetric -FolderSiteRelativeUrl \"Shared Documents\"", - "Id": 513, "CommandName": "Get-PnPFolderStorageMetric", + "Command": "Get-PnPFolderStorageMetric -FolderSiteRelativeUrl \"Shared Documents\"", + "Id": 517, "Rank": 3 }, { - "Command": "Get-PnPFooter", - "Id": 514, "CommandName": "Get-PnPFooter", + "Command": "Get-PnPFooter", + "Id": 518, "Rank": 1 }, { - "Command": "Get-PnPGraphAccessToken", - "Id": 515, "CommandName": "Get-PnPGraphAccessToken", + "Command": "Get-PnPGraphAccessToken", + "Id": 519, "Rank": 1 }, { - "Command": "Get-PnPGraphAccessToken -Decoded", - "Id": 516, "CommandName": "Get-PnPGraphAccessToken", + "Command": "Get-PnPGraphAccessToken -Decoded", + "Id": 520, "Rank": 2 }, { - "Command": "Get-PnPGraphSubscription", - "Id": 517, "CommandName": "Get-PnPGraphSubscription", + "Command": "Get-PnPGraphSubscription", + "Id": 521, "Rank": 1 }, { - "Command": "Get-PnPGraphSubscription -Identity 328c7693-5524-44ac-a946-73e02d6b0f98", - "Id": 518, "CommandName": "Get-PnPGraphSubscription", + "Command": "Get-PnPGraphSubscription -Identity 328c7693-5524-44ac-a946-73e02d6b0f98", + "Id": 522, "Rank": 2 }, { - "Command": "Get-PnPGroup", - "Id": 519, "CommandName": "Get-PnPGroup", + "Command": "Get-PnPGroup", + "Id": 523, "Rank": 1 }, { - "Command": "Get-PnPGroup -Identity 'My Site Users'", - "Id": 520, "CommandName": "Get-PnPGroup", + "Command": "Get-PnPGroup -Identity 'My Site Users'", + "Id": 524, "Rank": 2 }, { - "Command": "Get-PnPGroup -AssociatedMemberGroup", - "Id": 521, "CommandName": "Get-PnPGroup", + "Command": "Get-PnPGroup -AssociatedMemberGroup", + "Id": 525, "Rank": 3 }, { - "Command": "Get-PnPGroupMember -Group \"Marketing Site Members\"", - "Id": 522, "CommandName": "Get-PnPGroupMember", + "Command": "Get-PnPGroupMember -Group \"Marketing Site Members\"", + "Id": 526, "Rank": 1 }, { - "Command": "Get-PnPGroupMember -Group \"Marketing Site Members\" -User \"manager@domain.com\"", - "Id": 523, "CommandName": "Get-PnPGroupMember", + "Command": "Get-PnPGroupMember -Group \"Marketing Site Members\" -User \"manager@domain.com\"", + "Id": 527, "Rank": 2 }, { - "Command": "Get-PnPGroupPermissions -Identity 'My Site Members'", - "Id": 524, "CommandName": "Get-PnPGroupPermissions", + "Command": "Get-PnPGroupPermissions -Identity 'My Site Members'", + "Id": 528, "Rank": 1 }, { - "Command": "Get-PnPHideDefaultThemes", - "Id": 525, "CommandName": "Get-PnPHideDefaultThemes", + "Command": "Get-PnPHideDefaultThemes", + "Id": 529, "Rank": 1 }, { - "Command": "Get-PnPHomePage", - "Id": 526, "CommandName": "Get-PnPHomePage", + "Command": "Get-PnPHomePage", + "Id": 530, "Rank": 1 }, { - "Command": "Get-PnPHomeSite", - "Id": 527, "CommandName": "Get-PnPHomeSite", + "Command": "Get-PnPHomeSite", + "Id": 531, "Rank": 1 }, { - "Command": "Get-PnPHomeSite -IsVivaConnectionsDefaultStartForCompanyPortalSiteEnabled", - "Id": 528, "CommandName": "Get-PnPHomeSite", + "Command": "Get-PnPHomeSite -IsVivaConnectionsDefaultStartForCompanyPortalSiteEnabled", + "Id": 532, "Rank": 2 }, { - "Command": "Get-PnPHomeSite -Detailed", - "Id": 529, "CommandName": "Get-PnPHomeSite", + "Command": "Get-PnPHomeSite -Detailed", + "Id": 533, "Rank": 3 }, { - "Command": "Get-PnPHubSite", - "Id": 530, "CommandName": "Get-PnPHubSite", + "Command": "Get-PnPHubSite", + "Id": 534, "Rank": 1 }, { - "Command": "Get-PnPHubSite -Identity \"https://contoso.sharepoint.com/sites/myhubsite\"", - "Id": 531, "CommandName": "Get-PnPHubSite", + "Command": "Get-PnPHubSite -Identity \"https://contoso.sharepoint.com/sites/myhubsite\"", + "Id": 535, "Rank": 2 }, { - "Command": "Get-PnPHubSite -Identity \"bc07d4b8-1c2f-4184-8cc2-a52dfd6fe0c4\"", - "Id": 532, "CommandName": "Get-PnPHubSite", + "Command": "Get-PnPHubSite -Identity \"bc07d4b8-1c2f-4184-8cc2-a52dfd6fe0c4\"", + "Id": 536, "Rank": 3 }, { - "Command": "Get-PnPHubSiteChild", - "Id": 533, "CommandName": "Get-PnPHubSiteChild", + "Command": "Get-PnPHubSiteChild", + "Id": 537, "Rank": 1 }, { - "Command": "Get-PnPHubSiteChild -Identity \"https://contoso.sharepoint.com/sites/myhubsite\"", - "Id": 534, "CommandName": "Get-PnPHubSiteChild", + "Command": "Get-PnPHubSiteChild -Identity \"https://contoso.sharepoint.com/sites/myhubsite\"", + "Id": 538, "Rank": 2 }, { - "Command": "Get-PnPInPlaceRecordsManagement", - "Id": 535, "CommandName": "Get-PnPInPlaceRecordsManagement", + "Command": "Get-PnPInPlaceRecordsManagement", + "Id": 539, "Rank": 1 }, { - "Command": "Get-PnPIsSiteAliasAvailable -Identity \"HR\"", - "Id": 536, "CommandName": "Get-PnPIsSiteAliasAvailable", + "Command": "Get-PnPIsSiteAliasAvailable -Identity \"HR\"", + "Id": 540, "Rank": 1 }, { - "Command": "Get-PnPJavaScriptLink", - "Id": 537, "CommandName": "Get-PnPJavaScriptLink", + "Command": "Get-PnPJavaScriptLink", + "Id": 541, "Rank": 1 }, { - "Command": "Get-PnPJavaScriptLink -Scope All", - "Id": 538, "CommandName": "Get-PnPJavaScriptLink", + "Command": "Get-PnPJavaScriptLink -Scope All", + "Id": 542, "Rank": 2 }, { - "Command": "Get-PnPJavaScriptLink -Scope Web", - "Id": 539, "CommandName": "Get-PnPJavaScriptLink", + "Command": "Get-PnPJavaScriptLink -Scope Web", + "Id": 543, "Rank": 3 }, { - "Command": "Get-PnPJavaScriptLink -Scope Site", - "Id": 540, "CommandName": "Get-PnPJavaScriptLink", + "Command": "Get-PnPJavaScriptLink -Scope Site", + "Id": 544, "Rank": 4 }, { - "Command": "Get-PnPJavaScriptLink -Name Test", - "Id": 541, "CommandName": "Get-PnPJavaScriptLink", + "Command": "Get-PnPJavaScriptLink -Name Test", + "Id": 545, "Rank": 5 }, { - "Command": "Get-PnPKnowledgeHubSite", - "Id": 542, "CommandName": "Get-PnPKnowledgeHubSite", + "Command": "Get-PnPKnowledgeHubSite", + "Id": 546, "Rank": 1 }, { - "Command": "Get-PnPLabel", - "Id": 543, "CommandName": "Get-PnPLabel", + "Command": "Get-PnPLabel", + "Id": 547, "Rank": 1 }, { - "Command": "Get-PnPLabel -List \"Demo List\" -ValuesOnly", - "Id": 544, "CommandName": "Get-PnPLabel", + "Command": "Get-PnPLabel -List \"Demo List\" -ValuesOnly", + "Id": 548, "Rank": 2 }, { - "Command": "Get-PnPLargeListOperationStatus -Identity 9ea5d197-2227-4156-9ae1-725d74dc029d -OperationId 924e6a34-5c90-4d0d-8083-2efc6d1cf481", - "Id": 545, "CommandName": "Get-PnPLargeListOperationStatus", + "Command": "Get-PnPLargeListOperationStatus -Identity 9ea5d197-2227-4156-9ae1-725d74dc029d -OperationId 924e6a34-5c90-4d0d-8083-2efc6d1cf481", + "Id": 549, "Rank": 1 }, { - "Command": "Get-PnPLibraryFileVersionBatchDeleteJobStatus -Identity \"Documents\"", - "Id": 546, "CommandName": "Get-PnPLibraryFileVersionBatchDeleteJobStatus", + "Command": "Get-PnPLibraryFileVersionBatchDeleteJobStatus -Identity \"Documents\"", + "Id": 550, "Rank": 1 }, { - "Command": "Get-PnPLibraryFileVersionExpirationReportJobStatus -Identity \"Documents\" -ReportUrl \"https://contoso.sharepoint.com/sites/reports/MyReports/VersionReport.csv\"", - "Id": 547, "CommandName": "Get-PnPLibraryFileVersionExpirationReportJobStatus", + "Command": "Get-PnPLibraryFileVersionExpirationReportJobStatus -Identity \"Documents\" -ReportUrl \"https://contoso.sharepoint.com/sites/reports/MyReports/VersionReport.csv\"", + "Id": 551, "Rank": 1 }, { - "Command": "Get-PnPList", - "Id": 548, "CommandName": "Get-PnPList", + "Command": "Get-PnPList", + "Id": 552, "Rank": 1 }, { - "Command": "Get-PnPList -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe", - "Id": 549, "CommandName": "Get-PnPList", + "Command": "Get-PnPList -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe", + "Id": 553, "Rank": 2 }, { - "Command": "Get-PnPList -Identity Lists/Announcements", - "Id": 550, "CommandName": "Get-PnPList", + "Command": "Get-PnPList -Identity Lists/Announcements", + "Id": 554, "Rank": 3 }, { - "Command": "Get-PnPList | Where-Object {$_.RootFolder.ServerRelativeUrl -like \"/lists/*\"}", - "Id": 551, "CommandName": "Get-PnPList", + "Command": "Get-PnPList | Where-Object {$_.RootFolder.ServerRelativeUrl -like \"/lists/*\"}", + "Id": 555, "Rank": 4 }, { - "Command": "Get-PnPList -Includes HasUniqueRoleAssignments", - "Id": 552, "CommandName": "Get-PnPList", + "Command": "Get-PnPList -Includes HasUniqueRoleAssignments", + "Id": 556, "Rank": 5 }, { - "Command": "Get-PnPListDesign", - "Id": 553, "CommandName": "Get-PnPListDesign", + "Command": "Get-PnPListDesign", + "Id": 557, "Rank": 1 }, { - "Command": "Get-PnPListDesign -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd", - "Id": 554, "CommandName": "Get-PnPListDesign", + "Command": "Get-PnPListDesign -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd", + "Id": 558, "Rank": 2 }, { - "Command": "Get-PnPListDesign -Identity ListEvent", - "Id": 555, "CommandName": "Get-PnPListDesign", + "Command": "Get-PnPListDesign -Identity ListEvent", + "Id": 559, "Rank": 3 }, { - "Command": "Get-PnPListInformationRightsManagement -List \"Documents\"", - "Id": 556, "CommandName": "Get-PnPListInformationRightsManagement", + "Command": "Get-PnPListInformationRightsManagement -List \"Documents\"", + "Id": 560, "Rank": 1 }, { - "Command": "Get-PnPListItem -List Tasks", - "Id": 557, "CommandName": "Get-PnPListItem", + "Command": "Get-PnPListItem -List Tasks", + "Id": 561, "Rank": 1 }, { - "Command": "Get-PnPListItem -List Tasks -Id 1", - "Id": 558, "CommandName": "Get-PnPListItem", + "Command": "Get-PnPListItem -List Tasks -Id 1", + "Id": 562, "Rank": 2 }, { - "Command": "Get-PnPListItem -List Tasks -UniqueId bd6c5b3b-d960-4ee7-a02c-85dc6cd78cc3", - "Id": 559, "CommandName": "Get-PnPListItem", + "Command": "Get-PnPListItem -List Tasks -UniqueId bd6c5b3b-d960-4ee7-a02c-85dc6cd78cc3", + "Id": 563, "Rank": 3 }, { - "Command": "Get-PnPListItem -List Tasks -Query \"bd6c5b3b-d960-4ee7-a02c-85dc6cd78cc3\"", - "Id": 560, "CommandName": "Get-PnPListItem", + "Command": "Get-PnPListItem -List Tasks -Query \"bd6c5b3b-d960-4ee7-a02c-85dc6cd78cc3\"", + "Id": 564, "Rank": 4 }, { - "Command": "Get-PnPListItem -List Tasks -Query \"\"", - "Id": 561, "CommandName": "Get-PnPListItem", + "Command": "Get-PnPListItem -List Tasks -Query \"\"", + "Id": 565, "Rank": 5 }, { - "Command": "Get-PnPListItem -List Tasks -PageSize 1000", - "Id": 562, "CommandName": "Get-PnPListItem", + "Command": "Get-PnPListItem -List Tasks -PageSize 1000", + "Id": 566, "Rank": 6 }, { - "Command": "Get-PnPListItem -List Tasks -PageSize 1000 -ScriptBlock { Param($items) $items.Context.ExecuteQuery() } | ForEach-Object { $_.BreakRoleInheritance($true, $true) }", - "Id": 563, "CommandName": "Get-PnPListItem", + "Command": "Get-PnPListItem -List Tasks -PageSize 1000 -ScriptBlock { Param($items) $items.Context.ExecuteQuery() } | ForEach-Object { $_.BreakRoleInheritance($true, $true) }", + "Id": 567, "Rank": 7 }, { - "Command": "Get-PnPListItem -List Samples -FolderServerRelativeUrl \"/sites/contosomarketing/Lists/Samples/Demo\"", - "Id": 564, "CommandName": "Get-PnPListItem", + "Command": "Get-PnPListItem -List Samples -FolderServerRelativeUrl \"/sites/contosomarketing/Lists/Samples/Demo\"", + "Id": 568, "Rank": 8 }, { - "Command": "Get-PnPListItem -List Tasks -Id 1 -IncludeContentType", - "Id": 565, "CommandName": "Get-PnPListItem", + "Command": "Get-PnPListItem -List Tasks -Id 1 -IncludeContentType", + "Id": 569, "Rank": 9 }, { - "Command": "Get-PnPListItemAttachment -List \"Demo List\" -Identity 1 -Path \"C:\\temp\"", - "Id": 566, "CommandName": "Get-PnPListItemAttachment", + "Command": "Get-PnPListItemAttachment -List \"Demo List\" -Identity 1 -Path \"C:\\temp\"", + "Id": 570, "Rank": 1 }, { - "Command": "Get-PnPListItemAttachment -List \"Demo List\" -Identity 1 -Path \"C:\\temp\" -Force", - "Id": 567, "CommandName": "Get-PnPListItemAttachment", + "Command": "Get-PnPListItemAttachment -List \"Demo List\" -Identity 1 -Path \"C:\\temp\" -Force", + "Id": 571, "Rank": 2 }, { - "Command": "Get-PnPListItemComment -List Tasks -Identity 1", - "Id": 568, "CommandName": "Get-PnPListItemComment", + "Command": "Get-PnPListItemComment -List Tasks -Identity 1", + "Id": 572, "Rank": 1 }, { - "Command": "Get-PnPListItemPermission -List 'Documents' -Identity 1", - "Id": 569, "CommandName": "Get-PnPListItemPermission", + "Command": "Get-PnPListItemPermission -List 'Documents' -Identity 1", + "Id": 573, "Rank": 1 }, { - "Command": "Get-PnPListItemVersion -List \"Demo List\" -Identity 1", - "Id": 570, "CommandName": "Get-PnPListItemVersion", + "Command": "Get-PnPListItemVersion -List \"Demo List\" -Identity 1", + "Id": 574, "Rank": 1 }, { - "Command": "Get-PnPListPermissions -Identity DemoList -PrincipalId 60", - "Id": 571, "CommandName": "Get-PnPListPermissions", + "Command": "Get-PnPListPermissions -Identity DemoList -PrincipalId 60", + "Id": 575, "Rank": 1 }, { - "Command": "Get-PnPListPermissions -Identity DemoList -PrincipalId (Get-PnPGroup -Identity DemoGroup).Id", - "Id": 572, "CommandName": "Get-PnPListPermissions", + "Command": "Get-PnPListPermissions -Identity DemoList -PrincipalId (Get-PnPGroup -Identity DemoGroup).Id", + "Id": 576, "Rank": 2 }, { - "Command": "Get-PnPListRecordDeclaration -List \"Documents\"", - "Id": 573, "CommandName": "Get-PnPListRecordDeclaration", + "Command": "Get-PnPListRecordDeclaration -List \"Documents\"", + "Id": 577, "Rank": 1 }, { - "Command": "Get-PnPMasterPage", - "Id": 574, "CommandName": "Get-PnPMasterPage", + "Command": "Get-PnPMasterPage", + "Id": 578, "Rank": 1 }, { - "Command": "Get-PnPMessageCenterAnnouncement", - "Id": 575, "CommandName": "Get-PnPMessageCenterAnnouncement", + "Command": "Get-PnPMessageCenterAnnouncement", + "Id": 579, "Rank": 1 }, { - "Command": "Get-PnPMessageCenterAnnouncement -Identity \"MC123456\"", - "Id": 576, "CommandName": "Get-PnPMessageCenterAnnouncement", + "Command": "Get-PnPMessageCenterAnnouncement -Identity \"MC123456\"", + "Id": 580, "Rank": 2 }, { - "Command": "Get-PnPMicrosoft365ExpiringGroup", - "Id": 577, "CommandName": "Get-PnPMicrosoft365ExpiringGroup", + "Command": "Get-PnPMicrosoft365ExpiringGroup", + "Id": 581, "Rank": 1 }, { - "Command": "Get-PnPMicrosoft365ExpiringGroup -Limit 93", - "Id": 578, "CommandName": "Get-PnPMicrosoft365ExpiringGroup", + "Command": "Get-PnPMicrosoft365ExpiringGroup -Limit 93", + "Id": 582, "Rank": 2 }, { - "Command": "Get-PnPMicrosoft365Group", - "Id": 579, "CommandName": "Get-PnPMicrosoft365Group", + "Command": "Get-PnPMicrosoft365Group", + "Id": 583, "Rank": 1 }, { - "Command": "Get-PnPMicrosoft365Group -Identity $groupId", - "Id": 580, "CommandName": "Get-PnPMicrosoft365Group", + "Command": "Get-PnPMicrosoft365Group -Identity $groupId", + "Id": 584, "Rank": 2 }, { - "Command": "Get-PnPMicrosoft365Group -Identity $groupDisplayName", - "Id": 581, "CommandName": "Get-PnPMicrosoft365Group", + "Command": "Get-PnPMicrosoft365Group -Identity $groupDisplayName", + "Id": 585, "Rank": 3 }, { - "Command": "Get-PnPMicrosoft365Group -Identity $groupSiteMailNickName", - "Id": 582, "CommandName": "Get-PnPMicrosoft365Group", + "Command": "Get-PnPMicrosoft365Group -Identity $groupSiteMailNickName", + "Id": 586, "Rank": 4 }, { - "Command": "Get-PnPMicrosoft365Group -Identity $group", - "Id": 583, "CommandName": "Get-PnPMicrosoft365Group", + "Command": "Get-PnPMicrosoft365Group -Identity $group", + "Id": 587, "Rank": 5 }, { - "Command": "Get-PnPMicrosoft365Group -IncludeSiteUrl", - "Id": 584, "CommandName": "Get-PnPMicrosoft365Group", + "Command": "Get-PnPMicrosoft365Group -IncludeSiteUrl", + "Id": 588, "Rank": 6 }, { - "Command": "Get-PnPMicrosoft365GroupEndpoint", - "Id": 585, "CommandName": "Get-PnPMicrosoft365GroupEndpoint", + "Command": "Get-PnPMicrosoft365GroupEndpoint", + "Id": 589, "Rank": 1 }, { - "Command": "Get-PnPMicrosoft365GroupEndpoint -Identity \"IT Team\"", - "Id": 586, "CommandName": "Get-PnPMicrosoft365GroupEndpoint", + "Command": "Get-PnPMicrosoft365GroupEndpoint -Identity \"IT Team\"", + "Id": 590, "Rank": 2 }, { - "Command": "Get-PnPMicrosoft365GroupEndpoint -Identity e6212531-7f09-4c3b-bc2e-12cae26fb409", - "Id": 587, "CommandName": "Get-PnPMicrosoft365GroupEndpoint", + "Command": "Get-PnPMicrosoft365GroupEndpoint -Identity e6212531-7f09-4c3b-bc2e-12cae26fb409", + "Id": 591, "Rank": 3 }, { - "Command": "Get-PnPMicrosoft365GroupMember -Identity $groupId", - "Id": 588, "CommandName": "Get-PnPMicrosoft365GroupMember", + "Command": "Get-PnPMicrosoft365GroupMember -Identity $groupId", + "Id": 592, "Rank": 1 }, { - "Command": "Get-PnPMicrosoft365GroupMember -Identity $group", - "Id": 589, "CommandName": "Get-PnPMicrosoft365GroupMember", + "Command": "Get-PnPMicrosoft365GroupMember -Identity $group", + "Id": 593, "Rank": 2 }, { - "Command": "Get-PnPMicrosoft365GroupMember -Identity \"Sales\" | Where-Object UserType -eq Guest", - "Id": 590, "CommandName": "Get-PnPMicrosoft365GroupMember", + "Command": "Get-PnPMicrosoft365GroupMember -Identity \"Sales\" | Where-Object UserType -eq Guest", + "Id": 594, "Rank": 3 }, { - "Command": "Get-PnPMicrosoft365GroupOwner -Identity $groupId", - "Id": 591, "CommandName": "Get-PnPMicrosoft365GroupOwner", + "Command": "Get-PnPMicrosoft365GroupOwner -Identity $groupId", + "Id": 595, "Rank": 1 }, { - "Command": "Get-PnPMicrosoft365GroupOwner -Identity $group", - "Id": 592, "CommandName": "Get-PnPMicrosoft365GroupOwner", + "Command": "Get-PnPMicrosoft365GroupOwner -Identity $group", + "Id": 596, "Rank": 2 }, { - "Command": "Get-PnPMicrosoft365GroupSettings", - "Id": 593, "CommandName": "Get-PnPMicrosoft365GroupSettings", + "Command": "Get-PnPMicrosoft365GroupSettings", + "Id": 597, "Rank": 1 }, { - "Command": "Get-PnPMicrosoft365GroupSettings -Identity $groupId", - "Id": 594, "CommandName": "Get-PnPMicrosoft365GroupSettings", + "Command": "Get-PnPMicrosoft365GroupSettings -Identity $groupId", + "Id": 598, "Rank": 2 }, { - "Command": "Get-PnPMicrosoft365GroupSettingTemplates", - "Id": 595, "CommandName": "Get-PnPMicrosoft365GroupSettingTemplates", + "Command": "Get-PnPMicrosoft365GroupSettingTemplates", + "Id": 599, "Rank": 1 }, { - "Command": "Get-PnPMicrosoft365GroupSettingTemplates -Identity \"08d542b9-071f-4e16-94b0-74abb372e3d9\"", - "Id": 596, "CommandName": "Get-PnPMicrosoft365GroupSettingTemplates", + "Command": "Get-PnPMicrosoft365GroupSettingTemplates -Identity \"08d542b9-071f-4e16-94b0-74abb372e3d9\"", + "Id": 600, "Rank": 2 }, { - "Command": "Get-PnPMicrosoft365GroupTeam", - "Id": 597, "CommandName": "Get-PnPMicrosoft365GroupTeam", + "Command": "Get-PnPMicrosoft365GroupTeam", + "Id": 601, "Rank": 1 }, { - "Command": "Get-PnPMicrosoft365GroupTeam -Identity \"IT Team\"", - "Id": 598, "CommandName": "Get-PnPMicrosoft365GroupTeam", + "Command": "Get-PnPMicrosoft365GroupTeam -Identity \"IT Team\"", + "Id": 602, "Rank": 2 }, { - "Command": "Get-PnPMicrosoft365GroupTeam -Identity e6212531-7f09-4c3b-bc2e-12cae26fb409", - "Id": 599, "CommandName": "Get-PnPMicrosoft365GroupTeam", + "Command": "Get-PnPMicrosoft365GroupTeam -Identity e6212531-7f09-4c3b-bc2e-12cae26fb409", + "Id": 603, "Rank": 3 }, { - "Command": "Get-PnPMicrosoft365GroupYammerCommunity", - "Id": 600, "CommandName": "Get-PnPMicrosoft365GroupYammerCommunity", + "Command": "Get-PnPMicrosoft365GroupYammerCommunity", + "Id": 604, "Rank": 1 }, { - "Command": "Get-PnPMicrosoft365GroupYammerCommunity -Identity \"IT Community\"", - "Id": 601, "CommandName": "Get-PnPMicrosoft365GroupYammerCommunity", + "Command": "Get-PnPMicrosoft365GroupYammerCommunity -Identity \"IT Community\"", + "Id": 605, "Rank": 2 }, { - "Command": "Get-PnPMicrosoft365GroupYammerCommunity -Identity e6212531-7f09-4c3b-bc2e-12cae26fb409", - "Id": 602, "CommandName": "Get-PnPMicrosoft365GroupYammerCommunity", + "Command": "Get-PnPMicrosoft365GroupYammerCommunity -Identity e6212531-7f09-4c3b-bc2e-12cae26fb409", + "Id": 606, "Rank": 3 }, { - "Command": "Get-PnPNavigationNode", - "Id": 603, "CommandName": "Get-PnPNavigationNode", + "Command": "Get-PnPNavigationNode", + "Id": 607, "Rank": 1 }, { - "Command": "Get-PnPNavigationNode -Location QuickLaunch", - "Id": 604, "CommandName": "Get-PnPNavigationNode", + "Command": "Get-PnPNavigationNode -Location QuickLaunch", + "Id": 608, "Rank": 2 }, { - "Command": "Get-PnPNavigationNode -Location TopNavigationBar", - "Id": 605, "CommandName": "Get-PnPNavigationNode", + "Command": "Get-PnPNavigationNode -Location TopNavigationBar", + "Id": 609, "Rank": 3 }, { - "Command": "Get-PnPOrgAssetsLibrary", - "Id": 606, "CommandName": "Get-PnPOrgAssetsLibrary", + "Command": "Get-PnPOrgAssetsLibrary", + "Id": 610, "Rank": 1 }, { - "Command": "Get-PnPOrgNewsSite", - "Id": 607, "CommandName": "Get-PnPOrgNewsSite", + "Command": "Get-PnPOrgNewsSite", + "Id": 611, "Rank": 1 }, { - "Command": "Get-PnPPage -Identity \"MyPage.aspx\"", - "Id": 608, "CommandName": "Get-PnPPage", + "Command": "Get-PnPPage -Identity \"MyPage.aspx\"", + "Id": 612, "Rank": 1 }, { - "Command": "Get-PnPPage \"MyPage\"", - "Id": 609, "CommandName": "Get-PnPPage", + "Command": "Get-PnPPage \"MyPage\"", + "Id": 613, "Rank": 2 }, { - "Command": "Get-PnPPage \"Templates/MyPageTemplate\"", - "Id": 610, "CommandName": "Get-PnPPage", + "Command": "Get-PnPPage \"Templates/MyPageTemplate\"", + "Id": 614, "Rank": 3 }, { - "Command": "Get-PnPPage -Identity \"MyPage.aspx\" -Web (Get-PnPWeb -Identity \"Subsite1\")", - "Id": 611, "CommandName": "Get-PnPPage", + "Command": "Get-PnPPage -Identity \"MyPage.aspx\" -Web (Get-PnPWeb -Identity \"Subsite1\")", + "Id": 615, "Rank": 4 }, { - "Command": "Get-PnPPageComponent -Page Home", - "Id": 612, "CommandName": "Get-PnPPageComponent", + "Command": "Get-PnPPageComponent -Page Home", + "Id": 616, "Rank": 1 }, { - "Command": "Get-PnPPageComponent -Page Home -InstanceId a2875399-d6ff-43a0-96da-be6ae5875f82", - "Id": 613, "CommandName": "Get-PnPPageComponent", + "Command": "Get-PnPPageComponent -Page Home -InstanceId a2875399-d6ff-43a0-96da-be6ae5875f82", + "Id": 617, "Rank": 2 }, { - "Command": "Get-PnPPageComponent -Page Home -ListAvailable", - "Id": 614, "CommandName": "Get-PnPPageComponent", + "Command": "Get-PnPPageComponent -Page Home -ListAvailable", + "Id": 618, "Rank": 3 }, { - "Command": "Get-PnPPageLikedByInformation -Identity \"MyPage.aspx\"", - "Id": 615, "CommandName": "Get-PnPPageLikedByInformation", + "Command": "Get-PnPPageLikedByInformation -Identity \"MyPage.aspx\"", + "Id": 619, "Rank": 1 }, { - "Command": "Get-PnPPageLikedByInformation \"MyPage\"", - "Id": 616, "CommandName": "Get-PnPPageLikedByInformation", + "Command": "Get-PnPPageLikedByInformation \"MyPage\"", + "Id": 620, "Rank": 2 }, { - "Command": "Get-PnPPageLikedByInformation -Identity \"MyPage.aspx\" -Web (Get-PnPWeb -Identity \"Subsite1\")", - "Id": 617, "CommandName": "Get-PnPPageLikedByInformation", + "Command": "Get-PnPPageLikedByInformation -Identity \"MyPage.aspx\" -Web (Get-PnPWeb -Identity \"Subsite1\")", + "Id": 621, "Rank": 3 }, { - "Command": "Get-PnPPageSchedulingEnabled", - "Id": 618, "CommandName": "Get-PnPPageSchedulingEnabled", + "Command": "Get-PnPPageSchedulingEnabled", + "Id": 622, "Rank": 1 }, { - "Command": "Get-PnPPlannerBucket -Group \"Marketing\" -Plan \"Conference Plan\"", - "Id": 619, "CommandName": "Get-PnPPlannerBucket", + "Command": "Get-PnPPlannerBucket -Group \"Marketing\" -Plan \"Conference Plan\"", + "Id": 623, "Rank": 1 }, { - "Command": "Get-PnPPlannerConfiguration", - "Id": 620, "CommandName": "Get-PnPPlannerConfiguration", + "Command": "Get-PnPPlannerConfiguration", + "Id": 624, "Rank": 1 }, { - "Command": "Get-PnPPlannerPlan -Group \"Marketing\"", - "Id": 621, "CommandName": "Get-PnPPlannerPlan", + "Command": "Get-PnPPlannerPlan -Group \"Marketing\"", + "Id": 625, "Rank": 1 }, { - "Command": "Get-PnPPlannerPlan -Group \"Marketing\" -Identity \"Conference Plan\"", - "Id": 622, "CommandName": "Get-PnPPlannerPlan", + "Command": "Get-PnPPlannerPlan -Group \"Marketing\" -Identity \"Conference Plan\"", + "Id": 626, "Rank": 2 }, { - "Command": "Get-PnPPlannerPlan -Id \"gndWOTSK60GfPQfiDDj43JgACDCb\" -ResolveIdentities", - "Id": 623, "CommandName": "Get-PnPPlannerPlan", + "Command": "Get-PnPPlannerPlan -Id \"gndWOTSK60GfPQfiDDj43JgACDCb\" -ResolveIdentities", + "Id": 627, "Rank": 3 }, { - "Command": "Get-PnPPlannerRosterMember -Identity \"6519868f-868f-6519-8f86-19658f861965\"", - "Id": 624, "CommandName": "Get-PnPPlannerRosterMember", + "Command": "Get-PnPPlannerRosterMember -Identity \"6519868f-868f-6519-8f86-19658f861965\"", + "Id": 628, "Rank": 1 }, { - "Command": "Get-PnPPlannerRosterPlan -Identity \"abcdefgh\"", - "Id": 625, "CommandName": "Get-PnPPlannerRosterPlan", + "Command": "Get-PnPPlannerRosterPlan -Identity \"abcdefgh\"", + "Id": 629, "Rank": 1 }, { - "Command": "Get-PnPPlannerRosterPlan -User \"johndoe@contoso.onmicrosoft.com\"", - "Id": 626, "CommandName": "Get-PnPPlannerRosterPlan", + "Command": "Get-PnPPlannerRosterPlan -User \"johndoe@contoso.onmicrosoft.com\"", + "Id": 630, "Rank": 2 }, { - "Command": "Get-PnPPlannerTask -Group \"Marketing\" -Plan \"Conference Plan\"", - "Id": 627, "CommandName": "Get-PnPPlannerTask", + "Command": "Get-PnPPlannerTask -Group \"Marketing\" -Plan \"Conference Plan\"", + "Id": 631, "Rank": 1 }, { - "Command": "Get-PnPPlannerTask -PlanId \"QvfkTd1mc02gwxHjHC_43JYABhAy\"", - "Id": 628, "CommandName": "Get-PnPPlannerTask", + "Command": "Get-PnPPlannerTask -PlanId \"QvfkTd1mc02gwxHjHC_43JYABhAy\"", + "Id": 632, "Rank": 2 }, { - "Command": "Get-PnPPlannerTask -TaskId \"QvfkTd1mc02gwxHjHC_43JYABhAy\"", - "Id": 629, "CommandName": "Get-PnPPlannerTask", + "Command": "Get-PnPPlannerTask -TaskId \"QvfkTd1mc02gwxHjHC_43JYABhAy\"", + "Id": 633, "Rank": 3 }, { - "Command": "Get-PnPPlannerUserPolicy -Identity \"johndoe@contoso.onmicrosoft.com\"", - "Id": 630, "CommandName": "Get-PnPPlannerUserPolicy", + "Command": "Get-PnPPlannerUserPolicy -Identity \"johndoe@contoso.onmicrosoft.com\"", + "Id": 634, "Rank": 1 }, { - "Command": "Get-PnPPowerPlatformCustomConnector -Environment (Get-PnPPowerPlatformEnvironment)", - "Id": 631, "CommandName": "Get-PnPPowerPlatformCustomConnector", + "Command": "Get-PnPPowerPlatformCustomConnector -Environment (Get-PnPPowerPlatformEnvironment)", + "Id": 635, "Rank": 1 }, { - "Command": "Get-PnPPowerPlatformEnvironment", - "Id": 632, "CommandName": "Get-PnPPowerPlatformEnvironment", + "Command": "Get-PnPPowerPlatformEnvironment", + "Id": 636, "Rank": 1 }, { - "Command": "Get-PnPPowerPlatformEnvironment -IsDefault $true", - "Id": 633, "CommandName": "Get-PnPPowerPlatformEnvironment", + "Command": "Get-PnPPowerPlatformEnvironment -IsDefault $true", + "Id": 637, "Rank": 2 }, { - "Command": "Get-PnPPowerPlatformEnvironment -Identity \"MyOrganization (default)\"", - "Id": 634, "CommandName": "Get-PnPPowerPlatformEnvironment", + "Command": "Get-PnPPowerPlatformEnvironment -Identity \"MyOrganization (default)\"", + "Id": 638, "Rank": 3 }, { - "Command": "Get-PnPPowerPlatformSolution -Environment (Get-PnPPowerPlatformEnvironment)", - "Id": 635, "CommandName": "Get-PnPPowerPlatformSolution", + "Command": "Get-PnPPowerPlatformSolution -Environment (Get-PnPPowerPlatformEnvironment)", + "Id": 639, "Rank": 1 }, { - "Command": "Get-PnPPowerPlatformSolution -Environment (Get-PnPPowerPlatformEnvironment -IsDefault) -Name 'My Solution Name'", - "Id": 636, "CommandName": "Get-PnPPowerPlatformSolution", + "Command": "Get-PnPPowerPlatformSolution -Environment (Get-PnPPowerPlatformEnvironment -IsDefault) -Name 'My Solution Name'", + "Id": 640, "Rank": 2 }, { - "Command": "Get-PnPPowerShellTelemetryEnabled", - "Id": 637, "CommandName": "Get-PnPPowerShellTelemetryEnabled", + "Command": "Get-PnPPowerShellTelemetryEnabled", + "Id": 641, "Rank": 1 }, { - "Command": "Get-PnPPropertyBag", - "Id": 638, "CommandName": "Get-PnPPropertyBag", + "Command": "Get-PnPPropertyBag", + "Id": 642, "Rank": 1 }, { - "Command": "Get-PnPPropertyBag -Key MyKey", - "Id": 639, "CommandName": "Get-PnPPropertyBag", + "Command": "Get-PnPPropertyBag -Key MyKey", + "Id": 643, "Rank": 2 }, { - "Command": "Get-PnPPropertyBag -Folder /MyFolder", - "Id": 640, "CommandName": "Get-PnPPropertyBag", + "Command": "Get-PnPPropertyBag -Folder /MyFolder", + "Id": 644, "Rank": 3 }, { - "Command": "Get-PnPPropertyBag -Folder /MyFolder -Key vti_mykey", - "Id": 641, "CommandName": "Get-PnPPropertyBag", + "Command": "Get-PnPPropertyBag -Folder /MyFolder -Key vti_mykey", + "Id": 645, "Rank": 4 }, { - "Command": "Get-PnPPropertyBag -Folder / -Key vti_mykey", - "Id": 642, "CommandName": "Get-PnPPropertyBag", + "Command": "Get-PnPPropertyBag -Folder / -Key vti_mykey", + "Id": 646, "Rank": 5 }, { - "Command": "Get-PnPPublishingImageRendition", - "Id": 643, "CommandName": "Get-PnPPublishingImageRendition", + "Command": "Get-PnPPublishingImageRendition", + "Id": 647, "Rank": 1 }, { - "Command": "Get-PnPPublishingImageRendition -Identity \"Test\"", - "Id": 644, "CommandName": "Get-PnPPublishingImageRendition", + "Command": "Get-PnPPublishingImageRendition -Identity \"Test\"", + "Id": 648, "Rank": 2 }, { - "Command": "Get-PnPPublishingImageRendition -Identity 2", - "Id": 645, "CommandName": "Get-PnPPublishingImageRendition", + "Command": "Get-PnPPublishingImageRendition -Identity 2", + "Id": 649, "Rank": 3 }, { - "Command": "Get-PnPRecycleBinItem", - "Id": 646, "CommandName": "Get-PnPRecycleBinItem", + "Command": "Get-PnPRecycleBinItem", + "Id": 650, "Rank": 1 }, { - "Command": "Get-PnPRecycleBinItem -Identity f3ef6195-9400-4121-9d1c-c997fb5b86c2", - "Id": 647, "CommandName": "Get-PnPRecycleBinItem", + "Command": "Get-PnPRecycleBinItem -Identity f3ef6195-9400-4121-9d1c-c997fb5b86c2", + "Id": 651, "Rank": 2 }, { - "Command": "Get-PnPRecycleBinItem -FirstStage", - "Id": 648, "CommandName": "Get-PnPRecycleBinItem", + "Command": "Get-PnPRecycleBinItem -FirstStage", + "Id": 652, "Rank": 3 }, { - "Command": "Get-PnPRecycleBinItem -SecondStage", - "Id": 649, "CommandName": "Get-PnPRecycleBinItem", + "Command": "Get-PnPRecycleBinItem -SecondStage", + "Id": 653, "Rank": 4 }, { - "Command": "Get-PnPRecycleBinItem -RowLimit 10000", - "Id": 650, "CommandName": "Get-PnPRecycleBinItem", + "Command": "Get-PnPRecycleBinItem -RowLimit 10000", + "Id": 654, "Rank": 5 }, { - "Command": "Get-PnPRequestAccessEmails", - "Id": 651, "CommandName": "Get-PnPRequestAccessEmails", + "Command": "Get-PnPRequestAccessEmails", + "Id": 655, "Rank": 1 }, { - "Command": "Get-PnPRoleDefinition", - "Id": 652, "CommandName": "Get-PnPRoleDefinition", + "Command": "Get-PnPRoleDefinition", + "Id": 656, "Rank": 1 }, { - "Command": "Get-PnPRoleDefinition -Identity Read", - "Id": 653, "CommandName": "Get-PnPRoleDefinition", + "Command": "Get-PnPRoleDefinition -Identity Read", + "Id": 657, "Rank": 2 }, { - "Command": "Get-PnPRoleDefinition | Where-Object { $_.RoleTypeKind -eq \"Administrator\" }", - "Id": 654, "CommandName": "Get-PnPRoleDefinition", + "Command": "Get-PnPRoleDefinition | Where-Object { $_.RoleTypeKind -eq \"Administrator\" }", + "Id": 658, "Rank": 3 }, { - "Command": "Get-PnPSearchConfiguration", - "Id": 655, "CommandName": "Get-PnPSearchConfiguration", + "Command": "Get-PnPSearchConfiguration", + "Id": 659, "Rank": 1 }, { - "Command": "Get-PnPSearchConfiguration -Scope Site", - "Id": 656, "CommandName": "Get-PnPSearchConfiguration", + "Command": "Get-PnPSearchConfiguration -Scope Site", + "Id": 660, "Rank": 2 }, { - "Command": "Get-PnPSearchConfiguration -Scope Subscription", - "Id": 657, "CommandName": "Get-PnPSearchConfiguration", + "Command": "Get-PnPSearchConfiguration -Scope Subscription", + "Id": 661, "Rank": 3 }, { - "Command": "Get-PnPSearchConfiguration -Path searchconfig.xml -Scope Subscription", - "Id": 658, "CommandName": "Get-PnPSearchConfiguration", + "Command": "Get-PnPSearchConfiguration -Path searchconfig.xml -Scope Subscription", + "Id": 662, "Rank": 4 }, { - "Command": "Get-PnPSearchConfiguration -Scope Site -OutputFormat ManagedPropertyMappings", - "Id": 659, "CommandName": "Get-PnPSearchConfiguration", + "Command": "Get-PnPSearchConfiguration -Scope Site -OutputFormat ManagedPropertyMappings", + "Id": 663, "Rank": 5 }, { - "Command": "Get-PnPSearchConfiguration -Scope Site -PromotedResultsToBookmarkCSV -Path bookmarks.csv", - "Id": 660, "CommandName": "Get-PnPSearchConfiguration", + "Command": "Get-PnPSearchConfiguration -Scope Site -PromotedResultsToBookmarkCSV -Path bookmarks.csv", + "Id": 664, "Rank": 6 }, { - "Command": "Get-PnPSearchConfiguration -Scope Site -PromotedResultsToBookmarkCSV -Path bookmarks.csv -BookmarkStatus Published", - "Id": 661, "CommandName": "Get-PnPSearchConfiguration", + "Command": "Get-PnPSearchConfiguration -Scope Site -PromotedResultsToBookmarkCSV -Path bookmarks.csv -BookmarkStatus Published", + "Id": 665, "Rank": 7 }, { - "Command": "Get-PnPSearchConfiguration -Scope Subscription -PromotedResultsToBookmarkCSV -ExcludeVisualPromotedResults $false", - "Id": 662, "CommandName": "Get-PnPSearchConfiguration", + "Command": "Get-PnPSearchConfiguration -Scope Subscription -PromotedResultsToBookmarkCSV -ExcludeVisualPromotedResults $false", + "Id": 666, "Rank": 8 }, { - "Command": "Get-PnPSearchCrawlLog", - "Id": 663, "CommandName": "Get-PnPSearchCrawlLog", + "Command": "Get-PnPSearchCrawlLog", + "Id": 667, "Rank": 1 }, { - "Command": "Get-PnPSearchCrawlLog -Filter \"https://contoso-my.sharepoint.com/personal\"", - "Id": 664, "CommandName": "Get-PnPSearchCrawlLog", + "Command": "Get-PnPSearchCrawlLog -Filter \"https://contoso-my.sharepoint.com/personal\"", + "Id": 668, "Rank": 2 }, { - "Command": "Get-PnPSearchCrawlLog -ContentSource UserProfiles", - "Id": 665, "CommandName": "Get-PnPSearchCrawlLog", + "Command": "Get-PnPSearchCrawlLog -ContentSource UserProfiles", + "Id": 669, "Rank": 3 }, { - "Command": "Get-PnPSearchCrawlLog -ContentSource UserProfiles -Filter \"mikael\"", - "Id": 666, "CommandName": "Get-PnPSearchCrawlLog", + "Command": "Get-PnPSearchCrawlLog -ContentSource UserProfiles -Filter \"mikael\"", + "Id": 670, "Rank": 4 }, { - "Command": "Get-PnPSearchCrawlLog -ContentSource Sites -LogLevel Error -RowLimit 10", - "Id": 667, "CommandName": "Get-PnPSearchCrawlLog", + "Command": "Get-PnPSearchCrawlLog -ContentSource Sites -LogLevel Error -RowLimit 10", + "Id": 671, "Rank": 5 }, { - "Command": "Get-PnPSearchCrawlLog -EndDate (Get-Date).AddDays(-100)", - "Id": 668, "CommandName": "Get-PnPSearchCrawlLog", + "Command": "Get-PnPSearchCrawlLog -EndDate (Get-Date).AddDays(-100)", + "Id": 672, "Rank": 6 }, { - "Command": "Get-PnPSearchCrawlLog -RowFilter 3 -RawFormat", - "Id": 669, "CommandName": "Get-PnPSearchCrawlLog", + "Command": "Get-PnPSearchCrawlLog -RowFilter 3 -RawFormat", + "Id": 673, "Rank": 7 }, { - "Command": "Get-PnPSearchSettings", - "Id": 670, + "CommandName": "Get-PnPSearchExternalConnection", + "Command": "Get-PnPSearchExternalConnection", + "Id": 674, + "Rank": 1 + }, + { + "CommandName": "Get-PnPSearchExternalConnection", + "Command": "Get-PnPSearchExternalConnection -Identity \"pnppowershell\"", + "Id": 675, + "Rank": 2 + }, + { + "CommandName": "Get-PnPSearchExternalSchema", + "Command": "Get-PnPSearchExternalSchema -ConnectionId \"pnppowershell\"", + "Id": 676, + "Rank": 1 + }, + { "CommandName": "Get-PnPSearchSettings", + "Command": "Get-PnPSearchSettings", + "Id": 677, "Rank": 1 }, { - "Command": "Get-PnPServiceCurrentHealth", - "Id": 671, "CommandName": "Get-PnPServiceCurrentHealth", + "Command": "Get-PnPServiceCurrentHealth", + "Id": 678, "Rank": 1 }, { - "Command": "Get-PnPServiceCurrentHealth -Identity \"SharePoint Online\"", - "Id": 672, "CommandName": "Get-PnPServiceCurrentHealth", + "Command": "Get-PnPServiceCurrentHealth -Identity \"SharePoint Online\"", + "Id": 679, "Rank": 2 }, { - "Command": "Get-PnPServiceHealthIssue", - "Id": 673, "CommandName": "Get-PnPServiceHealthIssue", + "Command": "Get-PnPServiceHealthIssue", + "Id": 680, "Rank": 1 }, { - "Command": "Get-PnPServiceHealthIssue -Identity \"EX123456\"", - "Id": 674, "CommandName": "Get-PnPServiceHealthIssue", + "Command": "Get-PnPServiceHealthIssue -Identity \"EX123456\"", + "Id": 681, "Rank": 2 }, { - "Command": "Get-PnPSharePointAddIn", - "Id": 675, "CommandName": "Get-PnPSharePointAddIn", + "Command": "Get-PnPSharePointAddIn", + "Id": 682, "Rank": 1 }, { - "Command": "Get-PnPSharePointAddIn -IncludeSubsites", - "Id": 676, "CommandName": "Get-PnPSharePointAddIn", + "Command": "Get-PnPSharePointAddIn -IncludeSubsites", + "Id": 683, "Rank": 2 }, { - "Command": "Get-PnPSharingForNonOwnersOfSite", - "Id": 677, "CommandName": "Get-PnPSharingForNonOwnersOfSite", + "Command": "Get-PnPSharingForNonOwnersOfSite", + "Id": 684, "Rank": 1 }, { - "Command": "Get-PnPSite", - "Id": 678, "CommandName": "Get-PnPSite", + "Command": "Get-PnPSite", + "Id": 685, "Rank": 1 }, { - "Command": "Get-PnPSite -Includes RootWeb,ServerRelativeUrl", - "Id": 679, "CommandName": "Get-PnPSite", + "Command": "Get-PnPSite -Includes RootWeb,ServerRelativeUrl", + "Id": 686, "Rank": 2 }, { - "Command": "Get-PnPSiteAnalyticsData -All", - "Id": 680, "CommandName": "Get-PnPSiteAnalyticsData", + "Command": "Get-PnPSiteAnalyticsData -All", + "Id": 687, "Rank": 1 }, { - "Command": "Get-PnPSiteAnalyticsData -LastSevenDays", - "Id": 681, "CommandName": "Get-PnPSiteAnalyticsData", + "Command": "Get-PnPSiteAnalyticsData -LastSevenDays", + "Id": 688, "Rank": 2 }, { - "Command": "Get-PnPSiteAnalyticsData -StartDate (Get-date).AddDays(-15) -EndDate (Get-date) -AnalyticsAggregationInterval Day", - "Id": 682, "CommandName": "Get-PnPSiteAnalyticsData", + "Command": "Get-PnPSiteAnalyticsData -StartDate (Get-date).AddDays(-15) -EndDate (Get-date) -AnalyticsAggregationInterval Day", + "Id": 689, "Rank": 3 }, { - "Command": "Get-PnPSiteAnalyticsData -Identity \"https://tenant.sharepoint.com/sites/mysite\" -StartDate (Get-date).AddDays(-15) -EndDate (Get-date) -AnalyticsAggregationInterval Day", - "Id": 683, "CommandName": "Get-PnPSiteAnalyticsData", + "Command": "Get-PnPSiteAnalyticsData -Identity \"https://tenant.sharepoint.com/sites/mysite\" -StartDate (Get-date).AddDays(-15) -EndDate (Get-date) -AnalyticsAggregationInterval Day", + "Id": 690, "Rank": 4 }, { - "Command": "Get-PnPSiteClosure", - "Id": 684, "CommandName": "Get-PnPSiteClosure", + "Command": "Get-PnPSiteClosure", + "Id": 691, "Rank": 1 }, { - "Command": "Get-PnPSiteCollectionAdmin", - "Id": 685, "CommandName": "Get-PnPSiteCollectionAdmin", + "Command": "Get-PnPSiteCollectionAdmin", + "Id": 692, "Rank": 1 }, { - "Command": "Get-PnPSiteCollectionAppCatalog", - "Id": 686, "CommandName": "Get-PnPSiteCollectionAppCatalog", + "Command": "Get-PnPSiteCollectionAppCatalog", + "Id": 693, "Rank": 1 }, { - "Command": "Get-PnPSiteCollectionAppCatalog -CurrentSite", - "Id": 687, "CommandName": "Get-PnPSiteCollectionAppCatalog", + "Command": "Get-PnPSiteCollectionAppCatalog -CurrentSite", + "Id": 694, "Rank": 2 }, { - "Command": "Get-PnPSiteCollectionAppCatalog -ExcludeDeletedSites", - "Id": 688, "CommandName": "Get-PnPSiteCollectionAppCatalog", + "Command": "Get-PnPSiteCollectionAppCatalog -ExcludeDeletedSites", + "Id": 695, "Rank": 3 }, { - "Command": "Get-PnPSiteCollectionTermStore", - "Id": 689, "CommandName": "Get-PnPSiteCollectionTermStore", + "Command": "Get-PnPSiteCollectionTermStore", + "Id": 696, "Rank": 1 }, { - "Command": "Get-PnPSiteDesign", - "Id": 690, "CommandName": "Get-PnPSiteDesign", + "Command": "Get-PnPSiteDesign", + "Id": 697, "Rank": 1 }, { - "Command": "Get-PnPSiteDesign -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd", - "Id": 691, "CommandName": "Get-PnPSiteDesign", + "Command": "Get-PnPSiteDesign -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd", + "Id": 698, "Rank": 2 }, { - "Command": "Get-PnPSiteDesignRights -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd", - "Id": 692, "CommandName": "Get-PnPSiteDesignRights", + "Command": "Get-PnPSiteDesignRights -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd", + "Id": 699, "Rank": 1 }, { - "Command": "Get-PnPSiteDesignRun", - "Id": 693, "CommandName": "Get-PnPSiteDesignRun", + "Command": "Get-PnPSiteDesignRun", + "Id": 700, "Rank": 1 }, { - "Command": "Get-PnPSiteDesignRun -WebUrl \"https://mytenant.sharepoint.com/sites/project\"", - "Id": 694, "CommandName": "Get-PnPSiteDesignRun", + "Command": "Get-PnPSiteDesignRun -WebUrl \"https://mytenant.sharepoint.com/sites/project\"", + "Id": 701, "Rank": 2 }, { - "Command": "Get-PnPSiteDesignTask -Identity 501z8c32-4147-44d4-8607-26c2f67cae82", - "Id": 695, "CommandName": "Get-PnPSiteDesignTask", + "Command": "Get-PnPSiteDesignTask -Identity 501z8c32-4147-44d4-8607-26c2f67cae82", + "Id": 702, "Rank": 1 }, { - "Command": "Get-PnPSiteDesignTask", - "Id": 696, "CommandName": "Get-PnPSiteDesignTask", + "Command": "Get-PnPSiteDesignTask", + "Id": 703, "Rank": 2 }, { - "Command": "Get-PnPSiteDesignTask -WebUrl \"https://contoso.sharepoint.com/sites/project\"", - "Id": 697, "CommandName": "Get-PnPSiteDesignTask", + "Command": "Get-PnPSiteDesignTask -WebUrl \"https://contoso.sharepoint.com/sites/project\"", + "Id": 704, "Rank": 3 }, { - "Command": "Get-PnPSiteFileVersionBatchDeleteJobStatus", - "Id": 698, "CommandName": "Get-PnPSiteFileVersionBatchDeleteJobStatus", + "Command": "Get-PnPSiteFileVersionBatchDeleteJobStatus", + "Id": 705, "Rank": 1 }, { - "Command": "Get-PnPSiteFileVersionExpirationReportJobStatus -ReportUrl \"https://contoso.sharepoint.com/sites/reports/MyReports/VersionReport.csv\"", - "Id": 699, "CommandName": "Get-PnPSiteFileVersionExpirationReportJobStatus", + "Command": "Get-PnPSiteFileVersionExpirationReportJobStatus -ReportUrl \"https://contoso.sharepoint.com/sites/reports/MyReports/VersionReport.csv\"", + "Id": 706, "Rank": 1 }, { - "Command": "Get-PnPSiteGroup", - "Id": 700, "CommandName": "Get-PnPSiteGroup", + "Command": "Get-PnPSiteGroup", + "Id": 707, "Rank": 1 }, { - "Command": "Get-PnPSiteGroup -Site \"https://contoso.sharepoint.com/sites/siteA\"", - "Id": 701, "CommandName": "Get-PnPSiteGroup", + "Command": "Get-PnPSiteGroup -Site \"https://contoso.sharepoint.com/sites/siteA\"", + "Id": 708, "Rank": 2 }, { - "Command": "Get-PnPSiteGroup -Group \"SiteA Members\"", - "Id": 702, "CommandName": "Get-PnPSiteGroup", + "Command": "Get-PnPSiteGroup -Group \"SiteA Members\"", + "Id": 709, "Rank": 3 }, { - "Command": "Get-PnPSiteGroup -Group \"SiteA Members\" -Site \"https://contoso.sharepoint.com/sites/siteA\"", - "Id": 703, "CommandName": "Get-PnPSiteGroup", + "Command": "Get-PnPSiteGroup -Group \"SiteA Members\" -Site \"https://contoso.sharepoint.com/sites/siteA\"", + "Id": 710, "Rank": 4 }, { - "Command": "Get-PnPSitePolicy", - "Id": 704, "CommandName": "Get-PnPSitePolicy", + "Command": "Get-PnPSitePolicy", + "Id": 711, "Rank": 1 }, { - "Command": "Get-PnPSitePolicy -AllAvailable", - "Id": 705, "CommandName": "Get-PnPSitePolicy", + "Command": "Get-PnPSitePolicy -AllAvailable", + "Id": 712, "Rank": 2 }, { - "Command": "Get-PnPSitePolicy -Name \"Contoso HBI\"", - "Id": 706, "CommandName": "Get-PnPSitePolicy", + "Command": "Get-PnPSitePolicy -Name \"Contoso HBI\"", + "Id": 713, "Rank": 3 }, { - "Command": "Get-PnPSiteScript", - "Id": 707, "CommandName": "Get-PnPSiteScript", + "Command": "Get-PnPSiteScript", + "Id": 714, "Rank": 1 }, { - "Command": "Get-PnPSiteScript -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd", - "Id": 708, "CommandName": "Get-PnPSiteScript", + "Command": "Get-PnPSiteScript -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd", + "Id": 715, "Rank": 2 }, { - "Command": "Get-PnPSiteScriptFromList -List \"MyList\"", - "Id": 709, "CommandName": "Get-PnPSiteScriptFromList", + "Command": "Get-PnPSiteScriptFromList -List \"MyList\"", + "Id": 716, "Rank": 1 }, { - "Command": "Get-PnPSiteScriptFromList -Url \"https://contoso.sharepoint.com/sites/teamsite/lists/MyList\"", - "Id": 710, "CommandName": "Get-PnPSiteScriptFromList", + "Command": "Get-PnPSiteScriptFromList -Url \"https://contoso.sharepoint.com/sites/teamsite/lists/MyList\"", + "Id": 717, "Rank": 2 }, { - "Command": "Get-PnPSiteScriptFromList -Url \"https://contoso.sharepoint.com/sites/teamsite/Shared Documents\"", - "Id": 711, "CommandName": "Get-PnPSiteScriptFromList", + "Command": "Get-PnPSiteScriptFromList -Url \"https://contoso.sharepoint.com/sites/teamsite/Shared Documents\"", + "Id": 718, "Rank": 3 }, { - "Command": "Get-PnPSiteScriptFromWeb -IncludeAll", - "Id": 712, "CommandName": "Get-PnPSiteScriptFromWeb", + "Command": "Get-PnPSiteScriptFromWeb -IncludeAll", + "Id": 719, "Rank": 1 }, { - "Command": "Get-PnPSiteScriptFromWeb -Url \"https://contoso.sharepoint.com/sites/teamsite\" -IncludeAll", - "Id": 713, "CommandName": "Get-PnPSiteScriptFromWeb", + "Command": "Get-PnPSiteScriptFromWeb -Url \"https://contoso.sharepoint.com/sites/teamsite\" -IncludeAll", + "Id": 720, "Rank": 2 }, { - "Command": "Get-PnPSiteScriptFromWeb -Url \"https://contoso.sharepoint.com/sites/teamsite\" -IncludeAll -Lists \"Shared Documents\",\"Lists\\MyList\"", - "Id": 714, "CommandName": "Get-PnPSiteScriptFromWeb", + "Command": "Get-PnPSiteScriptFromWeb -Url \"https://contoso.sharepoint.com/sites/teamsite\" -IncludeAll -Lists \"Shared Documents\",\"Lists\\MyList\"", + "Id": 721, "Rank": 3 }, { - "Command": "Get-PnPSiteScriptFromWeb -Url \"https://contoso.sharepoint.com/sites/teamsite\" -IncludeBranding -IncludeLinksToExportedItems", - "Id": 715, "CommandName": "Get-PnPSiteScriptFromWeb", + "Command": "Get-PnPSiteScriptFromWeb -Url \"https://contoso.sharepoint.com/sites/teamsite\" -IncludeBranding -IncludeLinksToExportedItems", + "Id": 722, "Rank": 4 }, { - "Command": "Get-PnPSiteScriptFromWeb -IncludeAllLists", - "Id": 716, "CommandName": "Get-PnPSiteScriptFromWeb", + "Command": "Get-PnPSiteScriptFromWeb -IncludeAllLists", + "Id": 723, "Rank": 5 }, { - "Command": "Get-PnPSiteScriptFromWeb -IncludeAllLists | Add-PnPSiteScript -Title \"My Site Script\" | Add-PnPSiteDesign -Title \"My Site Design\" -WebTemplate TeamSite", - "Id": 717, "CommandName": "Get-PnPSiteScriptFromWeb", + "Command": "Get-PnPSiteScriptFromWeb -IncludeAllLists | Add-PnPSiteScript -Title \"My Site Script\" | Add-PnPSiteDesign -Title \"My Site Design\" -WebTemplate TeamSite", + "Id": 724, "Rank": 6 }, { - "Command": "Get-PnPSiteSearchQueryResults", - "Id": 718, "CommandName": "Get-PnPSiteSearchQueryResults", + "Command": "Get-PnPSiteSearchQueryResults", + "Id": 725, "Rank": 1 }, { - "Command": "Get-PnPSiteSearchQueryResults -Query \"WebTemplate:STS\"", - "Id": 719, "CommandName": "Get-PnPSiteSearchQueryResults", + "Command": "Get-PnPSiteSearchQueryResults -Query \"WebTemplate:STS\"", + "Id": 726, "Rank": 2 }, { - "Command": "Get-PnPSiteSearchQueryResults -Query \"WebTemplate:SPSPERS\"", - "Id": 720, "CommandName": "Get-PnPSiteSearchQueryResults", + "Command": "Get-PnPSiteSearchQueryResults -Query \"WebTemplate:SPSPERS\"", + "Id": 727, "Rank": 3 }, { - "Command": "Get-PnPSiteSearchQueryResults -Query \"Title:Intranet*\"", - "Id": 721, "CommandName": "Get-PnPSiteSearchQueryResults", + "Command": "Get-PnPSiteSearchQueryResults -Query \"Title:Intranet*\"", + "Id": 728, "Rank": 4 }, { - "Command": "Get-PnPSiteSearchQueryResults -MaxResults 10", - "Id": 722, "CommandName": "Get-PnPSiteSearchQueryResults", + "Command": "Get-PnPSiteSearchQueryResults -MaxResults 10", + "Id": 729, "Rank": 5 }, { - "Command": "Get-PnPSiteSearchQueryResults -All", - "Id": 723, "CommandName": "Get-PnPSiteSearchQueryResults", + "Command": "Get-PnPSiteSearchQueryResults -All", + "Id": 730, "Rank": 6 }, { - "Command": "Get-PnPSiteSensitivityLabel", - "Id": 724, "CommandName": "Get-PnPSiteSensitivityLabel", + "Command": "Get-PnPSiteSensitivityLabel", + "Id": 731, "Rank": 1 }, { - "Command": "Get-PnPSiteTemplate -Out template.pnp", - "Id": 725, "CommandName": "Get-PnPSiteTemplate", + "Command": "Get-PnPSiteTemplate -Out template.pnp", + "Id": 732, "Rank": 1 }, { - "Command": "Get-PnPSiteTemplate -Out template.xml", - "Id": 726, "CommandName": "Get-PnPSiteTemplate", + "Command": "Get-PnPSiteTemplate -Out template.xml", + "Id": 733, "Rank": 2 }, { - "Command": "Get-PnPSiteTemplate -Out template.md", - "Id": 727, "CommandName": "Get-PnPSiteTemplate", + "Command": "Get-PnPSiteTemplate -Out template.md", + "Id": 734, "Rank": 3 }, { - "Command": "Get-PnPSiteTemplate -Out template.pnp -Schema V201503", - "Id": 728, "CommandName": "Get-PnPSiteTemplate", + "Command": "Get-PnPSiteTemplate -Out template.pnp -Schema V201503", + "Id": 735, "Rank": 4 }, { - "Command": "Get-PnPSiteTemplate -Out template.pnp -IncludeAllTermGroups", - "Id": 729, "CommandName": "Get-PnPSiteTemplate", + "Command": "Get-PnPSiteTemplate -Out template.pnp -IncludeAllTermGroups", + "Id": 736, "Rank": 5 }, { - "Command": "Get-PnPSiteTemplate -Out template.pnp -IncludeSiteCollectionTermGroup", - "Id": 730, "CommandName": "Get-PnPSiteTemplate", + "Command": "Get-PnPSiteTemplate -Out template.pnp -IncludeSiteCollectionTermGroup", + "Id": 737, "Rank": 6 }, { - "Command": "Get-PnPSiteTemplate -Out template.pnp -PersistBrandingFiles", - "Id": 731, "CommandName": "Get-PnPSiteTemplate", + "Command": "Get-PnPSiteTemplate -Out template.pnp -PersistBrandingFiles", + "Id": 738, "Rank": 7 }, { - "Command": "Get-PnPSiteTemplate -Out template.pnp -Handlers Lists, SiteSecurity", - "Id": 732, "CommandName": "Get-PnPSiteTemplate", + "Command": "Get-PnPSiteTemplate -Out template.pnp -Handlers Lists, SiteSecurity", + "Id": 739, "Rank": 8 }, { - "Command": "Get-PnPSiteTemplate -Out template.pnp -PersistMultiLanguageResources", - "Id": 733, "CommandName": "Get-PnPSiteTemplate", + "Command": "Get-PnPSiteTemplate -Out template.pnp -PersistMultiLanguageResources", + "Id": 740, "Rank": 9 }, { - "Command": "Get-PnPSiteTemplate -Out template.pnp -PersistMultiLanguageResources -ResourceFilePrefix MyResources", - "Id": 734, "CommandName": "Get-PnPSiteTemplate", + "Command": "Get-PnPSiteTemplate -Out template.pnp -PersistMultiLanguageResources -ResourceFilePrefix MyResources", + "Id": 741, "Rank": 10 }, { - "Command": "Get-PnPSiteTemplate -Out template.pnp -ContentTypeGroups \"Group A\",\"Group B\"", - "Id": 735, "CommandName": "Get-PnPSiteTemplate", + "Command": "Get-PnPSiteTemplate -Out template.pnp -ContentTypeGroups \"Group A\",\"Group B\"", + "Id": 742, "Rank": 11 }, { - "Command": "Get-PnPSiteTemplate -Out template.pnp -ExcludeContentTypesFromSyndication", - "Id": 736, "CommandName": "Get-PnPSiteTemplate", + "Command": "Get-PnPSiteTemplate -Out template.pnp -ExcludeContentTypesFromSyndication", + "Id": 743, "Rank": 12 }, { - "Command": "Get-PnPSiteTemplate -Out template.pnp -ListsToExtract \"Title of List One\",\"95c4efd6-08f4-4c67-94ae-49d696ba1298\",\"Title of List Three\"", - "Id": 737, "CommandName": "Get-PnPSiteTemplate", + "Command": "Get-PnPSiteTemplate -Out template.pnp -ListsToExtract \"Title of List One\",\"95c4efd6-08f4-4c67-94ae-49d696ba1298\",\"Title of List Three\"", + "Id": 744, "Rank": 13 }, { - "Command": "Get-PnPSiteTemplate -Out template.xml -Handlers Fields, ContentTypes, SupportedUILanguages -PersistMultiLanguageResources", - "Id": 738, "CommandName": "Get-PnPSiteTemplate", + "Command": "Get-PnPSiteTemplate -Out template.xml -Handlers Fields, ContentTypes, SupportedUILanguages -PersistMultiLanguageResources", + "Id": 745, "Rank": 14 }, { - "Command": "Get-PnPSiteUserInvitations -Site \"https://contoso.sharepoint.com/sites/ContosoWeb1/\" -EmailAddress someone@example.com", - "Id": 739, "CommandName": "Get-PnPSiteUserInvitations", + "Command": "Get-PnPSiteUserInvitations -Site \"https://contoso.sharepoint.com/sites/ContosoWeb1/\" -EmailAddress someone@example.com", + "Id": 746, "Rank": 1 }, { - "Command": "Get-PnPSiteVersionPolicy", - "Id": 740, "CommandName": "Get-PnPSiteVersionPolicy", + "Command": "Get-PnPSiteVersionPolicy", + "Id": 747, "Rank": 1 }, { - "Command": "Get-PnPSiteVersionPolicyStatus", - "Id": 741, "CommandName": "Get-PnPSiteVersionPolicyStatus", + "Command": "Get-PnPSiteVersionPolicyStatus", + "Id": 748, "Rank": 1 }, { - "Command": "Get-PnPStorageEntity", - "Id": 742, "CommandName": "Get-PnPStorageEntity", + "Command": "Get-PnPStorageEntity", + "Id": 749, "Rank": 1 }, { - "Command": "Get-PnPStorageEntity -Key MyKey", - "Id": 743, "CommandName": "Get-PnPStorageEntity", + "Command": "Get-PnPStorageEntity -Key MyKey", + "Id": 750, "Rank": 2 }, { - "Command": "Get-PnPStorageEntity -Scope Site", - "Id": 744, "CommandName": "Get-PnPStorageEntity", + "Command": "Get-PnPStorageEntity -Scope Site", + "Id": 751, "Rank": 3 }, { - "Command": "Get-PnPStorageEntity -Key MyKey -Scope Site", - "Id": 745, "CommandName": "Get-PnPStorageEntity", + "Command": "Get-PnPStorageEntity -Key MyKey -Scope Site", + "Id": 752, "Rank": 4 }, { - "Command": "Get-PnPStoredCredential -Name O365", - "Id": 746, "CommandName": "Get-PnPStoredCredential", + "Command": "Get-PnPStoredCredential -Name O365", + "Id": 753, "Rank": 1 }, { - "Command": "Get-PnPStructuralNavigationCacheSiteState -SiteUrl \"https://contoso.sharepoint.com/sites/product/\"", - "Id": 747, "CommandName": "Get-PnPStructuralNavigationCacheSiteState", + "Command": "Get-PnPStructuralNavigationCacheSiteState -SiteUrl \"https://contoso.sharepoint.com/sites/product/\"", + "Id": 754, "Rank": 1 }, { - "Command": "Get-PnPStructuralNavigationCacheWebState -WebUrl \"https://contoso.sharepoint.com/sites/product/electronics\"", - "Id": 748, "CommandName": "Get-PnPStructuralNavigationCacheWebState", + "Command": "Get-PnPStructuralNavigationCacheWebState -WebUrl \"https://contoso.sharepoint.com/sites/product/electronics\"", + "Id": 755, "Rank": 1 }, { - "Command": "Get-PnPSubscribeSharePointNewsDigest -Account 'user@domain.com'", - "Id": 749, "CommandName": "Get-PnPSubscribeSharePointNewsDigest", + "Command": "Get-PnPSubscribeSharePointNewsDigest -Account 'user@domain.com'", + "Id": 756, "Rank": 1 }, { - "Command": "Get-PnPSubWeb", - "Id": 750, "CommandName": "Get-PnPSubWeb", + "Command": "Get-PnPSubWeb", + "Id": 757, "Rank": 1 }, { - "Command": "Get-PnPSubWeb -Recurse", - "Id": 751, "CommandName": "Get-PnPSubWeb", + "Command": "Get-PnPSubWeb -Recurse", + "Id": 758, "Rank": 2 }, { - "Command": "Get-PnPSubWeb -Recurse -Includes \"WebTemplate\",\"Description\" | Select ServerRelativeUrl, WebTemplate, Description", - "Id": 752, "CommandName": "Get-PnPSubWeb", + "Command": "Get-PnPSubWeb -Recurse -Includes \"WebTemplate\",\"Description\" | Select ServerRelativeUrl, WebTemplate, Description", + "Id": 759, "Rank": 3 }, { - "Command": "Get-PnPSubWeb -Identity Team1 -Recurse", - "Id": 753, "CommandName": "Get-PnPSubWeb", + "Command": "Get-PnPSubWeb -Identity Team1 -Recurse", + "Id": 760, "Rank": 4 }, { - "Command": "Get-PnPSubWeb -Identity Team1 -Recurse -IncludeRootWeb", - "Id": 754, "CommandName": "Get-PnPSubWeb", + "Command": "Get-PnPSubWeb -Identity Team1 -Recurse -IncludeRootWeb", + "Id": 761, "Rank": 5 }, { - "Command": "Get-PnPSyntexModel", - "Id": 755, "CommandName": "Get-PnPSyntexModel", + "Command": "Get-PnPSyntexModel", + "Id": 762, "Rank": 1 }, { - "Command": "Get-PnPSyntexModel -Identity 1", - "Id": 756, "CommandName": "Get-PnPSyntexModel", + "Command": "Get-PnPSyntexModel -Identity 1", + "Id": 763, "Rank": 2 }, { - "Command": "Get-PnPSyntexModel -Identity \"Invoice model\"", - "Id": 757, "CommandName": "Get-PnPSyntexModel", + "Command": "Get-PnPSyntexModel -Identity \"Invoice model\"", + "Id": 764, "Rank": 3 }, { - "Command": "Get-PnPSyntexModelPublication -Identity \"Invoice model\"", - "Id": 758, "CommandName": "Get-PnPSyntexModelPublication", + "Command": "Get-PnPSyntexModelPublication -Identity \"Invoice model\"", + "Id": 765, "Rank": 1 }, { - "Command": "Get-PnPTaxonomyItem -TermPath \"My Term Group|My Term Set|Contoso\"", - "Id": 759, "CommandName": "Get-PnPTaxonomyItem", + "Command": "Get-PnPTaxonomyItem -TermPath \"My Term Group|My Term Set|Contoso\"", + "Id": 766, "Rank": 1 }, { - "Command": "Get-PnPTeamsApp", - "Id": 760, "CommandName": "Get-PnPTeamsApp", + "Command": "Get-PnPTeamsApp", + "Id": 767, "Rank": 1 }, { - "Command": "Get-PnPTeamsApp -Identity a54224d7-608b-4839-bf74-1b68148e65d4", - "Id": 761, "CommandName": "Get-PnPTeamsApp", + "Command": "Get-PnPTeamsApp -Identity a54224d7-608b-4839-bf74-1b68148e65d4", + "Id": 768, "Rank": 2 }, { - "Command": "Get-PnPTeamsApp -Identity \"MyTeamsApp\"", - "Id": 762, "CommandName": "Get-PnPTeamsApp", + "Command": "Get-PnPTeamsApp -Identity \"MyTeamsApp\"", + "Id": 769, "Rank": 3 }, { - "Command": "Get-PnPTeamsChannel -Team a6c1e0d7-f579-4993-81ab-4b666f8edea8", - "Id": 763, "CommandName": "Get-PnPTeamsChannel", + "Command": "Get-PnPTeamsChannel -Team a6c1e0d7-f579-4993-81ab-4b666f8edea8", + "Id": 770, "Rank": 1 }, { - "Command": "Get-PnPTeamsChannel -Team a6c1e0d7-f579-4993-81ab-4b666f8edea8 -Identity \"Test Channel\"", - "Id": 764, "CommandName": "Get-PnPTeamsChannel", + "Command": "Get-PnPTeamsChannel -Team a6c1e0d7-f579-4993-81ab-4b666f8edea8 -Identity \"Test Channel\"", + "Id": 771, "Rank": 2 }, { - "Command": "Get-PnPTeamsChannel -Team a6c1e0d7-f579-4993-81ab-4b666f8edea8 -Identity \"19:796d063b63e34497aeaf092c8fb9b44e@thread.skype\"", - "Id": 765, "CommandName": "Get-PnPTeamsChannel", + "Command": "Get-PnPTeamsChannel -Team a6c1e0d7-f579-4993-81ab-4b666f8edea8 -Identity \"19:796d063b63e34497aeaf092c8fb9b44e@thread.skype\"", + "Id": 772, "Rank": 3 }, { - "Command": "Get-PnPTeamsChannel -Team a6c1e0d7-f579-4993-81ab-4b666f8edea8 -Identity \"19:796d063b63e34497aeaf092c8fb9b44e@thread.skype\" -IncludeModerationSettings", - "Id": 766, "CommandName": "Get-PnPTeamsChannel", + "Command": "Get-PnPTeamsChannel -Team a6c1e0d7-f579-4993-81ab-4b666f8edea8 -Identity \"19:796d063b63e34497aeaf092c8fb9b44e@thread.skype\" -IncludeModerationSettings", + "Id": 773, "Rank": 4 }, { - "Command": "Get-PnPTeamsChannelFilesFolder -Team \"Sales Team\" -Channel \"Test Channel\"", - "Id": 767, "CommandName": "Get-PnPTeamsChannelFilesFolder", + "Command": "Get-PnPTeamsChannelFilesFolder -Team \"Sales Team\" -Channel \"Test Channel\"", + "Id": 774, "Rank": 1 }, { - "Command": "Get-PnPTeamsChannelFilesFolder -Team a6c1e0d7-f579-4993-81ab-4b666f8edea8 -Channel \"19:796d063b63e34497aeaf092c8fb9b44e@thread.skype\"", - "Id": 768, "CommandName": "Get-PnPTeamsChannelFilesFolder", + "Command": "Get-PnPTeamsChannelFilesFolder -Team a6c1e0d7-f579-4993-81ab-4b666f8edea8 -Channel \"19:796d063b63e34497aeaf092c8fb9b44e@thread.skype\"", + "Id": 775, "Rank": 2 }, { - "Command": "Get-PnPTeamsChannelMessage -Team MyTestTeam -Channel \"My Channel\"", - "Id": 769, "CommandName": "Get-PnPTeamsChannelMessage", + "Command": "Get-PnPTeamsChannelMessage -Team MyTestTeam -Channel \"My Channel\"", + "Id": 776, "Rank": 1 }, { - "Command": "Get-PnPTeamsChannelMessage -Team MyTestTeam -Channel \"My Channel\" -Identity 1653089769293", - "Id": 770, "CommandName": "Get-PnPTeamsChannelMessage", + "Command": "Get-PnPTeamsChannelMessage -Team MyTestTeam -Channel \"My Channel\" -Identity 1653089769293", + "Id": 777, "Rank": 2 }, { - "Command": "Get-PnPTeamsChannelMessageReply -Team MyTestTeam -Channel \"My Channel\" -Message 1653089769293 -IncludeDeleted", - "Id": 771, "CommandName": "Get-PnPTeamsChannelMessageReply", + "Command": "Get-PnPTeamsChannelMessageReply -Team MyTestTeam -Channel \"My Channel\" -Message 1653089769293 -IncludeDeleted", + "Id": 778, "Rank": 1 }, { - "Command": "Get-PnPTeamsChannelMessageReply -Team MyTestTeam -Channel \"My Channel\" -Message 1653089769293 -Identity 1653086004630", - "Id": 772, "CommandName": "Get-PnPTeamsChannelMessageReply", + "Command": "Get-PnPTeamsChannelMessageReply -Team MyTestTeam -Channel \"My Channel\" -Message 1653089769293 -Identity 1653086004630", + "Id": 779, "Rank": 2 }, { - "Command": "Get-PnPTeamsChannelUser -Team \"My Team\" -Channel \"My Channel\"", - "Id": 773, "CommandName": "Get-PnPTeamsChannelUser", + "Command": "Get-PnPTeamsChannelUser -Team \"My Team\" -Channel \"My Channel\"", + "Id": 780, "Rank": 1 }, { - "Command": "Get-PnPTeamsChannelUser -Team \"My Team\" -Channel \"My Channel\" -Role Member", - "Id": 774, "CommandName": "Get-PnPTeamsChannelUser", + "Command": "Get-PnPTeamsChannelUser -Team \"My Team\" -Channel \"My Channel\" -Role Member", + "Id": 781, "Rank": 2 }, { - "Command": "Get-PnPTeamsChannelUser -Team \"My Team\" -Channel \"My Channel\" -Identity john.doe@contoso.com", - "Id": 775, "CommandName": "Get-PnPTeamsChannelUser", + "Command": "Get-PnPTeamsChannelUser -Team \"My Team\" -Channel \"My Channel\" -Identity john.doe@contoso.com", + "Id": 782, "Rank": 3 }, { - "Command": "Get-PnPTeamsChannelUser -Team \"My Team\" -Channel \"My Channel\" -Identity 00000000-0000-0000-0000-000000000000", - "Id": 776, "CommandName": "Get-PnPTeamsChannelUser", + "Command": "Get-PnPTeamsChannelUser -Team \"My Team\" -Channel \"My Channel\" -Identity 00000000-0000-0000-0000-000000000000", + "Id": 783, "Rank": 4 }, { - "Command": "Get-PnPTeamsPrimaryChannel -Team ee0f40fc-b2f7-45c7-b62d-11b90dd2ea8e", - "Id": 777, "CommandName": "Get-PnPTeamsPrimaryChannel", + "Command": "Get-PnPTeamsPrimaryChannel -Team ee0f40fc-b2f7-45c7-b62d-11b90dd2ea8e", + "Id": 784, "Rank": 1 }, { - "Command": "Get-PnPTeamsPrimaryChannel -Team Sales", - "Id": 778, "CommandName": "Get-PnPTeamsPrimaryChannel", + "Command": "Get-PnPTeamsPrimaryChannel -Team Sales", + "Id": 785, "Rank": 2 }, { - "Command": "Get-PnPTeamsTab -Team 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -Channel 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype", - "Id": 779, "CommandName": "Get-PnPTeamsTab", + "Command": "Get-PnPTeamsTab -Team 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -Channel 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype", + "Id": 786, "Rank": 1 }, { - "Command": "Get-PnPTeamsTab -Team 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -Channel 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype -Identity \"Wiki\"", - "Id": 780, "CommandName": "Get-PnPTeamsTab", + "Command": "Get-PnPTeamsTab -Team 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -Channel 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype -Identity \"Wiki\"", + "Id": 787, "Rank": 2 }, { - "Command": "Get-PnPTeamsTab -Team 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -Channel 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype -Identity d8740a7a-e44e-46c5-8f13-e699f964fc25", - "Id": 781, "CommandName": "Get-PnPTeamsTab", + "Command": "Get-PnPTeamsTab -Team 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -Channel 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype -Identity d8740a7a-e44e-46c5-8f13-e699f964fc25", + "Id": 788, "Rank": 3 }, { - "Command": "Get-PnPTeamsTab -Team \"My Team\" -Channel \"My Channel\"", - "Id": 782, "CommandName": "Get-PnPTeamsTab", + "Command": "Get-PnPTeamsTab -Team \"My Team\" -Channel \"My Channel\"", + "Id": 789, "Rank": 4 }, { - "Command": "Get-PnPTeamsTab -Team \"My Team\" -Channel \"My Channel\" -Identity \"Wiki\"", - "Id": 783, "CommandName": "Get-PnPTeamsTab", + "Command": "Get-PnPTeamsTab -Team \"My Team\" -Channel \"My Channel\" -Identity \"Wiki\"", + "Id": 790, "Rank": 5 }, { - "Command": "Get-PnPTeamsTag -Team 5beb63c5-0571-499e-94d5-3279fdd9b6b5", - "Id": 784, "CommandName": "Get-PnPTeamsTag", + "Command": "Get-PnPTeamsTag -Team 5beb63c5-0571-499e-94d5-3279fdd9b6b5", + "Id": 791, "Rank": 1 }, { - "Command": "Get-PnPTeamsTag -Team 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -Identity \"ZmY1ZjdmMjctZDhiNy00MWRkLTk2ZDQtYzcyYmVhMWIwOGYxIyM3ZTVhNGRmZS1kNWNlLTRkOTAtODM4MC04ZDIxM2FkYzYzOGIjI3RiVlVpR01rcg==\"", - "Id": 785, "CommandName": "Get-PnPTeamsTag", + "Command": "Get-PnPTeamsTag -Team 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -Identity \"ZmY1ZjdmMjctZDhiNy00MWRkLTk2ZDQtYzcyYmVhMWIwOGYxIyM3ZTVhNGRmZS1kNWNlLTRkOTAtODM4MC04ZDIxM2FkYzYzOGIjI3RiVlVpR01rcg==\"", + "Id": 792, "Rank": 2 }, { - "Command": "Get-PnPTeamsTeam", - "Id": 786, "CommandName": "Get-PnPTeamsTeam", + "Command": "Get-PnPTeamsTeam", + "Id": 793, "Rank": 1 }, { - "Command": "Get-PnPTeamsTeam -Identity \"PnP PowerShell\"", - "Id": 787, "CommandName": "Get-PnPTeamsTeam", + "Command": "Get-PnPTeamsTeam -Identity \"PnP PowerShell\"", + "Id": 794, "Rank": 2 }, { - "Command": "Get-PnPTeamsTeam -Identity \"baba9192-55be-488a-9fb7-2e2e76edbef2\"", - "Id": 788, "CommandName": "Get-PnPTeamsTeam", + "Command": "Get-PnPTeamsTeam -Identity \"baba9192-55be-488a-9fb7-2e2e76edbef2\"", + "Id": 795, "Rank": 3 }, { - "Command": "Get-PnPTeamsTeam -Filter \"startswith(mailNickName, 'contoso')\"", - "Id": 789, "CommandName": "Get-PnPTeamsTeam", + "Command": "Get-PnPTeamsTeam -Filter \"startswith(mailNickName, 'contoso')\"", + "Id": 796, "Rank": 4 }, { - "Command": "Get-PnPTeamsTeam -Filter \"startswith(description, 'contoso')\"", - "Id": 790, "CommandName": "Get-PnPTeamsTeam", + "Command": "Get-PnPTeamsTeam -Filter \"startswith(description, 'contoso')\"", + "Id": 797, "Rank": 5 }, { - "Command": "Get-PnPTeamsUser -Team MyTeam", - "Id": 791, "CommandName": "Get-PnPTeamsUser", + "Command": "Get-PnPTeamsUser -Team MyTeam", + "Id": 798, "Rank": 1 }, { - "Command": "Get-PnPTeamsUser -Team MyTeam -Role Owner", - "Id": 792, "CommandName": "Get-PnPTeamsUser", + "Command": "Get-PnPTeamsUser -Team MyTeam -Role Owner", + "Id": 799, "Rank": 2 }, { - "Command": "Get-PnPTeamsUser -Team MyTeam -Role Member", - "Id": 793, "CommandName": "Get-PnPTeamsUser", + "Command": "Get-PnPTeamsUser -Team MyTeam -Role Member", + "Id": 800, "Rank": 3 }, { - "Command": "Get-PnPTeamsUser -Team MyTeam -Role Guest", - "Id": 794, "CommandName": "Get-PnPTeamsUser", + "Command": "Get-PnPTeamsUser -Team MyTeam -Role Guest", + "Id": 801, "Rank": 4 }, { - "Command": "Get-PnPTemporarilyDisableAppBar", - "Id": 795, "CommandName": "Get-PnPTemporarilyDisableAppBar", + "Command": "Get-PnPTemporarilyDisableAppBar", + "Id": 802, "Rank": 1 }, { - "Command": "Get-PnPTenant", - "Id": 796, "CommandName": "Get-PnPTenant", + "Command": "Get-PnPTenant", + "Id": 803, "Rank": 1 }, { - "Command": "Get-PnPTenantAppCatalogUrl", - "Id": 797, "CommandName": "Get-PnPTenantAppCatalogUrl", + "Command": "Get-PnPTenantAppCatalogUrl", + "Id": 804, "Rank": 1 }, { - "Command": "Get-PnPTenantCdnEnabled -CdnType Public", - "Id": 798, "CommandName": "Get-PnPTenantCdnEnabled", + "Command": "Get-PnPTenantCdnEnabled -CdnType Public", + "Id": 805, "Rank": 1 }, { - "Command": "Get-PnPTenantCdnOrigin -CdnType Public", - "Id": 799, "CommandName": "Get-PnPTenantCdnOrigin", + "Command": "Get-PnPTenantCdnOrigin -CdnType Public", + "Id": 806, "Rank": 1 }, { - "Command": "Get-PnPTenantCdnPolicies -CdnType Public", - "Id": 800, "CommandName": "Get-PnPTenantCdnPolicies", + "Command": "Get-PnPTenantCdnPolicies -CdnType Public", + "Id": 807, "Rank": 1 }, { - "Command": "Get-PnPTenantDeletedSite", - "Id": 801, "CommandName": "Get-PnPTenantDeletedSite", + "Command": "Get-PnPTenantDeletedSite", + "Id": 808, "Rank": 1 }, { - "Command": "Get-PnPTenantDeletedSite -Detailed", - "Id": 802, "CommandName": "Get-PnPTenantDeletedSite", + "Command": "Get-PnPTenantDeletedSite -Detailed", + "Id": 809, "Rank": 2 }, { - "Command": "Get-PnPTenantDeletedSite -Identity \"https://tenant.sharepoint.com/sites/contoso\"", - "Id": 803, "CommandName": "Get-PnPTenantDeletedSite", + "Command": "Get-PnPTenantDeletedSite -Identity \"https://tenant.sharepoint.com/sites/contoso\"", + "Id": 810, "Rank": 3 }, { - "Command": "Get-PnPTenantDeletedSite -IncludePersonalSite", - "Id": 804, "CommandName": "Get-PnPTenantDeletedSite", + "Command": "Get-PnPTenantDeletedSite -IncludePersonalSite", + "Id": 811, "Rank": 4 }, { - "Command": "Get-PnPTenantDeletedSite -IncludeOnlyPersonalSite", - "Id": 805, "CommandName": "Get-PnPTenantDeletedSite", + "Command": "Get-PnPTenantDeletedSite -IncludeOnlyPersonalSite", + "Id": 812, "Rank": 5 }, { - "Command": "Get-PnPTenantId", - "Id": 806, "CommandName": "Get-PnPTenantId", + "Command": "Get-PnPTenantId", + "Id": 813, "Rank": 1 }, { - "Command": "Get-PnPTenantId contoso", - "Id": 807, "CommandName": "Get-PnPTenantId", + "Command": "Get-PnPTenantId contoso", + "Id": 814, "Rank": 2 }, { - "Command": "Get-PnPTenantId -TenantUrl contoso.sharepoint.com", - "Id": 808, "CommandName": "Get-PnPTenantId", + "Command": "Get-PnPTenantId -TenantUrl contoso.sharepoint.com", + "Id": 815, "Rank": 3 }, { - "Command": "Get-PnPTenantId -TenantUrl contoso.sharepoint.us -AzureEnvironment USGovernment", - "Id": 809, "CommandName": "Get-PnPTenantId", + "Command": "Get-PnPTenantId -TenantUrl contoso.sharepoint.us -AzureEnvironment USGovernment", + "Id": 816, "Rank": 4 }, { - "Command": "Get-PnPTenantInfo -TenantId \"e65b162c-6f87-4eb1-a24e-1b37d3504663\"", - "Id": 810, "CommandName": "Get-PnPTenantInfo", + "Command": "Get-PnPTenantInfo -TenantId \"e65b162c-6f87-4eb1-a24e-1b37d3504663\"", + "Id": 817, "Rank": 1 }, { - "Command": "Get-PnPTenantInfo -DomainName \"contoso.com\"", - "Id": 811, "CommandName": "Get-PnPTenantInfo", + "Command": "Get-PnPTenantInfo -DomainName \"contoso.com\"", + "Id": 818, "Rank": 2 }, { - "Command": "Get-PnPTenantInfo", - "Id": 812, "CommandName": "Get-PnPTenantInfo", + "Command": "Get-PnPTenantInfo", + "Id": 819, "Rank": 3 }, { - "Command": "Get-PnPTenantInfo -CurrentTenant", - "Id": 813, "CommandName": "Get-PnPTenantInfo", + "Command": "Get-PnPTenantInfo -CurrentTenant", + "Id": 820, "Rank": 4 }, { - "Command": "Get-PnPTenantInstance", - "Id": 814, "CommandName": "Get-PnPTenantInstance", + "Command": "Get-PnPTenantInstance", + "Id": 821, "Rank": 1 }, { - "Command": "Get-PnPTenantInternalSetting", - "Id": 815, "CommandName": "Get-PnPTenantInternalSetting", + "Command": "Get-PnPTenantInternalSetting", + "Id": 822, "Rank": 1 }, { - "Command": "Get-PnPTenantRecycleBinItem", - "Id": 816, "CommandName": "Get-PnPTenantRecycleBinItem", + "Command": "Get-PnPTenantRecycleBinItem", + "Id": 823, + "Rank": 1 + }, + { + "CommandName": "Get-PnPTenantRestrictedSearchAllowedList", + "Command": "Get-PnPTenantRestrictedSearchAllowedList", + "Id": 824, "Rank": 1 }, { - "Command": "Get-PnPTenantRestrictedSearchMode", - "Id": 817, "CommandName": "Get-PnPTenantRestrictedSearchMode", + "Command": "Get-PnPTenantRestrictedSearchMode", + "Id": 825, "Rank": 1 }, { - "Command": "Get-PnPTenantSequence -Template $myTemplateObject", - "Id": 818, "CommandName": "Get-PnPTenantSequence", + "Command": "Get-PnPTenantSequence -Template $myTemplateObject", + "Id": 826, "Rank": 1 }, { - "Command": "Get-PnPTenantSequence -Template $myTemplateObject -Identity \"mysequence\"", - "Id": 819, "CommandName": "Get-PnPTenantSequence", + "Command": "Get-PnPTenantSequence -Template $myTemplateObject -Identity \"mysequence\"", + "Id": 827, "Rank": 2 }, { - "Command": "Get-PnPTenantSequenceSite -Sequence $mysequence", - "Id": 820, "CommandName": "Get-PnPTenantSequenceSite", + "Command": "Get-PnPTenantSequenceSite -Sequence $mysequence", + "Id": 828, "Rank": 1 }, { - "Command": "Get-PnPTenantSequenceSite -Sequence $mysequence -Identity 8058ea99-af7b-4bb7-b12a-78f93398041e", - "Id": 821, "CommandName": "Get-PnPTenantSequenceSite", + "Command": "Get-PnPTenantSequenceSite -Sequence $mysequence -Identity 8058ea99-af7b-4bb7-b12a-78f93398041e", + "Id": 829, "Rank": 2 }, { - "Command": "Get-PnPTenantSite", - "Id": 822, "CommandName": "Get-PnPTenantSite", + "Command": "Get-PnPTenantSite", + "Id": 830, "Rank": 1 }, { - "Command": "Get-PnPTenantSite -Detailed", - "Id": 823, "CommandName": "Get-PnPTenantSite", + "Command": "Get-PnPTenantSite -Detailed", + "Id": 831, "Rank": 2 }, { - "Command": "Get-PnPTenantSite -IncludeOneDriveSites", - "Id": 824, "CommandName": "Get-PnPTenantSite", + "Command": "Get-PnPTenantSite -IncludeOneDriveSites", + "Id": 832, "Rank": 3 }, { - "Command": "Get-PnPTenantSite -IncludeOneDriveSites -Filter \"Url -like '-my.sharepoint.com/personal/'\"", - "Id": 825, "CommandName": "Get-PnPTenantSite", + "Command": "Get-PnPTenantSite -IncludeOneDriveSites -Filter \"Url -like '-my.sharepoint.com/personal/'\"", + "Id": 833, "Rank": 4 }, { - "Command": "Get-PnPTenantSite -Identity \"http://tenant.sharepoint.com/sites/projects\"", - "Id": 826, "CommandName": "Get-PnPTenantSite", + "Command": "Get-PnPTenantSite -Identity \"http://tenant.sharepoint.com/sites/projects\"", + "Id": 834, "Rank": 5 }, { - "Command": "Get-PnPTenantSite -Identity 7e8a6f56-92fe-4b22-9364-41799e579e8a", - "Id": 827, "CommandName": "Get-PnPTenantSite", + "Command": "Get-PnPTenantSite -Identity 7e8a6f56-92fe-4b22-9364-41799e579e8a", + "Id": 835, "Rank": 6 }, { - "Command": "Get-PnPTenantSite -Template SITEPAGEPUBLISHING#0", - "Id": 828, "CommandName": "Get-PnPTenantSite", + "Command": "Get-PnPTenantSite -Template SITEPAGEPUBLISHING#0", + "Id": 836, "Rank": 7 }, { - "Command": "Get-PnPTenantSite -Filter \"Url -like 'sales'\"", - "Id": 829, "CommandName": "Get-PnPTenantSite", + "Command": "Get-PnPTenantSite -Filter \"Url -like 'sales'\"", + "Id": 837, "Rank": 8 }, { - "Command": "Get-PnPTenantSite -GroupIdDefined $true", - "Id": 830, "CommandName": "Get-PnPTenantSite", + "Command": "Get-PnPTenantSite -GroupIdDefined $true", + "Id": 838, "Rank": 9 }, { - "Command": "Get-PnPTenantSyncClientRestriction", - "Id": 831, "CommandName": "Get-PnPTenantSyncClientRestriction", + "Command": "Get-PnPTenantSyncClientRestriction", + "Id": 839, "Rank": 1 }, { - "Command": "Get-PnPTenantTemplate -Out tenanttemplate.xml", - "Id": 832, "CommandName": "Get-PnPTenantTemplate", + "Command": "Get-PnPTenantTemplate -Out tenanttemplate.xml", + "Id": 840, "Rank": 1 }, { - "Command": "Get-PnPTenantTemplate -Out tenanttemplate.xml -SiteUrl https://m365x123456.sharepoint.com/sites/HomeSite", - "Id": 833, "CommandName": "Get-PnPTenantTemplate", + "Command": "Get-PnPTenantTemplate -Out tenanttemplate.xml -SiteUrl https://m365x123456.sharepoint.com/sites/HomeSite", + "Id": 841, "Rank": 2 }, { - "Command": "Get-PnPTenantTemplate -Out tenanttemplate.xml -SiteUrl https://m365x123456.sharepoint.com/sites/HomeSite -Force", - "Id": 834, "CommandName": "Get-PnPTenantTemplate", + "Command": "Get-PnPTenantTemplate -Out tenanttemplate.xml -SiteUrl https://m365x123456.sharepoint.com/sites/HomeSite -Force", + "Id": 842, "Rank": 3 }, { - "Command": "Get-PnPTenantTheme", - "Id": 835, "CommandName": "Get-PnPTenantTheme", + "Command": "Get-PnPTenantTheme", + "Id": 843, "Rank": 1 }, { - "Command": "Get-PnPTenantTheme -Name \"MyCompanyTheme\"", - "Id": 836, "CommandName": "Get-PnPTenantTheme", + "Command": "Get-PnPTenantTheme -Name \"MyCompanyTheme\"", + "Id": 844, "Rank": 2 }, { - "Command": "Get-PnPTenantTheme -Name \"MyCompanyTheme\" -AsJson", - "Id": 837, "CommandName": "Get-PnPTenantTheme", + "Command": "Get-PnPTenantTheme -Name \"MyCompanyTheme\" -AsJson", + "Id": 845, "Rank": 3 }, { - "Command": "Get-PnPTerm -TermSet \"Departments\" -TermGroup \"Corporate\"", - "Id": 838, "CommandName": "Get-PnPTerm", + "Command": "Get-PnPTerm -TermSet \"Departments\" -TermGroup \"Corporate\"", + "Id": 846, "Rank": 1 }, { - "Command": "Get-PnPTerm -Identity \"Finance\" -TermSet \"Departments\" -TermGroup \"Corporate\"", - "Id": 839, "CommandName": "Get-PnPTerm", + "Command": "Get-PnPTerm -Identity \"Finance\" -TermSet \"Departments\" -TermGroup \"Corporate\"", + "Id": 847, "Rank": 2 }, { - "Command": "Get-PnPTerm -Identity ab2af486-e097-4b4a-9444-527b251f1f8d -TermSet \"Departments\" -TermGroup \"Corporate\"", - "Id": 840, "CommandName": "Get-PnPTerm", + "Command": "Get-PnPTerm -Identity ab2af486-e097-4b4a-9444-527b251f1f8d -TermSet \"Departments\" -TermGroup \"Corporate\"", + "Id": 848, "Rank": 3 }, { - "Command": "Get-PnPTerm -Identity \"Small Finance\" -TermSet \"Departments\" -TermGroup \"Corporate\" -Recursive", - "Id": 841, "CommandName": "Get-PnPTerm", + "Command": "Get-PnPTerm -Identity \"Small Finance\" -TermSet \"Departments\" -TermGroup \"Corporate\" -Recursive", + "Id": 849, "Rank": 4 }, { - "Command": "Get-PnPTerm -Identity \"Small Finance\" -TermSet \"Departments\" -TermGroup \"Corporate\" -Recursive -IncludeDeprecated", - "Id": 842, "CommandName": "Get-PnPTerm", + "Command": "Get-PnPTerm -Identity \"Small Finance\" -TermSet \"Departments\" -TermGroup \"Corporate\" -Recursive -IncludeDeprecated", + "Id": 850, "Rank": 5 }, { - "Command": "Get-PnPTermGroup", - "Id": 843, "CommandName": "Get-PnPTermGroup", + "Command": "Get-PnPTermGroup", + "Id": 851, "Rank": 1 }, { - "Command": "Get-PnPTermGroup -Identity \"Departments\"", - "Id": 844, "CommandName": "Get-PnPTermGroup", + "Command": "Get-PnPTermGroup -Identity \"Departments\"", + "Id": 852, "Rank": 2 }, { - "Command": "Get-PnPTermGroup -Identity ab2af486-e097-4b4a-9444-527b251f1f8d", - "Id": 845, "CommandName": "Get-PnPTermGroup", + "Command": "Get-PnPTermGroup -Identity ab2af486-e097-4b4a-9444-527b251f1f8d", + "Id": 853, "Rank": 3 }, { - "Command": "Get-PnPTermLabel -Term af8601d6-d925-46dd-af7b-4a58515ffd83", - "Id": 846, "CommandName": "Get-PnPTermLabel", + "Command": "Get-PnPTermLabel -Term af8601d6-d925-46dd-af7b-4a58515ffd83", + "Id": 854, "Rank": 1 }, { - "Command": "Get-PnPTermLabel -Term af8601d6-d925-46dd-af7b-4a58515ffd83 -Lcid 1033", - "Id": 847, "CommandName": "Get-PnPTermLabel", + "Command": "Get-PnPTermLabel -Term af8601d6-d925-46dd-af7b-4a58515ffd83 -Lcid 1033", + "Id": 855, "Rank": 2 }, { - "Command": "Get-PnPTermLabel -Term \"Marketing\" -TermSet \"Departments\" -TermGroup \"Corporate\"", - "Id": 848, "CommandName": "Get-PnPTermLabel", + "Command": "Get-PnPTermLabel -Term \"Marketing\" -TermSet \"Departments\" -TermGroup \"Corporate\"", + "Id": 856, "Rank": 3 }, { - "Command": "Get-PnPTermSet -TermGroup \"Corporate\"", - "Id": 849, "CommandName": "Get-PnPTermSet", + "Command": "Get-PnPTermSet -TermGroup \"Corporate\"", + "Id": 857, "Rank": 1 }, { - "Command": "Get-PnPTermSet -Identity \"Departments\" -TermGroup \"Corporate\"", - "Id": 850, "CommandName": "Get-PnPTermSet", + "Command": "Get-PnPTermSet -Identity \"Departments\" -TermGroup \"Corporate\"", + "Id": 858, "Rank": 2 }, { - "Command": "Get-PnPTermSet -Identity ab2af486-e097-4b4a-9444-527b251f1f8d -TermGroup \"Corporate", - "Id": 851, "CommandName": "Get-PnPTermSet", + "Command": "Get-PnPTermSet -Identity ab2af486-e097-4b4a-9444-527b251f1f8d -TermGroup \"Corporate", + "Id": 859, "Rank": 3 }, { - "Command": "Get-PnPTheme", - "Id": 852, "CommandName": "Get-PnPTheme", + "Command": "Get-PnPTheme", + "Id": 860, "Rank": 1 }, { - "Command": "Get-PnPTheme -DetectCurrentComposedLook", - "Id": 853, "CommandName": "Get-PnPTheme", + "Command": "Get-PnPTheme -DetectCurrentComposedLook", + "Id": 861, "Rank": 2 }, { - "Command": "Get-PnPTimeZoneId", - "Id": 854, "CommandName": "Get-PnPTimeZoneId", + "Command": "Get-PnPTimeZoneId", + "Id": 862, "Rank": 1 }, { - "Command": "Get-PnPTimeZoneId -Match Stockholm", - "Id": 855, "CommandName": "Get-PnPTimeZoneId", + "Command": "Get-PnPTimeZoneId -Match Stockholm", + "Id": 863, "Rank": 2 }, { - "Command": "Get-PnPUnfurlLink -Url \"https://contoso.sharepoint.com/:u:/s/testsitecol/ERs6pDuyD95LpUSUsJxi1EIBr9FMEYVBvMcs_B7cPdNPgQ?e=ZL3DPe\"", - "Id": 856, "CommandName": "Get-PnPUnfurlLink", + "Command": "Get-PnPUnfurlLink -Url \"https://contoso.sharepoint.com/:u:/s/testsitecol/ERs6pDuyD95LpUSUsJxi1EIBr9FMEYVBvMcs_B7cPdNPgQ?e=ZL3DPe\"", + "Id": 864, "Rank": 1 }, { - "Command": "Get-PnPUnifiedAuditLog -ContentType SharePoint -StartTime (Get-Date -asUtc).AddDays(-2) -EndTime (Get-Date -asUtc).AddDays(-1)", - "Id": 857, "CommandName": "Get-PnPUnifiedAuditLog", + "Command": "Get-PnPUnifiedAuditLog -ContentType SharePoint -StartTime (Get-Date -asUtc).AddDays(-2) -EndTime (Get-Date -asUtc).AddDays(-1)", + "Id": 865, "Rank": 1 }, { - "Command": "Get-PnPUPABulkImportStatus", - "Id": 858, "CommandName": "Get-PnPUPABulkImportStatus", + "Command": "Get-PnPUPABulkImportStatus", + "Id": 866, "Rank": 1 }, { - "Command": "Get-PnPUPABulkImportStatus -IncludeErrorDetails", - "Id": 859, "CommandName": "Get-PnPUPABulkImportStatus", + "Command": "Get-PnPUPABulkImportStatus -IncludeErrorDetails", + "Id": 867, "Rank": 2 }, { - "Command": "Get-PnPUPABulkImportStatus -JobId ", - "Id": 860, "CommandName": "Get-PnPUPABulkImportStatus", + "Command": "Get-PnPUPABulkImportStatus -JobId ", + "Id": 868, "Rank": 3 }, { - "Command": "Get-PnPUPABulkImportStatus -JobId -IncludeErrorDetails", - "Id": 861, "CommandName": "Get-PnPUPABulkImportStatus", + "Command": "Get-PnPUPABulkImportStatus -JobId -IncludeErrorDetails", + "Id": 869, "Rank": 4 }, { - "Command": "Get-PnPUser", - "Id": 862, "CommandName": "Get-PnPUser", + "Command": "Get-PnPUser", + "Id": 870, "Rank": 1 }, { - "Command": "Get-PnPUser -Identity 23", - "Id": 863, "CommandName": "Get-PnPUser", + "Command": "Get-PnPUser -Identity 23", + "Id": 871, "Rank": 2 }, { - "Command": "Get-PnPUser -Identity \"i:0#.f|membership|user@tenant.onmicrosoft.com\"", - "Id": 864, "CommandName": "Get-PnPUser", + "Command": "Get-PnPUser -Identity \"i:0#.f|membership|user@tenant.onmicrosoft.com\"", + "Id": 872, "Rank": 3 }, { - "Command": "Get-PnPUser | ? Email -eq \"user@tenant.onmicrosoft.com\"", - "Id": 865, "CommandName": "Get-PnPUser", + "Command": "Get-PnPUser | ? Email -eq \"user@tenant.onmicrosoft.com\"", + "Id": 873, "Rank": 4 }, { - "Command": "Get-PnPUser -WithRightsAssigned", - "Id": 866, "CommandName": "Get-PnPUser", + "Command": "Get-PnPUser -WithRightsAssigned", + "Id": 874, "Rank": 5 }, { - "Command": "Get-PnPUser -WithRightsAssigned -Web subsite1", - "Id": 867, "CommandName": "Get-PnPUser", + "Command": "Get-PnPUser -WithRightsAssigned -Web subsite1", + "Id": 875, "Rank": 6 }, { - "Command": "Get-PnPUser -WithRightsAssignedDetailed", - "Id": 868, "CommandName": "Get-PnPUser", + "Command": "Get-PnPUser -WithRightsAssignedDetailed", + "Id": 876, "Rank": 7 }, { - "Command": "Get-PnPUserOneDriveQuota -Account 'user@domain.com'", - "Id": 869, "CommandName": "Get-PnPUserOneDriveQuota", + "Command": "Get-PnPUserOneDriveQuota -Account 'user@domain.com'", + "Id": 877, "Rank": 1 }, { - "Command": "Get-PnPUserProfileProperty -Account 'user@domain.com'", - "Id": 870, "CommandName": "Get-PnPUserProfileProperty", + "Command": "Get-PnPUserProfileProperty -Account 'user@domain.com'", + "Id": 878, "Rank": 1 }, { - "Command": "Get-PnPUserProfileProperty -Account 'user@domain.com','user2@domain.com'", - "Id": 871, "CommandName": "Get-PnPUserProfileProperty", + "Command": "Get-PnPUserProfileProperty -Account 'user@domain.com','user2@domain.com'", + "Id": 879, "Rank": 2 }, { - "Command": "Get-PnPUserProfileProperty -Account 'user@domain.com' -Properties 'FirstName','LastName'", - "Id": 872, "CommandName": "Get-PnPUserProfileProperty", + "Command": "Get-PnPUserProfileProperty -Account 'user@domain.com' -Properties 'FirstName','LastName'", + "Id": 880, "Rank": 3 }, { - "Command": "Get-PnPView -List \"Demo List\"", - "Id": 873, "CommandName": "Get-PnPView", + "Command": "Get-PnPView -List \"Demo List\"", + "Id": 881, "Rank": 1 }, { - "Command": "Get-PnPView -List \"Demo List\" -Identity \"Demo View\"", - "Id": 874, "CommandName": "Get-PnPView", + "Command": "Get-PnPView -List \"Demo List\" -Identity \"Demo View\"", + "Id": 882, "Rank": 2 }, { - "Command": "Get-PnPView -List \"Demo List\" -Identity \"5275148a-6c6c-43d8-999a-d2186989a661\"", - "Id": 875, "CommandName": "Get-PnPView", + "Command": "Get-PnPView -List \"Demo List\" -Identity \"5275148a-6c6c-43d8-999a-d2186989a661\"", + "Id": 883, "Rank": 3 }, { - "Command": "Get-PnPVivaConnectionsDashboardACE", - "Id": 876, "CommandName": "Get-PnPVivaConnectionsDashboardACE", + "Command": "Get-PnPVivaConnectionsDashboardACE", + "Id": 884, "Rank": 1 }, { - "Command": "Get-PnPVivaConnectionsDashboardACE -Identity \"58108715-185e-4214-8786-01218e7ab9ef\"", - "Id": 877, "CommandName": "Get-PnPVivaConnectionsDashboardACE", + "Command": "Get-PnPVivaConnectionsDashboardACE -Identity \"58108715-185e-4214-8786-01218e7ab9ef\"", + "Id": 885, "Rank": 2 }, { - "Command": "Get-PnPWeb", - "Id": 878, "CommandName": "Get-PnPWeb", + "Command": "Get-PnPWeb", + "Id": 886, "Rank": 1 }, { - "Command": "Get-PnPWebHeader", - "Id": 879, "CommandName": "Get-PnPWebHeader", + "Command": "Get-PnPWebHeader", + "Id": 887, "Rank": 1 }, { - "Command": "Get-PnPWebhookSubscription -List MyList", - "Id": 880, "CommandName": "Get-PnPWebhookSubscription", + "Command": "Get-PnPWebhookSubscription -List MyList", + "Id": 888, "Rank": 1 }, { - "Command": "Get-PnPWebPart -ServerRelativePageUrl \"/sites/demo/sitepages/home.aspx\"", - "Id": 881, "CommandName": "Get-PnPWebPart", + "Command": "Get-PnPWebPart -ServerRelativePageUrl \"/sites/demo/sitepages/home.aspx\"", + "Id": 889, "Rank": 1 }, { - "Command": "Get-PnPWebPart -ServerRelativePageUrl \"/sites/demo/sitepages/home.aspx\" -Identity a2875399-d6ff-43a0-96da-be6ae5875f82", - "Id": 882, "CommandName": "Get-PnPWebPart", + "Command": "Get-PnPWebPart -ServerRelativePageUrl \"/sites/demo/sitepages/home.aspx\" -Identity a2875399-d6ff-43a0-96da-be6ae5875f82", + "Id": 890, "Rank": 2 }, { - "Command": "Get-PnPWebPartProperty -ServerRelativePageUrl /sites/demo/sitepages/home.aspx -Identity ccd2c98a-c9ae-483b-ae72-19992d583914", - "Id": 883, "CommandName": "Get-PnPWebPartProperty", + "Command": "Get-PnPWebPartProperty -ServerRelativePageUrl /sites/demo/sitepages/home.aspx -Identity ccd2c98a-c9ae-483b-ae72-19992d583914", + "Id": 891, "Rank": 1 }, { - "Command": "Get-PnPWebPartProperty -ServerRelativePageUrl /sites/demo/sitepages/home.aspx -Identity ccd2c98a-c9ae-483b-ae72-19992d583914 -Key \"Title\"", - "Id": 884, "CommandName": "Get-PnPWebPartProperty", + "Command": "Get-PnPWebPartProperty -ServerRelativePageUrl /sites/demo/sitepages/home.aspx -Identity ccd2c98a-c9ae-483b-ae72-19992d583914 -Key \"Title\"", + "Id": 892, "Rank": 2 }, { - "Command": "Get-PnPWebPartXml -ServerRelativePageUrl \"/sites/demo/sitepages/home.aspx\" -Identity a2875399-d6ff-43a0-96da-be6ae5875f82", - "Id": 885, "CommandName": "Get-PnPWebPartXml", + "Command": "Get-PnPWebPartXml -ServerRelativePageUrl \"/sites/demo/sitepages/home.aspx\" -Identity a2875399-d6ff-43a0-96da-be6ae5875f82", + "Id": 893, "Rank": 1 }, { - "Command": "Get-PnPWebPermission -Identity (Get-PnPWeb) -PrincipalId 60", - "Id": 886, "CommandName": "Get-PnPWebPermission", + "Command": "Get-PnPWebPermission -Identity (Get-PnPWeb) -PrincipalId 60", + "Id": 894, "Rank": 1 }, { - "Command": "Get-PnPWebPermission -Identity \"subsite\" -PrincipalId (Get-PnPGroup -Identity DemoGroup).Id", - "Id": 887, "CommandName": "Get-PnPWebPermission", + "Command": "Get-PnPWebPermission -Identity \"subsite\" -PrincipalId (Get-PnPGroup -Identity DemoGroup).Id", + "Id": 895, "Rank": 2 }, { - "Command": "Get-PnPWebTemplates", - "Id": 888, "CommandName": "Get-PnPWebTemplates", + "Command": "Get-PnPWebTemplates", + "Id": 896, "Rank": 1 }, { - "Command": "Get-PnPWebTemplates -LCID 1033", - "Id": 889, "CommandName": "Get-PnPWebTemplates", + "Command": "Get-PnPWebTemplates -LCID 1033", + "Id": 897, "Rank": 2 }, { - "Command": "Get-PnPWebTemplates -CompatibilityLevel 15", - "Id": 890, "CommandName": "Get-PnPWebTemplates", + "Command": "Get-PnPWebTemplates -CompatibilityLevel 15", + "Id": 898, "Rank": 3 }, { - "Command": "Get-PnPWikiPageContent -PageUrl '/sites/demo1/pages/wikipage.aspx'", - "Id": 891, "CommandName": "Get-PnPWikiPageContent", + "Command": "Get-PnPWikiPageContent -PageUrl '/sites/demo1/pages/wikipage.aspx'", + "Id": 899, "Rank": 1 }, { - "Command": "Grant-PnPAzureADAppSitePermission -AppId \"aa37b89e-75a7-47e3-bdb6-b763851c61b6\" -DisplayName \"TestApp\" -Permissions Read", - "Id": 892, "CommandName": "Grant-PnPAzureADAppSitePermission", + "Command": "Grant-PnPAzureADAppSitePermission -AppId \"aa37b89e-75a7-47e3-bdb6-b763851c61b6\" -DisplayName \"TestApp\" -Permissions Read", + "Id": 900, "Rank": 1 }, { - "Command": "Grant-PnPAzureADAppSitePermission -AppId \"aa37b89e-75a7-47e3-bdb6-b763851c61b6\" -DisplayName \"TestApp\" -Permissions FullControl -Site https://contoso.sharepoint.com/sites/projects", - "Id": 893, "CommandName": "Grant-PnPAzureADAppSitePermission", + "Command": "Grant-PnPAzureADAppSitePermission -AppId \"aa37b89e-75a7-47e3-bdb6-b763851c61b6\" -DisplayName \"TestApp\" -Permissions FullControl -Site https://contoso.sharepoint.com/sites/projects", + "Id": 901, "Rank": 2 }, { - "Command": "Grant-PnPHubSiteRights -Identity \"https://contoso.sharepoint.com/sites/hubsite\" -Principals \"myuser@mydomain.com\",\"myotheruser@mydomain.com\"", - "Id": 894, "CommandName": "Grant-PnPHubSiteRights", + "Command": "Grant-PnPHubSiteRights -Identity \"https://contoso.sharepoint.com/sites/hubsite\" -Principals \"myuser@mydomain.com\",\"myotheruser@mydomain.com\"", + "Id": 902, "Rank": 1 }, { - "Command": "Grant-PnPSiteDesignRights -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd -Principals \"myuser@mydomain.com\",\"myotheruser@mydomain.com\"", - "Id": 895, "CommandName": "Grant-PnPSiteDesignRights", + "Command": "Grant-PnPSiteDesignRights -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd -Principals \"myuser@mydomain.com\",\"myotheruser@mydomain.com\"", + "Id": 903, "Rank": 1 }, { - "Command": "Grant-PnPTenantServicePrincipalPermission -Scope \"Group.Read.All\"", - "Id": 896, "CommandName": "Grant-PnPTenantServicePrincipalPermission", + "Command": "Grant-PnPTenantServicePrincipalPermission -Scope \"Group.Read.All\"", + "Id": 904, "Rank": 1 }, { - "Command": "Import-PnPTaxonomy -Terms 'Company|Locations|Stockholm'", - "Id": 897, "CommandName": "Import-PnPTaxonomy", + "Command": "Import-PnPTaxonomy -Terms 'Company|Locations|Stockholm'", + "Id": 905, "Rank": 1 }, { - "Command": "Import-PnPTaxonomy -Terms 'Company|Locations|\"Stockholm,Central\"'", - "Id": 898, "CommandName": "Import-PnPTaxonomy", + "Command": "Import-PnPTaxonomy -Terms 'Company|Locations|\"Stockholm,Central\"'", + "Id": 906, "Rank": 2 }, { - "Command": "Import-PnPTaxonomy -Terms 'Company|Locations|Stockholm|Central','Company|Locations|Stockholm|North'", - "Id": 899, "CommandName": "Import-PnPTaxonomy", + "Command": "Import-PnPTaxonomy -Terms 'Company|Locations|Stockholm|Central','Company|Locations|Stockholm|North'", + "Id": 907, "Rank": 3 }, { - "Command": "Import-PnPTaxonomy -Path ./mytaxonomyterms.txt", - "Id": 900, "CommandName": "Import-PnPTaxonomy", + "Command": "Import-PnPTaxonomy -Path ./mytaxonomyterms.txt", + "Id": 908, "Rank": 4 }, { - "Command": "Import-PnPTermGroupFromXml -Xml $xml", - "Id": 901, "CommandName": "Import-PnPTermGroupFromXml", + "Command": "Import-PnPTermGroupFromXml -Xml $xml", + "Id": 909, "Rank": 1 }, { - "Command": "Import-PnPTermGroupFromXml -Path input.xml", - "Id": 902, "CommandName": "Import-PnPTermGroupFromXml", + "Command": "Import-PnPTermGroupFromXml -Path input.xml", + "Id": 910, "Rank": 2 }, { - "Command": "Import-PnPTermSet -GroupName 'Standard Terms' -Path 'C:\\\\Temp\\\\ImportTermSet.csv' -SynchronizeDeletions", - "Id": 903, "CommandName": "Import-PnPTermSet", + "Command": "Import-PnPTermSet -GroupName 'Standard Terms' -Path 'C:\\\\Temp\\\\ImportTermSet.csv' -SynchronizeDeletions", + "Id": 911, "Rank": 1 }, { - "Command": "Import-PnPTermSet -TermStoreName 'My Term Store' -GroupName 'Standard Terms' -Path 'C:\\\\Temp\\\\ImportTermSet.csv' -TermSetId '{15A98DB6-D8E2-43E6-8771-066C1EC2B8D8}'", - "Id": 904, "CommandName": "Import-PnPTermSet", + "Command": "Import-PnPTermSet -TermStoreName 'My Term Store' -GroupName 'Standard Terms' -Path 'C:\\\\Temp\\\\ImportTermSet.csv' -TermSetId '{15A98DB6-D8E2-43E6-8771-066C1EC2B8D8}'", + "Id": 912, "Rank": 2 }, { - "Command": "Import-PnPTermSet -GroupName 'Standard Terms' -Path 'C:\\\\Temp\\\\ImportTermSet.csv' -IsOpen $true -Contact 'user@example.org' -Owner 'user@example.org'", - "Id": 905, "CommandName": "Import-PnPTermSet", + "Command": "Import-PnPTermSet -GroupName 'Standard Terms' -Path 'C:\\\\Temp\\\\ImportTermSet.csv' -IsOpen $true -Contact 'user@example.org' -Owner 'user@example.org'", + "Id": 913, "Rank": 3 }, { - "Command": "Install-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe", - "Id": 906, "CommandName": "Install-PnPApp", + "Command": "Install-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe", + "Id": 914, "Rank": 1 }, { - "Command": "Install-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe -Scope Site", - "Id": 907, "CommandName": "Install-PnPApp", + "Command": "Install-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe -Scope Site", + "Id": 915, "Rank": 2 }, { - "Command": "Invoke-PnPGraphMethod -Url \"groups?`$filter=startsWith(displayName,'ZZ')&`$select=displayName\"\r ; Invoke-PnPGraphMethod -Url 'groups/{id}?`$select=hideFromOutlookClients'", - "Id": 908, "CommandName": "Invoke-PnPGraphMethod", + "Command": "Invoke-PnPGraphMethod -Url \"groups?`$filter=startsWith(displayName,'ZZ')&`$select=displayName\"\r ; Invoke-PnPGraphMethod -Url 'groups/{id}?`$select=hideFromOutlookClients'", + "Id": 916, "Rank": 1 }, { - "Command": "Invoke-PnPGraphMethod -Url \"groups/{id}\" -Method Delete", - "Id": 909, "CommandName": "Invoke-PnPGraphMethod", + "Command": "Invoke-PnPGraphMethod -Url \"groups/{id}\" -Method Delete", + "Id": 917, "Rank": 2 }, { - "Command": "Invoke-PnPGraphMethod -Url \"groups/{id}\" -Method Patch -Content @{ displayName = \"NewName\" }", - "Id": 910, "CommandName": "Invoke-PnPGraphMethod", + "Command": "Invoke-PnPGraphMethod -Url \"groups/{id}\" -Method Patch -Content @{ displayName = \"NewName\" }", + "Id": 918, "Rank": 3 }, { - "Command": "Invoke-PnPGraphMethod -Url \"v1.0/users?$filter=accountEnabled ne true&$count=true\" -Method Get -ConsistencyLevelEventual", - "Id": 911, "CommandName": "Invoke-PnPGraphMethod", + "Command": "Invoke-PnPGraphMethod -Url \"v1.0/users?$filter=accountEnabled ne true&$count=true\" -Method Get -ConsistencyLevelEventual", + "Id": 919, "Rank": 4 }, { - "Command": "Invoke-PnPGraphMethod \"https://graph.microsoft.com/v1.0/users\"", - "Id": 912, "CommandName": "Invoke-PnPGraphMethod", + "Command": "Invoke-PnPGraphMethod -Url \"https://graph.microsoft.com/v1.0/users\"", + "Id": 920, "Rank": 5 }, { - "Command": "Invoke-PnPGraphMethod \"https://graph.microsoft.com/v1.0/users/user@contoso.com/photo/`$value\" -OutFile c:\\temp\\photo.jpg", - "Id": 913, "CommandName": "Invoke-PnPGraphMethod", + "Command": "Invoke-PnPGraphMethod -Url \"https://graph.microsoft.com/v1.0/users/user@contoso.com/photo/`$value\" -OutFile c:\\temp\\photo.jpg", + "Id": 921, "Rank": 6 }, { - "Command": "Invoke-PnPGraphMethod \"https://graph.microsoft.com/v1.0/users/user@contoso.com/photo/`$value\" -OutStream | Add-PnPFile -FileName user.jpg -Folder \"Shared Documents\"", - "Id": 914, "CommandName": "Invoke-PnPGraphMethod", + "Command": "Invoke-PnPGraphMethod -Url \"https://graph.microsoft.com/v1.0/users/user@contoso.com/photo/`$value\" -OutStream | Add-PnPFile -FileName user.jpg -Folder \"Shared Documents\"", + "Id": 922, "Rank": 7 }, { - "Command": "Invoke-PnPListDesign -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd", - "Id": 915, "CommandName": "Invoke-PnPListDesign", + "Command": "Invoke-PnPListDesign -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd", + "Id": 923, "Rank": 1 }, { - "Command": "Invoke-PnPListDesign -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd -WebUrl \"https://contoso.sharepoint.com/sites/mydemosite\"", - "Id": 916, "CommandName": "Invoke-PnPListDesign", + "Command": "Invoke-PnPListDesign -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd -WebUrl \"https://contoso.sharepoint.com/sites/mydemosite\"", + "Id": 924, "Rank": 2 }, { - "Command": "Invoke-PnPQuery -RetryCount 5", - "Id": 917, "CommandName": "Invoke-PnPQuery", + "Command": "Invoke-PnPQuery -RetryCount 5", + "Id": 925, "Rank": 1 }, { - "Command": "Invoke-PnPSiteDesign -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd", - "Id": 918, "CommandName": "Invoke-PnPSiteDesign", + "Command": "Invoke-PnPSiteDesign -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd", + "Id": 926, "Rank": 1 }, { - "Command": "Invoke-PnPSiteDesign -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd -WebUrl \"https://contoso.sharepoint.com/sites/mydemosite\"", - "Id": 919, "CommandName": "Invoke-PnPSiteDesign", + "Command": "Invoke-PnPSiteDesign -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd -WebUrl \"https://contoso.sharepoint.com/sites/mydemosite\"", + "Id": 927, "Rank": 2 }, { - "Command": "Invoke-PnPSiteScript -Identity \"My awesome script\" -WebUrl https://contoso.sharepoint.com/sites/mydemosite", - "Id": 920, "CommandName": "Invoke-PnPSiteScript", + "Command": "Invoke-PnPSiteScript -Identity \"My awesome script\" -WebUrl https://contoso.sharepoint.com/sites/mydemosite", + "Id": 928, "Rank": 1 }, { - "Command": "Invoke-PnPSiteSwap -SourceUrl https://contoso.sharepoint.com/sites/CommunicationSite -TargetUrl https://contoso.sharepoint.com -ArchiveUrl https://contoso.sharepoint.com/sites/Archive", - "Id": 921, "CommandName": "Invoke-PnPSiteSwap", + "Command": "Invoke-PnPSiteSwap -SourceUrl https://contoso.sharepoint.com/sites/CommunicationSite -TargetUrl https://contoso.sharepoint.com -ArchiveUrl https://contoso.sharepoint.com/sites/Archive", + "Id": 929, "Rank": 1 }, { - "Command": "Invoke-PnPSiteSwap -SourceUrl https://contoso.sharepoint.com/sites/SearchSite -TargetUrl https://contoso.sharepoint.com/search -ArchiveUrl https://contoso.sharepoint.com/sites/Archive", - "Id": 922, "CommandName": "Invoke-PnPSiteSwap", + "Command": "Invoke-PnPSiteSwap -SourceUrl https://contoso.sharepoint.com/sites/SearchSite -TargetUrl https://contoso.sharepoint.com/search -ArchiveUrl https://contoso.sharepoint.com/sites/Archive", + "Id": 930, "Rank": 2 }, { - "Command": "Invoke-PnPSiteSwap -SourceUrl https://contoso.sharepoint.com/sites/CommunicationSite -TargetUrl https://contoso.sharepoint.com -ArchiveUrl https://contoso.sharepoint.com/sites/Archive -DisableRedirection", - "Id": 923, "CommandName": "Invoke-PnPSiteSwap", + "Command": "Invoke-PnPSiteSwap -SourceUrl https://contoso.sharepoint.com/sites/CommunicationSite -TargetUrl https://contoso.sharepoint.com -ArchiveUrl https://contoso.sharepoint.com/sites/Archive -DisableRedirection", + "Id": 931, "Rank": 3 }, { - "Command": "Invoke-PnPSiteTemplate -Path template.xml", - "Id": 924, "CommandName": "Invoke-PnPSiteTemplate", + "Command": "Invoke-PnPSiteTemplate -Path template.xml", + "Id": 932, "Rank": 1 }, { - "Command": "Invoke-PnPSiteTemplate -Path template.xml -ResourceFolder c:\\provisioning\\resources", - "Id": 925, "CommandName": "Invoke-PnPSiteTemplate", + "Command": "Invoke-PnPSiteTemplate -Path template.xml -ResourceFolder c:\\provisioning\\resources", + "Id": 933, "Rank": 2 }, { - "Command": "Invoke-PnPSiteTemplate -Path template.xml -Parameters @{\"ListTitle\"=\"Projects\";\"parameter2\"=\"a second value\"}", - "Id": 926, "CommandName": "Invoke-PnPSiteTemplate", + "Command": "Invoke-PnPSiteTemplate -Path template.xml -Parameters @{\"ListTitle\"=\"Projects\";\"parameter2\"=\"a second value\"}", + "Id": 934, "Rank": 3 }, { - "Command": "Invoke-PnPSiteTemplate -Path template.xml -Handlers Lists, SiteSecurity", - "Id": 927, "CommandName": "Invoke-PnPSiteTemplate", + "Command": "Invoke-PnPSiteTemplate -Path template.xml -Handlers Lists, SiteSecurity", + "Id": 935, "Rank": 4 }, { - "Command": "Invoke-PnPSiteTemplate -Path template.pnp", - "Id": 928, "CommandName": "Invoke-PnPSiteTemplate", + "Command": "Invoke-PnPSiteTemplate -Path template.pnp", + "Id": 936, "Rank": 5 }, { - "Command": "Invoke-PnPSiteTemplate -Path \"https://tenant.sharepoint.com/sites/templatestorage/Documents/template.pnp\"", - "Id": 929, "CommandName": "Invoke-PnPSiteTemplate", + "Command": "Invoke-PnPSiteTemplate -Path \"https://tenant.sharepoint.com/sites/templatestorage/Documents/template.pnp\"", + "Id": 937, "Rank": 6 }, { - "Command": "Invoke-PnPSiteTemplate -Path .\\ -InputInstance $template", - "Id": 930, "CommandName": "Invoke-PnPSiteTemplate", + "Command": "Invoke-PnPSiteTemplate -Path .\\ -InputInstance $template", + "Id": 938, "Rank": 7 }, { - "Command": "Invoke-PnPSiteTemplate -Path .\\template.xml -TemplateId \"MyTemplate\"", - "Id": 931, "CommandName": "Invoke-PnPSiteTemplate", + "Command": "Invoke-PnPSiteTemplate -Path .\\template.xml -TemplateId \"MyTemplate\"", + "Id": 939, "Rank": 8 }, { - "Command": "Invoke-PnPSPRestMethod -Url /_api/web", - "Id": 932, "CommandName": "Invoke-PnPSPRestMethod", + "Command": "Invoke-PnPSPRestMethod -Url /_api/web", + "Id": 940, "Rank": 1 }, { - "Command": "Invoke-PnPTenantTemplate -Path myfile.pnp", - "Id": 933, "CommandName": "Invoke-PnPTenantTemplate", + "Command": "Invoke-PnPTenantTemplate -Path myfile.pnp", + "Id": 941, "Rank": 1 }, { - "Command": "Invoke-PnPTenantTemplate -Path myfile.pnp -SequenceId \"mysequence\"", - "Id": 934, "CommandName": "Invoke-PnPTenantTemplate", + "Command": "Invoke-PnPTenantTemplate -Path myfile.pnp -SequenceId \"mysequence\"", + "Id": 942, "Rank": 2 }, { - "Command": "Invoke-PnPTenantTemplate -Path myfile.pnp -Parameters @{\"ListTitle\"=\"Projects\";\"parameter2\"=\"a second value\"}", - "Id": 935, "CommandName": "Invoke-PnPTenantTemplate", + "Command": "Invoke-PnPTenantTemplate -Path myfile.pnp -Parameters @{\"ListTitle\"=\"Projects\";\"parameter2\"=\"a second value\"}", + "Id": 943, "Rank": 3 }, { - "Command": "Invoke-PnPWebAction -ListAction ${function:ListAction}", - "Id": 936, "CommandName": "Invoke-PnPWebAction", + "Command": "Invoke-PnPWebAction -ListAction ${function:ListAction}", + "Id": 944, "Rank": 1 }, { - "Command": "Invoke-PnPWebAction -ShouldProcessListAction ${function:ShouldProcessList} -ListAction ${function:ListAction}", - "Id": 937, "CommandName": "Invoke-PnPWebAction", + "Command": "Invoke-PnPWebAction -ShouldProcessListAction ${function:ShouldProcessList} -ListAction ${function:ListAction}", + "Id": 945, "Rank": 2 }, { - "Command": "Measure-PnPList \"Documents\"", - "Id": 938, "CommandName": "Measure-PnPList", + "Command": "Measure-PnPList \"Documents\"", + "Id": 946, "Rank": 1 }, { - "Command": "Measure-PnPList \"Documents\" -BrokenPermissions -ItemLevel", - "Id": 939, "CommandName": "Measure-PnPList", + "Command": "Measure-PnPList \"Documents\" -BrokenPermissions -ItemLevel", + "Id": 947, "Rank": 2 }, { - "Command": "Measure-PnPWeb", - "Id": 940, "CommandName": "Measure-PnPWeb", + "Command": "Measure-PnPWeb", + "Id": 948, "Rank": 1 }, { - "Command": "Measure-PnPWeb $web -Recursive", - "Id": 941, "CommandName": "Measure-PnPWeb", + "Command": "Measure-PnPWeb $web -Recursive", + "Id": 949, "Rank": 2 }, { - "Command": "Merge-PnPTerm -Identity d67966b0-3b60-4331-8dc4-0b5a2ca730fc -TargetTerm 95e13729-3ccf-4ec8-998c-78e9ef1daa0b", - "Id": 942, "CommandName": "Merge-PnPTerm", + "Command": "Merge-PnPTerm -Identity d67966b0-3b60-4331-8dc4-0b5a2ca730fc -TargetTerm 95e13729-3ccf-4ec8-998c-78e9ef1daa0b", + "Id": 950, "Rank": 1 }, { - "Command": "Move-PnPFile -SourceUrl \"Shared Documents/Document.docx\" -TargetUrl \"Archive/Document2.docx\"", - "Id": 943, "CommandName": "Move-PnPFile", + "Command": "Move-PnPFile -SourceUrl \"Shared Documents/Document.docx\" -TargetUrl \"Archive/Document2.docx\"", + "Id": 951, "Rank": 1 }, { - "Command": "Move-PnPFile -SourceUrl \"Shared Documents/Document.docx\" -TargetUrl \"Archive\" -Overwrite", - "Id": 944, "CommandName": "Move-PnPFile", + "Command": "Move-PnPFile -SourceUrl \"Shared Documents/Document.docx\" -TargetUrl \"Archive\" -Overwrite", + "Id": 952, "Rank": 2 }, { - "Command": "Move-PnPFile -SourceUrl \"Shared Documents/Document.docx\" -TargetUrl \"/sites/otherproject/Shared Documents\" -Overwrite -AllowSchemaMismatch -AllowSmallerVersionLimitOnDestination", - "Id": 945, "CommandName": "Move-PnPFile", + "Command": "Move-PnPFile -SourceUrl \"Shared Documents/Document.docx\" -TargetUrl \"/sites/otherproject/Shared Documents\" -Overwrite -AllowSchemaMismatch -AllowSmallerVersionLimitOnDestination", + "Id": 953, "Rank": 3 }, { - "Command": "Move-PnPFile -SourceUrl \"/sites/project/Shared Documents/Archive\" -TargetUrl \"/sites/archive/Project\" -AllowSchemaMismatch -AllowSmallerVersionLimitOnDestination", - "Id": 946, "CommandName": "Move-PnPFile", + "Command": "Move-PnPFile -SourceUrl \"/sites/project/Shared Documents/Archive\" -TargetUrl \"/sites/archive/Project\" -AllowSchemaMismatch -AllowSmallerVersionLimitOnDestination", + "Id": 954, "Rank": 4 }, { - "Command": "Move-PnPFolder -Folder Documents/Reports -TargetFolder 'Archived Reports'", - "Id": 947, "CommandName": "Move-PnPFolder", + "Command": "Move-PnPFolder -Folder Documents/Reports -TargetFolder 'Archived Reports'", + "Id": 955, "Rank": 1 }, { - "Command": "Move-PnPFolder -Folder 'Shared Documents/Reports/2016/Templates' -TargetFolder 'Shared Documents/Reports'", - "Id": 948, "CommandName": "Move-PnPFolder", + "Command": "Move-PnPFolder -Folder 'Shared Documents/Reports/2016/Templates' -TargetFolder 'Shared Documents/Reports'", + "Id": 956, "Rank": 2 }, { - "Command": "Move-PnPListItemToRecycleBin -List \"Demo List\" -Identity \"1\" -Force", - "Id": 949, "CommandName": "Move-PnPListItemToRecycleBin", + "Command": "Move-PnPListItemToRecycleBin -List \"Demo List\" -Identity \"1\" -Force", + "Id": 957, "Rank": 1 }, { - "Command": "Move-PnPPageComponent -Page Home -InstanceId a2875399-d6ff-43a0-96da-be6ae5875f82 -Section 1", - "Id": 950, "CommandName": "Move-PnPPageComponent", + "Command": "Move-PnPPageComponent -Page Home -InstanceId a2875399-d6ff-43a0-96da-be6ae5875f82 -Section 1", + "Id": 958, "Rank": 1 }, { - "Command": "Move-PnPPageComponent -Page Home -InstanceId a2875399-d6ff-43a0-96da-be6ae5875f82 -Column 2", - "Id": 951, "CommandName": "Move-PnPPageComponent", + "Command": "Move-PnPPageComponent -Page Home -InstanceId a2875399-d6ff-43a0-96da-be6ae5875f82 -Column 2", + "Id": 959, "Rank": 2 }, { - "Command": "Move-PnPPageComponent -Page Home -InstanceId a2875399-d6ff-43a0-96da-be6ae5875f82 -Section 1 -Column 2", - "Id": 952, "CommandName": "Move-PnPPageComponent", + "Command": "Move-PnPPageComponent -Page Home -InstanceId a2875399-d6ff-43a0-96da-be6ae5875f82 -Section 1 -Column 2", + "Id": 960, "Rank": 3 }, { - "Command": "Move-PnPPageComponent -Page Home -InstanceId a2875399-d6ff-43a0-96da-be6ae5875f82 -Section 1 -Column 2 -Position 2", - "Id": 953, "CommandName": "Move-PnPPageComponent", + "Command": "Move-PnPPageComponent -Page Home -InstanceId a2875399-d6ff-43a0-96da-be6ae5875f82 -Section 1 -Column 2 -Position 2", + "Id": 961, "Rank": 4 }, { - "Command": "Move-PnPRecycleBinItem", - "Id": 954, "CommandName": "Move-PnpRecycleBinItem", + "Command": "Move-PnPRecycleBinItem", + "Id": 962, "Rank": 1 }, { - "Command": "Move-PnPRecycleBinItem -Identity 26ffff29-b526-4451-9b6f-7f0e56ba7125", - "Id": 955, "CommandName": "Move-PnpRecycleBinItem", + "Command": "Move-PnPRecycleBinItem -Identity 26ffff29-b526-4451-9b6f-7f0e56ba7125", + "Id": 963, "Rank": 2 }, { - "Command": "Move-PnPRecycleBinItem -Force", - "Id": 956, "CommandName": "Move-PnpRecycleBinItem", + "Command": "Move-PnPRecycleBinItem -Force", + "Id": 964, "Rank": 3 }, { - "Command": "Move-PnPTerm -Identity d67966b0-3b60-4331-8dc4-0b5a2ca730fc -TargetTermSet 95e13729-3ccf-4ec8-998c-78e9ef1daa0b -TargetTermGroup b2645144-5757-4cd7-b7f9-e5d24757addf", - "Id": 957, "CommandName": "Move-PnPTerm", + "Command": "Move-PnPTerm -Identity d67966b0-3b60-4331-8dc4-0b5a2ca730fc -TargetTermSet 95e13729-3ccf-4ec8-998c-78e9ef1daa0b -TargetTermGroup b2645144-5757-4cd7-b7f9-e5d24757addf", + "Id": 965, "Rank": 1 }, { - "Command": "Move-PnPTerm -Identity \"Test\" -TargetTermSet \"TestTermSet1\" -TermSet \"OperationLevel-1 Test\" -TermGroup \"FromPowerAutomate\" -TargetTermGroup \"TestingGroup\"", - "Id": 958, "CommandName": "Move-PnPTerm", + "Command": "Move-PnPTerm -Identity \"Test\" -TargetTermSet \"TestTermSet1\" -TermSet \"OperationLevel-1 Test\" -TermGroup \"FromPowerAutomate\" -TargetTermGroup \"TestingGroup\"", + "Id": 966, "Rank": 2 }, { - "Command": "Move-PnPTerm -Identity d67966b0-3b60-4331-8dc4-0b5a2ca730fc -TargetTerm 2ad90b20-b5c0-4544-ac64-25e32d51fa3b -MoveToTerm", - "Id": 959, "CommandName": "Move-PnPTerm", + "Command": "Move-PnPTerm -Identity d67966b0-3b60-4331-8dc4-0b5a2ca730fc -TargetTerm 2ad90b20-b5c0-4544-ac64-25e32d51fa3b -MoveToTerm", + "Id": 967, "Rank": 3 }, { - "Command": "Move-PnPTermSet -Identity 81e0a4b8-701d-459c-ad61-a1c7a81810ff -TermGroup 17e16b98-a8c2-4db6-a860-5c42dbc818f4 -TargetTermGroup cf33d1cd-42d8-431c-9e43-3d8dab9ea8fd", - "Id": 960, "CommandName": "Move-PnPTermSet", + "Command": "Move-PnPTermSet -Identity 81e0a4b8-701d-459c-ad61-a1c7a81810ff -TermGroup 17e16b98-a8c2-4db6-a860-5c42dbc818f4 -TargetTermGroup cf33d1cd-42d8-431c-9e43-3d8dab9ea8fd", + "Id": 968, "Rank": 1 }, { - "Command": "Move-PnPTermSet -Identity \"OperationLevel-1 Test\" -TermGroup \"FromPowerAutomate\" -TargetTermGroup \"TargetTermGroup\"", - "Id": 961, "CommandName": "Move-PnPTermSet", + "Command": "Move-PnPTermSet -Identity \"OperationLevel-1 Test\" -TermGroup \"FromPowerAutomate\" -TargetTermGroup \"TargetTermGroup\"", + "Id": 969, "Rank": 2 }, { - "Command": "New-PnPAzureADGroup -DisplayName $displayName -Description $description -MailNickname $nickname", - "Id": 962, "CommandName": "New-PnPAzureADGroup", + "Command": "New-PnPAzureADGroup -DisplayName $displayName -Description $description -MailNickname $nickname", + "Id": 970, "Rank": 1 }, { - "Command": "New-PnPAzureADGroup -DisplayName $displayName -Description $description -MailNickname $nickname -Owners $arrayOfOwners -Members $arrayOfMembers", - "Id": 963, "CommandName": "New-PnPAzureADGroup", + "Command": "New-PnPAzureADGroup -DisplayName $displayName -Description $description -MailNickname $nickname -Owners $arrayOfOwners -Members $arrayOfMembers", + "Id": 971, "Rank": 2 }, { - "Command": "New-PnPAzureADGroup -DisplayName $displayName -Description $description -MailNickname $nickname -IsSecurityEnabled -IsMailEnabled", - "Id": 964, "CommandName": "New-PnPAzureADGroup", + "Command": "New-PnPAzureADGroup -DisplayName $displayName -Description $description -MailNickname $nickname -IsSecurityEnabled -IsMailEnabled", + "Id": 972, "Rank": 3 }, { - "Command": "New-PnPAzureADUserTemporaryAccessPass -Identity johndoe@contoso.onmicrosoft.com", - "Id": 965, "CommandName": "New-PnPAzureADUserTemporaryAccessPass", + "Command": "New-PnPAzureADUserTemporaryAccessPass -Identity johndoe@contoso.onmicrosoft.com", + "Id": 973, "Rank": 1 }, { - "Command": "New-PnPAzureADUserTemporaryAccessPass -Identity 72e2eb87-c124-4bd9-8e01-a447a1752058 -IsUseableOnce:$true", - "Id": 966, "CommandName": "New-PnPAzureADUserTemporaryAccessPass", + "Command": "New-PnPAzureADUserTemporaryAccessPass -Identity 72e2eb87-c124-4bd9-8e01-a447a1752058 -IsUseableOnce:$true", + "Id": 974, "Rank": 2 }, { - "Command": "New-PnPAzureADUserTemporaryAccessPass -Identity johndoe@contoso.onmicrosoft.com -StartDateTime (Get-Date).AddHours(2) -LifeTimeInMinutes 10 -IsUseableOnce:$true", - "Id": 967, "CommandName": "New-PnPAzureADUserTemporaryAccessPass", + "Command": "New-PnPAzureADUserTemporaryAccessPass -Identity johndoe@contoso.onmicrosoft.com -StartDateTime (Get-Date).AddHours(2) -LifeTimeInMinutes 10 -IsUseableOnce:$true", + "Id": 975, "Rank": 3 }, { - "Command": "New-PnPAzureCertificate -OutPfx pnp.pfx -OutCert pnp.cer", - "Id": 968, "CommandName": "New-PnPAzureCertificate", + "Command": "New-PnPAzureCertificate -OutPfx pnp.pfx -OutCert pnp.cer", + "Id": 976, "Rank": 1 }, { - "Command": "New-PnPAzureCertificate -CommonName \"My Certificate\" -ValidYears 30", - "Id": 969, "CommandName": "New-PnPAzureCertificate", + "Command": "New-PnPAzureCertificate -CommonName \"My Certificate\" -ValidYears 30", + "Id": 977, "Rank": 2 }, { - "Command": "New-PnPAzureCertificate -OutPfx pnp.pfx -OutCert pnp.cer -CertificatePassword (ConvertTo-SecureString -String \"pass@word1\" -AsPlainText -Force)", - "Id": 970, "CommandName": "New-PnPAzureCertificate", + "Command": "New-PnPAzureCertificate -OutPfx pnp.pfx -OutCert pnp.cer -CertificatePassword (ConvertTo-SecureString -String \"pass@word1\" -AsPlainText -Force)", + "Id": 978, "Rank": 3 }, { - "Command": "New-PnPAzureCertificate -OutPfx pnp.pfx -OutCert pnp.cer -SanNames $null", - "Id": 971, "CommandName": "New-PnPAzureCertificate", + "Command": "New-PnPAzureCertificate -OutPfx pnp.pfx -OutCert pnp.cer -SanNames $null", + "Id": 979, "Rank": 4 }, { - "Command": "New-PnPContainerType -ContainerTypeName \"test1\" -OwningApplicationId 50785fde-3082-47ac-a36d-06282ac5c7da -AzureSubscription c7170373-eb8d-4984-8cc9-59bcc88c65a0 -ResouceGroup \"SPEmbed\" -Region \"Uk-South\"", - "Id": 972, "CommandName": "New-PnPContainerType", + "Command": "New-PnPContainerType -ContainerTypeName \"test1\" -OwningApplicationId 50785fde-3082-47ac-a36d-06282ac5c7da -AzureSubscription c7170373-eb8d-4984-8cc9-59bcc88c65a0 -ResouceGroup \"SPEmbed\" -Region \"Uk-South\"", + "Id": 980, "Rank": 1 }, { - "Command": "New-PnPGraphSubscription -ChangeType Create -NotificationUrl https://mywebapiservice/notifications -Resource \"me/mailFolders('Inbox')/messages\" -ExpirationDateTime (Get-Date).AddDays(1) -ClientState [Guid]::NewGuid().ToString()", - "Id": 973, "CommandName": "New-PnPGraphSubscription", + "Command": "New-PnPGraphSubscription -ChangeType Create -NotificationUrl https://mywebapiservice/notifications -Resource \"me/mailFolders('Inbox')/messages\" -ExpirationDateTime (Get-Date).AddDays(1) -ClientState [Guid]::NewGuid().ToString()", + "Id": 981, "Rank": 1 }, { - "Command": "New-PnPGraphSubscription -ChangeType Updates -NotificationUrl https://mywebapiservice/notifications -Resource \"Users\" -ExpirationDateTime (Get-Date).AddHours(1) -ClientState [Guid]::NewGuid().ToString()", - "Id": 974, "CommandName": "New-PnPGraphSubscription", + "Command": "New-PnPGraphSubscription -ChangeType Updates -NotificationUrl https://mywebapiservice/notifications -Resource \"Users\" -ExpirationDateTime (Get-Date).AddHours(1) -ClientState [Guid]::NewGuid().ToString()", + "Id": 982, "Rank": 2 }, { - "Command": "New-PnPGroup -Title \"My Site Users\"", - "Id": 975, "CommandName": "New-PnPGroup", + "Command": "New-PnPGroup -Title \"My Site Users\"", + "Id": 983, "Rank": 1 }, { - "Command": "New-PnPLibraryFileVersionBatchDeleteJob -Identity \"Documents\" -DeleteBeforeDays 360", - "Id": 976, "CommandName": "New-PnPLibraryFileVersionBatchDeleteJob", + "Command": "New-PnPLibraryFileVersionBatchDeleteJob -Identity \"Documents\" -DeleteBeforeDays 360", + "Id": 984, "Rank": 1 }, { - "Command": "New-PnPLibraryFileVersionBatchDeleteJob -Identity \"Documents\" -DeleteBeforeDays 360 -Force", - "Id": 977, "CommandName": "New-PnPLibraryFileVersionBatchDeleteJob", + "Command": "New-PnPLibraryFileVersionBatchDeleteJob -Identity \"Documents\" -DeleteBeforeDays 360 -Force", + "Id": 985, "Rank": 2 }, { - "Command": "New-PnPLibraryFileVersionBatchDeleteJob -Automatic", - "Id": 978, "CommandName": "New-PnPLibraryFileVersionBatchDeleteJob", + "Command": "New-PnPLibraryFileVersionBatchDeleteJob -Identity \"Documents\" -Automatic", + "Id": 986, "Rank": 3 }, { - "Command": "New-PnPLibraryFileVersionBatchDeleteJob -MajorVersionLimit 30 -MajorWithMinorVersionsLimit 10", - "Id": 979, "CommandName": "New-PnPLibraryFileVersionBatchDeleteJob", + "Command": "New-PnPLibraryFileVersionBatchDeleteJob -Identity \"Documents\" -MajorVersionLimit 30 -MajorWithMinorVersionsLimit 10", + "Id": 987, "Rank": 4 }, { - "Command": "New-PnPLibraryFileVersionExpirationReportJob -Identity \"Documents\" -ReportUrl \"https://contoso.sharepoint.com/sites/reports/MyReports/VersionReport.csv\"", - "Id": 980, "CommandName": "New-PnPLibraryFileVersionExpirationReportJob", + "Command": "New-PnPLibraryFileVersionExpirationReportJob -Identity \"Documents\" -ReportUrl \"https://contoso.sharepoint.com/sites/reports/MyReports/VersionReport.csv\"", + "Id": 988, "Rank": 1 }, { - "Command": "New-PnPList -Title Announcements -Template Announcements", - "Id": 981, "CommandName": "New-PnPList", + "Command": "New-PnPList -Title Announcements -Template Announcements", + "Id": 989, "Rank": 1 }, { - "Command": "New-PnPList -Title \"Demo List\" -Url \"lists/DemoList\" -Template Announcements", - "Id": 982, "CommandName": "New-PnPList", + "Command": "New-PnPList -Title \"Demo List\" -Url \"lists/DemoList\" -Template Announcements", + "Id": 990, "Rank": 2 }, { - "Command": "New-PnPList -Title HiddenList -Template GenericList -Hidden", - "Id": 983, "CommandName": "New-PnPList", + "Command": "New-PnPList -Title HiddenList -Template GenericList -Hidden", + "Id": 991, "Rank": 3 }, { - "Command": "New-PnPMicrosoft365Group -DisplayName $displayName -Description $description -MailNickname $nickname", - "Id": 984, "CommandName": "New-PnPMicrosoft365Group", + "Command": "New-PnPMicrosoft365Group -DisplayName $displayName -Description $description -MailNickname $nickname", + "Id": 992, "Rank": 1 }, { - "Command": "New-PnPMicrosoft365Group -DisplayName $displayName -Description $description -MailNickname $nickname -Owners \"owner1@domain.com\" -Members \"member1@domain.com\"", - "Id": 985, "CommandName": "New-PnPMicrosoft365Group", + "Command": "New-PnPMicrosoft365Group -DisplayName $displayName -Description $description -MailNickname $nickname -Owners \"owner1@domain.com\" -Members \"member1@domain.com\"", + "Id": 993, "Rank": 2 }, { - "Command": "New-PnPMicrosoft365Group -DisplayName $displayName -Description $description -MailNickname $nickname -IsPrivate", - "Id": 986, "CommandName": "New-PnPMicrosoft365Group", + "Command": "New-PnPMicrosoft365Group -DisplayName $displayName -Description $description -MailNickname $nickname -IsPrivate", + "Id": 994, "Rank": 3 }, { - "Command": "New-PnPMicrosoft365Group -DisplayName $displayName -Description $description -MailNickname $nickname -Owners $arrayOfOwners -Members $arrayOfMembers -IsPrivate", - "Id": 987, "CommandName": "New-PnPMicrosoft365Group", + "Command": "New-PnPMicrosoft365Group -DisplayName $displayName -Description $description -MailNickname $nickname -Owners $arrayOfOwners -Members $arrayOfMembers -IsPrivate", + "Id": 995, "Rank": 4 }, { - "Command": "New-PnPMicrosoft365Group -DisplayName \"myPnPDemo1\" -Description $description -MailNickname $nickname -Owners $arrayOfOwners -Members $arrayOfMembers -IsPrivate -ResourceBehaviorOptions WelcomeEmailDisabled, HideGroupInOutlook", - "Id": 988, "CommandName": "New-PnPMicrosoft365Group", + "Command": "New-PnPMicrosoft365Group -DisplayName \"myPnPDemo1\" -Description $description -MailNickname $nickname -Owners $arrayOfOwners -Members $arrayOfMembers -IsPrivate -ResourceBehaviorOptions WelcomeEmailDisabled, HideGroupInOutlook", + "Id": 996, "Rank": 5 }, { - "Command": "New-PnPMicrosoft365Group -DisplayName $displayName -Description $description -MailNickname $nickname -IsPrivate -SensitivityLabels \"bc98af29-59eb-4869-baaa-9a8dff631aa4\"", - "Id": 989, "CommandName": "New-PnPMicrosoft365Group", + "Command": "New-PnPMicrosoft365Group -DisplayName $displayName -Description $description -MailNickname $nickname -IsPrivate -SensitivityLabels \"bc98af29-59eb-4869-baaa-9a8dff631aa4\"", + "Id": 997, "Rank": 6 }, { - "Command": "New-PnPMicrosoft365Group -DisplayName $displayName -Description $description -MailNickname $nickname -DynamicMembershipRule \"(user.department -eq \"\"HR\"\")\"", - "Id": 990, "CommandName": "New-PnPMicrosoft365Group", + "Command": "New-PnPMicrosoft365Group -DisplayName $displayName -Description $description -MailNickname $nickname -DynamicMembershipRule \"(user.department -eq \"\"HR\"\")\"", + "Id": 998, "Rank": 7 }, { - "Command": "New-PnPMicrosoft365GroupSettings -DisplayName \"Group.Unified\" -TemplateId \"62375ab9-6b52-47ed-826b-58e47e0e304b\" -Values @{\"GuestUsageGuidelinesUrl\"=\"https://privacy.contoso.com/privacystatement\";\"EnableMSStandardBlockedWords\"=\"true\"}", - "Id": 991, "CommandName": "New-PnPMicrosoft365GroupSettings", + "Command": "New-PnPMicrosoft365GroupSettings -DisplayName \"Group.Unified\" -TemplateId \"62375ab9-6b52-47ed-826b-58e47e0e304b\" -Values @{\"GuestUsageGuidelinesUrl\"=\"https://privacy.contoso.com/privacystatement\";\"EnableMSStandardBlockedWords\"=\"true\"}", + "Id": 999, "Rank": 1 }, { - "Command": "New-PnPMicrosoft365GroupSettings -Identity $groupId -DisplayName \"Group.Unified.Guest\" -TemplateId \"08d542b9-071f-4e16-94b0-74abb372e3d9\" -Values @{\"AllowToAddGuests\"=\"false\"}", - "Id": 992, "CommandName": "New-PnPMicrosoft365GroupSettings", + "Command": "New-PnPMicrosoft365GroupSettings -Identity $groupId -DisplayName \"Group.Unified.Guest\" -TemplateId \"08d542b9-071f-4e16-94b0-74abb372e3d9\" -Values @{\"AllowToAddGuests\"=\"false\"}", + "Id": 1000, "Rank": 2 }, { - "Command": "New-PnPPersonalSite -Email @('katiej@contoso.onmicrosoft.com','garth@contoso.onmicrosoft.com')", - "Id": 993, "CommandName": "New-PnPPersonalSite", + "Command": "New-PnPPersonalSite -Email @('katiej@contoso.onmicrosoft.com','garth@contoso.onmicrosoft.com')", + "Id": 1001, "Rank": 1 }, { - "Command": "New-PnPPlannerPlan -Group \"Marketing\" -Title \"Conference Plan\"", - "Id": 994, "CommandName": "New-PnPPlannerPlan", + "Command": "New-PnPPlannerPlan -Group \"Marketing\" -Title \"Conference Plan\"", + "Id": 1002, "Rank": 1 }, { - "Command": "New-PnPSdnProvider -ID \"Hive\" -License \"\"", - "Id": 995, "CommandName": "New-PnPSdnProvider", + "Command": "New-PnPSdnProvider -ID \"Hive\" -License \"\"", + "Id": 1003, "Rank": 1 }, { - "Command": "New-PnPSite -Type CommunicationSite -Title Contoso -Url https://tenant.sharepoint.com/sites/contoso", - "Id": 996, + "CommandName": "New-PnPSearchExternalConnection", + "Command": "New-PnPSearchExternalConnection -Identity \"pnppowershell\" -Name \"PnP PowerShell\" -Description \"External content ingested using PnP PowerShell\"", + "Id": 1004, + "Rank": 1 + }, + { + "CommandName": "New-PnPSearchExternalConnection", + "Command": "New-PnPSearchExternalConnection -Identity \"pnppowershell\" -Name \"PnP PowerShell\" -Description \"External content ingested using PnP PowerShell\" -AuthorizedAppIds \"00000000-0000-0000-0000-000000000000\",\"11111111-1111-1111-1111-111111111111\"", + "Id": 1005, + "Rank": 2 + }, + { "CommandName": "New-PnPSite", + "Command": "New-PnPSite -Type CommunicationSite -Title Contoso -Url https://tenant.sharepoint.com/sites/contoso", + "Id": 1006, "Rank": 1 }, { - "Command": "New-PnPSite -Type CommunicationSite -Title Contoso -Url https://tenant.sharepoint.com/sites/contoso -SiteDesign Showcase", - "Id": 997, "CommandName": "New-PnPSite", + "Command": "New-PnPSite -Type CommunicationSite -Title Contoso -Url https://tenant.sharepoint.com/sites/contoso -SiteDesign Showcase", + "Id": 1007, "Rank": 2 }, { - "Command": "New-PnPSite -Type CommunicationSite -Title Contoso -Url https://tenant.sharepoint.com/sites/contoso -SiteDesignId ae2349d5-97d6-4440-94d1-6516b72449ac", - "Id": 998, "CommandName": "New-PnPSite", + "Command": "New-PnPSite -Type CommunicationSite -Title Contoso -Url https://tenant.sharepoint.com/sites/contoso -SiteDesignId ae2349d5-97d6-4440-94d1-6516b72449ac", + "Id": 1008, "Rank": 3 }, { - "Command": "New-PnPSite -Type CommunicationSite -Title Contoso -Url https://tenant.sharepoint.com/sites/contoso -Classification \"HBI\"", - "Id": 999, "CommandName": "New-PnPSite", + "Command": "New-PnPSite -Type CommunicationSite -Title Contoso -Url https://tenant.sharepoint.com/sites/contoso -Classification \"HBI\"", + "Id": 1009, "Rank": 4 }, { - "Command": "New-PnPSite -Type CommunicationSite -Title Contoso -Url https://tenant.sharepoint.com/sites/contoso -ShareByEmailEnabled", - "Id": 1000, "CommandName": "New-PnPSite", + "Command": "New-PnPSite -Type CommunicationSite -Title Contoso -Url https://tenant.sharepoint.com/sites/contoso -ShareByEmailEnabled", + "Id": 1010, "Rank": 5 }, { - "Command": "New-PnPSite -Type CommunicationSite -Title Contoso -Url https://tenant.sharepoint.com/sites/contoso -Lcid 1040", - "Id": 1001, "CommandName": "New-PnPSite", + "Command": "New-PnPSite -Type CommunicationSite -Title Contoso -Url https://tenant.sharepoint.com/sites/contoso -Lcid 1040", + "Id": 1011, "Rank": 6 }, { - "Command": "New-PnPSite -Type TeamSite -Title 'Team Contoso' -Alias contoso", - "Id": 1002, "CommandName": "New-PnPSite", + "Command": "New-PnPSite -Type TeamSite -Title 'Team Contoso' -Alias contoso", + "Id": 1012, "Rank": 7 }, { - "Command": "New-PnPSite -Type TeamSite -Title 'Team Contoso' -Alias contoso -IsPublic", - "Id": 1003, "CommandName": "New-PnPSite", + "Command": "New-PnPSite -Type TeamSite -Title 'Team Contoso' -Alias contoso -IsPublic", + "Id": 1013, "Rank": 8 }, { - "Command": "New-PnPSite -Type TeamSite -Title 'Team Contoso' -Alias contoso -Lcid 1040", - "Id": 1004, "CommandName": "New-PnPSite", + "Command": "New-PnPSite -Type TeamSite -Title 'Team Contoso' -Alias contoso -Lcid 1040", + "Id": 1014, "Rank": 9 }, { - "Command": "New-PnPSite -Type TeamSite -Title 'Team Contoso' -Alias contoso -SiteAlias contoso-site", - "Id": 1005, "CommandName": "New-PnPSite", + "Command": "New-PnPSite -Type TeamSite -Title 'Team Contoso' -Alias contoso -SiteAlias contoso-site", + "Id": 1015, "Rank": 10 }, { - "Command": "New-PnPSite -Type TeamSiteWithoutMicrosoft365Group -Title Contoso -Url https://tenant.sharepoint.com/sites/contoso", - "Id": 1006, "CommandName": "New-PnPSite", + "Command": "New-PnPSite -Type TeamSiteWithoutMicrosoft365Group -Title Contoso -Url https://tenant.sharepoint.com/sites/contoso", + "Id": 1016, "Rank": 11 }, { - "Command": "New-PnPSite -Type TeamSiteWithoutMicrosoft365Group -Title Contoso -Url https://tenant.sharepoint.com/sites/contoso -SiteDesignId ae2349d5-97d6-4440-94d1-6516b72449ac", - "Id": 1007, "CommandName": "New-PnPSite", + "Command": "New-PnPSite -Type TeamSiteWithoutMicrosoft365Group -Title Contoso -Url https://tenant.sharepoint.com/sites/contoso -SiteDesignId ae2349d5-97d6-4440-94d1-6516b72449ac", + "Id": 1017, "Rank": 12 }, { - "Command": "New-PnPSite -Type TeamSiteWithoutMicrosoft365Group -Title Contoso -Url https://tenant.sharepoint.com/sites/contoso -Classification \"HBI\"", - "Id": 1008, "CommandName": "New-PnPSite", + "Command": "New-PnPSite -Type TeamSiteWithoutMicrosoft365Group -Title Contoso -Url https://tenant.sharepoint.com/sites/contoso -Classification \"HBI\"", + "Id": 1018, "Rank": 13 }, { - "Command": "New-PnPSite -Type TeamSiteWithoutMicrosoft365Group -Title Contoso -Url https://tenant.sharepoint.com/sites/contoso -ShareByEmailEnabled", - "Id": 1009, "CommandName": "New-PnPSite", + "Command": "New-PnPSite -Type TeamSiteWithoutMicrosoft365Group -Title Contoso -Url https://tenant.sharepoint.com/sites/contoso -ShareByEmailEnabled", + "Id": 1019, "Rank": 14 }, { - "Command": "New-PnPSite -Type TeamSiteWithoutMicrosoft365Group -Title Contoso -Url https://tenant.sharepoint.com/sites/contoso -Lcid 1040", - "Id": 1010, "CommandName": "New-PnPSite", + "Command": "New-PnPSite -Type TeamSiteWithoutMicrosoft365Group -Title Contoso -Url https://tenant.sharepoint.com/sites/contoso -Lcid 1040", + "Id": 1020, "Rank": 15 }, { - "Command": "New-PnPSite -Type TeamSite -TimeZone UTCPLUS0200_HELSINKI_KYIV_RIGA_SOFIA_TALLINN_VILNIUS -Title \"Contoso\" -Alias \"Contoso\"", - "Id": 1011, "CommandName": "New-PnPSite", + "Command": "New-PnPSite -Type TeamSite -TimeZone UTCPLUS0200_HELSINKI_KYIV_RIGA_SOFIA_TALLINN_VILNIUS -Title \"Contoso\" -Alias \"Contoso\"", + "Id": 1021, "Rank": 16 }, { - "Command": "New-PnPSiteCollectionTermStore", - "Id": 1012, "CommandName": "New-PnPSiteCollectionTermStore", + "Command": "New-PnPSiteCollectionTermStore", + "Id": 1022, "Rank": 1 }, { - "Command": "New-PnPSiteFileVersionBatchDeleteJob -DeleteBeforeDays 360", - "Id": 1013, "CommandName": "New-PnPSiteFileVersionBatchDeleteJob", + "Command": "New-PnPSiteFileVersionBatchDeleteJob -DeleteBeforeDays 360", + "Id": 1023, "Rank": 1 }, { - "Command": "New-PnPSiteFileVersionBatchDeleteJob -DeleteBeforeDays 360 -Force", - "Id": 1014, "CommandName": "New-PnPSiteFileVersionBatchDeleteJob", + "Command": "New-PnPSiteFileVersionBatchDeleteJob -DeleteBeforeDays 360 -Force", + "Id": 1024, "Rank": 2 }, { - "Command": "New-PnPSiteFileVersionBatchDeleteJob -Automatic", - "Id": 1015, "CommandName": "New-PnPSiteFileVersionBatchDeleteJob", + "Command": "New-PnPSiteFileVersionBatchDeleteJob -Automatic", + "Id": 1025, "Rank": 3 }, { - "Command": "New-PnPSiteFileVersionBatchDeleteJob -MajorVersionLimit 30 -MajorWithMinorVersionsLimit 10", - "Id": 1016, "CommandName": "New-PnPSiteFileVersionBatchDeleteJob", + "Command": "New-PnPSiteFileVersionBatchDeleteJob -MajorVersionLimit 30 -MajorWithMinorVersionsLimit 10", + "Id": 1026, "Rank": 4 }, { - "Command": "New-PnPSiteFileVersionExpirationReportJob -ReportUrl \"https://contoso.sharepoint.com/sites/reports/MyReports/VersionReport.csv\"", - "Id": 1017, "CommandName": "New-PnPSiteFileVersionExpirationReportJob", + "Command": "New-PnPSiteFileVersionExpirationReportJob -ReportUrl \"https://contoso.sharepoint.com/sites/reports/MyReports/VersionReport.csv\"", + "Id": 1027, "Rank": 1 }, { - "Command": "New-PnPSiteGroup -Site \"https://contoso.sharepoint.com/sites/siteA\" -Name \"Project Leads\" -PermissionLevels \"Full Control\"", - "Id": 1018, "CommandName": "New-PnPSiteGroup", + "Command": "New-PnPSiteGroup -Site \"https://contoso.sharepoint.com/sites/siteA\" -Name \"Project Leads\" -PermissionLevels \"Full Control\"", + "Id": 1028, "Rank": 1 }, { - "Command": "New-PnPSiteGroup -Site \"https://contoso.sharepoint.com/sites/marketing\" -Name \"NewGroupName\" -PermissionLevels \"Design\"", - "Id": 1019, "CommandName": "New-PnPSiteGroup", + "Command": "New-PnPSiteGroup -Site \"https://contoso.sharepoint.com/sites/marketing\" -Name \"NewGroupName\" -PermissionLevels \"Design\"", + "Id": 1029, "Rank": 2 }, { - "Command": "New-PnPSiteTemplateFromFolder -Out template.xml", - "Id": 1020, "CommandName": "New-PnPSiteTemplateFromFolder", + "Command": "New-PnPSiteTemplateFromFolder -Out template.xml", + "Id": 1030, "Rank": 1 }, { - "Command": "New-PnPSiteTemplateFromFolder -Out template.xml -Folder c:\\temp", - "Id": 1021, "CommandName": "New-PnPSiteTemplateFromFolder", + "Command": "New-PnPSiteTemplateFromFolder -Out template.xml -Folder c:\\temp", + "Id": 1031, "Rank": 2 }, { - "Command": "New-PnPSiteTemplateFromFolder -Out template.xml -Folder c:\\temp -Match *.js", - "Id": 1022, "CommandName": "New-PnPSiteTemplateFromFolder", + "Command": "New-PnPSiteTemplateFromFolder -Out template.xml -Folder c:\\temp -Match *.js", + "Id": 1032, "Rank": 3 }, { - "Command": "New-PnPSiteTemplateFromFolder -Out template.xml -Folder c:\\temp -Match *.js -TargetFolder \"Shared Documents\"", - "Id": 1023, "CommandName": "New-PnPSiteTemplateFromFolder", + "Command": "New-PnPSiteTemplateFromFolder -Out template.xml -Folder c:\\temp -Match *.js -TargetFolder \"Shared Documents\"", + "Id": 1033, "Rank": 4 }, { - "Command": "New-PnPSiteTemplateFromFolder -Out template.xml -Folder c:\\temp -Match *.js -TargetFolder \"Shared Documents\" -ContentType \"Test Content Type\"", - "Id": 1024, "CommandName": "New-PnPSiteTemplateFromFolder", + "Command": "New-PnPSiteTemplateFromFolder -Out template.xml -Folder c:\\temp -Match *.js -TargetFolder \"Shared Documents\" -ContentType \"Test Content Type\"", + "Id": 1034, "Rank": 5 }, { - "Command": "New-PnPSiteTemplateFromFolder -Out template.xml -Folder c:\\temp -Match *.js -TargetFolder \"Shared Documents\" -Properties @{\"Title\" = \"Test Title\"; \"Category\"=\"Test Category\"}", - "Id": 1025, "CommandName": "New-PnPSiteTemplateFromFolder", + "Command": "New-PnPSiteTemplateFromFolder -Out template.xml -Folder c:\\temp -Match *.js -TargetFolder \"Shared Documents\" -Properties @{\"Title\" = \"Test Title\"; \"Category\"=\"Test Category\"}", + "Id": 1035, "Rank": 6 }, { - "Command": "New-PnPSiteTemplateFromFolder -Out template.pnp", - "Id": 1026, "CommandName": "New-PnPSiteTemplateFromFolder", + "Command": "New-PnPSiteTemplateFromFolder -Out template.pnp", + "Id": 1036, "Rank": 7 }, { - "Command": "New-PnPSiteTemplateFromFolder -Out template.pnp -Folder c:\\temp", - "Id": 1027, "CommandName": "New-PnPSiteTemplateFromFolder", + "Command": "New-PnPSiteTemplateFromFolder -Out template.pnp -Folder c:\\temp", + "Id": 1037, "Rank": 8 }, { - "Command": "New-PnPTeamsApp -Path c:\\myapp.zip", - "Id": 1028, "CommandName": "New-PnPTeamsApp", + "Command": "New-PnPTeamsApp -Path c:\\myapp.zip", + "Id": 1038, "Rank": 1 }, { - "Command": "New-PnPTeamsTeam -DisplayName \"myPnPDemo1\" -Visibility Private -AllowCreateUpdateRemoveTabs $false -AllowUserDeleteMessages $false", - "Id": 1029, "CommandName": "New-PnPTeamsTeam", + "Command": "New-PnPTeamsTeam -DisplayName \"myPnPDemo1\" -Visibility Private -AllowCreateUpdateRemoveTabs $false -AllowUserDeleteMessages $false", + "Id": 1039, "Rank": 1 }, { - "Command": "New-PnPTeamsTeam -GroupId $groupId", - "Id": 1030, "CommandName": "New-PnPTeamsTeam", + "Command": "New-PnPTeamsTeam -GroupId $groupId", + "Id": 1040, "Rank": 2 }, { - "Command": "New-PnPTeamsTeam -DisplayName \"myPnPDemo1\" -Visibility Private -AllowCreateUpdateRemoveTabs $false -AllowUserDeleteMessages $false -ResourceBehaviorOptions WelcomeEmailDisabled", - "Id": 1031, "CommandName": "New-PnPTeamsTeam", + "Command": "New-PnPTeamsTeam -DisplayName \"myPnPDemo1\" -Visibility Private -AllowCreateUpdateRemoveTabs $false -AllowUserDeleteMessages $false -ResourceBehaviorOptions WelcomeEmailDisabled", + "Id": 1041, "Rank": 3 }, { - "Command": "New-PnPTeamsTeam -DisplayName \"myPnPDemo1\" -Visibility Private -AllowCreateUpdateRemoveTabs $false -AllowUserDeleteMessages $false -ResourceBehaviorOptions WelcomeEmailDisabled, HideGroupInOutlook", - "Id": 1032, "CommandName": "New-PnPTeamsTeam", + "Command": "New-PnPTeamsTeam -DisplayName \"myPnPDemo1\" -Visibility Private -AllowCreateUpdateRemoveTabs $false -AllowUserDeleteMessages $false -ResourceBehaviorOptions WelcomeEmailDisabled, HideGroupInOutlook", + "Id": 1042, "Rank": 4 }, { - "Command": "New-PnPTeamsTeam -DisplayName \"myPnPDemo1\" -Visibility Private -Owners \"user1@contoso.onmicrosoft.com\",\"user2@contoso.onmicrosoft.com\" -Members \"user3@contoso.onmicrosoft.com\"", - "Id": 1033, "CommandName": "New-PnPTeamsTeam", + "Command": "New-PnPTeamsTeam -DisplayName \"myPnPDemo1\" -Visibility Private -Owners \"user1@contoso.onmicrosoft.com\",\"user2@contoso.onmicrosoft.com\" -Members \"user3@contoso.onmicrosoft.com\"", + "Id": 1043, "Rank": 5 }, { - "Command": "New-PnPTeamsTeam -DisplayName \"myPnPDemo1\" -Visibility Private -Owners \"user1@contoso.onmicrosoft.com\",\"user2@contoso.onmicrosoft.com\" -Members \"user3@contoso.onmicrosoft.com\" -SensitivityLabels \"bc98af29-59eb-4869-baaa-9a8dff631aa4\"", - "Id": 1034, "CommandName": "New-PnPTeamsTeam", + "Command": "New-PnPTeamsTeam -DisplayName \"myPnPDemo1\" -Visibility Private -Owners \"user1@contoso.onmicrosoft.com\",\"user2@contoso.onmicrosoft.com\" -Members \"user3@contoso.onmicrosoft.com\" -SensitivityLabels \"bc98af29-59eb-4869-baaa-9a8dff631aa4\"", + "Id": 1044, "Rank": 6 }, { - "Command": "New-PnPTenantSite -Title Contoso -Url \"https://tenant.sharepoint.com/sites/contoso\" -Owner user@example.org -TimeZone 4 -Template STS#0", - "Id": 1035, "CommandName": "New-PnPTenantSite", + "Command": "New-PnPTenantSite -Title Contoso -Url \"https://tenant.sharepoint.com/sites/contoso\" -Owner user@example.org -TimeZone 4 -Template STS#0", + "Id": 1045, "Rank": 1 }, { - "Command": "New-PnPTenantSite -Title Contoso -Url /sites/contososite -Owner user@example.org -TimeZone 4 -Template STS#0", - "Id": 1036, "CommandName": "New-PnPTenantSite", + "Command": "New-PnPTenantSite -Title Contoso -Url /sites/contososite -Owner user@example.org -TimeZone 4 -Template STS#0", + "Id": 1046, "Rank": 2 }, { - "Command": "New-PnPTerm -TermSet \"Departments\" -TermGroup \"Corporate\" -Name \"Finance\"", - "Id": 1037, "CommandName": "New-PnPTerm", + "Command": "New-PnPTerm -TermSet \"Departments\" -TermGroup \"Corporate\" -Name \"Finance\"", + "Id": 1047, "Rank": 1 }, { - "Command": "New-PnPTerm -TermSet \"Departments\" -TermGroup \"Corporate\" -Name \"Finance\" -CustomProperties @{\"IsCorporate\"=\"True\"}", - "Id": 1038, "CommandName": "New-PnPTerm", + "Command": "New-PnPTerm -TermSet \"Departments\" -TermGroup \"Corporate\" -Name \"Finance\" -CustomProperties @{\"IsCorporate\"=\"True\"}", + "Id": 1048, "Rank": 2 }, { - "Command": "New-PnPTermGroup -GroupName \"Countries\"", - "Id": 1039, "CommandName": "New-PnPTermGroup", + "Command": "New-PnPTermGroup -GroupName \"Countries\"", + "Id": 1049, "Rank": 1 }, { - "Command": "New-PnPTermLabel -Name \"Finanzwesen\" -Lcid 1031 -Term (Get-PnPTerm -Identity \"Finance\" -TermSet \"Departments\" -TermGroup \"Corporate\")", - "Id": 1040, "CommandName": "New-PnPTermLabel", + "Command": "New-PnPTermLabel -Name \"Finanzwesen\" -Lcid 1031 -Term (Get-PnPTerm -Identity \"Finance\" -TermSet \"Departments\" -TermGroup \"Corporate\")", + "Id": 1050, "Rank": 1 }, { - "Command": "New-PnPTermSet -Name \"Department\" -TermGroup \"Corporate\"", - "Id": 1041, "CommandName": "New-PnPTermSet", + "Command": "New-PnPTermSet -Name \"Department\" -TermGroup \"Corporate\"", + "Id": 1051, "Rank": 1 }, { - "Command": "New-PnPUPABulkImportJob -Url \"https://{tenant}.sharepoint.com/Shared Documents/profiles.json\" -IdProperty \"IdName\" -UserProfilePropertyMapping @{\"Department\"=\"Department\"}", - "Id": 1042, "CommandName": "New-PnPUPABulkImportJob", + "Command": "New-PnPUPABulkImportJob -Url \"https://{tenant}.sharepoint.com/Shared Documents/profiles.json\" -IdProperty \"IdName\" -UserProfilePropertyMapping @{\"Department\"=\"Department\"}", + "Id": 1052, "Rank": 1 }, { - "Command": "New-PnPUPABulkImportJob -Url \"https://{tenant}.sharepoint.com/sites/userprofilesync/Shared Documents/profiles.json\" -IdProperty \"IdName\" -UserProfilePropertyMapping @{\"Department\"=\"Department\"} -Wait -Verbose", - "Id": 1043, "CommandName": "New-PnPUPABulkImportJob", + "Command": "New-PnPUPABulkImportJob -Url \"https://{tenant}.sharepoint.com/sites/userprofilesync/Shared Documents/profiles.json\" -IdProperty \"IdName\" -UserProfilePropertyMapping @{\"Department\"=\"Department\"} -Wait -Verbose", + "Id": 1053, "Rank": 2 }, { - "Command": "New-PnPUser -LoginName user@company.com", - "Id": 1044, "CommandName": "New-PnPUser", + "Command": "New-PnPUser -LoginName user@company.com", + "Id": 1054, "Rank": 1 }, { - "Command": "New-PnPWeb -Title \"Project A Web\" -Url projectA -Description \"Information about Project A\" -Locale 1033 -Template \"STS#0\"", - "Id": 1045, "CommandName": "New-PnPWeb", + "Command": "New-PnPWeb -Title \"Project A Web\" -Url projectA -Description \"Information about Project A\" -Locale 1033 -Template \"STS#0\"", + "Id": 1055, "Rank": 1 }, { - "Command": "Publish-PnPApp -Identity 2646ccc3-6a2b-46ef-9273-81411cbbb60f", - "Id": 1046, "CommandName": "Publish-PnPApp", + "Command": "Publish-PnPApp -Identity 2646ccc3-6a2b-46ef-9273-81411cbbb60f", + "Id": 1056, "Rank": 1 }, { - "Command": "Publish-PnPApp -Identity 2646ccc3-6a2b-46ef-9273-81411cbbb60f -Scope Site", - "Id": 1047, "CommandName": "Publish-PnPApp", + "Command": "Publish-PnPApp -Identity 2646ccc3-6a2b-46ef-9273-81411cbbb60f -Scope Site", + "Id": 1057, "Rank": 2 }, { - "Command": "Publish-PnPCompanyApp -PortalUrl https://contoso.sharepoint.com/sites/portal -AppName \"Contoso Portal\" -CompanyName \"Contoso\" -CompanyWebSite \"https://www.contoso.com\" -ColoredIconPath ./coloricon.png -OutlineIconPath ./outlinedicon", - "Id": 1048, "CommandName": "Publish-PnPCompanyApp", + "Command": "Publish-PnPCompanyApp -PortalUrl https://contoso.sharepoint.com/sites/portal -AppName \"Contoso Portal\" -CompanyName \"Contoso\" -CompanyWebSite \"https://www.contoso.com\" -ColoredIconPath ./coloricon.png -OutlineIconPath ./outlinedicon", + "Id": 1058, "Rank": 1 }, { - "Command": "Publish-PnPContentType -ContentType 0x0101", - "Id": 1049, "CommandName": "Publish-PnPContentType", + "Command": "Publish-PnPContentType -ContentType 0x0101", + "Id": 1059, "Rank": 1 }, { - "Command": "Publish-PnPSyntexModel -Model \"Invoice model\" -ListWebUrl \"https://contoso.sharepoint.com/sites/finance\" -List \"Documents\"", - "Id": 1050, "CommandName": "Publish-PnPSyntexModel", + "Command": "Publish-PnPSyntexModel -Model \"Invoice model\" -ListWebUrl \"https://contoso.sharepoint.com/sites/finance\" -List \"Documents\"", + "Id": 1060, "Rank": 1 }, { - "Command": "Publish-PnPSyntexModel -Model \"Invoice model\" -TargetSiteUrl \"https://contoso.sharepoint.com/sites/finance\" -TargetWebServerRelativeUrl \"/sites/finance\" -TargetLibraryServerRelativeUrl \"/sites/finance/shared%20documents\" -Batch $batch", - "Id": 1051, "CommandName": "Publish-PnPSyntexModel", + "Command": "Publish-PnPSyntexModel -Model \"Invoice model\" -TargetSiteUrl \"https://contoso.sharepoint.com/sites/finance\" -TargetWebServerRelativeUrl \"/sites/finance\" -TargetLibraryServerRelativeUrl \"/sites/finance/shared%20documents\" -Batch $batch", + "Id": 1061, "Rank": 2 }, { - "Command": "Read-PnPSiteTemplate -Path template.pnp", - "Id": 1052, "CommandName": "Read-PnPSiteTemplate", + "Command": "Read-PnPSiteTemplate -Path template.pnp", + "Id": 1062, "Rank": 1 }, { - "Command": "Read-PnPSiteTemplate -Path template.pnp -TemplateProviderExtensions $extensions", - "Id": 1053, "CommandName": "Read-PnPSiteTemplate", + "Command": "Read-PnPSiteTemplate -Path template.pnp -TemplateProviderExtensions $extensions", + "Id": 1063, "Rank": 2 }, { - "Command": "Read-PnPSiteTemplate -Xml $xml", - "Id": 1054, "CommandName": "Read-PnPSiteTemplate", + "Command": "Read-PnPSiteTemplate -Xml $xml", + "Id": 1064, "Rank": 3 }, { - "Command": "Read-PnPTenantTemplate -Path template.pnp", - "Id": 1055, "CommandName": "Read-PnPTenantTemplate", + "Command": "Read-PnPTenantTemplate -Path template.pnp", + "Id": 1065, "Rank": 1 }, { - "Command": "Register-PnPAppCatalogSite -Url \"https://yourtenant.sharepoint.com/sites/appcatalog\" -Owner admin@domain.com -TimeZoneId 4", - "Id": 1056, "CommandName": "Register-PnPAppCatalogSite", + "Command": "Register-PnPAppCatalogSite -Url \"https://yourtenant.sharepoint.com/sites/appcatalog\" -Owner admin@domain.com -TimeZoneId 4", + "Id": 1066, "Rank": 1 }, { - "Command": "Register-PnPAzureADApp -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -Store CurrentUser -Username \"yourname@domain.com\" -Password (Read-Host -AsSecureString -Prompt \"Enter Password\")", - "Id": 1057, "CommandName": "Register-PnPAzureADApp", + "Command": "Register-PnPAzureADApp -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -Store CurrentUser -Interactive", + "Id": 1067, "Rank": 1 }, { - "Command": "Register-PnPAzureADApp -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -CertificatePath c:\\certificate.pfx -CertificatePassword (ConvertTo-SecureString -String \"password\" -AsPlainText -Force) -Username \"yourname@domain.com\" -Password (Read-Host -AsSecureString -Prompt \"Enter password\")", - "Id": 1058, "CommandName": "Register-PnPAzureADApp", + "Command": "Register-PnPAzureADApp -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -CertificatePath c:\\certificate.pfx -CertificatePassword (ConvertTo-SecureString -String \"password\" -AsPlainText -Force) -Interactive", + "Id": 1068, "Rank": 2 }, { - "Command": "Register-PnPAzureADApp -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -Store CurrentUser -GraphApplicationPermissions \"User.Read.All\" -SharePointApplicationPermissions \"Sites.Read.All\" -Username \"yourname@domain.com\" -Password (Read-Host -AsSecureString -Prompt \"Enter Password\")", - "Id": 1059, "CommandName": "Register-PnPAzureADApp", + "Command": "Register-PnPAzureADApp -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -Store CurrentUser -GraphApplicationPermissions \"User.Read.All\" -SharePointApplicationPermissions \"Sites.Read.All\" -Interactive", + "Id": 1069, "Rank": 3 }, { - "Command": "Register-PnPAzureADApp -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -OutPath c:\\ -CertificatePassword (ConvertTo-SecureString -String \"password\" -AsPlainText -Force) -Username \"yourname@domain.com\" -Password (Read-Host -AsSecureString -Prompt \"Enter Password\")", - "Id": 1060, "CommandName": "Register-PnPAzureADApp", + "Command": "Register-PnPAzureADApp -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -OutPath c:\\ -CertificatePassword (ConvertTo-SecureString -String \"password\" -AsPlainText -Force) -Interactive", + "Id": 1070, "Rank": 4 }, { - "Command": "Register-PnPAzureADApp -DeviceLogin -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -CertificatePath c:\\certificate.pfx -CertificatePassword (ConvertTo-SecureString -String \"password\" -AsPlainText -Force)", - "Id": 1061, "CommandName": "Register-PnPAzureADApp", + "Command": "Register-PnPAzureADApp -DeviceLogin -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -CertificatePath c:\\certificate.pfx -CertificatePassword (ConvertTo-SecureString -String \"password\" -AsPlainText -Force)", + "Id": 1071, "Rank": 5 }, { - "Command": "Register-PnPAzureADApp -Interactive -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -CertificatePath c:\\certificate.pfx -CertificatePassword (ConvertTo-SecureString -String \"password\" -AsPlainText -Force)", - "Id": 1062, "CommandName": "Register-PnPAzureADApp", + "Command": "Register-PnPAzureADApp -Interactive -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -CertificatePath c:\\certificate.pfx -CertificatePassword (ConvertTo-SecureString -String \"password\" -AsPlainText -Force)", + "Id": 1072, "Rank": 6 }, { - "Command": "Register-PnPAzureADApp -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -CertificatePath c:\\certificate.pfx -CertificatePassword (ConvertTo-SecureString -String \"password\" -AsPlainText -Force) -Username \"yourname@domain.com\" -Password (Read-Host -AsSecureString -Prompt \"Enter password\") -LogoFilePath c:\\logo.png", - "Id": 1063, "CommandName": "Register-PnPAzureADApp", + "Command": "Register-PnPAzureADApp -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -CertificatePath c:\\certificate.pfx -CertificatePassword (ConvertTo-SecureString -String \"password\" -AsPlainText -Force) -Interactive -LogoFilePath c:\\logo.png", + "Id": 1073, "Rank": 7 }, { - "Command": "Register-PnPHubSite -Site \"https://tenant.sharepoint.com/sites/myhubsite\"", - "Id": 1064, + "CommandName": "Register-PnPEntraIDAppForInteractiveLogin", + "Command": "Register-PnPEntraIDAppForInteractiveLogin -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -Interactive", + "Id": 1074, + "Rank": 1 + }, + { + "CommandName": "Register-PnPEntraIDAppForInteractiveLogin", + "Command": "Register-PnPEntraIDAppForInteractiveLogin -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -GraphDelegatePermissions \"Group.Read.All\" -SharePointDelegatePermissions \"AllSites.FullControl\" -Interactive", + "Id": 1075, + "Rank": 2 + }, + { "CommandName": "Register-PnPHubSite", + "Command": "Register-PnPHubSite -Site \"https://tenant.sharepoint.com/sites/myhubsite\"", + "Id": 1076, "Rank": 1 }, { - "Command": "Register-PnPHubSite -Site \"https://tenant.sharepoint.com/sites/myhubsite\" -Principals \"user@contoso.com\"", - "Id": 1065, "CommandName": "Register-PnPHubSite", + "Command": "Register-PnPHubSite -Site \"https://tenant.sharepoint.com/sites/myhubsite\" -Principals \"user@contoso.com\"", + "Id": 1077, "Rank": 2 }, { - "Command": "Register-PnPManagementShellAccess", - "Id": 1066, "CommandName": "Register-PnPManagementShellAccess", + "Command": "Register-PnPManagementShellAccess", + "Id": 1078, "Rank": 1 }, { - "Command": "Register-PnPManagementShellAccess -ShowConsentUrl", - "Id": 1067, "CommandName": "Register-PnPManagementShellAccess", + "Command": "Register-PnPManagementShellAccess -ShowConsentUrl", + "Id": 1079, "Rank": 2 }, { - "Command": "Register-PnPManagementShellAccess -ShowConsentUrl -TenantName yourtenant.onmicrosoft.com", - "Id": 1068, "CommandName": "Register-PnPManagementShellAccess", + "Command": "Register-PnPManagementShellAccess -ShowConsentUrl -TenantName yourtenant.onmicrosoft.com", + "Id": 1080, "Rank": 3 }, { - "Command": "Remove-PnPAdaptiveScopeProperty -Key MyKey", - "Id": 1069, "CommandName": "Remove-PnPAdaptiveScopeProperty", + "Command": "Remove-PnPAdaptiveScopeProperty -Key MyKey", + "Id": 1081, "Rank": 1 }, { - "Command": "Remove-PnPAdaptiveScopeProperty -Key MyKey -Force", - "Id": 1070, "CommandName": "Remove-PnPAdaptiveScopeProperty", + "Command": "Remove-PnPAdaptiveScopeProperty -Key MyKey -Force", + "Id": 1082, "Rank": 2 }, { - "Command": "Remove-PnPAlert -Identity 641ac67f-0ce0-4837-874a-743c8f8572a7", - "Id": 1071, "CommandName": "Remove-PnPAlert", + "Command": "Remove-PnPAlert -Identity 641ac67f-0ce0-4837-874a-743c8f8572a7", + "Id": 1083, "Rank": 1 }, { - "Command": "Remove-PnPAlert -Identity 641ac67f-0ce0-4837-874a-743c8f8572a7 -User \"i:0#.f|membership|Alice@contoso.onmicrosoft.com\"", - "Id": 1072, "CommandName": "Remove-PnPAlert", + "Command": "Remove-PnPAlert -Identity 641ac67f-0ce0-4837-874a-743c8f8572a7 -User \"i:0#.f|membership|Alice@contoso.onmicrosoft.com\"", + "Id": 1084, "Rank": 2 }, { - "Command": "Remove-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe", - "Id": 1073, "CommandName": "Remove-PnPApp", + "Command": "Remove-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe", + "Id": 1085, "Rank": 1 }, { - "Command": "Remove-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe -Scope Site", - "Id": 1074, "CommandName": "Remove-PnPApp", + "Command": "Remove-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe -Scope Site", + "Id": 1086, "Rank": 2 }, { - "Command": "Remove-PnPApplicationCustomizer -Identity aa66f67e-46c0-4474-8a82-42bf467d07f2", - "Id": 1075, "CommandName": "Remove-PnPApplicationCustomizer", + "Command": "Remove-PnPApplicationCustomizer -Identity aa66f67e-46c0-4474-8a82-42bf467d07f2", + "Id": 1087, "Rank": 1 }, { - "Command": "Remove-PnPApplicationCustomizer -ClientSideComponentId aa66f67e-46c0-4474-8a82-42bf467d07f2 -Scope web", - "Id": 1076, "CommandName": "Remove-PnPApplicationCustomizer", + "Command": "Remove-PnPApplicationCustomizer -ClientSideComponentId aa66f67e-46c0-4474-8a82-42bf467d07f2 -Scope web", + "Id": 1088, "Rank": 2 }, { - "Command": "Remove-PnPAvailableSiteClassification -Classifications \"HBI\"", - "Id": 1077, "CommandName": "Remove-PnPAvailableSiteClassification", + "Command": "Remove-PnPAvailableSiteClassification -Classifications \"HBI\"", + "Id": 1089, "Rank": 1 }, { - "Command": "Remove-PnPAvailableSiteClassification -Classifications \"HBI\",\"Top Secret\"", - "Id": 1078, "CommandName": "Remove-PnPAvailableSiteClassification", + "Command": "Remove-PnPAvailableSiteClassification -Classifications \"HBI\",\"Top Secret\"", + "Id": 1090, "Rank": 2 }, { - "Command": "Remove-PnPAzureADApp -Identity MyApp", - "Id": 1079, "CommandName": "Remove-PnPAzureADApp", + "Command": "Remove-PnPAzureADApp -Identity MyApp", + "Id": 1091, "Rank": 1 }, { - "Command": "Remove-PnPAzureADApp -Identity 93a9772d-d0af-4ed8-9821-17282b64690e", - "Id": 1080, "CommandName": "Remove-PnPAzureADApp", + "Command": "Remove-PnPAzureADApp -Identity 93a9772d-d0af-4ed8-9821-17282b64690e", + "Id": 1092, "Rank": 2 }, { - "Command": "Remove-PnPAzureADGroup -Identity $groupId", - "Id": 1081, "CommandName": "Remove-PnPAzureADGroup", + "Command": "Remove-PnPAzureADGroup -Identity $groupId", + "Id": 1093, "Rank": 1 }, { - "Command": "Remove-PnPAzureADGroup -Identity $group", - "Id": 1082, "CommandName": "Remove-PnPAzureADGroup", + "Command": "Remove-PnPAzureADGroup -Identity $group", + "Id": 1094, "Rank": 2 }, { - "Command": "Remove-PnPAzureADGroupMember -Identity \"Project Team\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\"", - "Id": 1083, "CommandName": "Remove-PnPAzureADGroupMember", + "Command": "Remove-PnPAzureADGroupMember -Identity \"Project Team\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\"", + "Id": 1095, "Rank": 1 }, { - "Command": "Remove-PnPAzureADGroupOwner -Identity \"Project Team\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\"", - "Id": 1084, "CommandName": "Remove-PnPAzureADGroupOwner", + "Command": "Remove-PnPAzureADGroupOwner -Identity \"Project Team\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\"", + "Id": 1096, "Rank": 1 }, { - "Command": "Remove-PnPAzureADServicePrincipalAssignedAppRole -Principal 797ee8a7-a950-4eb8-945d-7f10cc68a933 -AppRoleName \"User.ReadWrite.All\"", - "Id": 1085, "CommandName": "Remove-PnPAzureADServicePrincipalAssignedAppRole", + "Command": "Remove-PnPAzureADServicePrincipalAssignedAppRole -Principal 797ee8a7-a950-4eb8-945d-7f10cc68a933 -AppRoleName \"User.ReadWrite.All\"", + "Id": 1097, "Rank": 1 }, { - "Command": "Remove-PnPAzureADServicePrincipalAssignedAppRole -Principal \"My application\" -AppRoleName \"Group.ReadWrite.All\"", - "Id": 1086, "CommandName": "Remove-PnPAzureADServicePrincipalAssignedAppRole", + "Command": "Remove-PnPAzureADServicePrincipalAssignedAppRole -Principal \"My application\" -AppRoleName \"Group.ReadWrite.All\"", + "Id": 1098, "Rank": 2 }, { - "Command": "Remove-PnPAzureADServicePrincipalAssignedAppRole -Principal 797ee8a7-a950-4eb8-945d-7f10cc68a933", - "Id": 1087, "CommandName": "Remove-PnPAzureADServicePrincipalAssignedAppRole", + "Command": "Remove-PnPAzureADServicePrincipalAssignedAppRole -Principal 797ee8a7-a950-4eb8-945d-7f10cc68a933", + "Id": 1099, "Rank": 3 }, { - "Command": "Remove-PnPAzureADServicePrincipalAssignedAppRole -Principal \"My application\"", - "Id": 1088, "CommandName": "Remove-PnPAzureADServicePrincipalAssignedAppRole", + "Command": "Remove-PnPAzureADServicePrincipalAssignedAppRole -Principal \"My application\"", + "Id": 1100, "Rank": 4 }, { - "Command": "Remove-PnPContainer -Identity \"b!aBrXSxKDdUKZsaK3Djug6C5rF4MG3pRBomypnjOHiSrjkM_EBk_1S57U3gD7oW-1\"", - "Id": 1089, + "CommandName": "Remove-PnPAzureADUser", + "Command": "Remove-PnPAzureADUser -Identity johndoe@contoso.onmicrosoft.com", + "Id": 1101, + "Rank": 1 + }, + { + "CommandName": "Remove-PnPAzureADUser", + "Command": "Remove-PnPAzureADUser -Identity 5a4c547a-1440-4f64-9952-a0c6f1c9e7ea", + "Id": 1102, + "Rank": 2 + }, + { "CommandName": "Remove-PnPContainer", + "Command": "Remove-PnPContainer -Identity \"b!aBrXSxKDdUKZsaK3Djug6C5rF4MG3pRBomypnjOHiSrjkM_EBk_1S57U3gD7oW-1\"", + "Id": 1103, "Rank": 1 }, { - "Command": "Remove-PnPContainer -Identity \"https://contoso.sharepoint.com/contentstorage/CSP_4bd71a68-8312-4275-99b1-a2b70e3ba0e8\"", - "Id": 1090, "CommandName": "Remove-PnPContainer", + "Command": "Remove-PnPContainer -Identity \"https://contoso.sharepoint.com/contentstorage/CSP_4bd71a68-8312-4275-99b1-a2b70e3ba0e8\"", + "Id": 1104, "Rank": 2 }, { - "Command": "Remove-PnPContainerType -Identity 00be1092-0c75-028a-18db-89e57908e7d6", - "Id": 1091, "CommandName": "Remove-PnPContainerType", + "Command": "Remove-PnPContainerType -Identity 00be1092-0c75-028a-18db-89e57908e7d6", + "Id": 1105, "Rank": 1 }, { - "Command": "Remove-PnPContentType -Identity \"Project Document\"", - "Id": 1092, "CommandName": "Remove-PnPContentType", + "Command": "Remove-PnPContentType -Identity \"Project Document\"", + "Id": 1106, "Rank": 1 }, { - "Command": "Remove-PnPContentType -Identity \"Project Document\" -Force", - "Id": 1093, "CommandName": "Remove-PnPContentType", + "Command": "Remove-PnPContentType -Identity \"Project Document\" -Force", + "Id": 1107, "Rank": 2 }, { - "Command": "Remove-PnPContentTypeFromDocumentSet -ContentType \"Test CT\" -DocumentSet \"Test Document Set\"", - "Id": 1094, "CommandName": "Remove-PnPContentTypeFromDocumentSet", + "Command": "Remove-PnPContentTypeFromDocumentSet -ContentType \"Test CT\" -DocumentSet \"Test Document Set\"", + "Id": 1108, "Rank": 1 }, { - "Command": "Remove-PnPContentTypeFromDocumentSet -ContentType 0x0101001F1CEFF1D4126E4CAD10F00B6137E969 -DocumentSet 0x0120D520005DB65D094035A241BAC9AF083F825F3B", - "Id": 1095, "CommandName": "Remove-PnPContentTypeFromDocumentSet", + "Command": "Remove-PnPContentTypeFromDocumentSet -ContentType 0x0101001F1CEFF1D4126E4CAD10F00B6137E969 -DocumentSet 0x0120D520005DB65D094035A241BAC9AF083F825F3B", + "Id": 1109, "Rank": 2 }, { - "Command": "Remove-PnPContentTypeFromList -List \"Documents\" -ContentType \"Project Document\"", - "Id": 1096, "CommandName": "Remove-PnPContentTypeFromList", + "Command": "Remove-PnPContentTypeFromList -List \"Documents\" -ContentType \"Project Document\"", + "Id": 1110, "Rank": 1 }, { - "Command": "Remove-PnPCustomAction -Identity aa66f67e-46c0-4474-8a82-42bf467d07f2", - "Id": 1097, "CommandName": "Remove-PnPCustomAction", + "Command": "Remove-PnPCustomAction -Identity aa66f67e-46c0-4474-8a82-42bf467d07f2", + "Id": 1111, "Rank": 1 }, { - "Command": "Remove-PnPCustomAction -Identity aa66f67e-46c0-4474-8a82-42bf467d07f2 -Scope web", - "Id": 1098, "CommandName": "Remove-PnPCustomAction", + "Command": "Remove-PnPCustomAction -Identity aa66f67e-46c0-4474-8a82-42bf467d07f2 -Scope web", + "Id": 1112, "Rank": 2 }, { - "Command": "Remove-PnPCustomAction -Identity aa66f67e-46c0-4474-8a82-42bf467d07f2 -Force", - "Id": 1099, "CommandName": "Remove-PnPCustomAction", + "Command": "Remove-PnPCustomAction -Identity aa66f67e-46c0-4474-8a82-42bf467d07f2 -Force", + "Id": 1113, "Rank": 3 }, { - "Command": "Remove-PnPDeletedMicrosoft365Group -Identity 38b32e13-e900-4d95-b860-fb52bc07ca7f", - "Id": 1100, "CommandName": "Remove-PnPDeletedMicrosoft365Group", + "Command": "Remove-PnPDeletedMicrosoft365Group -Identity 38b32e13-e900-4d95-b860-fb52bc07ca7f", + "Id": 1114, "Rank": 1 }, { - "Command": "Remove-PnPEventReceiver -Identity fb689d0e-eb99-4f13-beb3-86692fd39f22", - "Id": 1101, "CommandName": "Remove-PnPEventReceiver", + "Command": "Remove-PnPEventReceiver -Identity fb689d0e-eb99-4f13-beb3-86692fd39f22", + "Id": 1115, "Rank": 1 }, { - "Command": "Remove-PnPEventReceiver -List ProjectList -Identity fb689d0e-eb99-4f13-beb3-86692fd39f22", - "Id": 1102, "CommandName": "Remove-PnPEventReceiver", + "Command": "Remove-PnPEventReceiver -List ProjectList -Identity fb689d0e-eb99-4f13-beb3-86692fd39f22", + "Id": 1116, "Rank": 2 }, { - "Command": "Remove-PnPEventReceiver -List ProjectList -Identity MyReceiver", - "Id": 1103, "CommandName": "Remove-PnPEventReceiver", + "Command": "Remove-PnPEventReceiver -List ProjectList -Identity MyReceiver", + "Id": 1117, "Rank": 3 }, { - "Command": "Remove-PnPEventReceiver -List ProjectList", - "Id": 1104, "CommandName": "Remove-PnPEventReceiver", + "Command": "Remove-PnPEventReceiver -List ProjectList", + "Id": 1118, "Rank": 4 }, { - "Command": "Remove-PnPEventReceiver", - "Id": 1105, "CommandName": "Remove-PnPEventReceiver", + "Command": "Remove-PnPEventReceiver", + "Id": 1119, "Rank": 5 }, { - "Command": "Remove-PnPEventReceiver -Scope Site", - "Id": 1106, "CommandName": "Remove-PnPEventReceiver", + "Command": "Remove-PnPEventReceiver -Scope Site", + "Id": 1120, "Rank": 6 }, { - "Command": "Remove-PnPEventReceiver -Scope Web", - "Id": 1107, "CommandName": "Remove-PnPEventReceiver", + "Command": "Remove-PnPEventReceiver -Scope Web", + "Id": 1121, "Rank": 7 }, { - "Command": "Remove-PnPEventReceiver -Scope All", - "Id": 1108, "CommandName": "Remove-PnPEventReceiver", + "Command": "Remove-PnPEventReceiver -Scope All", + "Id": 1122, "Rank": 8 }, { - "Command": "Remove-PnPField -Identity \"Speakers\"", - "Id": 1109, "CommandName": "Remove-PnPField", + "Command": "Remove-PnPField -Identity \"Speakers\"", + "Id": 1123, "Rank": 1 }, { - "Command": "Remove-PnPField -List \"Demo list\" -Identity \"Speakers\"", - "Id": 1110, "CommandName": "Remove-PnPField", + "Command": "Remove-PnPField -List \"Demo list\" -Identity \"Speakers\"", + "Id": 1124, "Rank": 2 }, { - "Command": "Remove-PnPFieldFromContentType -Field \"Project_Name\" -ContentType \"Project Document\"", - "Id": 1111, "CommandName": "Remove-PnPFieldFromContentType", + "Command": "Remove-PnPFieldFromContentType -Field \"Project_Name\" -ContentType \"Project Document\"", + "Id": 1125, "Rank": 1 }, { - "Command": "Remove-PnPFieldFromContentType -Field \"Project_Name\" -ContentType \"Project Document\" -DoNotUpdateChildren", - "Id": 1112, "CommandName": "Remove-PnPFieldFromContentType", + "Command": "Remove-PnPFieldFromContentType -Field \"Project_Name\" -ContentType \"Project Document\" -DoNotUpdateChildren", + "Id": 1126, "Rank": 2 }, { - "Command": "Remove-PnPFile -ServerRelativeUrl /sites/project/_catalogs/themes/15/company.spcolor", - "Id": 1113, "CommandName": "Remove-PnPFile", + "Command": "Remove-PnPFile -ServerRelativeUrl /sites/project/_catalogs/themes/15/company.spcolor", + "Id": 1127, "Rank": 1 }, { - "Command": "Remove-PnPFile -SiteRelativeUrl _catalogs/themes/15/company.spcolor", - "Id": 1114, "CommandName": "Remove-PnPFile", + "Command": "Remove-PnPFile -SiteRelativeUrl _catalogs/themes/15/company.spcolor", + "Id": 1128, "Rank": 2 }, { - "Command": "Remove-PnPFile -SiteRelativeUrl _catalogs/themes/15/company.spcolor -Recycle", - "Id": 1115, "CommandName": "Remove-PnPFile", + "Command": "Remove-PnPFile -SiteRelativeUrl _catalogs/themes/15/company.spcolor -Recycle", + "Id": 1129, "Rank": 3 }, { - "Command": "Remove-PnPFileFromSiteTemplate -Path template.pnp -FilePath filePath", - "Id": 1116, "CommandName": "Remove-PnPFileFromSiteTemplate", + "Command": "Remove-PnPFileFromSiteTemplate -Path template.pnp -FilePath filePath", + "Id": 1130, "Rank": 1 }, { - "Command": "Remove-PnPFileSharingLink -FileUrl \"/sites/demo/Shared Documents/Test.docx\"", - "Id": 1117, "CommandName": "Remove-PnPFileSharingLink", + "Command": "Remove-PnPFileSharingLink -FileUrl \"/sites/demo/Shared Documents/Test.docx\"", + "Id": 1131, "Rank": 1 }, { - "Command": "Remove-PnPFileSharingLink -FileUrl \"/sites/demo/Shared Documents/Test.docx\" -Force", - "Id": 1118, "CommandName": "Remove-PnPFileSharingLink", + "Command": "Remove-PnPFileSharingLink -FileUrl \"/sites/demo/Shared Documents/Test.docx\" -Force", + "Id": 1132, "Rank": 2 }, { - "Command": "Remove-PnPFileVersion -Url Documents/MyDocument.docx -Identity 512", - "Id": 1119, "CommandName": "Remove-PnPFileVersion", + "Command": "Remove-PnPFileVersion -Url Documents/MyDocument.docx -Identity 512", + "Id": 1133, "Rank": 1 }, { - "Command": "Remove-PnPFileVersion -Url Documents/MyDocument.docx -Identity \"Version 1.0\"", - "Id": 1120, "CommandName": "Remove-PnPFileVersion", + "Command": "Remove-PnPFileVersion -Url Documents/MyDocument.docx -Identity \"Version 1.0\"", + "Id": 1134, "Rank": 2 }, { - "Command": "Remove-PnPFileVersion -Url Documents/MyDocument.docx -All", - "Id": 1121, "CommandName": "Remove-PnPFileVersion", + "Command": "Remove-PnPFileVersion -Url Documents/MyDocument.docx -All", + "Id": 1135, "Rank": 3 }, { - "Command": "Remove-PnPFlowOwner (Get-PnPPowerPlatformEnvironment -IsDefault) -Identity f07c34a9-a586-4e58-91fb-e7ea19741b61 -User username@tenant.onmicrosoft.com", - "Id": 1122, "CommandName": "Remove-PnPFlowOwner", + "Command": "Remove-PnPFlowOwner (Get-PnPPowerPlatformEnvironment -IsDefault) -Identity f07c34a9-a586-4e58-91fb-e7ea19741b61 -User username@tenant.onmicrosoft.com", + "Id": 1136, "Rank": 1 }, { - "Command": "Remove-PnPFlowOwner (Get-PnPPowerPlatformEnvironment -IsDefault) -Identity f07c34a9-a586-4e58-91fb-e7ea19741b61 -User 6844c04a-8ee7-40ad-af66-28f6e948cd04", - "Id": 1123, "CommandName": "Remove-PnPFlowOwner", + "Command": "Remove-PnPFlowOwner (Get-PnPPowerPlatformEnvironment -IsDefault) -Identity f07c34a9-a586-4e58-91fb-e7ea19741b61 -User 6844c04a-8ee7-40ad-af66-28f6e948cd04", + "Id": 1137, "Rank": 2 }, { - "Command": "Remove-PnPFlowOwner (Get-PnPPowerPlatformEnvironment -IsDefault) -Identity f07c34a9-a586-4e58-91fb-e7ea19741b61 -User username@tenant.onmicrosoft.com -AsAdmin", - "Id": 1124, "CommandName": "Remove-PnPFlowOwner", + "Command": "Remove-PnPFlowOwner (Get-PnPPowerPlatformEnvironment -IsDefault) -Identity f07c34a9-a586-4e58-91fb-e7ea19741b61 -User username@tenant.onmicrosoft.com -AsAdmin", + "Id": 1138, "Rank": 3 }, { - "Command": "Remove-PnPFlowOwner (Get-PnPPowerPlatformEnvironment -IsDefault) -Identity f07c34a9-a586-4e58-91fb-e7ea19741b61 -User username@tenant.onmicrosoft.com -AsAdmin -Force", - "Id": 1125, "CommandName": "Remove-PnPFlowOwner", + "Command": "Remove-PnPFlowOwner (Get-PnPPowerPlatformEnvironment -IsDefault) -Identity f07c34a9-a586-4e58-91fb-e7ea19741b61 -User username@tenant.onmicrosoft.com -AsAdmin -Force", + "Id": 1139, "Rank": 4 }, { - "Command": "Remove-PnPFolder -Name NewFolder -Folder _catalogs/masterpage", - "Id": 1126, "CommandName": "Remove-PnPFolder", + "Command": "Remove-PnPFolder -Name NewFolder -Folder _catalogs/masterpage", + "Id": 1140, "Rank": 1 }, { - "Command": "Remove-PnPFolder -Name NewFolder -Folder _catalogs/masterpage -Recycle", - "Id": 1127, "CommandName": "Remove-PnPFolder", + "Command": "Remove-PnPFolder -Name NewFolder -Folder _catalogs/masterpage -Recycle", + "Id": 1141, "Rank": 2 }, { - "Command": "Remove-PnPFolderSharingLink -Folder \"/sites/demo/Shared Documents/Test\"", - "Id": 1128, "CommandName": "Remove-PnPFolderSharingLink", + "Command": "Remove-PnPFolderSharingLink -Folder \"/sites/demo/Shared Documents/Test\"", + "Id": 1142, "Rank": 1 }, { - "Command": "Remove-PnPFolderSharingLink -Folder \"/sites/demo/Shared Documents/Test\" -Force", - "Id": 1129, "CommandName": "Remove-PnPFolderSharingLink", + "Command": "Remove-PnPFolderSharingLink -Folder \"/sites/demo/Shared Documents/Test\" -Force", + "Id": 1143, "Rank": 2 }, { - "Command": "Remove-PnPGraphSubscription -Identity bc204397-1128-4911-9d70-1d8bceee39da", - "Id": 1130, "CommandName": "Remove-PnPGraphSubscription", + "Command": "Remove-PnPGraphSubscription -Identity bc204397-1128-4911-9d70-1d8bceee39da", + "Id": 1144, "Rank": 1 }, { - "Command": "Remove-PnPGroup -Identity \"My Users\"", - "Id": 1131, "CommandName": "Remove-PnPGroup", + "Command": "Remove-PnPGroup -Identity \"My Users\"", + "Id": 1145, "Rank": 1 }, { - "Command": "Remove-PnPGroupMember -LoginName user@company.com -Group 'Marketing Site Members'", - "Id": 1132, "CommandName": "Remove-PnPGroupMember", + "Command": "Remove-PnPGroupMember -LoginName user@company.com -Group 'Marketing Site Members'", + "Id": 1146, "Rank": 1 }, { - "Command": "Remove-PnPHomeSite", - "Id": 1133, "CommandName": "Remove-PnPHomeSite", + "Command": "Remove-PnPHomeSite", + "Id": 1147, "Rank": 1 }, { - "Command": "Remove-PnPHubSiteAssociation -Site \"https://tenant.sharepoint.com/sites/mysite\"", - "Id": 1134, "CommandName": "Remove-PnPHubSiteAssociation", + "Command": "Remove-PnPHubSiteAssociation -Site \"https://tenant.sharepoint.com/sites/mysite\"", + "Id": 1148, "Rank": 1 }, { - "Command": "Remove-PnPHubToHubAssociation -HubSiteId 6638bd4c-d88d-447c-9eb2-c84f28ba8b15", - "Id": 1135, "CommandName": "Remove-PnPHubToHubAssociation", + "Command": "Remove-PnPHubToHubAssociation -HubSiteId 6638bd4c-d88d-447c-9eb2-c84f28ba8b15", + "Id": 1149, "Rank": 1 }, { - "Command": "Remove-PnPHubToHubAssociation -HubSiteUrl \"https://yourtenant.sharepoint.com/sites/sourcehub\"", - "Id": 1136, "CommandName": "Remove-PnPHubToHubAssociation", + "Command": "Remove-PnPHubToHubAssociation -HubSiteUrl \"https://yourtenant.sharepoint.com/sites/sourcehub\"", + "Id": 1150, "Rank": 2 }, { - "Command": "Remove-PnPIndexedProperty -key \"MyIndexProperty\"", - "Id": 1137, "CommandName": "Remove-PnPIndexedProperty", + "Command": "Remove-PnPIndexedProperty -key \"MyIndexProperty\"", + "Id": 1151, "Rank": 1 }, { - "Command": "Remove-PnPJavaScriptLink -Identity jQuery", - "Id": 1138, "CommandName": "Remove-PnPJavaScriptLink", + "Command": "Remove-PnPJavaScriptLink -Identity jQuery", + "Id": 1152, "Rank": 1 }, { - "Command": "Remove-PnPJavaScriptLink -Identity jQuery -Scope Site", - "Id": 1139, "CommandName": "Remove-PnPJavaScriptLink", + "Command": "Remove-PnPJavaScriptLink -Identity jQuery -Scope Site", + "Id": 1153, "Rank": 2 }, { - "Command": "Remove-PnPJavaScriptLink -Identity jQuery -Scope Site -Confirm:$false", - "Id": 1140, "CommandName": "Remove-PnPJavaScriptLink", + "Command": "Remove-PnPJavaScriptLink -Identity jQuery -Scope Site -Confirm:$false", + "Id": 1154, "Rank": 3 }, { - "Command": "Remove-PnPJavaScriptLink -Scope Site", - "Id": 1141, "CommandName": "Remove-PnPJavaScriptLink", + "Command": "Remove-PnPJavaScriptLink -Scope Site", + "Id": 1155, "Rank": 4 }, { - "Command": "Remove-PnPJavaScriptLink -Identity faea0ce2-f0c2-4d45-a4dc-73898f3c2f2e -Scope All", - "Id": 1142, "CommandName": "Remove-PnPJavaScriptLink", + "Command": "Remove-PnPJavaScriptLink -Identity faea0ce2-f0c2-4d45-a4dc-73898f3c2f2e -Scope All", + "Id": 1156, "Rank": 5 }, { - "Command": "Remove-PnPKnowledgeHubSite", - "Id": 1143, "CommandName": "Remove-PnPKnowledgeHubSite", + "Command": "Remove-PnPKnowledgeHubSite", + "Id": 1157, "Rank": 1 }, { - "Command": "Remove-PnPLibraryFileVersionBatchDeleteJob -Identity \"Documents\"", - "Id": 1144, "CommandName": "Remove-PnPLibraryFileVersionBatchDeleteJob", + "Command": "Remove-PnPLibraryFileVersionBatchDeleteJob -Identity \"Documents\"", + "Id": 1158, "Rank": 1 }, { - "Command": "Remove-PnPLibraryFileVersionBatchDeleteJob -Identity \"Documents\" -DeleteBeforeDays 360 -Force", - "Id": 1145, "CommandName": "Remove-PnPLibraryFileVersionBatchDeleteJob", + "Command": "Remove-PnPLibraryFileVersionBatchDeleteJob -Identity \"Documents\" -DeleteBeforeDays 360 -Force", + "Id": 1159, "Rank": 2 }, { - "Command": "Remove-PnPList -Identity Announcements", - "Id": 1146, "CommandName": "Remove-PnPList", + "Command": "Remove-PnPList -Identity Announcements", + "Id": 1160, "Rank": 1 }, { - "Command": "Remove-PnPList -Identity Announcements -Force", - "Id": 1147, "CommandName": "Remove-PnPList", + "Command": "Remove-PnPList -Identity Announcements -Force", + "Id": 1161, "Rank": 2 }, { - "Command": "Remove-PnPList -Identity Announcements -Recycle", - "Id": 1148, "CommandName": "Remove-PnPList", + "Command": "Remove-PnPList -Identity Announcements -Recycle", + "Id": 1162, "Rank": 3 }, { - "Command": "Remove-PnPList -Identity Announcements -Recycle -LargeList", - "Id": 1149, "CommandName": "Remove-PnPList", + "Command": "Remove-PnPList -Identity Announcements -Recycle -LargeList", + "Id": 1163, "Rank": 4 }, { - "Command": "Remove-PnPListDesign -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd", - "Id": 1150, "CommandName": "Remove-PnPListDesign", + "Command": "Remove-PnPListDesign -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd", + "Id": 1164, "Rank": 1 }, { - "Command": "Remove-PnPListItem -List \"Demo List\" -Identity \"1\" -Force", - "Id": 1151, "CommandName": "Remove-PnPListItem", + "Command": "Remove-PnPListItem -List \"Demo List\" -Identity \"1\" -Force", + "Id": 1165, "Rank": 1 }, { - "Command": "Remove-PnPListItem -List \"Demo List\" -Identity \"1\" -Force -Recycle", - "Id": 1152, "CommandName": "Remove-PnPListItem", + "Command": "Remove-PnPListItem -List \"Demo List\" -Identity \"1\" -Force -Recycle", + "Id": 1166, "Rank": 2 }, { - "Command": "Remove-PnPListItem -List \"Demo List\"", - "Id": 1153, "CommandName": "Remove-PnPListItem", + "Command": "Remove-PnPListItem -List \"Demo List\"", + "Id": 1167, "Rank": 3 }, { - "Command": "Remove-PnPListItemAttachment -List \"Demo List\" -Identity 1 -FileName test.txt", - "Id": 1154, "CommandName": "Remove-PnPListItemAttachment", + "Command": "Remove-PnPListItemAttachment -List \"Demo List\" -Identity 1 -FileName test.txt", + "Id": 1168, "Rank": 1 }, { - "Command": "Remove-PnPListItemAttachment -List \"Demo List\" -Identity 1 -FileName test.txt -Recycle", - "Id": 1155, "CommandName": "Remove-PnPListItemAttachment", + "Command": "Remove-PnPListItemAttachment -List \"Demo List\" -Identity 1 -FileName test.txt -Recycle", + "Id": 1169, "Rank": 2 }, { - "Command": "Remove-PnPListItemAttachment -List \"Demo List\" -Identity 1 -FileName test.txt -Recycle -Force", - "Id": 1156, "CommandName": "Remove-PnPListItemAttachment", + "Command": "Remove-PnPListItemAttachment -List \"Demo List\" -Identity 1 -FileName test.txt -Recycle -Force", + "Id": 1170, "Rank": 3 }, { - "Command": "Remove-PnPListItemAttachment -List \"Demo List\" -Identity 1 -All -Recycle -Force", - "Id": 1157, "CommandName": "Remove-PnPListItemAttachment", + "Command": "Remove-PnPListItemAttachment -List \"Demo List\" -Identity 1 -All -Recycle -Force", + "Id": 1171, "Rank": 4 }, { - "Command": "Remove-PnPListItemAttachment -List \"Demo List\" -Identity 1 -All", - "Id": 1158, "CommandName": "Remove-PnPListItemAttachment", + "Command": "Remove-PnPListItemAttachment -List \"Demo List\" -Identity 1 -All", + "Id": 1172, "Rank": 5 }, { - "Command": "Remove-PnPListItemVersion -List \"Demo List\" -Identity 1 -Version 512", - "Id": 1159, "CommandName": "Remove-PnPListItemVersion", + "Command": "Remove-PnPListItemVersion -List \"Demo List\" -Identity 1 -Version 512", + "Id": 1173, "Rank": 1 }, { - "Command": "Remove-PnPListItemVersion -List \"Demo List\" -Identity 1 -Version \"1.0\"", - "Id": 1160, "CommandName": "Remove-PnPListItemVersion", + "Command": "Remove-PnPListItemVersion -List \"Demo List\" -Identity 1 -Version \"1.0\"", + "Id": 1174, "Rank": 2 }, { - "Command": "Remove-PnPMicrosoft365Group -Identity $groupId", - "Id": 1161, "CommandName": "Remove-PnPMicrosoft365Group", + "Command": "Remove-PnPMicrosoft365Group -Identity $groupId", + "Id": 1175, "Rank": 1 }, { - "Command": "Remove-PnPMicrosoft365Group -Identity $group", - "Id": 1162, "CommandName": "Remove-PnPMicrosoft365Group", + "Command": "Remove-PnPMicrosoft365Group -Identity $group", + "Id": 1176, "Rank": 2 }, { - "Command": "Remove-PnPMicrosoft365GroupMember -Identity \"Project Team\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\"", - "Id": 1163, "CommandName": "Remove-PnPMicrosoft365GroupMember", + "Command": "Remove-PnPMicrosoft365GroupMember -Identity \"Project Team\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\"", + "Id": 1177, "Rank": 1 }, { - "Command": "Remove-PnPMicrosoft365GroupOwner -Identity \"Project Team\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\"", - "Id": 1164, "CommandName": "Remove-PnPMicrosoft365GroupOwner", + "Command": "Remove-PnPMicrosoft365GroupOwner -Identity \"Project Team\" -Users \"john@contoso.onmicrosoft.com\",\"jane@contoso.onmicrosoft.com\"", + "Id": 1178, "Rank": 1 }, { - "Command": "Remove-PnPMicrosoft365GroupPhoto -Identity \"Project Team\"", - "Id": 1165, "CommandName": "Remove-PnPMicrosoft365GroupPhoto", + "Command": "Remove-PnPMicrosoft365GroupPhoto -Identity \"Project Team\"", + "Id": 1179, "Rank": 1 }, { - "Command": "Remove-PnPMicrosoft365GroupSettings -Identity \"10f686b9-9deb-4ad8-ba8c-1f9b7a00a22b\"", - "Id": 1166, "CommandName": "Remove-PnPMicrosoft365GroupSettings", + "Command": "Remove-PnPMicrosoft365GroupSettings -Identity \"10f686b9-9deb-4ad8-ba8c-1f9b7a00a22b\"", + "Id": 1180, "Rank": 1 }, { - "Command": "Remove-PnPMicrosoft365GroupSettings -Identity \"10f686b9-9deb-4ad8-ba8c-1f9b7a00a22b\" -Group $groupId", - "Id": 1167, "CommandName": "Remove-PnPMicrosoft365GroupSettings", + "Command": "Remove-PnPMicrosoft365GroupSettings -Identity \"10f686b9-9deb-4ad8-ba8c-1f9b7a00a22b\" -Group $groupId", + "Id": 1181, "Rank": 2 }, { - "Command": "Remove-PnPNavigationNode -Identity 1032", - "Id": 1168, "CommandName": "Remove-PnPNavigationNode", + "Command": "Remove-PnPNavigationNode -Identity 1032", + "Id": 1182, "Rank": 1 }, { - "Command": "Remove-PnPNavigationNode -Title Recent -Location QuickLaunch", - "Id": 1169, "CommandName": "Remove-PnPNavigationNode", + "Command": "Remove-PnPNavigationNode -Title Recent -Location QuickLaunch", + "Id": 1183, "Rank": 2 }, { - "Command": "Remove-PnPNavigationNode -Title Home -Location TopNavigationBar -Force", - "Id": 1170, "CommandName": "Remove-PnPNavigationNode", + "Command": "Remove-PnPNavigationNode -Title Home -Location TopNavigationBar -Force", + "Id": 1184, "Rank": 3 }, { - "Command": "Remove-PnPOrgAssetsLibrary -LibraryUrl \"sites/branding/logos\"", - "Id": 1171, "CommandName": "Remove-PnPOrgAssetsLibrary", + "Command": "Remove-PnPOrgAssetsLibrary -LibraryUrl \"sites/branding/logos\"", + "Id": 1185, "Rank": 1 }, { - "Command": "Remove-PnPOrgAssetsLibrary -LibraryUrl \"sites/branding/logos\" -ShouldRemoveFromCdn $true", - "Id": 1172, "CommandName": "Remove-PnPOrgAssetsLibrary", + "Command": "Remove-PnPOrgAssetsLibrary -LibraryUrl \"sites/branding/logos\" -ShouldRemoveFromCdn $true", + "Id": 1186, "Rank": 2 }, { - "Command": "Remove-PnPOrgAssetsLibrary -LibraryUrl \"sites/branding/logos\" -ShouldRemoveFromCdn $true -CdnType Private", - "Id": 1173, "CommandName": "Remove-PnPOrgAssetsLibrary", + "Command": "Remove-PnPOrgAssetsLibrary -LibraryUrl \"sites/branding/logos\" -ShouldRemoveFromCdn $true -CdnType Private", + "Id": 1187, "Rank": 3 }, { - "Command": "Remove-PnPOrgNewsSite -OrgNewsSiteUrl \"https://tenant.sharepoint.com/sites/mysite\"", - "Id": 1174, "CommandName": "Remove-PnPOrgNewsSite", + "Command": "Remove-PnPOrgNewsSite -OrgNewsSiteUrl \"https://tenant.sharepoint.com/sites/mysite\"", + "Id": 1188, "Rank": 1 }, { - "Command": "Remove-PnPPage -Identity \"MyPage\"", - "Id": 1175, "CommandName": "Remove-PnPPage", + "Command": "Remove-PnPPage -Identity \"MyPage\"", + "Id": 1189, "Rank": 1 }, { - "Command": "Remove-PnPPage -Identity \"Templates/MyPageTemplate\"", - "Id": 1176, "CommandName": "Remove-PnPPage", + "Command": "Remove-PnPPage -Identity \"Templates/MyPageTemplate\"", + "Id": 1190, "Rank": 2 }, { - "Command": "Remove-PnPPage $page", - "Id": 1177, "CommandName": "Remove-PnPPage", + "Command": "Remove-PnPPage $page", + "Id": 1191, "Rank": 3 }, { - "Command": "Remove-PnPPage -Identity \"MyPage\" -Recycle", - "Id": 1178, "CommandName": "Remove-PnPPage", + "Command": "Remove-PnPPage -Identity \"MyPage\" -Recycle", + "Id": 1192, "Rank": 4 }, { - "Command": "Remove-PnPPageComponent -Page Home -InstanceId a2875399-d6ff-43a0-96da-be6ae5875f82", - "Id": 1179, "CommandName": "Remove-PnPPageComponent", + "Command": "Remove-PnPPageComponent -Page Home -InstanceId a2875399-d6ff-43a0-96da-be6ae5875f82", + "Id": 1193, "Rank": 1 }, { - "Command": "Remove-PnPPlannerBucket -Group \"Marketing\" -Plan \"Conference\" -Identity \"Pre-conference Todos\"", - "Id": 1180, "CommandName": "Remove-PnPPlannerBucket", + "Command": "Remove-PnPPlannerBucket -Group \"Marketing\" -Plan \"Conference\" -Identity \"Pre-conference Todos\"", + "Id": 1194, "Rank": 1 }, { - "Command": "Remove-PnPPlannerPlan -Group \"Marketing\" -Identity \"Conference Planning\"", - "Id": 1181, "CommandName": "Remove-PnPPlannerPlan", + "Command": "Remove-PnPPlannerPlan -Group \"Marketing\" -Identity \"Conference Planning\"", + "Id": 1195, "Rank": 1 }, { - "Command": "Remove-PnPPlannerRoster -Identity \"6519868f-868f-6519-8f86-19658f861965\"", - "Id": 1182, "CommandName": "Remove-PnPPlannerRoster", + "Command": "Remove-PnPPlannerRoster -Identity \"6519868f-868f-6519-8f86-19658f861965\"", + "Id": 1196, "Rank": 1 }, { - "Command": "Remove-PnPPlannerRosterMember -Identity \"6519868f-868f-6519-8f86-19658f861965\" -User \"johndoe@contoso.onmicrosoft.com\"", - "Id": 1183, "CommandName": "Remove-PnPPlannerRosterMember", + "Command": "Remove-PnPPlannerRosterMember -Identity \"6519868f-868f-6519-8f86-19658f861965\" -User \"johndoe@contoso.onmicrosoft.com\"", + "Id": 1197, "Rank": 1 }, { - "Command": "Remove-PnPPlannerTask -Task _LIqnL4lZUqurT71i2-iY5YALFLk", - "Id": 1184, "CommandName": "Remove-PnPPlannerTask", + "Command": "Remove-PnPPlannerTask -Task _LIqnL4lZUqurT71i2-iY5YALFLk", + "Id": 1198, "Rank": 1 }, { - "Command": "Remove-PnPPropertyBagValue -Key MyKey", - "Id": 1185, "CommandName": "Remove-PnPPropertyBagValue", + "Command": "Remove-PnPPropertyBagValue -Key MyKey", + "Id": 1199, "Rank": 1 }, { - "Command": "Remove-PnPPropertyBagValue -Key MyKey -Folder /MyFolder", - "Id": 1186, "CommandName": "Remove-PnPPropertyBagValue", + "Command": "Remove-PnPPropertyBagValue -Key MyKey -Folder /MyFolder", + "Id": 1200, "Rank": 2 }, { - "Command": "Remove-PnPPropertyBagValue -Key MyKey -Folder /", - "Id": 1187, "CommandName": "Remove-PnPPropertyBagValue", + "Command": "Remove-PnPPropertyBagValue -Key MyKey -Folder /", + "Id": 1201, "Rank": 3 }, { - "Command": "Remove-PnPPublishingImageRendition -Name \"MyImageRendition\" -Width 800 -Height 600", - "Id": 1188, "CommandName": "Remove-PnPPublishingImageRendition", + "Command": "Remove-PnPPublishingImageRendition -Name \"MyImageRendition\" -Width 800 -Height 600", + "Id": 1202, "Rank": 1 }, { - "Command": "Remove-PnPRoleDefinition -Identity MyRoleDefinition", - "Id": 1189, "CommandName": "Remove-PnPRoleDefinition", + "Command": "Remove-PnPRoleDefinition -Identity MyRoleDefinition", + "Id": 1203, "Rank": 1 }, { - "Command": "Remove-PnPSdnProvider -Confirm:false", - "Id": 1190, "CommandName": "Remove-PnPSdnProvider", + "Command": "Remove-PnPSdnProvider -Confirm:false", + "Id": 1204, "Rank": 1 }, { - "Command": "Remove-PnPSearchConfiguration -Configuration $config", - "Id": 1191, "CommandName": "Remove-PnPSearchConfiguration", + "Command": "Remove-PnPSearchConfiguration -Configuration $config", + "Id": 1205, "Rank": 1 }, { - "Command": "Remove-PnPSearchConfiguration -Configuration $config -Scope Site", - "Id": 1192, "CommandName": "Remove-PnPSearchConfiguration", + "Command": "Remove-PnPSearchConfiguration -Configuration $config -Scope Site", + "Id": 1206, "Rank": 2 }, { - "Command": "Remove-PnPSearchConfiguration -Configuration $config -Scope Subscription", - "Id": 1193, "CommandName": "Remove-PnPSearchConfiguration", + "Command": "Remove-PnPSearchConfiguration -Configuration $config -Scope Subscription", + "Id": 1207, "Rank": 3 }, { - "Command": "Remove-PnPSearchConfiguration -Path searchconfig.xml -Scope Subscription", - "Id": 1194, "CommandName": "Remove-PnPSearchConfiguration", + "Command": "Remove-PnPSearchConfiguration -Path searchconfig.xml -Scope Subscription", + "Id": 1208, "Rank": 4 }, { - "Command": "Remove-PnPSiteCollectionAdmin -Owners \"user@contoso.onmicrosoft.com\"", - "Id": 1195, + "CommandName": "Remove-PnPSearchExternalConnection", + "Command": "Remove-PnPSearchExternalConnection -Identity \"pnppowershell\"", + "Id": 1209, + "Rank": 1 + }, + { "CommandName": "Remove-PnPSiteCollectionAdmin", + "Command": "Remove-PnPSiteCollectionAdmin -Owners \"user@contoso.onmicrosoft.com\"", + "Id": 1210, "Rank": 1 }, { - "Command": "Remove-PnPSiteCollectionAdmin -Owners @(\"user1@contoso.onmicrosoft.com\", \"user2@contoso.onmicrosoft.com\")", - "Id": 1196, "CommandName": "Remove-PnPSiteCollectionAdmin", + "Command": "Remove-PnPSiteCollectionAdmin -Owners @(\"user1@contoso.onmicrosoft.com\", \"user2@contoso.onmicrosoft.com\")", + "Id": 1211, "Rank": 2 }, { - "Command": "Remove-PnPSiteCollectionAppCatalog -Site \"https://contoso.sharepoint.com/sites/FinanceTeamsite\"", - "Id": 1197, "CommandName": "Remove-PnPSiteCollectionAppCatalog", + "Command": "Remove-PnPSiteCollectionAppCatalog -Site \"https://contoso.sharepoint.com/sites/FinanceTeamsite\"", + "Id": 1212, "Rank": 1 }, { - "Command": "Remove-PnPSiteCollectionTermStore", - "Id": 1198, "CommandName": "Remove-PnPSiteCollectionTermStore", + "Command": "Remove-PnPSiteCollectionTermStore", + "Id": 1213, "Rank": 1 }, { - "Command": "Remove-PnPSiteDesign -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd", - "Id": 1199, "CommandName": "Remove-PnPSiteDesign", + "Command": "Remove-PnPSiteDesign -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd", + "Id": 1214, "Rank": 1 }, { - "Command": "Remove-PnPSiteDesignTask -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd", - "Id": 1200, "CommandName": "Remove-PnPSiteDesignTask", + "Command": "Remove-PnPSiteDesignTask -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd", + "Id": 1215, "Rank": 1 }, { - "Command": "Remove-PnPSiteFileVersionBatchDeleteJob", - "Id": 1201, "CommandName": "Remove-PnPSiteFileVersionBatchDeleteJob", + "Command": "Remove-PnPSiteFileVersionBatchDeleteJob", + "Id": 1216, "Rank": 1 }, { - "Command": "Remove-PnPSiteFileVersionBatchDeleteJob -Force", - "Id": 1202, "CommandName": "Remove-PnPSiteFileVersionBatchDeleteJob", + "Command": "Remove-PnPSiteFileVersionBatchDeleteJob -Force", + "Id": 1217, "Rank": 2 }, { - "Command": "Remove-PnPSiteGroup -Identity GroupToRemove -Site \"https://contoso.sharepoint.com/sites/marketing\"", - "Id": 1203, "CommandName": "Remove-PnPSiteGroup", + "Command": "Remove-PnPSiteGroup -Identity GroupToRemove -Site \"https://contoso.sharepoint.com/sites/marketing\"", + "Id": 1218, "Rank": 1 }, { - "Command": "Remove-PnPSiteGroup -Identity GroupToRemove", - "Id": 1204, "CommandName": "Remove-PnPSiteGroup", + "Command": "Remove-PnPSiteGroup -Identity GroupToRemove", + "Id": 1219, "Rank": 2 }, { - "Command": "Remove-PnPSiteScript -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd", - "Id": 1205, "CommandName": "Remove-PnPSiteScript", + "Command": "Remove-PnPSiteScript -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd", + "Id": 1220, "Rank": 1 }, { - "Command": "Remove-PnPSiteUserInvitations -Site \"https://contoso.sharepoint.com/sites/ContosoWeb1/\" -EmailAddress someone@example.com", - "Id": 1206, "CommandName": "Remove-PnPSiteUserInvitations", + "Command": "Remove-PnPSiteUserInvitations -Site \"https://contoso.sharepoint.com/sites/ContosoWeb1/\" -EmailAddress someone@example.com", + "Id": 1221, "Rank": 1 }, { - "Command": "Remove-PnPStorageEntity -Key MyKey", - "Id": 1207, "CommandName": "Remove-PnPStorageEntity", + "Command": "Remove-PnPStorageEntity -Key MyKey", + "Id": 1222, "Rank": 1 }, { - "Command": "Remove-PnPStorageEntity -Key MyKey -Scope Site", - "Id": 1208, "CommandName": "Remove-PnPStorageEntity", + "Command": "Remove-PnPStorageEntity -Key MyKey -Scope Site", + "Id": 1223, "Rank": 2 }, { - "Command": "Remove-PnPStoredCredential -Name \"https://tenant.sharepoint.com\"", - "Id": 1209, "CommandName": "Remove-PnPStoredCredential", + "Command": "Remove-PnPStoredCredential -Name \"https://tenant.sharepoint.com\"", + "Id": 1224, "Rank": 1 }, { - "Command": "Remove-PnPTaxonomyItem -TermPath \"HR|Recruitment|Marketing\"", - "Id": 1210, "CommandName": "Remove-PnPTaxonomyItem", + "Command": "Remove-PnPTaxonomyItem -TermPath \"HR|Recruitment|Marketing\"", + "Id": 1225, "Rank": 1 }, { - "Command": "Remove-PnPTaxonomyItem -TermPath \"HR|Recruitment|Marketing\" -Force", - "Id": 1211, "CommandName": "Remove-PnPTaxonomyItem", + "Command": "Remove-PnPTaxonomyItem -TermPath \"HR|Recruitment|Marketing\" -Force", + "Id": 1226, "Rank": 2 }, { - "Command": "Remove-PnPTeamsApp -Identity ac139d8b-fa2b-4ffe-88b3-f0b30158b58b", - "Id": 1212, "CommandName": "Remove-PnPTeamsApp", + "Command": "Remove-PnPTeamsApp -Identity ac139d8b-fa2b-4ffe-88b3-f0b30158b58b", + "Id": 1227, "Rank": 1 }, { - "Command": "Remove-PnPTeamsApp -Identity \"My Teams App\"", - "Id": 1213, "CommandName": "Remove-PnPTeamsApp", + "Command": "Remove-PnPTeamsApp -Identity \"My Teams App\"", + "Id": 1228, "Rank": 2 }, { - "Command": "Remove-PnPTeamsChannel -Team 4efdf392-8225-4763-9e7f-4edeb7f721aa -Identity \"My Channel\"", - "Id": 1214, "CommandName": "Remove-PnPTeamsChannel", + "Command": "Remove-PnPTeamsChannel -Team 4efdf392-8225-4763-9e7f-4edeb7f721aa -Identity \"My Channel\"", + "Id": 1229, "Rank": 1 }, { - "Command": "Remove-PnPTeamsChannelUser -Team \"My Team\" -Channel \"My Channel\" -Identity MCMjMiMjMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwIyMxOTowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMEB0aHJlYWQuc2t5cGUjIzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMA==", - "Id": 1215, "CommandName": "Remove-PnPTeamsChannelUser", + "Command": "Remove-PnPTeamsChannelUser -Team \"My Team\" -Channel \"My Channel\" -Identity MCMjMiMjMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwIyMxOTowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMEB0aHJlYWQuc2t5cGUjIzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMA==", + "Id": 1230, "Rank": 1 }, { - "Command": "Remove-PnPTeamsChannelUser -Team \"My Team\" -Channel \"My Channel\" -Identity 00000000-0000-0000-0000-000000000000", - "Id": 1216, "CommandName": "Remove-PnPTeamsChannelUser", + "Command": "Remove-PnPTeamsChannelUser -Team \"My Team\" -Channel \"My Channel\" -Identity 00000000-0000-0000-0000-000000000000", + "Id": 1231, "Rank": 2 }, { - "Command": "Remove-PnPTeamsChannelUser -Team \"My Team\" -Channel \"My Channel\" -Identity john.doe@contoso.com -Force", - "Id": 1217, "CommandName": "Remove-PnPTeamsChannelUser", + "Command": "Remove-PnPTeamsChannelUser -Team \"My Team\" -Channel \"My Channel\" -Identity john.doe@contoso.com -Force", + "Id": 1232, "Rank": 3 }, { - "Command": "Remove-PnPTeamsTab -Team 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -Channel \"General\" -Identity Wiki", - "Id": 1218, "CommandName": "Remove-PnPTeamsTab", + "Command": "Remove-PnPTeamsTab -Team 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -Channel \"General\" -Identity Wiki", + "Id": 1233, "Rank": 1 }, { - "Command": "Remove-PnPTeamsTab -Team 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -Channel 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype -Identity Wiki", - "Id": 1219, "CommandName": "Remove-PnPTeamsTab", + "Command": "Remove-PnPTeamsTab -Team 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -Channel 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype -Identity Wiki", + "Id": 1234, "Rank": 2 }, { - "Command": "Remove-PnPTeamsTab -Team 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -Channel 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype -Identity fcef815d-2e8e-47a5-b06b-9bebba5c7852", - "Id": 1220, "CommandName": "Remove-PnPTeamsTab", + "Command": "Remove-PnPTeamsTab -Team 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -Channel 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype -Identity fcef815d-2e8e-47a5-b06b-9bebba5c7852", + "Id": 1235, "Rank": 3 }, { - "Command": "Remove-PnPTeamsTag -Team 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -Identity \"ZmY1ZjdmMjctZDhiNy00MWRkLTk2ZDQtYzcyYmVhMWIwOGYxIyM3ZTVhNGRmZS1kNWNlLTRkOTAtODM4MC04ZDIxM2FkYzYzOGIjI3RiVlVpR01rcg==\"", - "Id": 1221, "CommandName": "Remove-PnPTeamsTag", + "Command": "Remove-PnPTeamsTag -Team 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -Identity \"ZmY1ZjdmMjctZDhiNy00MWRkLTk2ZDQtYzcyYmVhMWIwOGYxIyM3ZTVhNGRmZS1kNWNlLTRkOTAtODM4MC04ZDIxM2FkYzYzOGIjI3RiVlVpR01rcg==\"", + "Id": 1236, "Rank": 1 }, { - "Command": "Remove-PnPTeamsTeam -Identity 5beb63c5-0571-499e-94d5-3279fdd9b6b5", - "Id": 1222, "CommandName": "Remove-PnPTeamsTeam", + "Command": "Remove-PnPTeamsTeam -Identity 5beb63c5-0571-499e-94d5-3279fdd9b6b5", + "Id": 1237, "Rank": 1 }, { - "Command": "Remove-PnPTeamsTeam -Identity testteam", - "Id": 1223, "CommandName": "Remove-PnPTeamsTeam", + "Command": "Remove-PnPTeamsTeam -Identity testteam", + "Id": 1238, "Rank": 2 }, { - "Command": "Remove-PnPTeamsUser -Team MyTeam -User john@doe.com", - "Id": 1224, "CommandName": "Remove-PnPTeamsUser", + "Command": "Remove-PnPTeamsUser -Team MyTeam -User john@doe.com", + "Id": 1239, "Rank": 1 }, { - "Command": "Remove-PnPTeamsUser -Team MyTeam -User john@doe.com -Role Owner", - "Id": 1225, "CommandName": "Remove-PnPTeamsUser", + "Command": "Remove-PnPTeamsUser -Team MyTeam -User john@doe.com -Role Owner", + "Id": 1240, "Rank": 2 }, { - "Command": "Remove-PnPTenantCdnOrigin -OriginUrl /sites/site/subfolder -CdnType Public", - "Id": 1226, "CommandName": "Remove-PnPTenantCdnOrigin", + "Command": "Remove-PnPTenantCdnOrigin -OriginUrl /sites/site/subfolder -CdnType Public", + "Id": 1241, "Rank": 1 }, { - "Command": "Remove-PnPTenantDeletedSite -Identity \"https://tenant.sharepoint.com/sites/contoso\"", - "Id": 1227, "CommandName": "Remove-PnPTenantDeletedSite", + "Command": "Remove-PnPTenantDeletedSite -Identity \"https://tenant.sharepoint.com/sites/contoso\"", + "Id": 1242, "Rank": 1 }, { - "Command": "Remove-PnPTenantDeletedSite -Identity \"https://tenant.sharepoint.com/sites/contoso\" -Force", - "Id": 1228, "CommandName": "Remove-PnPTenantDeletedSite", + "Command": "Remove-PnPTenantDeletedSite -Identity \"https://tenant.sharepoint.com/sites/contoso\" -Force", + "Id": 1243, "Rank": 2 }, { - "Command": "Remove-PnPTenantSite -Url \"https://tenant.sharepoint.com/sites/contoso\"", - "Id": 1229, "CommandName": "Remove-PnPTenantSite", + "Command": "Remove-PnPTenantSite -Url \"https://tenant.sharepoint.com/sites/contoso\"", + "Id": 1244, "Rank": 1 }, { - "Command": "Remove-PnPTenantSite -Url \"https://tenant.sharepoint.com/sites/contoso\" -Force -SkipRecycleBin", - "Id": 1230, "CommandName": "Remove-PnPTenantSite", + "Command": "Remove-PnPTenantSite -Url \"https://tenant.sharepoint.com/sites/contoso\" -Force -SkipRecycleBin", + "Id": 1245, "Rank": 2 }, { - "Command": "Remove-PnPTenantSite -Url \"https://tenant.sharepoint.com/sites/contoso\" -FromRecycleBin", - "Id": 1231, "CommandName": "Remove-PnPTenantSite", + "Command": "Remove-PnPTenantSite -Url \"https://tenant.sharepoint.com/sites/contoso\" -FromRecycleBin", + "Id": 1246, "Rank": 3 }, { - "Command": "Remove-PnPTenantSyncClientRestriction", - "Id": 1232, "CommandName": "Remove-PnPTenantSyncClientRestriction", + "Command": "Remove-PnPTenantSyncClientRestriction", + "Id": 1247, "Rank": 1 }, { - "Command": "Remove-PnPTenantTheme -Name \"MyCompanyTheme\"", - "Id": 1233, "CommandName": "Remove-PnPTenantTheme", + "Command": "Remove-PnPTenantTheme -Name \"MyCompanyTheme\"", + "Id": 1248, "Rank": 1 }, { - "Command": "Remove-PnPTerm -Identity 3d9e60e8-d89c-4cd4-af61-a010cf93b380", - "Id": 1234, "CommandName": "Remove-PnPTerm", + "Command": "Remove-PnPTerm -Identity 3d9e60e8-d89c-4cd4-af61-a010cf93b380", + "Id": 1249, "Rank": 1 }, { - "Command": "Remove-PnPTerm -Identity \"Marketing\" -TermSet \"Departments\" -TermGroup \"Corporate\"", - "Id": 1235, "CommandName": "Remove-PnPTerm", + "Command": "Remove-PnPTerm -Identity \"Marketing\" -TermSet \"Departments\" -TermGroup \"Corporate\"", + "Id": 1250, "Rank": 2 }, { - "Command": "Remove-PnPTermGroup -Identity 3d9e60e8-d89c-4cd4-af61-a010cf93b380", - "Id": 1236, "CommandName": "Remove-PnPTermGroup", + "Command": "Remove-PnPTermGroup -Identity 3d9e60e8-d89c-4cd4-af61-a010cf93b380", + "Id": 1251, "Rank": 1 }, { - "Command": "Remove-PnPTermGroup -Identity \"Corporate\"", - "Id": 1237, "CommandName": "Remove-PnPTermGroup", + "Command": "Remove-PnPTermGroup -Identity \"Corporate\"", + "Id": 1252, "Rank": 2 }, { - "Command": "Remove-PnPTermGroup -Identity \"HR\" -Force", - "Id": 1238, "CommandName": "Remove-PnPTermGroup", + "Command": "Remove-PnPTermGroup -Identity \"HR\" -Force", + "Id": 1253, "Rank": 3 }, { - "Command": "Remove-PnPTermLabel -Label \"Marknadsföring\" -Lcid 1053 -Term 2d1f298b-804a-4a05-96dc-29b667adec62", - "Id": 1239, "CommandName": "Remove-PnPTermLabel", + "Command": "Remove-PnPTermLabel -Label \"Marknadsföring\" -Lcid 1053 -Term 2d1f298b-804a-4a05-96dc-29b667adec62", + "Id": 1254, "Rank": 1 }, { - "Command": "Remove-PnPTermLabel -Label \"Marknadsföring\" -Lcid 1053 -Term \"Marketing\" -TermSet \"Departments\" -TermGroup \"Corporate\"", - "Id": 1240, "CommandName": "Remove-PnPTermLabel", + "Command": "Remove-PnPTermLabel -Label \"Marknadsföring\" -Lcid 1053 -Term \"Marketing\" -TermSet \"Departments\" -TermGroup \"Corporate\"", + "Id": 1255, "Rank": 2 }, { - "Command": "Remove-PnPUser -Identity 23", - "Id": 1241, "CommandName": "Remove-PnPUser", + "Command": "Remove-PnPUser -Identity 23", + "Id": 1256, "Rank": 1 }, { - "Command": "Remove-PnPUser -Identity i:0#.f|membership|user@tenant.onmicrosoft.com", - "Id": 1242, "CommandName": "Remove-PnPUser", + "Command": "Remove-PnPUser -Identity i:0#.f|membership|user@tenant.onmicrosoft.com", + "Id": 1257, "Rank": 2 }, { - "Command": "Remove-PnPUser -Identity i:0#.f|membership|user@tenant.onmicrosoft.com -Confirm:$false", - "Id": 1243, "CommandName": "Remove-PnPUser", + "Command": "Remove-PnPUser -Identity i:0#.f|membership|user@tenant.onmicrosoft.com -Confirm:$false", + "Id": 1258, "Rank": 3 }, { - "Command": "Remove-PnPUserInfo -LoginName user@domain.com -Site \"https://yoursite.sharepoint.com/sites/team\"", - "Id": 1244, "CommandName": "Remove-PnPUserInfo", + "Command": "Remove-PnPUserInfo -LoginName user@domain.com -Site \"https://yoursite.sharepoint.com/sites/team\"", + "Id": 1259, "Rank": 1 }, { - "Command": "Remove-PnPUserProfile -LoginName user@domain.com", - "Id": 1245, "CommandName": "Remove-PnPUserProfile", + "Command": "Remove-PnPUserProfile -LoginName user@domain.com", + "Id": 1260, "Rank": 1 }, { - "Command": "Remove-PnPView -List \"Demo List\" -Identity \"All Items\"", - "Id": 1246, "CommandName": "Remove-PnPView", + "Command": "Remove-PnPView -List \"Demo List\" -Identity \"All Items\"", + "Id": 1261, "Rank": 1 }, { - "Command": "Remove-PnPVivaConnectionsDashboardACE -Identity \"58108715-185e-4214-8786-01218e7ab9ef\"", - "Id": 1247, "CommandName": "Remove-PnPVivaConnectionsDashboardACE", + "Command": "Remove-PnPVivaConnectionsDashboardACE -Identity \"58108715-185e-4214-8786-01218e7ab9ef\"", + "Id": 1262, "Rank": 1 }, { - "Command": "Remove-PnPWeb -Identity projectA", - "Id": 1248, "CommandName": "Remove-PnPWeb", + "Command": "Remove-PnPWeb -Identity projectA", + "Id": 1263, "Rank": 1 }, { - "Command": "Remove-PnPWeb -Identity 5fecaf67-6b9e-4691-a0ff-518fc9839aa0", - "Id": 1249, "CommandName": "Remove-PnPWeb", + "Command": "Remove-PnPWeb -Identity 5fecaf67-6b9e-4691-a0ff-518fc9839aa0", + "Id": 1264, "Rank": 2 }, { - "Command": "Remove-PnPWebhookSubscription -List MyList -Identity ea1533a8-ff03-415b-a7b6-517ee50db8b6", - "Id": 1250, "CommandName": "Remove-PnPWebhookSubscription", + "Command": "Remove-PnPWebhookSubscription -List MyList -Identity ea1533a8-ff03-415b-a7b6-517ee50db8b6", + "Id": 1265, "Rank": 1 }, { - "Command": "Remove-PnPWebPart -ServerRelativePageUrl \"/sites/demo/sitepages/home.aspx\" -Identity a2875399-d6ff-43a0-96da-be6ae5875f82", - "Id": 1251, "CommandName": "Remove-PnPWebPart", + "Command": "Remove-PnPWebPart -ServerRelativePageUrl \"/sites/demo/sitepages/home.aspx\" -Identity a2875399-d6ff-43a0-96da-be6ae5875f82", + "Id": 1266, "Rank": 1 }, { - "Command": "Remove-PnPWebPart -ServerRelativePageUrl \"/sites/demo/sitepages/home.aspx\" -Title MyWebpart", - "Id": 1252, "CommandName": "Remove-PnPWebPart", + "Command": "Remove-PnPWebPart -ServerRelativePageUrl \"/sites/demo/sitepages/home.aspx\" -Title MyWebpart", + "Id": 1267, "Rank": 2 }, { - "Command": "Remove-PnPWikiPage -PageUrl '/pages/wikipage.aspx'", - "Id": 1253, "CommandName": "Remove-PnPWikiPage", + "Command": "Remove-PnPWikiPage -PageUrl '/pages/wikipage.aspx'", + "Id": 1268, "Rank": 1 }, { - "Command": "Rename-PnPFile -ServerRelativeUrl /sites/project/Documents/company.docx -TargetFileName mycompany.docx", - "Id": 1254, "CommandName": "Rename-PnPFile", + "Command": "Rename-PnPFile -ServerRelativeUrl /sites/project/Documents/company.docx -TargetFileName mycompany.docx", + "Id": 1269, "Rank": 1 }, { - "Command": "Rename-PnPFile -SiteRelativeUrl Documents/company.aspx -TargetFileName mycompany.docx", - "Id": 1255, "CommandName": "Rename-PnPFile", + "Command": "Rename-PnPFile -SiteRelativeUrl Documents/company.aspx -TargetFileName mycompany.docx", + "Id": 1270, "Rank": 2 }, { - "Command": "Rename-PnPFile -ServerRelativeUrl /sites/project/Documents/company.docx -TargetFileName mycompany.docx -OverwriteIfAlreadyExists", - "Id": 1256, "CommandName": "Rename-PnPFile", + "Command": "Rename-PnPFile -ServerRelativeUrl /sites/project/Documents/company.docx -TargetFileName mycompany.docx -OverwriteIfAlreadyExists", + "Id": 1271, "Rank": 3 }, { - "Command": "Rename-PnPFolder -Folder Documents/Reports -TargetFolderName 'Archived Reports'", - "Id": 1257, "CommandName": "Rename-PnPFolder", + "Command": "Rename-PnPFolder -Folder Documents/Reports -TargetFolderName 'Archived Reports'", + "Id": 1272, "Rank": 1 }, { - "Command": "Repair-PnPSite -Identity \"https://contoso.sharepoint.com/sites/marketing\"", - "Id": 1258, "CommandName": "Repair-PnPSite", + "Command": "Repair-PnPSite -Identity \"https://contoso.sharepoint.com/sites/marketing\"", + "Id": 1273, "Rank": 1 }, { - "Command": "Repair-PnPSite -Identity \"https://contoso.sharepoint.com/sites/marketing\" -RuleID \"ee967197-ccbe-4c00-88e4-e6fab81145e1\"", - "Id": 1259, "CommandName": "Repair-PnPSite", + "Command": "Repair-PnPSite -Identity \"https://contoso.sharepoint.com/sites/marketing\" -RuleID \"ee967197-ccbe-4c00-88e4-e6fab81145e1\"", + "Id": 1274, "Rank": 2 }, { - "Command": "Request-PnPAccessToken", - "Id": 1260, "CommandName": "Request-PnPAccessToken", + "Command": "Request-PnPAccessToken", + "Id": 1275, "Rank": 1 }, { - "Command": "Request-PnPAccessToken -ClientId 26e29fec-aa10-4f99-8381-d96cddc650c2", - "Id": 1261, "CommandName": "Request-PnPAccessToken", + "Command": "Request-PnPAccessToken -ClientId 26e29fec-aa10-4f99-8381-d96cddc650c2", + "Id": 1276, "Rank": 2 }, { - "Command": "Request-PnPAccessToken -ClientId 26e29fec-aa10-4f99-8381-d96cddc650c2 -Scopes Group.ReadWrite.All", - "Id": 1262, "CommandName": "Request-PnPAccessToken", + "Command": "Request-PnPAccessToken -ClientId 26e29fec-aa10-4f99-8381-d96cddc650c2 -Scopes Group.ReadWrite.All", + "Id": 1277, "Rank": 3 }, { - "Command": "Request-PnPAccessToken -ClientId 26e29fec-aa10-4f99-8381-d96cddc650c2 -Scopes Group.ReadWrite.All, AllSites.FullControl", - "Id": 1263, "CommandName": "Request-PnPAccessToken", + "Command": "Request-PnPAccessToken -ClientId 26e29fec-aa10-4f99-8381-d96cddc650c2 -Scopes Group.ReadWrite.All, AllSites.FullControl", + "Id": 1278, "Rank": 4 }, { - "Command": "Request-PnPPersonalSite -UserEmails @(\"user1@contoso.com\", \"user2@contoso.com\")", - "Id": 1264, "CommandName": "Request-PnPPersonalSite", + "Command": "Request-PnPPersonalSite -UserEmails @(\"user1@contoso.com\", \"user2@contoso.com\")", + "Id": 1279, "Rank": 1 }, { - "Command": "Request-PnPPersonalSite -UserEmails \"user1@contoso.com\"", - "Id": 1265, "CommandName": "Request-PnPPersonalSite", + "Command": "Request-PnPPersonalSite -UserEmails \"user1@contoso.com\"", + "Id": 1280, "Rank": 2 }, { - "Command": "Request-PnPReIndexList -Identity \"Demo List\"", - "Id": 1266, "CommandName": "Request-PnPReIndexList", + "Command": "Request-PnPReIndexList -Identity \"Demo List\"", + "Id": 1281, "Rank": 1 }, { - "Command": "Request-PnPReIndexWeb", - "Id": 1267, "CommandName": "Request-PnPReIndexWeb", + "Command": "Request-PnPReIndexWeb", + "Id": 1282, "Rank": 1 }, { - "Command": "Request-PnPSyntexClassifyAndExtract -FileUrl \"/sites/finance/invoices/invoice1.docx\"", - "Id": 1268, "CommandName": "Request-PnPSyntexClassifyAndExtract", + "Command": "Request-PnPSyntexClassifyAndExtract -FileUrl \"/sites/finance/invoices/invoice1.docx\"", + "Id": 1283, "Rank": 1 }, { - "Command": "Request-PnPSyntexClassifyAndExtract -List \"Invoices\"", - "Id": 1269, "CommandName": "Request-PnPSyntexClassifyAndExtract", + "Command": "Request-PnPSyntexClassifyAndExtract -List \"Invoices\"", + "Id": 1284, "Rank": 2 }, { - "Command": "Request-PnPSyntexClassifyAndExtract -Folder (Get-PnPFolder -Url \"invoices/Q1/jan\")", - "Id": 1270, "CommandName": "Request-PnPSyntexClassifyAndExtract", + "Command": "Request-PnPSyntexClassifyAndExtract -Folder (Get-PnPFolder -Url \"invoices/Q1/jan\")", + "Id": 1285, "Rank": 3 }, { - "Command": "Reset-PnPFileVersion -ServerRelativeUrl \"/sites/test/office365.png\"", - "Id": 1271, "CommandName": "Reset-PnPFileVersion", + "Command": "Reset-PnPFileVersion -ServerRelativeUrl \"/sites/test/office365.png\"", + "Id": 1286, "Rank": 1 }, { - "Command": "Reset-PnPFileVersion -ServerRelativeUrl \"/sites/test/office365.png\" -CheckinType MajorCheckin -Comment \"Restored to previous version\"", - "Id": 1272, "CommandName": "Reset-PnPFileVersion", + "Command": "Reset-PnPFileVersion -ServerRelativeUrl \"/sites/test/office365.png\" -CheckinType MajorCheckin -Comment \"Restored to previous version\"", + "Id": 1287, "Rank": 2 }, { - "Command": "Reset-PnPMicrosoft365GroupExpiration", - "Id": 1273, "CommandName": "Reset-PnPMicrosoft365GroupExpiration", + "Command": "Reset-PnPMicrosoft365GroupExpiration", + "Id": 1288, "Rank": 1 }, { - "Command": "Reset-PnPRetentionLabel -List \"Demo List\"", - "Id": 1274, "CommandName": "Reset-PnPRetentionLabel", + "Command": "Reset-PnPRetentionLabel -List \"Demo List\"", + "Id": 1289, "Rank": 1 }, { - "Command": "Reset-PnPRetentionLabel -List \"Demo List\" -SyncToItems $true", - "Id": 1275, "CommandName": "Reset-PnPRetentionLabel", + "Command": "Reset-PnPRetentionLabel -List \"Demo List\" -SyncToItems $true", + "Id": 1290, "Rank": 2 }, { - "Command": "Reset-PnPUserOneDriveQuotaToDefault -Account 'user@domain.com'", - "Id": 1276, "CommandName": "Reset-PnPUserOneDriveQuotaToDefault", + "Command": "Reset-PnPUserOneDriveQuotaToDefault -Account 'user@domain.com'", + "Id": 1291, "Rank": 1 }, { - "Command": "Resolve-PnPFolder -SiteRelativePath \"demofolder/subfolder\"", - "Id": 1277, "CommandName": "Resolve-PnPFolder", + "Command": "Resolve-PnPFolder -SiteRelativePath \"demofolder/subfolder\"", + "Id": 1292, "Rank": 1 }, { - "Command": "Restore-PnPDeletedContainer -Identity \"b!jKRbiovfMEWUWKabObEnjC5rF4MG3pRBomypnjOHiSrjkM_EBk_1S57U3gD7oW-1\"", - "Id": 1278, "CommandName": "Restore-PnPDeletedContainer", + "Command": "Restore-PnPDeletedContainer -Identity \"b!jKRbiovfMEWUWKabObEnjC5rF4MG3pRBomypnjOHiSrjkM_EBk_1S57U3gD7oW-1\"", + "Id": 1293, "Rank": 1 }, { - "Command": "Restore-PnPDeletedMicrosoft365Group -Identity 38b32e13-e900-4d95-b860-fb52bc07ca7f", - "Id": 1279, "CommandName": "Restore-PnPDeletedMicrosoft365Group", + "Command": "Restore-PnPDeletedMicrosoft365Group -Identity 38b32e13-e900-4d95-b860-fb52bc07ca7f", + "Id": 1294, "Rank": 1 }, { - "Command": "Restore-PnPFileVersion -Url Documents/MyDocument.docx -Identity 512", - "Id": 1280, "CommandName": "Restore-PnPFileVersion", + "Command": "Restore-PnPFileVersion -Url Documents/MyDocument.docx -Identity 512", + "Id": 1295, "Rank": 1 }, { - "Command": "Restore-PnPFileVersion -Url /sites/HRSite/Documents/MyDocument.docx -Identity 512", - "Id": 1281, "CommandName": "Restore-PnPFileVersion", + "Command": "Restore-PnPFileVersion -Url /sites/HRSite/Documents/MyDocument.docx -Identity 512", + "Id": 1296, "Rank": 2 }, { - "Command": "Restore-PnPFileVersion -Url Documents/MyDocument.docx -Identity \"Version 1.0\"", - "Id": 1282, "CommandName": "Restore-PnPFileVersion", + "Command": "Restore-PnPFileVersion -Url Documents/MyDocument.docx -Identity \"Version 1.0\"", + "Id": 1297, "Rank": 3 }, { - "Command": "Restore-PnPListItemVersion -List \"Demo List\" -Identity 1 -Version 512", - "Id": 1283, "CommandName": "Restore-PnPListItemVersion", + "Command": "Restore-PnPListItemVersion -List \"Demo List\" -Identity 1 -Version 512", + "Id": 1298, "Rank": 1 }, { - "Command": "Restore-PnPListItemVersion -List \"Demo List\" -Identity 1 -Version \"1.0\"", - "Id": 1284, "CommandName": "Restore-PnPListItemVersion", + "Command": "Restore-PnPListItemVersion -List \"Demo List\" -Identity 1 -Version \"1.0\"", + "Id": 1299, "Rank": 2 }, { - "Command": "Restore-PnPRecycleBinItem -Identity 72e4d749-d750-4989-b727-523d6726e442", - "Id": 1285, "CommandName": "Restore-PnPRecycleBinItem", + "Command": "Restore-PnPRecycleBinItem -Identity 72e4d749-d750-4989-b727-523d6726e442", + "Id": 1300, "Rank": 1 }, { - "Command": "Restore-PnPTenantRecycleBinItem -Url \"https://tenant.sharepoint.com/sites/contoso\"", - "Id": 1286, "CommandName": "Restore-PnPTenantRecycleBinItem", + "Command": "Restore-PnPTenantRecycleBinItem -Url \"https://tenant.sharepoint.com/sites/contoso\"", + "Id": 1301, "Rank": 1 }, { - "Command": "Restore-PnPTenantRecycleBinItem -Url \"https://tenant.sharepoint.com/sites/contoso\" -Wait", - "Id": 1287, "CommandName": "Restore-PnPTenantRecycleBinItem", + "Command": "Restore-PnPTenantRecycleBinItem -Url \"https://tenant.sharepoint.com/sites/contoso\" -Wait", + "Id": 1302, "Rank": 2 }, { - "Command": "Restore-PnPTenantSite -Identity \"https://tenant.sharepoint.com/sites/contoso\"", - "Id": 1288, "CommandName": "Restore-PnPTenantSite", + "Command": "Restore-PnPTenantSite -Identity \"https://tenant.sharepoint.com/sites/contoso\"", + "Id": 1303, "Rank": 1 }, { - "Command": "Restore-PnPTenantSite -Identity \"https://tenant.sharepoint.com/sites/contoso\" -Force", - "Id": 1289, "CommandName": "Restore-PnPTenantSite", + "Command": "Restore-PnPTenantSite -Identity \"https://tenant.sharepoint.com/sites/contoso\" -Force", + "Id": 1304, "Rank": 2 }, { - "Command": "Restore-PnPTenantSite -Identity \"https://tenant.sharepoint.com/sites/contoso\" -Force -NoWait", - "Id": 1290, "CommandName": "Restore-PnPTenantSite", + "Command": "Restore-PnPTenantSite -Identity \"https://tenant.sharepoint.com/sites/contoso\" -Force -NoWait", + "Id": 1305, "Rank": 3 }, { - "Command": "Revoke-PnPAzureADAppSitePermission -PermissionId ABSDFefsdfef33fsdFSvsadf3e3fsdaffsa", - "Id": 1291, "CommandName": "Revoke-PnPAzureADAppSitePermission", + "Command": "Revoke-PnPAzureADAppSitePermission -PermissionId ABSDFefsdfef33fsdFSvsadf3e3fsdaffsa", + "Id": 1306, "Rank": 1 }, { - "Command": "Revoke-PnPHubSiteRights -Identity \"https://contoso.sharepoint.com/sites/hubsite\" -Principals \"myuser@mydomain.com\",\"myotheruser@mydomain.com\"", - "Id": 1292, "CommandName": "Revoke-PnPHubSiteRights", + "Command": "Revoke-PnPHubSiteRights -Identity \"https://contoso.sharepoint.com/sites/hubsite\" -Principals \"myuser@mydomain.com\",\"myotheruser@mydomain.com\"", + "Id": 1307, "Rank": 1 }, { - "Command": "Revoke-PnPSiteDesignRights -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd -Principals \"myuser@mydomain.com\",\"myotheruser@mydomain.com\"", - "Id": 1293, "CommandName": "Revoke-PnPSiteDesignRights", + "Command": "Revoke-PnPSiteDesignRights -Identity 5c73382d-9643-4aa0-9160-d0cba35e40fd -Principals \"myuser@mydomain.com\",\"myotheruser@mydomain.com\"", + "Id": 1308, "Rank": 1 }, { - "Command": "Revoke-PnPTenantServicePrincipalPermission -Scope \"Group.Read.All\"", - "Id": 1294, "CommandName": "Revoke-PnPTenantServicePrincipalPermission", + "Command": "Revoke-PnPTenantServicePrincipalPermission -Scope \"Group.Read.All\"", + "Id": 1309, "Rank": 1 }, { - "Command": "Revoke-PnPUserSession -User user1@contoso.com", - "Id": 1295, "CommandName": "Revoke-PnPUserSession", + "Command": "Revoke-PnPUserSession -User user1@contoso.com", + "Id": 1310, "Rank": 1 }, { - "Command": "Save-PnPPageConversionLog", - "Id": 1296, "CommandName": "Save-PnPPageConversionLog", + "Command": "Save-PnPPageConversionLog", + "Id": 1311, "Rank": 1 }, { - "Command": "Save-PnPSiteTemplate -Template .\\template.xml -Out .\\template.pnp", - "Id": 1297, "CommandName": "Save-PnPSiteTemplate", + "Command": "Save-PnPSiteTemplate -Template .\\template.xml -Out .\\template.pnp", + "Id": 1312, "Rank": 1 }, { - "Command": "Save-PnPTenantTemplate -Template template.xml -Out .\\tenanttemplate.pnp", - "Id": 1298, "CommandName": "Save-PnPTenantTemplate", + "Command": "Save-PnPTenantTemplate -Template template.xml -Out .\\tenanttemplate.pnp", + "Id": 1313, "Rank": 1 }, { - "Command": "Send-PnPMail -From \"user@contoso.onmicrosoft.com\" -To \"recipient@contoso.com\" -Subject \"Test message\" -Body \"This is a test message\"", - "Id": 1299, "CommandName": "Send-PnPMail", + "Command": "Send-PnPMail -From \"user@contoso.onmicrosoft.com\" -To \"recipient@contoso.com\" -Subject \"Test message\" -Body \"This is a test message\"", + "Id": 1314, "Rank": 1 }, { - "Command": "Send-PnPMail -From \"sharedmailbox@contoso.onmicrosoft.com\" -To \"recipient1@contoso.com\",\"recipient2@contoso.com\",\"recipient3@contoso.com\" -Cc \"recipient4@contoso.com\" -Bcc \"recipient5@contoso.com\" -Subject \"Test message\" -Body \"This is a test message\" -Importance Low", - "Id": 1300, "CommandName": "Send-PnPMail", + "Command": "Send-PnPMail -From \"sharedmailbox@contoso.onmicrosoft.com\" -To \"recipient1@contoso.com\",\"recipient2@contoso.com\",\"recipient3@contoso.com\" -Cc \"recipient4@contoso.com\" -Bcc \"recipient5@contoso.com\" -Subject \"Test message\" -Body \"This is a test message\" -Importance Low", + "Id": 1315, "Rank": 2 }, { - "Command": "Send-PnPMail -To \"address@tenant.microsoftonline.com\" -Subject \"Test message\" -Body \"This is a test message\"", - "Id": 1301, "CommandName": "Send-PnPMail", + "Command": "Send-PnPMail -To \"address@tenant.microsoftonline.com\" -Subject \"Test message\" -Body \"This is a test message\"", + "Id": 1316, "Rank": 3 }, { - "Command": "Send-PnPMail -From \"user@contoso.onmicrosoft.com\" -To \"recipient@contoso.onmicrosoft.com\" -Subject \"Test message\" -Body \"This is a test message\" -Server contoso.mail.protection.outlook.com", - "Id": 1302, "CommandName": "Send-PnPMail", + "Command": "Send-PnPMail -From \"user@contoso.onmicrosoft.com\" -To \"recipient@contoso.onmicrosoft.com\" -Subject \"Test message\" -Body \"This is a test message\" -Server contoso.mail.protection.outlook.com", + "Id": 1317, "Rank": 4 }, { - "Command": "Send-PnPMail -From \"user@contoso.onmicrosoft.com\" -To \"recipient@contoso.com\" -Subject \"Test message\" -Body \"This is a test message\" -Server smtp.myisp.com", - "Id": 1303, "CommandName": "Send-PnPMail", + "Command": "Send-PnPMail -From \"user@contoso.onmicrosoft.com\" -To \"recipient@contoso.com\" -Subject \"Test message\" -Body \"This is a test message\" -Server smtp.myisp.com", + "Id": 1318, "Rank": 5 }, { - "Command": "Send-PnPMail -From \"user@contoso.onmicrosoft.com\" -To \"recipient@contoso.com\" -Subject \"Test message\" -Body \"This is a test message\" -Server smtp.myisp.com -Port 587 -EnableSsl:$true -Username \"userxyz\" -Password \"password123\"", - "Id": 1304, "CommandName": "Send-PnPMail", + "Command": "Send-PnPMail -From \"user@contoso.onmicrosoft.com\" -To \"recipient@contoso.com\" -Subject \"Test message\" -Body \"This is a test message\" -Server smtp.myisp.com -Port 587 -EnableSsl:$true -Username \"userxyz\" -Password \"password123\"", + "Id": 1319, "Rank": 6 }, { - "Command": "Set-PnPAdaptiveScopeProperty -Key MyKey -Value MyValue", - "Id": 1305, "CommandName": "Set-PnPAdaptiveScopeProperty", + "Command": "Set-PnPAdaptiveScopeProperty -Key MyKey -Value MyValue", + "Id": 1320, "Rank": 1 }, { - "Command": "Set-PnPApplicationCustomizer -Identity aa66f67e-46c0-4474-8a82-42bf467d07f2", - "Id": 1306, "CommandName": "Set-PnPApplicationCustomizer", + "Command": "Set-PnPApplicationCustomizer -Identity aa66f67e-46c0-4474-8a82-42bf467d07f2", + "Id": 1321, "Rank": 1 }, { - "Command": "Set-PnPApplicationCustomizer -ClientSideComponentId aa66f67e-46c0-4474-8a82-42bf467d07f2 -Scope web -ClientSideComponentProperties \"{`\"sourceTermSet`\":`\"PnP-CollabFooter-SharedLinks`\",`\"personalItemsStorageProperty`\":`\"PnP-CollabFooter-MyLinks`\"}\"", - "Id": 1307, "CommandName": "Set-PnPApplicationCustomizer", + "Command": "Set-PnPApplicationCustomizer -ClientSideComponentId aa66f67e-46c0-4474-8a82-42bf467d07f2 -Scope web -ClientSideComponentProperties \"{`\"sourceTermSet`\":`\"PnP-CollabFooter-SharedLinks`\",`\"personalItemsStorageProperty`\":`\"PnP-CollabFooter-MyLinks`\"}\"", + "Id": 1322, "Rank": 2 }, { - "Command": "Set-PnPAppSideLoading -On", - "Id": 1308, "CommandName": "Set-PnPAppSideLoading", + "Command": "Set-PnPAppSideLoading -On", + "Id": 1323, "Rank": 1 }, { - "Command": "Set-PnPAppSideLoading -Off", - "Id": 1309, "CommandName": "Set-PnPAppSideLoading", + "Command": "Set-PnPAppSideLoading -Off", + "Id": 1324, "Rank": 2 }, { - "Command": "Set-PnPAuditing -EnableAll", - "Id": 1310, "CommandName": "Set-PnPAuditing", + "Command": "Set-PnPAuditing -EnableAll", + "Id": 1325, "Rank": 1 }, { - "Command": "Set-PnPAuditing -DisableAll", - "Id": 1311, "CommandName": "Set-PnPAuditing", + "Command": "Set-PnPAuditing -DisableAll", + "Id": 1326, "Rank": 2 }, { - "Command": "Set-PnPAuditing -RetentionTime 7", - "Id": 1312, "CommandName": "Set-PnPAuditing", + "Command": "Set-PnPAuditing -RetentionTime 7", + "Id": 1327, "Rank": 3 }, { - "Command": "Set-PnPAuditing -TrimAuditLog", - "Id": 1313, "CommandName": "Set-PnPAuditing", + "Command": "Set-PnPAuditing -TrimAuditLog", + "Id": 1328, "Rank": 4 }, { - "Command": "Set-PnPAuditing -RetentionTime 7 -CheckOutCheckInItems -MoveCopyItems -SearchContent", - "Id": 1314, "CommandName": "Set-PnPAuditing", + "Command": "Set-PnPAuditing -RetentionTime 7 -CheckOutCheckInItems -MoveCopyItems -SearchContent", + "Id": 1329, "Rank": 5 }, { - "Command": "Set-PnPAvailablePageLayouts -AllowAllPageLayouts", - "Id": 1315, "CommandName": "Set-PnPAvailablePageLayouts", + "Command": "Set-PnPAvailablePageLayouts -AllowAllPageLayouts", + "Id": 1330, "Rank": 1 }, { - "Command": "Set-PnPAzureADAppSitePermission -PermissionId ABSDFefsdfef33fsdFSvsadf3e3fsdaffsa -Permissions Read", - "Id": 1316, "CommandName": "Set-PnPAzureADAppSitePermission", + "Command": "Set-PnPAzureADAppSitePermission -PermissionId ABSDFefsdfef33fsdFSvsadf3e3fsdaffsa -Permissions Read", + "Id": 1331, "Rank": 1 }, { - "Command": "Set-PnPAzureADAppSitePermission -PermissionId ABSDFefsdfef33fsdFSvsadf3e3fsdaffsa -Permissions FullControl -Site https://contoso.microsoft.com/sites/projects", - "Id": 1317, "CommandName": "Set-PnPAzureADAppSitePermission", + "Command": "Set-PnPAzureADAppSitePermission -PermissionId ABSDFefsdfef33fsdFSvsadf3e3fsdaffsa -Permissions FullControl -Site https://contoso.microsoft.com/sites/projects", + "Id": 1332, "Rank": 2 }, { - "Command": "Set-PnPAzureADGroup -Identity $group -DisplayName \"My DisplayName\"", - "Id": 1318, "CommandName": "Set-PnPAzureADGroup", + "Command": "Set-PnPAzureADGroup -Identity $group -DisplayName \"My DisplayName\"", + "Id": 1333, "Rank": 1 }, { - "Command": "Set-PnPAzureADGroup -Identity $groupId -Descriptions \"My Description\" -DisplayName \"My DisplayName\"", - "Id": 1319, "CommandName": "Set-PnPAzureADGroup", + "Command": "Set-PnPAzureADGroup -Identity $groupId -Descriptions \"My Description\" -DisplayName \"My DisplayName\"", + "Id": 1334, "Rank": 2 }, { - "Command": "Set-PnPAzureADGroup -Identity $group -Owners demo@contoso.com", - "Id": 1320, "CommandName": "Set-PnPAzureADGroup", + "Command": "Set-PnPAzureADGroup -Identity $group -Owners demo@contoso.com", + "Id": 1335, "Rank": 3 }, { - "Command": "Set-PnPBrowserIdleSignOut -Enabled:$true -WarnAfter \"0.00:45:00\" -SignOutAfter \"0.01:00:00\"", - "Id": 1321, "CommandName": "Set-PnPBrowserIdleSignout", + "Command": "Set-PnPBrowserIdleSignOut -Enabled:$true -WarnAfter \"0.00:45:00\" -SignOutAfter \"0.01:00:00\"", + "Id": 1336, "Rank": 1 }, { - "Command": "Set-PnPBrowserIdleSignOut -Enabled:$true -WarnAfter (New-TimeSpan -Minutes 45) -SignOutAfter (New-TimeSpan -Hours 1)", - "Id": 1322, "CommandName": "Set-PnPBrowserIdleSignout", + "Command": "Set-PnPBrowserIdleSignOut -Enabled:$true -WarnAfter (New-TimeSpan -Minutes 45) -SignOutAfter (New-TimeSpan -Hours 1)", + "Id": 1337, "Rank": 2 }, { - "Command": "Set-PnPBrowserIdleSignOut -Enabled:$false", - "Id": 1323, "CommandName": "Set-PnPBrowserIdleSignout", + "Command": "Set-PnPBrowserIdleSignOut -Enabled:$false", + "Id": 1338, "Rank": 3 }, { - "Command": "Set-PnPBuiltInDesignPackageVisibility -DesignPackage Showcase -IsVisible:$false", - "Id": 1324, "CommandName": "Set-PnPBuiltInDesignPackageVisibility", + "Command": "Set-PnPBuiltInDesignPackageVisibility -DesignPackage Showcase -IsVisible:$false", + "Id": 1339, "Rank": 1 }, { - "Command": "Set-PnPBuiltInDesignPackageVisibility -DesignPackage TeamSite -IsVisible:$true", - "Id": 1325, "CommandName": "Set-PnPBuiltInDesignPackageVisibility", + "Command": "Set-PnPBuiltInDesignPackageVisibility -DesignPackage TeamSite -IsVisible:$true", + "Id": 1340, "Rank": 2 }, { - "Command": "Set-PnPBuiltInSiteTemplateSettings -Identity 9522236e-6802-4972-a10d-e98dc74b3344 -IsHidden $false", - "Id": 1326, "CommandName": "Set-PnPBuiltInSiteTemplateSettings", + "Command": "Set-PnPBuiltInSiteTemplateSettings -Identity 9522236e-6802-4972-a10d-e98dc74b3344 -IsHidden $false", + "Id": 1341, "Rank": 1 }, { - "Command": "Set-PnPBuiltInSiteTemplateSettings -Identity 00000000-0000-0000-0000-000000000000 -IsHidden $true", - "Id": 1327, "CommandName": "Set-PnPBuiltInSiteTemplateSettings", + "Command": "Set-PnPBuiltInSiteTemplateSettings -Identity 00000000-0000-0000-0000-000000000000 -IsHidden $true", + "Id": 1342, "Rank": 2 }, { - "Command": "Set-PnPBuiltInSiteTemplateSettings -Template CrisisManagement -IsHidden $true", - "Id": 1328, "CommandName": "Set-PnPBuiltInSiteTemplateSettings", + "Command": "Set-PnPBuiltInSiteTemplateSettings -Template CrisisManagement -IsHidden $true", + "Id": 1343, "Rank": 3 }, { - "Command": "Set-PnPBuiltInSiteTemplateSettings -Template All -IsHidden $false", - "Id": 1329, "CommandName": "Set-PnPBuiltInSiteTemplateSettings", + "Command": "Set-PnPBuiltInSiteTemplateSettings -Template All -IsHidden $false", + "Id": 1344, "Rank": 4 }, { - "Command": "Set-PnPContentType -Identity \"Project Document\" -UpdateChildren -Name \"Project Documentation\" -Description \"Documentation for projects\"", - "Id": 1330, "CommandName": "Set-PnPContentType", + "Command": "Set-PnPContentType -Identity \"Project Document\" -UpdateChildren -Name \"Project Documentation\" -Description \"Documentation for projects\"", + "Id": 1345, "Rank": 1 }, { - "Command": "Set-PnPContentType -Identity \"Project Document\" -UpdateChildren -Group \"Custom Content Types\" -Hidden", - "Id": 1331, "CommandName": "Set-PnPContentType", + "Command": "Set-PnPContentType -Identity \"Project Document\" -UpdateChildren -Group \"Custom Content Types\" -Hidden", + "Id": 1346, "Rank": 2 }, { - "Command": "Set-PnPContentType -Identity \"Project Document\" -List \"Projects\" -Name \"Project Documentation\" -Description \"Documentation for projects\"", - "Id": 1332, "CommandName": "Set-PnPContentType", + "Command": "Set-PnPContentType -Identity \"Project Document\" -List \"Projects\" -Name \"Project Documentation\" -Description \"Documentation for projects\"", + "Id": 1347, "Rank": 3 }, { - "Command": "Set-PnPContentType -Identity \"Project Document\" -List \"Projects\" -FormClientSideComponentId \"dfed9a30-ec25-4aaf-ae9f-a68f3598f13a\" -FormClientSideComponentProperties '{ \"someKey\": \"some value\" }'", - "Id": 1333, "CommandName": "Set-PnPContentType", + "Command": "Set-PnPContentType -Identity \"Project Document\" -List \"Projects\" -FormClientSideComponentId \"dfed9a30-ec25-4aaf-ae9f-a68f3598f13a\" -FormClientSideComponentProperties '{ \"someKey\": \"some value\" }'", + "Id": 1348, "Rank": 4 }, { - "Command": "Set-PnPContentType -Identity \"Project Document\" -List \"Projects\" -DisplayFormClientSideComponentId \"dfed9a30-ec25-4aaf-ae9f-a68f3598f13a\" -DisplayFormClientSideComponentProperties '{ \"someKey\": \"some value\" }'", - "Id": 1334, "CommandName": "Set-PnPContentType", + "Command": "Set-PnPContentType -Identity \"Project Document\" -List \"Projects\" -DisplayFormClientSideComponentId \"dfed9a30-ec25-4aaf-ae9f-a68f3598f13a\" -DisplayFormClientSideComponentProperties '{ \"someKey\": \"some value\" }'", + "Id": 1349, "Rank": 5 }, { - "Command": "Set-PnPDefaultColumnValues -List Documents -Field TaxKeyword -Value \"Company|Locations|Stockholm\"", - "Id": 1335, "CommandName": "Set-PnPDefaultColumnValues", + "Command": "Set-PnPDefaultColumnValues -List Documents -Field TaxKeyword -Value \"Company|Locations|Stockholm\"", + "Id": 1350, "Rank": 1 }, { - "Command": "Set-PnPDefaultColumnValues -List Documents -Field TaxKeyword -Value \"15c4c4e4-4b67-4894-a1d8-de5ff811c791\"", - "Id": 1336, "CommandName": "Set-PnPDefaultColumnValues", + "Command": "Set-PnPDefaultColumnValues -List Documents -Field TaxKeyword -Value \"15c4c4e4-4b67-4894-a1d8-de5ff811c791\"", + "Id": 1351, "Rank": 2 }, { - "Command": "Set-PnPDefaultColumnValues -List Documents -Field MyTextField -Value \"DefaultValue\" -Folder \"My folder\"", - "Id": 1337, "CommandName": "Set-PnPDefaultColumnValues", + "Command": "Set-PnPDefaultColumnValues -List Documents -Field MyTextField -Value \"DefaultValue\" -Folder \"My folder\"", + "Id": 1352, "Rank": 3 }, { - "Command": "Set-PnPDefaultColumnValues -List Documents -Field MyPeopleField -Value \"1;#Foo Bar\"", - "Id": 1338, "CommandName": "Set-PnPDefaultColumnValues", + "Command": "Set-PnPDefaultColumnValues -List Documents -Field MyPeopleField -Value \"1;#Foo Bar\"", + "Id": 1353, "Rank": 4 }, { - "Command": "Set-PnPDefaultContentTypeToList -List \"Project Documents\" -ContentType \"Project\"", - "Id": 1339, "CommandName": "Set-PnPDefaultContentTypeToList", + "Command": "Set-PnPDefaultContentTypeToList -List \"Project Documents\" -ContentType \"Project\"", + "Id": 1354, "Rank": 1 }, { - "Command": "Set-PnPDefaultPageLayout -Title projectpage.aspx", - "Id": 1340, "CommandName": "Set-PnPDefaultPageLayout", + "Command": "Set-PnPDefaultPageLayout -Title projectpage.aspx", + "Id": 1355, "Rank": 1 }, { - "Command": "Set-PnPDefaultPageLayout -Title test/testpage.aspx", - "Id": 1341, "CommandName": "Set-PnPDefaultPageLayout", + "Command": "Set-PnPDefaultPageLayout -Title test/testpage.aspx", + "Id": 1356, "Rank": 2 }, { - "Command": "Set-PnPDefaultPageLayout -InheritFromParentSite", - "Id": 1342, "CommandName": "Set-PnPDefaultPageLayout", + "Command": "Set-PnPDefaultPageLayout -InheritFromParentSite", + "Id": 1357, "Rank": 3 }, { - "Command": "Set-PnPDisableSpacesActivation -Disable:$true -Scope Tenant", - "Id": 1343, "CommandName": "Set-PnPDisableSpacesActivation", + "Command": "Set-PnPDisableSpacesActivation -Disable:$true -Scope Tenant", + "Id": 1358, "Rank": 1 }, { - "Command": "Set-PnPDisableSpacesActivation -Disable -Scope Site -Identity \"https://contoso.sharepoint.com\"", - "Id": 1344, "CommandName": "Set-PnPDisableSpacesActivation", + "Command": "Set-PnPDisableSpacesActivation -Disable -Scope Site -Identity \"https://contoso.sharepoint.com\"", + "Id": 1359, "Rank": 2 }, { - "Command": "Set-PnPDisableSpacesActivation -Disable:$false -Scope Site -Identity \"https://contoso.sharepoint.com\"", - "Id": 1345, "CommandName": "Set-PnPDisableSpacesActivation", + "Command": "Set-PnPDisableSpacesActivation -Disable:$false -Scope Site -Identity \"https://contoso.sharepoint.com\"", + "Id": 1360, "Rank": 3 }, { - "Command": "Set-PnPDocumentSetField -Field \"Test Field\" -DocumentSet \"Test Document Set\" -SetSharedField -SetWelcomePageField", - "Id": 1346, "CommandName": "Set-PnPDocumentSetField", + "Command": "Set-PnPDocumentSetField -Field \"Test Field\" -DocumentSet \"Test Document Set\" -SetSharedField -SetWelcomePageField", + "Id": 1361, "Rank": 1 }, { - "Command": "Set-PnPDocumentSetField -Field \"Test Field\" -DocumentSet \"Test Document Set\" -RemoveSharedField -RemoveWelcomePageField", - "Id": 1347, "CommandName": "Set-PnPDocumentSetField", + "Command": "Set-PnPDocumentSetField -Field \"Test Field\" -DocumentSet \"Test Document Set\" -RemoveSharedField -RemoveWelcomePageField", + "Id": 1362, "Rank": 2 }, { - "Command": "Set-PnPField -Identity AssignedTo -Values @{JSLink=\"customrendering.js\";Group=\"My fields\"}", - "Id": 1348, "CommandName": "Set-PnPField", + "Command": "Set-PnPField -Identity AssignedTo -Values @{JSLink=\"customrendering.js\";Group=\"My fields\"}", + "Id": 1363, "Rank": 1 }, { - "Command": "Set-PnPField -Identity AssignedTo -Values @{JSLink=\"customrendering.js\";Group=\"My fields\"} -UpdateExistingLists", - "Id": 1349, "CommandName": "Set-PnPField", + "Command": "Set-PnPField -Identity AssignedTo -Values @{JSLink=\"customrendering.js\";Group=\"My fields\"} -UpdateExistingLists", + "Id": 1364, "Rank": 2 }, { - "Command": "Set-PnPField -List \"Tasks\" -Identity \"AssignedTo\" -Values @{JSLink=\"customrendering.js\"}", - "Id": 1350, "CommandName": "Set-PnPField", + "Command": "Set-PnPField -List \"Tasks\" -Identity \"AssignedTo\" -Values @{JSLink=\"customrendering.js\"}", + "Id": 1365, "Rank": 3 }, { - "Command": "Set-PnPFileCheckedIn -Url \"/Documents/Contract.docx\"", - "Id": 1351, "CommandName": "Set-PnPFileCheckedIn", + "Command": "Set-PnPFileCheckedIn -Url \"/Documents/Contract.docx\"", + "Id": 1366, "Rank": 1 }, { - "Command": "Set-PnPFileCheckedIn -Url \"/Documents/Contract.docx\" -CheckInType MinorCheckIn -Comment \"Smaller changes\"", - "Id": 1352, "CommandName": "Set-PnPFileCheckedIn", + "Command": "Set-PnPFileCheckedIn -Url \"/Documents/Contract.docx\" -CheckInType MinorCheckIn -Comment \"Smaller changes\"", + "Id": 1367, "Rank": 2 }, { - "Command": "Set-PnPFileCheckedOut -Url \"/sites/testsite/subsite/Documents/Contract.docx\"", - "Id": 1353, "CommandName": "Set-PnPFileCheckedOut", + "Command": "Set-PnPFileCheckedOut -Url \"/sites/testsite/subsite/Documents/Contract.docx\"", + "Id": 1368, "Rank": 1 }, { - "Command": "Set-PnPFolderPermission -List 'Shared Documents' -Identity 'Shared Documents/Folder' -User 'user@contoso.com' -AddRole 'Contribute'", - "Id": 1354, "CommandName": "Set-PnPFolderPermission", + "Command": "Set-PnPFolderPermission -List 'Shared Documents' -Identity 'Shared Documents/Folder' -User 'user@contoso.com' -AddRole 'Contribute'", + "Id": 1369, "Rank": 1 }, { - "Command": "Set-PnPFolderPermission -List 'AnotherDocumentLibrary' -Identity 'AnotherDocumentLibrary/Folder/Subfolder' -User 'user@contoso.com' -RemoveRole 'Contribute'", - "Id": 1355, "CommandName": "Set-PnPFolderPermission", + "Command": "Set-PnPFolderPermission -List 'AnotherDocumentLibrary' -Identity 'AnotherDocumentLibrary/Folder/Subfolder' -User 'user@contoso.com' -RemoveRole 'Contribute'", + "Id": 1370, "Rank": 2 }, { - "Command": "Set-PnPFolderPermission -List 'Shared Documents' -Identity 'Shared Documents/Folder' -User 'user@contoso.com' -AddRole 'Contribute' -ClearExisting", - "Id": 1356, "CommandName": "Set-PnPFolderPermission", + "Command": "Set-PnPFolderPermission -List 'Shared Documents' -Identity 'Shared Documents/Folder' -User 'user@contoso.com' -AddRole 'Contribute' -ClearExisting", + "Id": 1371, "Rank": 3 }, { - "Command": "Set-PnPFooter -Enabled:$true", - "Id": 1357, "CommandName": "Set-PnPFooter", + "Command": "Set-PnPFooter -Enabled:$true", + "Id": 1372, "Rank": 1 }, { - "Command": "Set-PnPFooter -Enabled:$true -Layout Extended -BackgroundTheme Neutral", - "Id": 1358, "CommandName": "Set-PnPFooter", + "Command": "Set-PnPFooter -Enabled:$true -Layout Extended -BackgroundTheme Neutral", + "Id": 1373, "Rank": 2 }, { - "Command": "Set-PnPFooter -Title \"Contoso Inc.\" -LogoUrl \"/sites/communication/Shared Documents/logo.png\"", - "Id": 1359, "CommandName": "Set-PnPFooter", + "Command": "Set-PnPFooter -Title \"Contoso Inc.\" -LogoUrl \"/sites/communication/Shared Documents/logo.png\"", + "Id": 1374, "Rank": 3 }, { - "Command": "Set-PnPFooter -LogoUrl \"\"", - "Id": 1360, "CommandName": "Set-PnPFooter", + "Command": "Set-PnPFooter -LogoUrl \"\"", + "Id": 1375, "Rank": 4 }, { - "Command": "Set-PnPGraphSubscription -Identity bc204397-1128-4911-9d70-1d8bceee39da -ExpirationDate \"2020-11-22T18:23:45.9356913Z\"", - "Id": 1361, "CommandName": "Set-PnPGraphSubscription", + "Command": "Set-PnPGraphSubscription -Identity bc204397-1128-4911-9d70-1d8bceee39da -ExpirationDate \"2020-11-22T18:23:45.9356913Z\"", + "Id": 1376, "Rank": 1 }, { - "Command": "Set-PnPGroup -Identity 'My Site Members' -SetAssociatedGroup Members", - "Id": 1362, "CommandName": "Set-PnPGroup", + "Command": "Set-PnPGroup -Identity 'My Site Members' -SetAssociatedGroup Members", + "Id": 1377, "Rank": 1 }, { - "Command": "Set-PnPGroup -Identity 'My Site Members' -Owner 'site owners'", - "Id": 1363, "CommandName": "Set-PnPGroup", + "Command": "Set-PnPGroup -Identity 'My Site Members' -Owner 'site owners'", + "Id": 1378, "Rank": 2 }, { - "Command": "Set-PnPGroupPermissions -Identity 'My Site Members' -AddRole Contribute", - "Id": 1364, "CommandName": "Set-PnPGroupPermissions", + "Command": "Set-PnPGroupPermissions -Identity 'My Site Members' -AddRole Contribute", + "Id": 1379, "Rank": 1 }, { - "Command": "Set-PnPGroupPermissions -Identity 'My Site Members' -RemoveRole 'Full Control' -AddRole 'Read'", - "Id": 1365, "CommandName": "Set-PnPGroupPermissions", + "Command": "Set-PnPGroupPermissions -Identity 'My Site Members' -RemoveRole 'Full Control' -AddRole 'Read'", + "Id": 1380, "Rank": 2 }, { - "Command": "Set-PnPGroupPermissions -Identity 'My Site Members' -AddRole @('Contribute', 'Design')", - "Id": 1366, "CommandName": "Set-PnPGroupPermissions", + "Command": "Set-PnPGroupPermissions -Identity 'My Site Members' -AddRole @('Contribute', 'Design')", + "Id": 1381, "Rank": 3 }, { - "Command": "Set-PnPGroupPermissions -Identity 'My Site Members' -RemoveRole @('Contribute', 'Design')", - "Id": 1367, "CommandName": "Set-PnPGroupPermissions", + "Command": "Set-PnPGroupPermissions -Identity 'My Site Members' -RemoveRole @('Contribute', 'Design')", + "Id": 1382, "Rank": 4 }, { - "Command": "Set-PnPGroupPermissions -Identity 'My Site Members' -List 'MyList' -RemoveRole @('Contribute')", - "Id": 1368, "CommandName": "Set-PnPGroupPermissions", + "Command": "Set-PnPGroupPermissions -Identity 'My Site Members' -List 'MyList' -RemoveRole @('Contribute')", + "Id": 1383, "Rank": 5 }, { - "Command": "Set-PnPHideDefaultThemes -HideDefaultThemes $true", - "Id": 1369, "CommandName": "Set-PnPHideDefaultThemes", + "Command": "Set-PnPHideDefaultThemes -HideDefaultThemes $true", + "Id": 1384, "Rank": 1 }, { - "Command": "Set-PnPHideDefaultThemes -HideDefaultThemes $false", - "Id": 1370, "CommandName": "Set-PnPHideDefaultThemes", + "Command": "Set-PnPHideDefaultThemes -HideDefaultThemes $false", + "Id": 1385, "Rank": 2 }, { - "Command": "Set-PnPHomePage -RootFolderRelativeUrl SitePages/Home.aspx", - "Id": 1371, "CommandName": "Set-PnPHomePage", + "Command": "Set-PnPHomePage -RootFolderRelativeUrl SitePages/Home.aspx", + "Id": 1386, "Rank": 1 }, { - "Command": "Set-PnPHomePage -RootFolderRelativeUrl Lists/Sample/AllItems.aspx", - "Id": 1372, "CommandName": "Set-PnPHomePage", + "Command": "Set-PnPHomePage -RootFolderRelativeUrl Lists/Sample/AllItems.aspx", + "Id": 1387, "Rank": 2 }, { - "Command": "Set-PnPHomeSite -HomeSiteUrl \"https://yourtenant.sharepoint.com/sites/myhome\"", - "Id": 1373, "CommandName": "Set-PnPHomeSite", + "Command": "Set-PnPHomeSite -HomeSiteUrl \"https://yourtenant.sharepoint.com/sites/myhome\"", + "Id": 1388, "Rank": 1 }, { - "Command": "Set-PnPHomeSite -HomeSiteUrl \"https://yourtenant.sharepoint.com/sites/myhome\" -VivaConnectionsDefaultStart:$true", - "Id": 1374, "CommandName": "Set-PnPHomeSite", + "Command": "Set-PnPHomeSite -HomeSiteUrl \"https://yourtenant.sharepoint.com/sites/myhome\" -VivaConnectionsDefaultStart:$true", + "Id": 1389, "Rank": 2 }, { - "Command": "Set-PnPHomeSite -HomeSiteUrl \"https://yourtenant.sharepoint.com/sites/myhome\" -VivaConnectionsDefaultStart:$true -DraftMode:$true", - "Id": 1375, "CommandName": "Set-PnPHomeSite", + "Command": "Set-PnPHomeSite -HomeSiteUrl \"https://yourtenant.sharepoint.com/sites/myhome\" -VivaConnectionsDefaultStart:$true -DraftMode:$true", + "Id": 1390, "Rank": 3 }, { - "Command": "Set-PnPHubSite -Identity \"https://tenant.sharepoint.com/sites/myhubsite\" -Title \"My New Title\"", - "Id": 1376, "CommandName": "Set-PnPHubSite", + "Command": "Set-PnPHubSite -Identity \"https://tenant.sharepoint.com/sites/myhubsite\" -Title \"My New Title\"", + "Id": 1391, "Rank": 1 }, { - "Command": "Set-PnPHubSite -Identity \"https://tenant.sharepoint.com/sites/myhubsite\" -Description \"My updated description\"", - "Id": 1377, "CommandName": "Set-PnPHubSite", + "Command": "Set-PnPHubSite -Identity \"https://tenant.sharepoint.com/sites/myhubsite\" -Description \"My updated description\"", + "Id": 1392, "Rank": 2 }, { - "Command": "Set-PnPHubSite -Identity \"https://tenant.sharepoint.com/sites/myhubsite\" -SiteDesignId df8a3ef1-9603-44c4-abd9-541aea2fa745", - "Id": 1378, "CommandName": "Set-PnPHubSite", + "Command": "Set-PnPHubSite -Identity \"https://tenant.sharepoint.com/sites/myhubsite\" -SiteDesignId df8a3ef1-9603-44c4-abd9-541aea2fa745", + "Id": 1393, "Rank": 3 }, { - "Command": "Set-PnPHubSite -Identity \"https://tenant.sharepoint.com/sites/myhubsite\" -LogoUrl \"https://tenant.sharepoint.com/SiteAssets/Logo.png\"", - "Id": 1379, "CommandName": "Set-PnPHubSite", + "Command": "Set-PnPHubSite -Identity \"https://tenant.sharepoint.com/sites/myhubsite\" -LogoUrl \"https://tenant.sharepoint.com/SiteAssets/Logo.png\"", + "Id": 1394, "Rank": 4 }, { - "Command": "Set-PnPHubSite -Identity \"https://tenant.sharepoint.com/sites/myhubsite\" -EnablePermissionsSync", - "Id": 1380, "CommandName": "Set-PnPHubSite", + "Command": "Set-PnPHubSite -Identity \"https://tenant.sharepoint.com/sites/myhubsite\" -EnablePermissionsSync", + "Id": 1395, "Rank": 5 }, { - "Command": "Set-PnPHubSite -Identity \"https://tenant.sharepoint.com/sites/myhubsite\" -RequiresJoinApproval:$false", - "Id": 1381, "CommandName": "Set-PnPHubSite", + "Command": "Set-PnPHubSite -Identity \"https://tenant.sharepoint.com/sites/myhubsite\" -RequiresJoinApproval:$false", + "Id": 1396, "Rank": 6 }, { - "Command": "Set-PnPImageListItemColumn -List \"Demo List\" -Identity 1 -Field \"Thumbnail\" -ServerRelativePath \"/sites/contoso/SiteAssets/test.png\"", - "Id": 1382, "CommandName": "Set-PnPImageListItemColumn", + "Command": "Set-PnPImageListItemColumn -List \"Demo List\" -Identity 1 -Field \"Thumbnail\" -ServerRelativePath \"/sites/contoso/SiteAssets/test.png\"", + "Id": 1397, "Rank": 1 }, { - "Command": "Set-PnPImageListItemColumn -List \"Demo List\" -Identity 1 -Field \"Thumbnail\" -Path sample.png", - "Id": 1383, "CommandName": "Set-PnPImageListItemColumn", + "Command": "Set-PnPImageListItemColumn -List \"Demo List\" -Identity 1 -Field \"Thumbnail\" -Path sample.png", + "Id": 1398, "Rank": 2 }, { - "Command": "Set-PnPIndexedProperties -Keys SiteClosed, PolicyName", - "Id": 1384, "CommandName": "Set-PnPIndexedProperties", + "Command": "Set-PnPIndexedProperties -Keys SiteClosed, PolicyName", + "Id": 1399, "Rank": 1 }, { - "Command": "Set-PnPInPlaceRecordsManagement -Enabled $true", - "Id": 1385, "CommandName": "Set-PnPInPlaceRecordsManagement", + "Command": "Set-PnPInPlaceRecordsManagement -Enabled $true", + "Id": 1400, "Rank": 1 }, { - "Command": "Set-PnPInPlaceRecordsManagement -Enabled $false", - "Id": 1386, "CommandName": "Set-PnPInPlaceRecordsManagement", + "Command": "Set-PnPInPlaceRecordsManagement -Enabled $false", + "Id": 1401, "Rank": 2 }, { - "Command": "Set-PnPKnowledgeHubSite -KnowledgeHubSiteUrl \"https://yoursite.sharepoint.com/sites/knowledge\"", - "Id": 1387, "CommandName": "Set-PnPKnowledgeHubSite", + "Command": "Set-PnPKnowledgeHubSite -KnowledgeHubSiteUrl \"https://yoursite.sharepoint.com/sites/knowledge\"", + "Id": 1402, "Rank": 1 }, { - "Command": "Set-PnPList -Identity \"Demo List\" -EnableContentTypes $true", - "Id": 1388, "CommandName": "Set-PnPList", + "Command": "Set-PnPList -Identity \"Demo List\" -EnableContentTypes $true", + "Id": 1403, "Rank": 1 }, { - "Command": "Set-PnPList -Identity \"Demo List\" -Hidden $true", - "Id": 1389, "CommandName": "Set-PnPList", + "Command": "Set-PnPList -Identity \"Demo List\" -Hidden $true", + "Id": 1404, "Rank": 2 }, { - "Command": "Set-PnPList -Identity \"Demo List\" -EnableVersioning $true", - "Id": 1390, "CommandName": "Set-PnPList", + "Command": "Set-PnPList -Identity \"Demo List\" -EnableVersioning $true", + "Id": 1405, "Rank": 3 }, { - "Command": "Set-PnPList -Identity \"Demo List\" -EnableVersioning $true -MajorVersions 20", - "Id": 1391, "CommandName": "Set-PnPList", + "Command": "Set-PnPList -Identity \"Demo List\" -EnableVersioning $true -MajorVersions 20", + "Id": 1406, "Rank": 4 }, { - "Command": "Set-PnPList -Identity \"Demo Library\" -EnableVersioning $true -EnableMinorVersions $true -MajorVersions 20 -MinorVersions 5", - "Id": 1392, "CommandName": "Set-PnPList", + "Command": "Set-PnPList -Identity \"Demo Library\" -EnableVersioning $true -EnableMinorVersions $true -MajorVersions 20 -MinorVersions 5", + "Id": 1407, "Rank": 5 }, { - "Command": "Set-PnPList -Identity \"Demo List\" -EnableAttachments $true", - "Id": 1393, "CommandName": "Set-PnPList", + "Command": "Set-PnPList -Identity \"Demo List\" -EnableAttachments $true", + "Id": 1408, "Rank": 6 }, { - "Command": "Set-PnPList -Identity \"Demo List\" -Title \"Demo List 2\" -Path \"Lists/DemoList2\"", - "Id": 1394, "CommandName": "Set-PnPList", + "Command": "Set-PnPList -Identity \"Demo List\" -Title \"Demo List 2\" -Path \"Lists/DemoList2\"", + "Id": 1409, "Rank": 7 }, { - "Command": "Set-PnPList -Identity \"Demo List\" -EnableAutoExpirationVersionTrim $true", - "Id": 1395, "CommandName": "Set-PnPList", + "Command": "Set-PnPList -Identity \"Demo List\" -EnableAutoExpirationVersionTrim $true", + "Id": 1410, "Rank": 8 }, { - "Command": "Set-PnPList -Identity \"Demo List\" -EnableAutoExpirationVersionTrim $false -ExpireVersionsAfterDays 30 -MajorVersions 500", - "Id": 1396, "CommandName": "Set-PnPList", + "Command": "Set-PnPList -Identity \"Demo List\" -EnableAutoExpirationVersionTrim $false -ExpireVersionsAfterDays 30 -MajorVersions 500", + "Id": 1411, "Rank": 9 }, { - "Command": "Set-PnPList -Identity \"Demo List\" -EnableAutoExpirationVersionTrim $false -ExpireVersionsAfterDays 0 -MajorVersions 500", - "Id": 1397, "CommandName": "Set-PnPList", + "Command": "Set-PnPList -Identity \"Demo List\" -EnableAutoExpirationVersionTrim $false -ExpireVersionsAfterDays 0 -MajorVersions 500", + "Id": 1412, "Rank": 10 }, { - "Command": "Set-PnPList -Identity \"Demo List\" -DefaultSensitivityLabelForLibrary \"Confidential\"", - "Id": 1398, "CommandName": "Set-PnPList", + "Command": "Set-PnPList -Identity \"Demo List\" -DefaultSensitivityLabelForLibrary \"Confidential\"", + "Id": 1413, "Rank": 11 }, { - "Command": "Set-PnPListInformationRightsManagement -List \"Documents\" -Enable $true", - "Id": 1399, "CommandName": "Set-PnPListInformationRightsManagement", + "Command": "Set-PnPListInformationRightsManagement -List \"Documents\" -Enable $true", + "Id": 1414, "Rank": 1 }, { - "Command": "Set-PnPListInformationRightsManagement -List \"Documents\" -Enable $true -EnableDocumentAccessExpire $true -DocumentAccessExpireDays 14", - "Id": 1400, "CommandName": "Set-PnPListInformationRightsManagement", + "Command": "Set-PnPListInformationRightsManagement -List \"Documents\" -Enable $true -EnableDocumentAccessExpire $true -DocumentAccessExpireDays 14", + "Id": 1415, "Rank": 2 }, { - "Command": "Set-PnPListItem -List \"Demo List\" -Identity 1 -Values @{\"Title\" = \"Test Title\"; \"Category\"=\"Test Category\"}", - "Id": 1401, "CommandName": "Set-PnPListItem", + "Command": "Set-PnPListItem -List \"Demo List\" -Identity 1 -Values @{\"Title\" = \"Test Title\"; \"Category\"=\"Test Category\"}", + "Id": 1416, "Rank": 1 }, { - "Command": "Set-PnPListItem -List \"Demo List\" -Identity 1 -ContentType \"Company\" -Values @{\"Title\" = \"Test Title\"; \"Category\"=\"Test Category\"}", - "Id": 1402, "CommandName": "Set-PnPListItem", + "Command": "Set-PnPListItem -List \"Demo List\" -Identity 1 -ContentType \"Company\" -Values @{\"Title\" = \"Test Title\"; \"Category\"=\"Test Category\"}", + "Id": 1417, "Rank": 2 }, { - "Command": "Set-PnPListItem -List \"Demo List\" -Identity $item -Values @{\"Title\" = \"Test Title\"; \"Category\"=\"Test Category\"}", - "Id": 1403, "CommandName": "Set-PnPListItem", + "Command": "Set-PnPListItem -List \"Demo List\" -Identity $item -Values @{\"Title\" = \"Test Title\"; \"Category\"=\"Test Category\"}", + "Id": 1418, "Rank": 3 }, { - "Command": "Set-PnPListItem -List \"Demo List\" -Identity 1 -Label \"Public\"", - "Id": 1404, "CommandName": "Set-PnPListItem", + "Command": "Set-PnPListItem -List \"Demo List\" -Identity 1 -Label \"Public\"", + "Id": 1419, "Rank": 4 }, { - "Command": "Set-PnPListItem -List \"Demo List\" -Identity 1 -Values @{\"Editor\"=\"testuser@domain.com\"} -UpdateType UpdateOverwriteVersion", - "Id": 1405, "CommandName": "Set-PnPListItem", + "Command": "Set-PnPListItem -List \"Demo List\" -Identity 1 -Values @{\"Editor\"=\"testuser@domain.com\"} -UpdateType UpdateOverwriteVersion", + "Id": 1420, "Rank": 5 }, { - "Command": "Set-PnPListItemAsRecord -List \"Documents\" -Identity 4", - "Id": 1406, "CommandName": "Set-PnPListItemAsRecord", + "Command": "Set-PnPListItemAsRecord -List \"Documents\" -Identity 4", + "Id": 1421, "Rank": 1 }, { - "Command": "Set-PnPListItemAsRecord -List \"Documents\" -Identity 4 -DeclarationDate $date", - "Id": 1407, "CommandName": "Set-PnPListItemAsRecord", + "Command": "Set-PnPListItemAsRecord -List \"Documents\" -Identity 4 -DeclarationDate $date", + "Id": 1422, "Rank": 2 }, { - "Command": "Set-PnPListItemPermission -List 'Documents' -Identity 1 -User 'user@contoso.com' -AddRole 'Contribute'", - "Id": 1408, "CommandName": "Set-PnPListItemPermission", + "Command": "Set-PnPListItemPermission -List 'Documents' -Identity 1 -User 'user@contoso.com' -AddRole 'Contribute'", + "Id": 1423, "Rank": 1 }, { - "Command": "Set-PnPListItemPermission -List 'Documents' -Identity 1 -User 'user@contoso.com' -RemoveRole 'Contribute'", - "Id": 1409, "CommandName": "Set-PnPListItemPermission", + "Command": "Set-PnPListItemPermission -List 'Documents' -Identity 1 -User 'user@contoso.com' -RemoveRole 'Contribute'", + "Id": 1424, "Rank": 2 }, { - "Command": "Set-PnPListItemPermission -List 'Documents' -Identity 1 -User 'user@contoso.com' -AddRole 'Contribute' -ClearExisting", - "Id": 1410, "CommandName": "Set-PnPListItemPermission", + "Command": "Set-PnPListItemPermission -List 'Documents' -Identity 1 -User 'user@contoso.com' -AddRole 'Contribute' -ClearExisting", + "Id": 1425, "Rank": 3 }, { - "Command": "Set-PnPListItemPermission -List 'Documents' -Identity 1 -InheritPermissions", - "Id": 1411, "CommandName": "Set-PnPListItemPermission", + "Command": "Set-PnPListItemPermission -List 'Documents' -Identity 1 -InheritPermissions", + "Id": 1426, "Rank": 4 }, { - "Command": "Set-PnPListItemPermission -List 'Documents' -Identity 1 -AddRole 'Read' -RemoveRole 'Contribute' -Group \"Site collection Visitors\"", - "Id": 1412, "CommandName": "Set-PnPListItemPermission", + "Command": "Set-PnPListItemPermission -List 'Documents' -Identity 1 -AddRole 'Read' -RemoveRole 'Contribute' -Group \"Site collection Visitors\"", + "Id": 1427, "Rank": 5 }, { - "Command": "Set-PnPListPermission -Identity 'Documents' -User 'user@contoso.com' -AddRole 'Contribute'", - "Id": 1413, "CommandName": "Set-PnPListPermission", + "Command": "Set-PnPListPermission -Identity 'Documents' -User 'user@contoso.com' -AddRole 'Contribute'", + "Id": 1428, "Rank": 1 }, { - "Command": "Set-PnPListPermission -Identity 'Documents' -User 'user@contoso.com' -RemoveRole 'Contribute'", - "Id": 1414, "CommandName": "Set-PnPListPermission", + "Command": "Set-PnPListPermission -Identity 'Documents' -User 'user@contoso.com' -RemoveRole 'Contribute'", + "Id": 1429, "Rank": 2 }, { - "Command": "Set-PnPListRecordDeclaration -List \"Documents\" -ManualRecordDeclaration NeverAllowManualDeclaration", - "Id": 1415, "CommandName": "Set-PnPListRecordDeclaration", + "Command": "Set-PnPListRecordDeclaration -List \"Documents\" -ManualRecordDeclaration NeverAllowManualDeclaration", + "Id": 1430, "Rank": 1 }, { - "Command": "Set-PnPListRecordDeclaration -List \"Documents\" -AutoRecordDeclaration $true", - "Id": 1416, "CommandName": "Set-PnPListRecordDeclaration", + "Command": "Set-PnPListRecordDeclaration -List \"Documents\" -AutoRecordDeclaration $true", + "Id": 1431, "Rank": 2 }, { - "Command": "Set-PnPMasterPage -MasterPageServerRelativeUrl /sites/projects/_catalogs/masterpage/oslo.master", - "Id": 1417, "CommandName": "Set-PnPMasterPage", + "Command": "Set-PnPMasterPage -MasterPageServerRelativeUrl /sites/projects/_catalogs/masterpage/oslo.master", + "Id": 1432, "Rank": 1 }, { - "Command": "Set-PnPMasterPage -MasterPageServerRelativeUrl /sites/projects/_catalogs/masterpage/oslo.master -CustomMasterPageServerRelativeUrl /sites/projects/_catalogs/masterpage/oslo.master", - "Id": 1418, "CommandName": "Set-PnPMasterPage", + "Command": "Set-PnPMasterPage -MasterPageServerRelativeUrl /sites/projects/_catalogs/masterpage/oslo.master -CustomMasterPageServerRelativeUrl /sites/projects/_catalogs/masterpage/oslo.master", + "Id": 1433, "Rank": 2 }, { - "Command": "Set-PnPMasterPage -MasterPageSiteRelativeUrl _catalogs/masterpage/oslo.master", - "Id": 1419, "CommandName": "Set-PnPMasterPage", + "Command": "Set-PnPMasterPage -MasterPageSiteRelativeUrl _catalogs/masterpage/oslo.master", + "Id": 1434, "Rank": 3 }, { - "Command": "Set-PnPMasterPage -MasterPageSiteRelativeUrl _catalogs/masterpage/oslo.master -CustomMasterPageSiteRelativeUrl _catalogs/masterpage/oslo.master", - "Id": 1420, "CommandName": "Set-PnPMasterPage", + "Command": "Set-PnPMasterPage -MasterPageSiteRelativeUrl _catalogs/masterpage/oslo.master -CustomMasterPageSiteRelativeUrl _catalogs/masterpage/oslo.master", + "Id": 1435, "Rank": 4 }, { - "Command": "Set-PnPMessageCenterAnnouncementAsArchived -Identity \"MC123456\"", - "Id": 1421, "CommandName": "Set-PnPMessageCenterAnnouncementAsArchived", + "Command": "Set-PnPMessageCenterAnnouncementAsArchived -Identity \"MC123456\"", + "Id": 1436, "Rank": 1 }, { - "Command": "Set-PnPMessageCenterAnnouncementAsArchived -Identity \"MC123456\", \"MC234567\"", - "Id": 1422, "CommandName": "Set-PnPMessageCenterAnnouncementAsArchived", + "Command": "Set-PnPMessageCenterAnnouncementAsArchived -Identity \"MC123456\", \"MC234567\"", + "Id": 1437, "Rank": 2 }, { - "Command": "Set-PnPMessageCenterAnnouncementAsArchived", - "Id": 1423, "CommandName": "Set-PnPMessageCenterAnnouncementAsArchived", + "Command": "Set-PnPMessageCenterAnnouncementAsArchived", + "Id": 1438, "Rank": 3 }, { - "Command": "Set-PnPMessageCenterAnnouncementAsFavorite -Identity \"MC123456\"", - "Id": 1424, "CommandName": "Set-PnPMessageCenterAnnouncementAsFavorite", + "Command": "Set-PnPMessageCenterAnnouncementAsFavorite -Identity \"MC123456\"", + "Id": 1439, "Rank": 1 }, { - "Command": "Set-PnPMessageCenterAnnouncementAsFavorite -Identity \"MC123456\", \"MC234567\"", - "Id": 1425, "CommandName": "Set-PnPMessageCenterAnnouncementAsFavorite", + "Command": "Set-PnPMessageCenterAnnouncementAsFavorite -Identity \"MC123456\", \"MC234567\"", + "Id": 1440, "Rank": 2 }, { - "Command": "Set-PnPMessageCenterAnnouncementAsFavorite", - "Id": 1426, "CommandName": "Set-PnPMessageCenterAnnouncementAsFavorite", + "Command": "Set-PnPMessageCenterAnnouncementAsFavorite", + "Id": 1441, "Rank": 3 }, { - "Command": "Set-PnPMessageCenterAnnouncementAsNotArchived -Identity \"MC123456\"", - "Id": 1427, "CommandName": "Set-PnPMessageCenterAnnouncementAsNotArchived", + "Command": "Set-PnPMessageCenterAnnouncementAsNotArchived -Identity \"MC123456\"", + "Id": 1442, "Rank": 1 }, { - "Command": "Set-PnPMessageCenterAnnouncementAsNotArchived -Identity \"MC123456\", \"MC234567\"", - "Id": 1428, "CommandName": "Set-PnPMessageCenterAnnouncementAsNotArchived", + "Command": "Set-PnPMessageCenterAnnouncementAsNotArchived -Identity \"MC123456\", \"MC234567\"", + "Id": 1443, "Rank": 2 }, { - "Command": "Set-PnPMessageCenterAnnouncementAsNotArchived", - "Id": 1429, "CommandName": "Set-PnPMessageCenterAnnouncementAsNotArchived", + "Command": "Set-PnPMessageCenterAnnouncementAsNotArchived", + "Id": 1444, "Rank": 3 }, { - "Command": "Set-PnPMessageCenterAnnouncementAsNotFavorite -Identity \"MC123456\"", - "Id": 1430, "CommandName": "Set-PnPMessageCenterAnnouncementAsNotFavorite", + "Command": "Set-PnPMessageCenterAnnouncementAsNotFavorite -Identity \"MC123456\"", + "Id": 1445, "Rank": 1 }, { - "Command": "Set-PnPMessageCenterAnnouncementAsNotFavorite -Identity \"MC123456\", \"MC234567\"", - "Id": 1431, "CommandName": "Set-PnPMessageCenterAnnouncementAsNotFavorite", + "Command": "Set-PnPMessageCenterAnnouncementAsNotFavorite -Identity \"MC123456\", \"MC234567\"", + "Id": 1446, "Rank": 2 }, { - "Command": "Set-PnPMessageCenterAnnouncementAsNotFavorite", - "Id": 1432, "CommandName": "Set-PnPMessageCenterAnnouncementAsNotFavorite", + "Command": "Set-PnPMessageCenterAnnouncementAsNotFavorite", + "Id": 1447, "Rank": 3 }, { - "Command": "Set-PnPMessageCenterAnnouncementAsRead -Identity \"MC123456\"", - "Id": 1433, "CommandName": "Set-PnPMessageCenterAnnouncementAsRead", + "Command": "Set-PnPMessageCenterAnnouncementAsRead -Identity \"MC123456\"", + "Id": 1448, "Rank": 1 }, { - "Command": "Set-PnPMessageCenterAnnouncementAsRead -Identity \"MC123456\", \"MC234567\"", - "Id": 1434, "CommandName": "Set-PnPMessageCenterAnnouncementAsRead", + "Command": "Set-PnPMessageCenterAnnouncementAsRead -Identity \"MC123456\", \"MC234567\"", + "Id": 1449, "Rank": 2 }, { - "Command": "Set-PnPMessageCenterAnnouncementAsRead", - "Id": 1435, "CommandName": "Set-PnPMessageCenterAnnouncementAsRead", + "Command": "Set-PnPMessageCenterAnnouncementAsRead", + "Id": 1450, "Rank": 3 }, { - "Command": "Set-PnPMessageCenterAnnouncementAsUnread -Identity \"MC123456\"", - "Id": 1436, "CommandName": "Set-PnPMessageCenterAnnouncementAsUnread", + "Command": "Set-PnPMessageCenterAnnouncementAsUnread -Identity \"MC123456\"", + "Id": 1451, "Rank": 1 }, { - "Command": "Set-PnPMessageCenterAnnouncementAsUnread -Identity \"MC123456\", \"MC234567\"", - "Id": 1437, "CommandName": "Set-PnPMessageCenterAnnouncementAsUnread", + "Command": "Set-PnPMessageCenterAnnouncementAsUnread -Identity \"MC123456\", \"MC234567\"", + "Id": 1452, "Rank": 2 }, { - "Command": "Set-PnPMessageCenterAnnouncementAsUnread", - "Id": 1438, "CommandName": "Set-PnPMessageCenterAnnouncementAsUnread", + "Command": "Set-PnPMessageCenterAnnouncementAsUnread", + "Id": 1453, "Rank": 3 }, { - "Command": "Set-PnPMicrosoft365Group -Identity $group -DisplayName \"My DisplayName\"", - "Id": 1439, "CommandName": "Set-PnPMicrosoft365Group", + "Command": "Set-PnPMicrosoft365Group -Identity $group -DisplayName \"My DisplayName\"", + "Id": 1454, "Rank": 1 }, { - "Command": "Set-PnPMicrosoft365Group -Identity $groupId -Descriptions \"My Description\" -DisplayName \"My DisplayName\"", - "Id": 1440, "CommandName": "Set-PnPMicrosoft365Group", + "Command": "Set-PnPMicrosoft365Group -Identity $groupId -Description \"My Description\" -DisplayName \"My DisplayName\"", + "Id": 1455, "Rank": 2 }, { - "Command": "Set-PnPMicrosoft365Group -Identity $group -GroupLogoPath \".\\MyLogo.png\"", - "Id": 1441, "CommandName": "Set-PnPMicrosoft365Group", + "Command": "Set-PnPMicrosoft365Group -Identity $group -GroupLogoPath \".\\MyLogo.png\"", + "Id": 1456, "Rank": 3 }, { - "Command": "Set-PnPMicrosoft365Group -Identity $group -IsPrivate:$false", - "Id": 1442, "CommandName": "Set-PnPMicrosoft365Group", + "Command": "Set-PnPMicrosoft365Group -Identity $group -IsPrivate:$false", + "Id": 1457, "Rank": 4 }, { - "Command": "Set-PnPMicrosoft365Group -Identity $group -Owners demo@contoso.com", - "Id": 1443, "CommandName": "Set-PnPMicrosoft365Group", + "Command": "Set-PnPMicrosoft365Group -Identity $group -Owners demo@contoso.com", + "Id": 1458, "Rank": 5 }, { - "Command": "Set-PnPMicrosoft365Group -Identity $group -SensitivityLabels \"bc98af29-59eb-4869-baaa-9a8dff631aa4\"", - "Id": 1444, "CommandName": "Set-PnPMicrosoft365Group", + "Command": "Set-PnPMicrosoft365Group -Identity $group -SensitivityLabels \"bc98af29-59eb-4869-baaa-9a8dff631aa4\"", + "Id": 1459, "Rank": 6 }, { - "Command": "Set-PnPMicrosoft365GroupSettings -Identity $groupSettingId -Values @{\"AllowToAddGuests\"=\"true\"}", - "Id": 1445, "CommandName": "Set-PnPMicrosoft365GroupSettings", + "Command": "Set-PnPMicrosoft365GroupSettings -Identity $groupSettingId -Values @{\"AllowToAddGuests\"=\"true\"}", + "Id": 1460, "Rank": 1 }, { - "Command": "Set-PnPMicrosoft365GroupSettings -Identity $groupSettingId -Values @{\"AllowToAddGuests\"=\"true\"} -Group $groupId", - "Id": 1446, "CommandName": "Set-PnPMicrosoft365GroupSettings", + "Command": "Set-PnPMicrosoft365GroupSettings -Identity $groupSettingId -Values @{\"AllowToAddGuests\"=\"true\"} -Group $groupId", + "Id": 1461, "Rank": 2 }, { - "Command": "Set-PnPMinimalDownloadStrategy -Off", - "Id": 1447, "CommandName": "Set-PnPMinimalDownloadStrategy", + "Command": "Set-PnPMinimalDownloadStrategy -Off", + "Id": 1462, "Rank": 1 }, { - "Command": "Set-PnPMinimalDownloadStrategy -On", - "Id": 1448, "CommandName": "Set-PnPMinimalDownloadStrategy", + "Command": "Set-PnPMinimalDownloadStrategy -On", + "Id": 1463, "Rank": 2 }, { - "Command": "Set-PnPPage -Identity \"MyPage\" -LayoutType Home -Title \"My Page\"", - "Id": 1449, "CommandName": "Set-PnPPage", + "Command": "Set-PnPPage -Identity \"MyPage\" -LayoutType Home -Title \"My Page\"", + "Id": 1464, "Rank": 1 }, { - "Command": "Set-PnPPage -Identity \"MyPage\" -CommentsEnabled", - "Id": 1450, "CommandName": "Set-PnPPage", + "Command": "Set-PnPPage -Identity \"MyPage\" -CommentsEnabled", + "Id": 1465, "Rank": 2 }, { - "Command": "Set-PnPPage -Identity \"MyPage\" -CommentsEnabled:$false", - "Id": 1451, "CommandName": "Set-PnPPage", + "Command": "Set-PnPPage -Identity \"MyPage\" -CommentsEnabled:$false", + "Id": 1466, "Rank": 3 }, { - "Command": "Set-PnPPage -Identity \"hr/MyPage\" -HeaderType Default", - "Id": 1452, "CommandName": "Set-PnPPage", + "Command": "Set-PnPPage -Identity \"hr/MyPage\" -HeaderType Default", + "Id": 1467, "Rank": 4 }, { - "Command": "Set-PnPPage -Identity \"MyPage\" -HeaderType None", - "Id": 1453, "CommandName": "Set-PnPPage", + "Command": "Set-PnPPage -Identity \"MyPage\" -HeaderType None", + "Id": 1468, "Rank": 5 }, { - "Command": "Set-PnPPage -Identity \"MyPage\" -HeaderType Custom -ServerRelativeImageUrl \"/sites/demo1/assets/myimage.png\" -TranslateX 10.5 -TranslateY 11.0", - "Id": 1454, "CommandName": "Set-PnPPage", + "Command": "Set-PnPPage -Identity \"MyPage\" -HeaderType Custom -ServerRelativeImageUrl \"/sites/demo1/assets/myimage.png\" -TranslateX 10.5 -TranslateY 11.0", + "Id": 1469, "Rank": 6 }, { - "Command": "Set-PnPPage -Identity \"MyPage\" -ScheduledPublishDate (Get-Date).AddHours(1)", - "Id": 1455, "CommandName": "Set-PnPPage", + "Command": "Set-PnPPage -Identity \"MyPage\" -ScheduledPublishDate (Get-Date).AddHours(1)", + "Id": 1470, "Rank": 7 }, { - "Command": "Set-PnPPage -Identity \"MyPage\" -Translate", - "Id": 1456, "CommandName": "Set-PnPPage", + "Command": "Set-PnPPage -Identity \"MyPage\" -Translate", + "Id": 1471, "Rank": 8 }, { - "Command": "Set-PnPPage -Identity \"MyPage\" -Translate -TranslationLanguageCodes 1043", - "Id": 1457, "CommandName": "Set-PnPPage", + "Command": "Set-PnPPage -Identity \"MyPage\" -Translate -TranslationLanguageCodes 1043", + "Id": 1472, "Rank": 9 }, { - "Command": "Set-PnPPage -Identity \"MyPage\" -Translate -TranslationLanguageCodes 1043,1035", - "Id": 1458, "CommandName": "Set-PnPPage", + "Command": "Set-PnPPage -Identity \"MyPage\" -Translate -TranslationLanguageCodes 1043,1035", + "Id": 1473, "Rank": 10 }, { - "Command": "Set-PnPPage -Identity \"MyPage\" -ShowPublishDate $true -Publish", - "Id": 1459, "CommandName": "Set-PnPPage", + "Command": "Set-PnPPage -Identity \"MyPage\" -ShowPublishDate $true -Publish", + "Id": 1474, "Rank": 11 }, { - "Command": "Set-PnPPage -Identity \"MyPage.aspx\" -Like", - "Id": 1460, "CommandName": "Set-PnPPage", + "Command": "Set-PnPPage -Identity \"MyPage.aspx\" -Like", + "Id": 1475, "Rank": 12 }, { - "Command": "Set-PnPPage -Identity \"MyPage.aspx\" -Like:$false", - "Id": 1461, "CommandName": "Set-PnPPage", + "Command": "Set-PnPPage -Identity \"MyPage.aspx\" -Like:$false", + "Id": 1476, "Rank": 13 }, { - "Command": "Set-PnPPageTextPart -Page Home -InstanceId a2875399-d6ff-43a0-96da-be6ae5875f82 -Text \"MyText\"", - "Id": 1462, "CommandName": "Set-PnPPageTextPart", + "Command": "Set-PnPPageTextPart -Page Home -InstanceId a2875399-d6ff-43a0-96da-be6ae5875f82 -Text \"MyText\"", + "Id": 1477, "Rank": 1 }, { - "Command": "Set-PnPPageWebPart -Page Home -Identity a2875399-d6ff-43a0-96da-be6ae5875f82 -PropertiesJson \"`\"Property1`\"=`\"Value1`\"\"", - "Id": 1463, "CommandName": "Set-PnPPageWebPart", + "Command": "Set-PnPPageWebPart -Page Home -Identity a2875399-d6ff-43a0-96da-be6ae5875f82 -PropertiesJson \"`\"Property1`\"=`\"Value1`\"\"", + "Id": 1478, "Rank": 1 }, { - "Command": "Set-PnPPageWebPart -Page Home -Identity a2875399-d6ff-43a0-96da-be6ae5875f82 -PropertiesJson $myproperties", - "Id": 1464, "CommandName": "Set-PnPPageWebPart", + "Command": "Set-PnPPageWebPart -Page Home -Identity a2875399-d6ff-43a0-96da-be6ae5875f82 -PropertiesJson $myproperties", + "Id": 1479, "Rank": 2 }, { - "Command": "Set-PnPPlannerBucket -Bucket \"Todos\" -Group \"Marketing\" -Plan \"Conference Plan\" -Name \"Pre-conf Todos\"", - "Id": 1465, "CommandName": "Set-PnPPlannerBucket", + "Command": "Set-PnPPlannerBucket -Bucket \"Todos\" -Group \"Marketing\" -Plan \"Conference Plan\" -Name \"Pre-conf Todos\"", + "Id": 1480, "Rank": 1 }, { - "Command": "Set-PnPPlannerConfiguration -AllowRosterCreation:$false -IsPlannerAllowed:$true", - "Id": 1466, "CommandName": "Set-PnPPlannerConfiguration", + "Command": "Set-PnPPlannerConfiguration -AllowRosterCreation:$false -IsPlannerAllowed:$true", + "Id": 1481, "Rank": 1 }, { - "Command": "Set-PnPPlannerConfiguration -AllowPlannerMobilePushNotifications $false", - "Id": 1467, "CommandName": "Set-PnPPlannerConfiguration", + "Command": "Set-PnPPlannerConfiguration -AllowPlannerMobilePushNotifications $false", + "Id": 1482, "Rank": 2 }, { - "Command": "Set-PnPPlannerPlan -Group \"Marketing\" -Plan \"Conference\" -Title \"Conference 2020\"", - "Id": 1468, "CommandName": "Set-PnPPlannerPlan", + "Command": "Set-PnPPlannerPlan -Group \"Marketing\" -Plan \"Conference\" -Title \"Conference 2020\"", + "Id": 1483, "Rank": 1 }, { - "Command": "Set-PnPPlannerTask -TaskId RSNNbc4HM0e7jt-btAKtTZYAFAf0 -Title \"New Title\" -StartDateTime 2020-10-01", - "Id": 1469, "CommandName": "Set-PnPPlannerTask", + "Command": "Set-PnPPlannerTask -TaskId RSNNbc4HM0e7jt-btAKtTZYAFAf0 -Title \"New Title\" -StartDateTime 2020-10-01", + "Id": 1484, "Rank": 1 }, { - "Command": "Set-PnPPlannerTask -TaskId RSNNbc4HM0e7jt-btAKtTZYAFAf0 -Title \"New Title\" -Bucket \"To do\"", - "Id": 1470, "CommandName": "Set-PnPPlannerTask", + "Command": "Set-PnPPlannerTask -TaskId RSNNbc4HM0e7jt-btAKtTZYAFAf0 -Title \"New Title\" -Bucket \"To do\"", + "Id": 1485, "Rank": 2 }, { - "Command": "Set-PnPPlannerTask -TaskId RSNNbc4HM0e7jt-btAKtTZYAFAf0 -AssignedTo \"user@contoso.com\",\"manager@contoso.com\"", - "Id": 1471, "CommandName": "Set-PnPPlannerTask", + "Command": "Set-PnPPlannerTask -TaskId RSNNbc4HM0e7jt-btAKtTZYAFAf0 -AssignedTo \"user@contoso.com\",\"manager@contoso.com\"", + "Id": 1486, "Rank": 3 }, { - "Command": "Set-PnPPlannerUserPolicy -Identity \"johndoe@contoso.onmicrosoft.com\"", - "Id": 1472, "CommandName": "Set-PnPPlannerUserPolicy", + "Command": "Set-PnPPlannerUserPolicy -Identity \"johndoe@contoso.onmicrosoft.com\"", + "Id": 1487, "Rank": 1 }, { - "Command": "Set-PnPPropertyBagValue -Key MyKey -Value MyValue", - "Id": 1473, "CommandName": "Set-PnPPropertyBagValue", + "Command": "Set-PnPPropertyBagValue -Key MyKey -Value MyValue", + "Id": 1488, "Rank": 1 }, { - "Command": "Set-PnPPropertyBagValue -Key MyKey -Value MyValue -Folder /", - "Id": 1474, "CommandName": "Set-PnPPropertyBagValue", + "Command": "Set-PnPPropertyBagValue -Key MyKey -Value MyValue -Folder /", + "Id": 1489, "Rank": 2 }, { - "Command": "Set-PnPPropertyBagValue -Key MyKey -Value MyValue -Folder /MyFolder", - "Id": 1475, "CommandName": "Set-PnPPropertyBagValue", + "Command": "Set-PnPPropertyBagValue -Key MyKey -Value MyValue -Folder /MyFolder", + "Id": 1490, "Rank": 3 }, { - "Command": "Set-PnPRequestAccessEmails -Emails someone@example.com", - "Id": 1476, "CommandName": "Set-PnPRequestAccessEmails", + "Command": "Set-PnPRequestAccessEmails -Emails someone@example.com", + "Id": 1491, "Rank": 1 }, { - "Command": "Set-PnPRequestAccessEmails -Disabled", - "Id": 1477, "CommandName": "Set-PnPRequestAccessEmails", + "Command": "Set-PnPRequestAccessEmails -Disabled", + "Id": 1492, "Rank": 2 }, { - "Command": "Set-PnPRequestAccessEmails -Disabled:$false", - "Id": 1478, "CommandName": "Set-PnPRequestAccessEmails", + "Command": "Set-PnPRequestAccessEmails -Disabled:$false", + "Id": 1493, "Rank": 3 }, { - "Command": "Set-PnPRetentionLabel -List \"Demo List\" -Label \"Project Documentation\"", - "Id": 1479, "CommandName": "Set-PnPRetentionLabel", + "Command": "Set-PnPRetentionLabel -List \"Demo List\" -Label \"Project Documentation\"", + "Id": 1494, "Rank": 1 }, { - "Command": "Set-PnPRetentionLabel -List \"Demo List\" -Label \"Project Documentation\" -SyncToItems $true", - "Id": 1480, "CommandName": "Set-PnPRetentionLabel", + "Command": "Set-PnPRetentionLabel -List \"Demo List\" -Label \"Project Documentation\" -SyncToItems $true", + "Id": 1495, "Rank": 2 }, { - "Command": "Set-PnPRetentionLabel -List \"Demo List\" -ItemIds @(1,2,3) -Label \"My demo label\"", - "Id": 1481, "CommandName": "Set-PnPRetentionLabel", + "Command": "Set-PnPRetentionLabel -List \"Demo List\" -ItemIds @(1,2,3) -Label \"My demo label\"", + "Id": 1496, "Rank": 3 }, { - "Command": "Set-PnPRoleDefinition -Identity \"CustomPerm\" -Clear EditListItems", - "Id": 1482, "CommandName": "Set-PnPRoleDefinition", + "Command": "Set-PnPRoleDefinition -Identity \"CustomPerm\" -Clear EditListItems", + "Id": 1497, "Rank": 1 }, { - "Command": "Set-PnPRoleDefinition -Identity \"NoDelete\" -SelectAll -Clear DeleteListItems", - "Id": 1483, "CommandName": "Set-PnPRoleDefinition", + "Command": "Set-PnPRoleDefinition -Identity \"NoDelete\" -SelectAll -Clear DeleteListItems", + "Id": 1498, "Rank": 2 }, { - "Command": "Set-PnPRoleDefinition -Identity \"CustomPerm\" -NewRoleName \"NoDelete\" -Description \"Contribute without delete\"", - "Id": 1484, "CommandName": "Set-PnPRoleDefinition", + "Command": "Set-PnPRoleDefinition -Identity \"CustomPerm\" -NewRoleName \"NoDelete\" -Description \"Contribute without delete\"", + "Id": 1499, "Rank": 3 }, { - "Command": "Set-PnPRoleDefinition -Identity \"CustomPerm\" -Order 500", - "Id": 1485, "CommandName": "Set-PnPRoleDefinition", + "Command": "Set-PnPRoleDefinition -Identity \"CustomPerm\" -Order 500", + "Id": 1500, "Rank": 4 }, { - "Command": "Set-PnPSearchConfiguration -Configuration $config", - "Id": 1486, "CommandName": "Set-PnPSearchConfiguration", + "Command": "Set-PnPSearchConfiguration -Configuration $config", + "Id": 1501, "Rank": 1 }, { - "Command": "Set-PnPSearchConfiguration -Configuration $config -Scope Site", - "Id": 1487, "CommandName": "Set-PnPSearchConfiguration", + "Command": "Set-PnPSearchConfiguration -Configuration $config -Scope Site", + "Id": 1502, "Rank": 2 }, { - "Command": "Set-PnPSearchConfiguration -Configuration $config -Scope Subscription", - "Id": 1488, "CommandName": "Set-PnPSearchConfiguration", + "Command": "Set-PnPSearchConfiguration -Configuration $config -Scope Subscription", + "Id": 1503, "Rank": 3 }, { - "Command": "Set-PnPSearchConfiguration -Path searchconfig.xml -Scope Subscription", - "Id": 1489, "CommandName": "Set-PnPSearchConfiguration", + "Command": "Set-PnPSearchConfiguration -Path searchconfig.xml -Scope Subscription", + "Id": 1504, "Rank": 4 }, { - "Command": "Set-PnPSearchExternalItem -ConnectionId \"pnppowershell\" -ItemId \"12345\" -Properties @{ \"Test1\"= \"Test of this PnP PowerShell Connector\"; \"Test2\" = \"Red\",\"Blue\"; \"Test3\" = ([System.DateTime]::Now)} -ContentValue \"Sample value\" -ContentType Text -GrantEveryone", - "Id": 1490, + "CommandName": "Set-PnPSearchExternalConnection", + "Command": "Set-PnPSearchExternalConnection -Identity \"pnppowershell\" -Name \"PnP PowerShell Rocks\"", + "Id": 1505, + "Rank": 1 + }, + { + "CommandName": "Set-PnPSearchExternalConnection", + "Command": "Set-PnPSearchExternalConnection -Identity \"pnppowershell\" -Name \"PnP PowerShell Rocks\" -Description \"External content ingested using PnP PowerShell which rocks\"", + "Id": 1506, + "Rank": 2 + }, + { + "CommandName": "Set-PnPSearchExternalConnection", + "Command": "Set-PnPSearchExternalConnection -Identity \"pnppowershell\" -AuthorizedAppIds \"00000000-0000-0000-0000-000000000000\",\"11111111-1111-1111-1111-111111111111\"", + "Id": 1507, + "Rank": 3 + }, + { "CommandName": "Set-PnPSearchExternalItem", + "Command": "Set-PnPSearchExternalItem -ConnectionId \"pnppowershell\" -ItemId \"12345\" -Properties @{ \"Test1\"= \"Test of this PnP PowerShell Connector\"; \"Test2\" = \"Red\",\"Blue\"; \"Test3\" = ([System.DateTime]::Now)} -ContentValue \"Sample value\" -ContentType Text -GrantEveryone", + "Id": 1508, "Rank": 1 }, { - "Command": "Set-PnPSearchExternalItem -ConnectionId \"pnppowershell\" -ItemId \"12345\" -Properties @{ \"Test1\"= \"Test of this PnP PowerShell Connector\"; \"Test2\" = \"Red\",\"Blue\"; \"Test3\" = ([System.DateTime]::Now)} -ContentValue \"Sample value\" -ContentType Text -GrantUsers \"user@contoso.onmicrosoft.com\"", - "Id": 1491, "CommandName": "Set-PnPSearchExternalItem", + "Command": "Set-PnPSearchExternalItem -ConnectionId \"pnppowershell\" -ItemId \"12345\" -Properties @{ \"Test1\"= \"Test of this PnP PowerShell Connector\"; \"Test2\" = \"Red\",\"Blue\"; \"Test3\" = ([System.DateTime]::Now)} -ContentValue \"Sample value\" -ContentType Text -GrantUsers \"user@contoso.onmicrosoft.com\"", + "Id": 1509, "Rank": 2 }, { - "Command": "Set-PnPSearchSettings -SearchBoxInNavBar Hidden -Scope Site", - "Id": 1492, + "CommandName": "Set-PnPSearchExternalSchema", + "Command": "Set-PnPSearchExternalSchema -ConnectionId \"pnppowershell\" -SchemaAsText '{\r ; \"baseType\": \"microsoft.graph.externalItem\",\r ; \"properties\": [\r ; {\r ; \"name\": \"ticketTitle\",\r ; \"type\": \"String\",\r ; \"isSearchable\": \"true\",\r ; \"isRetrievable\": \"true\",\r ; \"labels\": [\r ; \"title\"\r ; ]\r ; },\r ; {\r ; \"name\": \"priority\",\r ; \"type\": \"String\",\r ; \"isQueryable\": \"true\",\r ; \"isRetrievable\": \"true\",\r ; \"isSearchable\": \"false\"\r ; },\r ; {\r ; \"name\": \"assignee\",\r ; \"type\": \"String\",\r ; \"isRetrievable\": \"true\"\r ; }\r ; ]\r ; }'", + "Id": 1510, + "Rank": 1 + }, + { "CommandName": "Set-PnPSearchSettings", + "Command": "Set-PnPSearchSettings -SearchBoxInNavBar Hidden -Scope Site", + "Id": 1511, "Rank": 1 }, { - "Command": "Set-PnPSearchSettings -SearchBoxInNavBar Hidden -Scope Web", - "Id": 1493, "CommandName": "Set-PnPSearchSettings", + "Command": "Set-PnPSearchSettings -SearchBoxInNavBar Hidden -Scope Web", + "Id": 1512, "Rank": 2 }, { - "Command": "Set-PnPSearchSettings -SearchPageUrl \"https://contoso.sharepoint.com/sites/mysearch/SitePages/search.aspx\"", - "Id": 1494, "CommandName": "Set-PnPSearchSettings", + "Command": "Set-PnPSearchSettings -SearchPageUrl \"https://contoso.sharepoint.com/sites/mysearch/SitePages/search.aspx\"", + "Id": 1513, "Rank": 3 }, { - "Command": "Set-PnPSearchSettings -SearchPageUrl \"\"", - "Id": 1495, "CommandName": "Set-PnPSearchSettings", + "Command": "Set-PnPSearchSettings -SearchPageUrl \"\"", + "Id": 1514, "Rank": 4 }, { - "Command": "Set-PnPSearchSettings -SearchPageUrl \"https://contoso.sharepoint.com/sites/mysearch/SitePages/search.aspx\" -Scope Site", - "Id": 1496, "CommandName": "Set-PnPSearchSettings", + "Command": "Set-PnPSearchSettings -SearchPageUrl \"https://contoso.sharepoint.com/sites/mysearch/SitePages/search.aspx\" -Scope Site", + "Id": 1515, "Rank": 5 }, { - "Command": "Set-PnPSearchSettings -SearchScope Tenant", - "Id": 1497, "CommandName": "Set-PnPSearchSettings", + "Command": "Set-PnPSearchSettings -SearchScope Tenant", + "Id": 1516, "Rank": 6 }, { - "Command": "Set-PnPSearchSettings -SearchScope Hub", - "Id": 1498, "CommandName": "Set-PnPSearchSettings", + "Command": "Set-PnPSearchSettings -SearchScope Hub", + "Id": 1517, "Rank": 7 }, { - "Command": "Set-PnPSite -Classification \"HBI\"", - "Id": 1499, "CommandName": "Set-PnPSite", + "Command": "Set-PnPSite -Classification \"HBI\"", + "Id": 1518, "Rank": 1 }, { - "Command": "Set-PnPSite -Classification $null", - "Id": 1500, "CommandName": "Set-PnPSite", + "Command": "Set-PnPSite -Classification $null", + "Id": 1519, "Rank": 2 }, { - "Command": "Set-PnPSite -DisableFlows", - "Id": 1501, "CommandName": "Set-PnPSite", + "Command": "Set-PnPSite -DisableFlows", + "Id": 1520, "Rank": 3 }, { - "Command": "Set-PnPSite -DisableFlows:$false", - "Id": 1502, "CommandName": "Set-PnPSite", + "Command": "Set-PnPSite -DisableFlows:$false", + "Id": 1521, "Rank": 4 }, { - "Command": "Set-PnPSite -LogoFilePath c:\\images\\mylogo.png", - "Id": 1503, "CommandName": "Set-PnPSite", + "Command": "Set-PnPSite -LogoFilePath c:\\images\\mylogo.png", + "Id": 1522, "Rank": 5 }, { - "Command": "Set-PnPSite -NoScriptSite $false", - "Id": 1504, "CommandName": "Set-PnPSite", + "Command": "Set-PnPSite -NoScriptSite $false", + "Id": 1523, "Rank": 6 }, { - "Command": "Set-PnPSiteArchiveState https://contoso.sharepoint.com/sites/Marketing -ArchiveState Archived", - "Id": 1505, "CommandName": "Set-PnPSiteArchiveState", + "Command": "Set-PnPSiteArchiveState https://contoso.sharepoint.com/sites/Marketing -ArchiveState Archived", + "Id": 1524, "Rank": 1 }, { - "Command": "Set-PnPSiteArchiveState https://contoso.sharepoint.com/sites/Marketing -ArchiveState Active", - "Id": 1506, "CommandName": "Set-PnPSiteArchiveState", + "Command": "Set-PnPSiteArchiveState https://contoso.sharepoint.com/sites/Marketing -ArchiveState Active", + "Id": 1525, "Rank": 2 }, { - "Command": "Set-PnPSiteClassification -Identity \"LBI\"", - "Id": 1507, "CommandName": "Set-PnPSiteClassification", + "Command": "Set-PnPSiteClassification -Identity \"LBI\"", + "Id": 1526, "Rank": 1 }, { - "Command": "Set-PnPSiteClosure -State Open", - "Id": 1508, "CommandName": "Set-PnPSiteClosure", + "Command": "Set-PnPSiteClosure -State Open", + "Id": 1527, "Rank": 1 }, { - "Command": "Set-PnPSiteClosure -State Closed", - "Id": 1509, "CommandName": "Set-PnPSiteClosure", + "Command": "Set-PnPSiteClosure -State Closed", + "Id": 1528, "Rank": 2 }, { - "Command": "Set-PnPSiteDesign -Identity 046e2e76-67ba-46ca-a5f6-8eb418a7821e -Title \"My Updated Company Design\"", - "Id": 1510, "CommandName": "Set-PnPSiteDesign", + "Command": "Set-PnPSiteDesign -Identity 046e2e76-67ba-46ca-a5f6-8eb418a7821e -Title \"My Updated Company Design\"", + "Id": 1529, "Rank": 1 }, { - "Command": "Set-PnPSiteDesign -Identity 046e2e76-67ba-46ca-a5f6-8eb418a7821e -Title \"My Company Design\" -Description \"My description\" -ThumbnailUrl \"https://contoso.sharepoint.com/sites/templates/my images/logo.png\"", - "Id": 1511, "CommandName": "Set-PnPSiteDesign", + "Command": "Set-PnPSiteDesign -Identity 046e2e76-67ba-46ca-a5f6-8eb418a7821e -Title \"My Company Design\" -Description \"My description\" -ThumbnailUrl \"https://contoso.sharepoint.com/sites/templates/my images/logo.png\"", + "Id": 1530, "Rank": 2 }, { - "Command": "Set-PnPSiteGroup -Site \"https://contoso.sharepoint.com/sites/siteA\" -Identity \"ProjectViewers\" -PermissionLevelsToRemove \"Full Control\" -PermissionLevelsToAdd \"View Only\"", - "Id": 1512, "CommandName": "Set-PnPSiteGroup", + "Command": "Set-PnPSiteGroup -Site \"https://contoso.sharepoint.com/sites/siteA\" -Identity \"ProjectViewers\" -PermissionLevelsToRemove \"Full Control\" -PermissionLevelsToAdd \"View Only\"", + "Id": 1531, "Rank": 1 }, { - "Command": "Set-PnPSiteGroup -Site \"https://contoso.sharepoint.com\" -Identity \"ProjectViewers\" -Owner user@domain.com", - "Id": 1513, "CommandName": "Set-PnPSiteGroup", + "Command": "Set-PnPSiteGroup -Site \"https://contoso.sharepoint.com\" -Identity \"ProjectViewers\" -Owner user@domain.com", + "Id": 1532, "Rank": 2 }, { - "Command": "Set-PnPSitePolicy -Name \"Contoso HBI\"", - "Id": 1514, "CommandName": "Set-PnPSitePolicy", + "Command": "Set-PnPSitePolicy -Name \"Contoso HBI\"", + "Id": 1533, "Rank": 1 }, { - "Command": "Set-PnPSiteScript -Identity f1d55d9b-b116-4f54-bc00-164a51e7e47f -Title \"My Site Script\"", - "Id": 1515, "CommandName": "Set-PnPSiteScript", + "Command": "Set-PnPSiteScript -Identity f1d55d9b-b116-4f54-bc00-164a51e7e47f -Title \"My Site Script\"", + "Id": 1534, "Rank": 1 }, { - "Command": "Set-PnPSiteScriptPackage -Identity f1d55d9b-b116-4f54-bc00-164a51e7e47f -Title \"My Site Script\"", - "Id": 1516, "CommandName": "Set-PnPSiteScriptPackage", + "Command": "Set-PnPSiteScriptPackage -Identity f1d55d9b-b116-4f54-bc00-164a51e7e47f -Title \"My Site Script\"", + "Id": 1535, "Rank": 1 }, { - "Command": "Set-PnPSiteSensitivityLabel -Identity \"Top Secret\"", - "Id": 1517, "CommandName": "Set-PnPSiteSensitivityLabel", + "Command": "Set-PnPSiteSensitivityLabel -Identity \"Top Secret\"", + "Id": 1536, "Rank": 1 }, { - "Command": "Set-PnPSiteSensitivityLabel -Identity a1888df2-84c2-4379-8d53-7091dd630ca7", - "Id": 1518, "CommandName": "Set-PnPSiteSensitivityLabel", + "Command": "Set-PnPSiteSensitivityLabel -Identity a1888df2-84c2-4379-8d53-7091dd630ca7", + "Id": 1537, "Rank": 2 }, { - "Command": "Set-PnPSiteTemplateMetadata -Path template.xml -TemplateDisplayName \"DisplayNameValue\"", - "Id": 1519, "CommandName": "Set-PnPSiteTemplateMetadata", + "Command": "Set-PnPSiteTemplateMetadata -Path template.xml -TemplateDisplayName \"DisplayNameValue\"", + "Id": 1538, "Rank": 1 }, { - "Command": "Set-PnPSiteTemplateMetadata -Path template.pnp -TemplateDisplayName \"DisplayNameValue\"", - "Id": 1520, "CommandName": "Set-PnPSiteTemplateMetadata", + "Command": "Set-PnPSiteTemplateMetadata -Path template.pnp -TemplateDisplayName \"DisplayNameValue\"", + "Id": 1539, "Rank": 2 }, { - "Command": "Set-PnPSiteTemplateMetadata -Path template.xml -TemplateImagePreviewUrl \"Full URL of the Image Preview\"", - "Id": 1521, "CommandName": "Set-PnPSiteTemplateMetadata", + "Command": "Set-PnPSiteTemplateMetadata -Path template.xml -TemplateImagePreviewUrl \"Full URL of the Image Preview\"", + "Id": 1540, "Rank": 3 }, { - "Command": "Set-PnPSiteTemplateMetadata -Path template.pnp -TemplateImagePreviewUrl \"Full URL of the Image Preview\"", - "Id": 1522, "CommandName": "Set-PnPSiteTemplateMetadata", + "Command": "Set-PnPSiteTemplateMetadata -Path template.pnp -TemplateImagePreviewUrl \"Full URL of the Image Preview\"", + "Id": 1541, "Rank": 4 }, { - "Command": "Set-PnPSiteTemplateMetadata -Path template.xml -TemplateProperties @{\"Property1\" = \"Test Value 1\"; \"Property2\"=\"Test Value 2\"}", - "Id": 1523, "CommandName": "Set-PnPSiteTemplateMetadata", + "Command": "Set-PnPSiteTemplateMetadata -Path template.xml -TemplateProperties @{\"Property1\" = \"Test Value 1\"; \"Property2\"=\"Test Value 2\"}", + "Id": 1542, "Rank": 5 }, { - "Command": "Set-PnPSiteTemplateMetadata -Path template.pnp -TemplateProperties @{\"Property1\" = \"Test Value 1\"; \"Property2\"=\"Test Value 2\"}", - "Id": 1524, "CommandName": "Set-PnPSiteTemplateMetadata", + "Command": "Set-PnPSiteTemplateMetadata -Path template.pnp -TemplateProperties @{\"Property1\" = \"Test Value 1\"; \"Property2\"=\"Test Value 2\"}", + "Id": 1543, "Rank": 6 }, { - "Command": "Set-PnPSiteVersionPolicy -EnableAutoExpirationVersionTrim $true", - "Id": 1525, "CommandName": "Set-PnPSiteVersionPolicy", + "Command": "Set-PnPSiteVersionPolicy -EnableAutoExpirationVersionTrim $true", + "Id": 1544, "Rank": 1 }, { - "Command": "Set-PnPSiteVersionPolicy -EnableAutoExpirationVersionTrim $false -MajorVersions 100 -MajorWithMinorVersions 10 -ExpireVersionsAfterDays 200", - "Id": 1526, "CommandName": "Set-PnPSiteVersionPolicy", + "Command": "Set-PnPSiteVersionPolicy -EnableAutoExpirationVersionTrim $false -MajorVersions 100 -MajorWithMinorVersions 10 -ExpireVersionsAfterDays 200", + "Id": 1545, "Rank": 2 }, { - "Command": "Set-PnPSiteVersionPolicy -EnableAutoExpirationVersionTrim $false -MajorVersions 300 -MajorWithMinorVersions 20 -ExpireVersionsAfterDays 0", - "Id": 1527, "CommandName": "Set-PnPSiteVersionPolicy", + "Command": "Set-PnPSiteVersionPolicy -EnableAutoExpirationVersionTrim $false -MajorVersions 300 -MajorWithMinorVersions 20 -ExpireVersionsAfterDays 0", + "Id": 1546, "Rank": 3 }, { - "Command": "Set-PnPSiteVersionPolicy -InheritFromTenant", - "Id": 1528, "CommandName": "Set-PnPSiteVersionPolicy", + "Command": "Set-PnPSiteVersionPolicy -InheritFromTenant", + "Id": 1547, "Rank": 4 }, { - "Command": "Set-PnPSiteVersionPolicy -EnableAutoExpirationVersionTrim $true -ApplyToNewDocumentLibraries", - "Id": 1529, "CommandName": "Set-PnPSiteVersionPolicy", + "Command": "Set-PnPSiteVersionPolicy -EnableAutoExpirationVersionTrim $true -ApplyToNewDocumentLibraries", + "Id": 1548, "Rank": 5 }, { - "Command": "Set-PnPSiteVersionPolicy -EnableAutoExpirationVersionTrim $false -MajorVersions 100 -ExpireVersionsAfterDays 200 -ApplyToNewDocumentLibraries", - "Id": 1530, "CommandName": "Set-PnPSiteVersionPolicy", + "Command": "Set-PnPSiteVersionPolicy -EnableAutoExpirationVersionTrim $false -MajorVersions 100 -ExpireVersionsAfterDays 200 -ApplyToNewDocumentLibraries", + "Id": 1549, "Rank": 6 }, { - "Command": "Set-PnPSiteVersionPolicy -EnableAutoExpirationVersionTrim $false -MajorVersions 300 -ExpireVersionsAfterDays 0 -ApplyToNewDocumentLibraries", - "Id": 1531, "CommandName": "Set-PnPSiteVersionPolicy", + "Command": "Set-PnPSiteVersionPolicy -EnableAutoExpirationVersionTrim $false -MajorVersions 300 -ExpireVersionsAfterDays 0 -ApplyToNewDocumentLibraries", + "Id": 1550, "Rank": 7 }, { - "Command": "Set-PnPSiteVersionPolicy -EnableAutoExpirationVersionTrim $true -ApplyToExistingDocumentLibraries", - "Id": 1532, "CommandName": "Set-PnPSiteVersionPolicy", + "Command": "Set-PnPSiteVersionPolicy -EnableAutoExpirationVersionTrim $true -ApplyToExistingDocumentLibraries", + "Id": 1551, "Rank": 8 }, { - "Command": "Set-PnPSiteVersionPolicy -EnableAutoExpirationVersionTrim $false -MajorVersions 100 -MajorWithMinorVersions 5 -ExpireVersionsAfterDays 200 -ApplyToExistingDocumentLibraries", - "Id": 1533, "CommandName": "Set-PnPSiteVersionPolicy", + "Command": "Set-PnPSiteVersionPolicy -EnableAutoExpirationVersionTrim $false -MajorVersions 100 -MajorWithMinorVersions 5 -ExpireVersionsAfterDays 200 -ApplyToExistingDocumentLibraries", + "Id": 1552, "Rank": 9 }, { - "Command": "Set-PnPSiteVersionPolicy -EnableAutoExpirationVersionTrim $false -MajorVersions 100 -MajorWithMinorVersions 5 -ExpireVersionsAfterDays 0 -ApplyToExistingDocumentLibraries", - "Id": 1534, "CommandName": "Set-PnPSiteVersionPolicy", + "Command": "Set-PnPSiteVersionPolicy -EnableAutoExpirationVersionTrim $false -MajorVersions 100 -MajorWithMinorVersions 5 -ExpireVersionsAfterDays 0 -ApplyToExistingDocumentLibraries", + "Id": 1553, "Rank": 10 }, { - "Command": "Set-PnPSiteVersionPolicy -CancelForExistingDocumentLibraries", - "Id": 1535, "CommandName": "Set-PnPSiteVersionPolicy", + "Command": "Set-PnPSiteVersionPolicy -CancelForExistingDocumentLibraries", + "Id": 1554, "Rank": 11 }, - { - "Command": "Set-PnPStorageEntity -Key MyKey -Value \"MyValue\" -Comment \"My Comment\" -Description \"My Description\"", - "Id": 1536, + { "CommandName": "Set-PnPStorageEntity", + "Command": "Set-PnPStorageEntity -Key MyKey -Value \"MyValue\" -Comment \"My Comment\" -Description \"My Description\"", + "Id": 1555, "Rank": 1 }, { - "Command": "Set-PnPStorageEntity -Scope Site -Key MyKey -Value \"MyValue\" -Comment \"My Comment\" -Description \"My Description\"", - "Id": 1537, "CommandName": "Set-PnPStorageEntity", + "Command": "Set-PnPStorageEntity -Scope Site -Key MyKey -Value \"MyValue\" -Comment \"My Comment\" -Description \"My Description\"", + "Id": 1556, "Rank": 2 }, { - "Command": "Set-PnPStructuralNavigationCacheSiteState -IsEnabled $true -SiteUrl \"https://contoso.sharepoint.com/sites/product/\"", - "Id": 1538, "CommandName": "Set-PnPStructuralNavigationCacheSiteState", + "Command": "Set-PnPStructuralNavigationCacheSiteState -IsEnabled $true -SiteUrl \"https://contoso.sharepoint.com/sites/product/\"", + "Id": 1557, "Rank": 1 }, { - "Command": "Set-PnPStructuralNavigationCacheSiteState -IsEnabled $false -SiteUrl \"https://contoso.sharepoint.com/sites/product/\"", - "Id": 1539, "CommandName": "Set-PnPStructuralNavigationCacheSiteState", + "Command": "Set-PnPStructuralNavigationCacheSiteState -IsEnabled $false -SiteUrl \"https://contoso.sharepoint.com/sites/product/\"", + "Id": 1558, "Rank": 2 }, { - "Command": "Set-PnPStructuralNavigationCacheWebState -IsEnabled $true -WebUrl \"https://contoso.sharepoint.com/sites/product/electronics\"", - "Id": 1540, "CommandName": "Set-PnPStructuralNavigationCacheWebState", + "Command": "Set-PnPStructuralNavigationCacheWebState -IsEnabled $true -WebUrl \"https://contoso.sharepoint.com/sites/product/electronics\"", + "Id": 1559, "Rank": 1 }, { - "Command": "Set-PnPStructuralNavigationCacheWebState -IsEnabled $false -WebUrl \"https://contoso.sharepoint.com/sites/product/electronics\"", - "Id": 1541, "CommandName": "Set-PnPStructuralNavigationCacheWebState", + "Command": "Set-PnPStructuralNavigationCacheWebState -IsEnabled $false -WebUrl \"https://contoso.sharepoint.com/sites/product/electronics\"", + "Id": 1560, "Rank": 2 }, { - "Command": "Set-PnPSubscribeSharePointNewsDigest -Account 'user@domain.com' -Enabled:$true", - "Id": 1542, "CommandName": "Set-PnPSubscribeSharePointNewsDigest", + "Command": "Set-PnPSubscribeSharePointNewsDigest -Account 'user@domain.com' -Enabled:$true", + "Id": 1561, "Rank": 1 }, { - "Command": "Set-PnPSubscribeSharePointNewsDigest -Account 'user@domain.com' -Enabled:$false", - "Id": 1543, "CommandName": "Set-PnPSubscribeSharePointNewsDigest", + "Command": "Set-PnPSubscribeSharePointNewsDigest -Account 'user@domain.com' -Enabled:$false", + "Id": 1562, "Rank": 2 }, { - "Command": "Set-PnPTaxonomyFieldValue -ListItem $item -InternalFieldName 'Department' -TermId 863b832b-6818-4e6a-966d-2d3ee057931c", - "Id": 1544, "CommandName": "Set-PnPTaxonomyFieldValue", + "Command": "Set-PnPTaxonomyFieldValue -ListItem $item -InternalFieldName 'Department' -TermId 863b832b-6818-4e6a-966d-2d3ee057931c", + "Id": 1563, "Rank": 1 }, { - "Command": "Set-PnPTaxonomyFieldValue -ListItem $item -InternalFieldName 'Department' -TermPath 'CORPORATE|DEPARTMENTS|HR'", - "Id": 1545, "CommandName": "Set-PnPTaxonomyFieldValue", + "Command": "Set-PnPTaxonomyFieldValue -ListItem $item -InternalFieldName 'Department' -TermPath 'CORPORATE|DEPARTMENTS|HR'", + "Id": 1564, "Rank": 2 }, { - "Command": "Set-PnPTaxonomyFieldValue -ListItem $item -InternalFieldName 'Department' -Terms @{\"TermId1\"=\"Label1\";\"TermId2\"=\"Label2\"}", - "Id": 1546, "CommandName": "Set-PnPTaxonomyFieldValue", + "Command": "Set-PnPTaxonomyFieldValue -ListItem $item -InternalFieldName 'Department' -Terms @{\"TermId1\"=\"Label1\";\"TermId2\"=\"Label2\"}", + "Id": 1565, "Rank": 3 }, { - "Command": "Set-PnPTeamifyPromptHidden", - "Id": 1547, "CommandName": "Set-PnPTeamifyPromptHidden", + "Command": "Set-PnPTeamifyPromptHidden", + "Id": 1566, "Rank": 1 }, { - "Command": "Set-PnPTeamsChannel -Team \"MyTeam\" -Channel \"MyChannel\" -DisplayName \"My Channel\"", - "Id": 1548, "CommandName": "Set-PnPTeamsChannel", + "Command": "Set-PnPTeamsChannel -Team \"MyTeam\" -Channel \"MyChannel\" -DisplayName \"My Channel\"", + "Id": 1567, "Rank": 1 }, { - "Command": "Set-PnPTeamsChannel -Team \"MyTeam\" -Channel \"MyChannel\" -IsFavoriteByDefault $true", - "Id": 1549, "CommandName": "Set-PnPTeamsChannel", + "Command": "Set-PnPTeamsChannel -Team \"MyTeam\" -Channel \"MyChannel\" -IsFavoriteByDefault $true", + "Id": 1568, "Rank": 2 }, { - "Command": "Set-PnPTeamsChannelUser -Team 4efdf392-8225-4763-9e7f-4edeb7f721aa -Channel \"19:796d063b63e34497aeaf092c8fb9b44e@thread.skype\" -Identity MCMjMiMjMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwIyMxOTowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMEB0aHJlYWQuc2t5cGUjIzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMA== -Role Owner", - "Id": 1550, "CommandName": "Set-PnpTeamsChannelUser", + "Command": "Set-PnPTeamsChannelUser -Team 4efdf392-8225-4763-9e7f-4edeb7f721aa -Channel \"19:796d063b63e34497aeaf092c8fb9b44e@thread.skype\" -Identity MCMjMiMjMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwIyMxOTowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMEB0aHJlYWQuc2t5cGUjIzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMA== -Role Owner", + "Id": 1569, "Rank": 1 }, { - "Command": "Set-PnPTeamsChannelUser -Team \"My Team\" -Channel \"My Private Channel\" -Identity john@doe.com -Role Member", - "Id": 1551, "CommandName": "Set-PnpTeamsChannelUser", + "Command": "Set-PnPTeamsChannelUser -Team \"My Team\" -Channel \"My Private Channel\" -Identity john@doe.com -Role Member", + "Id": 1570, "Rank": 2 }, { - "Command": "Set-PnPTeamsTab -Team \"MyTeam\" -Channel \"My Channel\" -Identity \"Wiki\" -DisplayName \"Channel Wiki\"", - "Id": 1552, "CommandName": "Set-PnPTeamsTab", + "Command": "Set-PnPTeamsTab -Team \"MyTeam\" -Channel \"My Channel\" -Identity \"Wiki\" -DisplayName \"Channel Wiki\"", + "Id": 1571, "Rank": 1 }, { - "Command": "Set-PnPTeamsTag -Team 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -Identity \"ZmY1ZjdmMjctZDhiNy00MWRkLTk2ZDQtYzcyYmVhMWIwOGYxIyM3ZTVhNGRmZS1kNWNlLTRkOTAtODM4MC04ZDIxM2FkYzYzOGIjI3RiVlVpR01rcg==\" -DisplayName \"Updated Tag\"", - "Id": 1553, "CommandName": "Set-PnPTeamsTag", + "Command": "Set-PnPTeamsTag -Team 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -Identity \"ZmY1ZjdmMjctZDhiNy00MWRkLTk2ZDQtYzcyYmVhMWIwOGYxIyM3ZTVhNGRmZS1kNWNlLTRkOTAtODM4MC04ZDIxM2FkYzYzOGIjI3RiVlVpR01rcg==\" -DisplayName \"Updated Tag\"", + "Id": 1572, "Rank": 1 }, { - "Command": "Set-PnPTeamsTeam -Identity 'MyTeam' -DisplayName 'My Team'", - "Id": 1554, "CommandName": "Set-PnPTeamsTeam", + "Command": "Set-PnPTeamsTeam -Identity 'MyTeam' -DisplayName 'My Team'", + "Id": 1573, "Rank": 1 }, { - "Command": "Set-PnPTeamsTeam -Identity \"baba9192-55be-488a-9fb7-2e2e76edbef2\" -Visibility Public", - "Id": 1555, "CommandName": "Set-PnPTeamsTeam", + "Command": "Set-PnPTeamsTeam -Identity \"baba9192-55be-488a-9fb7-2e2e76edbef2\" -Visibility Public", + "Id": 1574, "Rank": 2 }, { - "Command": "Set-PnPTeamsTeam -Identity \"My Team\" -AllowTeamMentions $false -AllowChannelMentions $true -AllowDeleteChannels $false", - "Id": 1556, "CommandName": "Set-PnPTeamsTeam", + "Command": "Set-PnPTeamsTeam -Identity \"My Team\" -AllowTeamMentions $false -AllowChannelMentions $true -AllowDeleteChannels $false", + "Id": 1575, "Rank": 3 }, { - "Command": "Set-PnPTeamsTeam -Identity \"My Team\" -GiphyContentRating Moderate", - "Id": 1557, "CommandName": "Set-PnPTeamsTeam", + "Command": "Set-PnPTeamsTeam -Identity \"My Team\" -GiphyContentRating Moderate", + "Id": 1576, "Rank": 4 }, { - "Command": "Set-PnPTeamsTeamArchivedState -Identity \"My Team\" -Archived $true", - "Id": 1558, "CommandName": "Set-PnPTeamsTeamArchivedState", + "Command": "Set-PnPTeamsTeamArchivedState -Identity \"My Team\" -Archived $true", + "Id": 1577, "Rank": 1 }, { - "Command": "Set-PnPTeamsTeamArchivedState -Identity \"My Team\" -Archived $false", - "Id": 1559, "CommandName": "Set-PnPTeamsTeamArchivedState", + "Command": "Set-PnPTeamsTeamArchivedState -Identity \"My Team\" -Archived $false", + "Id": 1578, "Rank": 2 }, { - "Command": "Set-PnPTeamsTeamArchivedState -Identity \"My Team\" -Archived $true -SetSiteReadOnlyForMembers $true", - "Id": 1560, "CommandName": "Set-PnPTeamsTeamArchivedState", + "Command": "Set-PnPTeamsTeamArchivedState -Identity \"My Team\" -Archived $true -SetSiteReadOnlyForMembers $true", + "Id": 1579, "Rank": 3 }, { - "Command": "Set-PnPTeamsTeamPicture -Team \"MyTeam\" -Path \"c:\\myimage.jpg\"", - "Id": 1561, "CommandName": "Set-PnPTeamsTeamPicture", + "Command": "Set-PnPTeamsTeamPicture -Team \"MyTeam\" -Path \"c:\\myimage.jpg\"", + "Id": 1580, "Rank": 1 }, { - "Command": "Set-PnPTemporarilyDisableAppBar $true", - "Id": 1562, "CommandName": "Set-PnPTemporarilyDisableAppBar", + "Command": "Set-PnPTemporarilyDisableAppBar $true", + "Id": 1581, "Rank": 1 }, { - "Command": "Set-PnPTemporarilyDisableAppBar $false", - "Id": 1563, "CommandName": "Set-PnPTemporarilyDisableAppBar", + "Command": "Set-PnPTemporarilyDisableAppBar $false", + "Id": 1582, "Rank": 2 }, { - "Command": "Set-PnPTenantSite -Identity \"https://contoso.sharepoint.com/sites/team1\" -LockState NoAccess\r ; Set-PnPTenant -NoAccessRedirectUrl \"http://www.contoso.com\"", - "Id": 1564, "CommandName": "Set-PnPTenant", + "Command": "Set-PnPTenantSite -Identity \"https://contoso.sharepoint.com/sites/team1\" -LockState NoAccess\r ; Set-PnPTenant -NoAccessRedirectUrl \"http://www.contoso.com\"", + "Id": 1583, "Rank": 1 }, { - "Command": "Set-PnPTenant -ShowEveryoneExceptExternalUsersClaim $false", - "Id": 1565, "CommandName": "Set-PnPTenant", + "Command": "Set-PnPTenant -ShowEveryoneExceptExternalUsersClaim $false", + "Id": 1584, "Rank": 2 }, { - "Command": "Set-PnPTenant -ShowAllUsersClaim $false", - "Id": 1566, "CommandName": "Set-PnPTenant", + "Command": "Set-PnPTenant -ShowAllUsersClaim $false", + "Id": 1585, "Rank": 3 }, { - "Command": "Set-PnPTenant -UsePersistentCookiesForExplorerView $true", - "Id": 1567, "CommandName": "Set-PnPTenant", + "Command": "Set-PnPTenant -UsePersistentCookiesForExplorerView $true", + "Id": 1586, "Rank": 4 }, { - "Command": "Set-PnPTenantAppCatalogUrl -Url \"https://yourtenant.sharepoint.com/sites/appcatalog\"", - "Id": 1568, + "CommandName": "Set-PnPTenant", + "Command": "Set-PnPTenant -GuestSharingGroupAllowListInTenantByPrincipalIdentity {c:0o.c|federateddirectoryclaimprovider|ee0f40fc-b2f7-45c7-b62d-11b90dd2ea8e}", + "Id": 1587, + "Rank": 5 + }, + { + "CommandName": "Set-PnPTenant", + "Command": "Set-PnPTenant -GuestSharingGroupAllowListInTenantByPrincipalIdentity {}", + "Id": 1588, + "Rank": 6 + }, + { "CommandName": "Set-PnPTenantAppCatalogUrl", + "Command": "Set-PnPTenantAppCatalogUrl -Url \"https://yourtenant.sharepoint.com/sites/appcatalog\"", + "Id": 1589, "Rank": 1 }, { - "Command": "Set-PnPTenantCdnEnabled -CdnType Public -Enable $true", - "Id": 1569, "CommandName": "Set-PnPTenantCdnEnabled", + "Command": "Set-PnPTenantCdnEnabled -CdnType Public -Enable $true", + "Id": 1590, "Rank": 1 }, { - "Command": "Set-PnPTenantCdnEnabled -CdnType Private -Enable $false", - "Id": 1570, "CommandName": "Set-PnPTenantCdnEnabled", + "Command": "Set-PnPTenantCdnEnabled -CdnType Private -Enable $false", + "Id": 1591, "Rank": 2 }, { - "Command": "Set-PnPTenantCdnEnabled -CdnType Public -Enable $true -NoDefaultOrigins", - "Id": 1571, "CommandName": "Set-PnPTenantCdnEnabled", + "Command": "Set-PnPTenantCdnEnabled -CdnType Public -Enable $true -NoDefaultOrigins", + "Id": 1592, "Rank": 3 }, { - "Command": "Set-PnPTenantCdnPolicy -CdnType Public -PolicyType IncludeFileExtensions -PolicyValue \"CSS,EOT,GIF,ICO,JPEG,JPG,JS,MAP,PNG,SVG,TTF,WOFF\"", - "Id": 1572, "CommandName": "Set-PnPTenantCdnPolicy", + "Command": "Set-PnPTenantCdnPolicy -CdnType Public -PolicyType IncludeFileExtensions -PolicyValue \"CSS,EOT,GIF,ICO,JPEG,JPG,JS,MAP,PNG,SVG,TTF,WOFF\"", + "Id": 1593, "Rank": 1 }, { - "Command": "Set-PnPTenantCdnPolicy -CdnType Public -PolicyType ExcludeRestrictedSiteClassifications -PolicyValue \"Confidential,Restricted\"", - "Id": 1573, "CommandName": "Set-PnPTenantCdnPolicy", + "Command": "Set-PnPTenantCdnPolicy -CdnType Public -PolicyType ExcludeRestrictedSiteClassifications -PolicyValue \"Confidential,Restricted\"", + "Id": 1594, "Rank": 2 }, { - "Command": "Set-PnPTenantRestrictedSearchMode -Mode Enabled", - "Id": 1574, "CommandName": "Set-PnPTenantRestrictedSearchMode", + "Command": "Set-PnPTenantRestrictedSearchMode -Mode Enabled", + "Id": 1595, "Rank": 1 }, { - "Command": "Set-PnPTenantRestrictedSearchMode -Mode Disabled", - "Id": 1575, "CommandName": "Set-PnPTenantRestrictedSearchMode", + "Command": "Set-PnPTenantRestrictedSearchMode -Mode Disabled", + "Id": 1596, "Rank": 2 }, { - "Command": "Set-PnPTenantSite -Identity \"https://contoso.sharepoint.com\" -Title \"Contoso Website\" -SharingCapability Disabled", - "Id": 1576, "CommandName": "Set-PnPTenantSite", + "Command": "Set-PnPTenantSite -Identity \"https://contoso.sharepoint.com\" -Title \"Contoso Website\" -SharingCapability Disabled", + "Id": 1597, "Rank": 1 }, { - "Command": "Set-PnPTenantSite -Identity \"https://contoso.sharepoint.com\" -Title \"Contoso Website\" -StorageWarningLevel 8000 -StorageMaximumLevel 10000", - "Id": 1577, "CommandName": "Set-PnPTenantSite", + "Command": "Set-PnPTenantSite -Identity \"https://contoso.sharepoint.com\" -Title \"Contoso Website\" -StorageWarningLevel 8000 -StorageMaximumLevel 10000", + "Id": 1598, "Rank": 2 }, { - "Command": "Set-PnPTenantSite -Identity \"https://contoso.sharepoint.com/sites/sales\" -Owners \"user@contoso.onmicrosoft.com\"", - "Id": 1578, "CommandName": "Set-PnPTenantSite", + "Command": "Set-PnPTenantSite -Identity \"https://contoso.sharepoint.com/sites/sales\" -Owners \"user@contoso.onmicrosoft.com\"", + "Id": 1599, "Rank": 3 }, { - "Command": "Set-PnPTenantSite -Identity \"https://contoso.sharepoint.com/sites/sales\" -Owners @(\"user1@contoso.onmicrosoft.com\", \"user2@contoso.onmicrosoft.com\")", - "Id": 1579, "CommandName": "Set-PnPTenantSite", + "Command": "Set-PnPTenantSite -Identity \"https://contoso.sharepoint.com/sites/sales\" -Owners @(\"user1@contoso.onmicrosoft.com\", \"user2@contoso.onmicrosoft.com\")", + "Id": 1600, "Rank": 4 }, { - "Command": "Set-PnPTenantSite -Identity \"https://contoso.sharepoint.com/sites/sales\" -DenyAddAndCustomizePages:$false", - "Id": 1580, "CommandName": "Set-PnPTenantSite", + "Command": "Set-PnPTenantSite -Identity \"https://contoso.sharepoint.com/sites/sales\" -DenyAddAndCustomizePages:$false", + "Id": 1601, "Rank": 5 }, { - "Command": "Set-PnPTenantSyncClientRestriction -BlockMacSync:$false", - "Id": 1581, "CommandName": "Set-PnPTenantSyncClientRestriction", + "Command": "Set-PnPTenantSyncClientRestriction -BlockMacSync:$false", + "Id": 1602, "Rank": 1 }, { - "Command": "Set-PnPTenantSyncClientRestriction -ExcludedFileExtensions \"pptx;docx;xlsx\"", - "Id": 1582, "CommandName": "Set-PnPTenantSyncClientRestriction", + "Command": "Set-PnPTenantSyncClientRestriction -ExcludedFileExtensions \"pptx;docx;xlsx\"", + "Id": 1603, "Rank": 2 }, { - "Command": "Set-PnPTerm -Identity 3d9e60e8-d89c-4cd4-af61-a010cf93b380 -Name \"New Name\"", - "Id": 1583, "CommandName": "Set-PnPTerm", + "Command": "Set-PnPTerm -Identity 3d9e60e8-d89c-4cd4-af61-a010cf93b380 -Name \"New Name\"", + "Id": 1604, "Rank": 1 }, { - "Command": "Set-PnPTerm -Identity \"Marketing\" -TermSet \"Departments\" -TermGroup \"Corporate\" -Name \"Finance\" -CustomProperties @{\"IsCorporate\"=\"True\"}", - "Id": 1584, "CommandName": "Set-PnPTerm", + "Command": "Set-PnPTerm -Identity \"Marketing\" -TermSet \"Departments\" -TermGroup \"Corporate\" -Name \"Finance\" -CustomProperties @{\"IsCorporate\"=\"True\"}", + "Id": 1605, "Rank": 2 }, { - "Command": "Set-PnPTerm -Identity \"Marketing\" -TermSet \"Departments\" -TermGroup \"Corporate\" -Name \"Finance\" -DeleteAllCustomProperties -CustomProperties @{\"IsCorporate\"=\"True\"}", - "Id": 1585, "CommandName": "Set-PnPTerm", + "Command": "Set-PnPTerm -Identity \"Marketing\" -TermSet \"Departments\" -TermGroup \"Corporate\" -Name \"Finance\" -DeleteAllCustomProperties -CustomProperties @{\"IsCorporate\"=\"True\"}", + "Id": 1606, "Rank": 3 }, { - "Command": "Set-PnPTerm -Identity \"Marketing\" -TermSet \"Departments\" -TermGroup \"Corporate\" -Deprecated $true", - "Id": 1586, "CommandName": "Set-PnPTerm", + "Command": "Set-PnPTerm -Identity \"Marketing\" -TermSet \"Departments\" -TermGroup \"Corporate\" -Deprecated $true", + "Id": 1607, "Rank": 4 }, { - "Command": "Set-PnPTermGroup -Identity \"Departments\" -Name \"Company Units\"", - "Id": 1587, "CommandName": "Set-PnPTermGroup", + "Command": "Set-PnPTermGroup -Identity \"Departments\" -Name \"Company Units\"", + "Id": 1608, "Rank": 1 }, { - "Command": "Set-PnPTermSet -Identity \"Departments\" -TermGroup \"Corporate\" -Name \"Business Units\"", - "Id": 1588, "CommandName": "Set-PnPTermSet", + "Command": "Set-PnPTermSet -Identity \"Departments\" -TermGroup \"Corporate\" -Name \"Business Units\"", + "Id": 1609, "Rank": 1 }, { - "Command": "Set-PnPTermSet -Identity \"Departments\" -TermGroup \"Corporate\" -UseForSiteNavigation $true", - "Id": 1589, "CommandName": "Set-PnPTermSet", + "Command": "Set-PnPTermSet -Identity \"Departments\" -TermGroup \"Corporate\" -UseForSiteNavigation $true", + "Id": 1610, "Rank": 2 }, { - "Command": "Set-PnPTermSet -Identity \"Departments\" -TermGroup \"Corporate\" -IsAvailableForTagging $false", - "Id": 1590, "CommandName": "Set-PnPTermSet", + "Command": "Set-PnPTermSet -Identity \"Departments\" -TermGroup \"Corporate\" -IsAvailableForTagging $false", + "Id": 1611, "Rank": 3 }, { - "Command": "Set-PnPTheme", - "Id": 1591, "CommandName": "Set-PnPTheme", + "Command": "Set-PnPTheme", + "Id": 1612, "Rank": 1 }, { - "Command": "Set-PnPTheme -ColorPaletteUrl _catalogs/theme/15/company.spcolor", - "Id": 1592, "CommandName": "Set-PnPTheme", + "Command": "Set-PnPTheme -ColorPaletteUrl _catalogs/theme/15/company.spcolor", + "Id": 1613, "Rank": 2 }, { - "Command": "Set-PnPTheme -ColorPaletteUrl _catalogs/theme/15/company.spcolor -BackgroundImageUrl 'style library/background.png'", - "Id": 1593, "CommandName": "Set-PnPTheme", + "Command": "Set-PnPTheme -ColorPaletteUrl _catalogs/theme/15/company.spcolor -BackgroundImageUrl 'style library/background.png'", + "Id": 1614, "Rank": 3 }, { - "Command": "Set-PnPTheme -ColorPaletteUrl _catalogs/theme/15/company.spcolor -BackgroundImageUrl 'style library/background.png' -ResetSubwebsToInherit", - "Id": 1594, "CommandName": "Set-PnPTheme", + "Command": "Set-PnPTheme -ColorPaletteUrl _catalogs/theme/15/company.spcolor -BackgroundImageUrl 'style library/background.png' -ResetSubwebsToInherit", + "Id": 1615, "Rank": 4 }, { - "Command": "Set-PnPTraceLog -On -LogFile traceoutput.txt", - "Id": 1595, "CommandName": "Set-PnPTraceLog", + "Command": "Set-PnPTraceLog -On -LogFile traceoutput.txt", + "Id": 1616, "Rank": 1 }, { - "Command": "Set-PnPTraceLog -On -LogFile traceoutput.txt -Level Debug", - "Id": 1596, "CommandName": "Set-PnPTraceLog", + "Command": "Set-PnPTraceLog -On -LogFile traceoutput.txt -Level Debug", + "Id": 1617, "Rank": 2 }, { - "Command": "Set-PnPTraceLog -On -LogFile traceoutput.txt -Level Debug -Delimiter \",\"", - "Id": 1597, "CommandName": "Set-PnPTraceLog", + "Command": "Set-PnPTraceLog -On -LogFile traceoutput.txt -Level Debug -Delimiter \",\"", + "Id": 1618, "Rank": 3 }, { - "Command": "Set-PnPTraceLog -Off", - "Id": 1598, "CommandName": "Set-PnPTraceLog", + "Command": "Set-PnPTraceLog -Off", + "Id": 1619, "Rank": 4 }, { - "Command": "Set-PnPUserOneDriveQuota -Account 'user@domain.com' -Quota 5368709120 -QuotaWarning 4831838208", - "Id": 1599, "CommandName": "Set-PnPUserOneDriveQuota", + "Command": "Set-PnPUserOneDriveQuota -Account 'user@domain.com' -Quota 5368709120 -QuotaWarning 4831838208", + "Id": 1620, "Rank": 1 }, { - "Command": "Set-PnPUserProfileProperty -Account 'john@domain.com' -Property 'SPS-Location' -Value 'Stockholm'", - "Id": 1600, "CommandName": "Set-PnPUserProfileProperty", + "Command": "Set-PnPUserProfileProperty -Account 'john@domain.com' -Property 'SPS-Location' -Value 'Stockholm'", + "Id": 1621, "Rank": 1 }, { - "Command": "Set-PnPUserProfileProperty -Account 'john@domain.com' -Property 'MyProperty' -Values 'Value 1','Value 2'", - "Id": 1601, "CommandName": "Set-PnPUserProfileProperty", + "Command": "Set-PnPUserProfileProperty -Account 'john@domain.com' -Property 'MyProperty' -Values 'Value 1','Value 2'", + "Id": 1622, "Rank": 2 }, { - "Command": "Set-PnPView -List \"Tasks\" -Identity \"All Tasks\" -Values @{JSLink=\"hierarchytaskslist.js|customrendering.js\";Title=\"My view\"}", - "Id": 1602, "CommandName": "Set-PnPView", + "Command": "Set-PnPView -List \"Tasks\" -Identity \"All Tasks\" -Values @{JSLink=\"hierarchytaskslist.js|customrendering.js\";Title=\"My view\"}", + "Id": 1623, "Rank": 1 }, { - "Command": "Set-PnPView -List \"Documents\" -Identity \"Corporate Documents\" -Fields \"Title\",\"Created\"", - "Id": 1603, "CommandName": "Set-PnPView", + "Command": "Set-PnPView -List \"Documents\" -Identity \"Corporate Documents\" -Fields \"Title\",\"Created\"", + "Id": 1624, "Rank": 2 }, { - "Command": "Set-PnPView -List \"Documents\" -Identity \"Corporate Documents\" -Fields \"Title\",\"Created\" -Aggregations \"\"", - "Id": 1604, "CommandName": "Set-PnPView", + "Command": "Set-PnPView -List \"Documents\" -Identity \"Corporate Documents\" -Fields \"Title\",\"Created\" -Aggregations \"\"", + "Id": 1625, "Rank": 3 }, { - "Command": "Set-PnPView -List \"Documents\" -Identity \"Dept Documents\" -Fields \"Title,\"Created\" -Values @{Paged=$true;RowLimit=[UInt32]\"100\"}", - "Id": 1605, "CommandName": "Set-PnPView", + "Command": "Set-PnPView -List \"Documents\" -Identity \"Dept Documents\" -Fields \"Title,\"Created\" -Values @{Paged=$true;RowLimit=[UInt32]\"100\"}", + "Id": 1626, "Rank": 4 }, { - "Command": "Set-PnPVivaConnectionsDashboardACE -Identity \"58108715-185e-4214-8786-01218e7ab9ef\" -Title \"Update title\" -Description \"Update Description\" -IconProperty \"https://cdn.hubblecontent.osi.office.net/m365content/publish/002f8bf9-b8ee-4689-ae97-e411b756099d/691108002.jpg\" -Order 4 -CardSize Large -PropertiesJSON $myProperties", - "Id": 1606, "CommandName": "Set-PnPVivaConnectionsDashboardACE", + "Command": "Set-PnPVivaConnectionsDashboardACE -Identity \"58108715-185e-4214-8786-01218e7ab9ef\" -Title \"Update title\" -Description \"Update Description\" -IconProperty \"https://cdn.hubblecontent.osi.office.net/m365content/publish/002f8bf9-b8ee-4689-ae97-e411b756099d/691108002.jpg\" -Order 4 -CardSize Large -PropertiesJSON $myProperties", + "Id": 1627, "Rank": 1 }, { - "Command": "Set-PnPVivaConnectionsDashboardACE -Identity \"58108715-185e-4214-8786-01218e7ab9ef\" -Title \"Update title\" -Description \"Update Description\"", - "Id": 1607, "CommandName": "Set-PnPVivaConnectionsDashboardACE", + "Command": "Set-PnPVivaConnectionsDashboardACE -Identity \"58108715-185e-4214-8786-01218e7ab9ef\" -Title \"Update title\" -Description \"Update Description\"", + "Id": 1628, "Rank": 2 }, { - "Command": "Set-PnPVivaConnectionsDashboardACE -Identity \"58108715-185e-4214-8786-01218e7ab9ef\" -IconProperty \"https://cdn.hubblecontent.osi.office.net/m365content/publish/002f8bf9-b8ee-4689-ae97-e411b756099d/691108002.jpg\" -Order 4", - "Id": 1608, "CommandName": "Set-PnPVivaConnectionsDashboardACE", + "Command": "Set-PnPVivaConnectionsDashboardACE -Identity \"58108715-185e-4214-8786-01218e7ab9ef\" -IconProperty \"https://cdn.hubblecontent.osi.office.net/m365content/publish/002f8bf9-b8ee-4689-ae97-e411b756099d/691108002.jpg\" -Order 4", + "Id": 1629, "Rank": 3 }, { - "Command": "Set-PnPVivaConnectionsDashboardACE -Identity \"58108715-185e-4214-8786-01218e7ab9ef\" -CardSize Large", - "Id": 1609, "CommandName": "Set-PnPVivaConnectionsDashboardACE", + "Command": "Set-PnPVivaConnectionsDashboardACE -Identity \"58108715-185e-4214-8786-01218e7ab9ef\" -CardSize Large", + "Id": 1630, "Rank": 4 }, { - "Command": "Set-PnPWeb -CommentsOnSitePagesDisabled:$true", - "Id": 1610, "CommandName": "Set-PnPWeb", + "Command": "Set-PnPWeb -CommentsOnSitePagesDisabled:$true", + "Id": 1631, "Rank": 1 }, { - "Command": "Set-PnPWeb -QuickLaunchEnabled:$false", - "Id": 1611, "CommandName": "Set-PnPWeb", + "Command": "Set-PnPWeb -QuickLaunchEnabled:$false", + "Id": 1632, "Rank": 2 }, { - "Command": "Set-PnPWeb -HeaderEmphasis Strong -HeaderLayout Compact", - "Id": 1612, "CommandName": "Set-PnPWeb", + "Command": "Set-PnPWeb -HeaderEmphasis Strong -HeaderLayout Compact", + "Id": 1633, "Rank": 3 }, { - "Command": "Set-PnPWeb -NoCrawl:$true", - "Id": 1613, "CommandName": "Set-PnPWeb", + "Command": "Set-PnPWeb -NoCrawl:$true", + "Id": 1634, "Rank": 4 }, { - "Command": "Set-PnPWebHeader -HeaderBackgroundImageUrl \"/sites/hrdepartment/siteassets/background.png\" -HeaderLayout Extended", - "Id": 1614, "CommandName": "Set-PnPWebHeader", + "Command": "Set-PnPWebHeader -HeaderBackgroundImageUrl \"/sites/hrdepartment/siteassets/background.png\" -HeaderLayout Extended", + "Id": 1635, "Rank": 1 }, { - "Command": "Set-PnPWebHeader -HeaderEmphasis Strong", - "Id": 1615, "CommandName": "Set-PnPWebHeader", + "Command": "Set-PnPWebHeader -HeaderEmphasis Strong", + "Id": 1636, "Rank": 2 }, { - "Command": "Set-PnPWebHeader -LogoAlignment Middle", - "Id": 1616, "CommandName": "Set-PnPWebHeader", + "Command": "Set-PnPWebHeader -LogoAlignment Middle", + "Id": 1637, "Rank": 3 }, { - "Command": "Set-PnPWebhookSubscription -List MyList -Subscription ea1533a8-ff03-415b-a7b6-517ee50db8b6 -NotificationUrl https://my-func.azurewebsites.net/webhook", - "Id": 1617, "CommandName": "Set-PnPWebhookSubscription", + "Command": "Set-PnPWebhookSubscription -List MyList -Subscription ea1533a8-ff03-415b-a7b6-517ee50db8b6 -NotificationUrl https://my-func.azurewebsites.net/webhook", + "Id": 1638, "Rank": 1 }, { - "Command": "Set-PnPWebhookSubscription -List MyList -Subscription ea1533a8-ff03-415b-a7b6-517ee50db8b6 -NotificationUrl https://my-func.azurewebsites.net/webhook -ExpirationDate \"2017-09-01\"", - "Id": 1618, "CommandName": "Set-PnPWebhookSubscription", + "Command": "Set-PnPWebhookSubscription -List MyList -Subscription ea1533a8-ff03-415b-a7b6-517ee50db8b6 -NotificationUrl https://my-func.azurewebsites.net/webhook -ExpirationDate \"2017-09-01\"", + "Id": 1639, "Rank": 2 }, { - "Command": "Set-PnPWebPartProperty -ServerRelativePageUrl /sites/demo/sitepages/home.aspx -Identity ccd2c98a-c9ae-483b-ae72-19992d583914 -Key \"Title\" -Value \"New Title\"", - "Id": 1619, "CommandName": "Set-PnPWebPartProperty", + "Command": "Set-PnPWebPartProperty -ServerRelativePageUrl /sites/demo/sitepages/home.aspx -Identity ccd2c98a-c9ae-483b-ae72-19992d583914 -Key \"Title\" -Value \"New Title\"", + "Id": 1640, "Rank": 1 }, { - "Command": "Set-PnPWebPermission -User \"user@contoso.com\" -AddRole \"Contribute\"", - "Id": 1620, "CommandName": "Set-PnPWebPermission", + "Command": "Set-PnPWebPermission -User \"user@contoso.com\" -AddRole \"Contribute\"", + "Id": 1641, "Rank": 1 }, { - "Command": "Set-PnPWebPermission -Group \"Project Managers\" -AddRole \"Contribute\"", - "Id": 1621, "CommandName": "Set-PnPWebPermission", + "Command": "Set-PnPWebPermission -Group \"Project Managers\" -AddRole \"Contribute\"", + "Id": 1642, "Rank": 2 }, { - "Command": "Set-PnPWebPermission -Identity projectA -User \"user@contoso.com\" -AddRole \"Contribute\"", - "Id": 1622, "CommandName": "Set-PnPWebPermission", + "Command": "Set-PnPWebPermission -Identity projectA -User \"user@contoso.com\" -AddRole \"Contribute\"", + "Id": 1643, "Rank": 3 }, { - "Command": "Set-PnPWebPermission -User \"user@contoso.com\" -AddRole \"Custom Role 1\",\"Custom Role 2\"", - "Id": 1623, "CommandName": "Set-PnPWebPermission", + "Command": "Set-PnPWebPermission -User \"user@contoso.com\" -AddRole \"Custom Role 1\",\"Custom Role 2\"", + "Id": 1644, "Rank": 4 }, { - "Command": "Set-PnPWebTheme -Theme MyTheme", - "Id": 1624, "CommandName": "Set-PnPWebTheme", + "Command": "Set-PnPWebTheme -Theme MyTheme", + "Id": 1645, "Rank": 1 }, { - "Command": "Set-PnPWebTheme -Theme \"MyCompanyTheme\" -WebUrl https://contoso.sharepoint.com/sites/MyWeb", - "Id": 1625, "CommandName": "Set-PnPWebTheme", + "Command": "Set-PnPWebTheme -Theme \"MyCompanyTheme\" -WebUrl https://contoso.sharepoint.com/sites/MyWeb", + "Id": 1646, "Rank": 2 }, { - "Command": "Set-PnPWikiPageContent -ServerRelativePageUrl /sites/PnPWikiCollection/SitePages/OurWikiPage.aspx -Path .\\sampleblog.html", - "Id": 1626, "CommandName": "Set-PnPWikiPageContent", + "Command": "Set-PnPWikiPageContent -ServerRelativePageUrl /sites/PnPWikiCollection/SitePages/OurWikiPage.aspx -Path .\\sampleblog.html", + "Id": 1647, "Rank": 1 }, { - "Command": "Submit-PnPSearchQuery -Query \"finance\"", - "Id": 1627, "CommandName": "Submit-PnPSearchQuery", + "Command": "Submit-PnPSearchQuery -Query \"finance\"", + "Id": 1648, "Rank": 1 }, { - "Command": "Submit-PnPSearchQuery -Query \"Title:Intranet*\" -MaxResults 10", - "Id": 1628, "CommandName": "Submit-PnPSearchQuery", + "Command": "Submit-PnPSearchQuery -Query \"Title:Intranet*\" -MaxResults 10", + "Id": 1649, "Rank": 2 }, { - "Command": "Submit-PnPSearchQuery -Query \"Title:Intranet*\" -All", - "Id": 1629, "CommandName": "Submit-PnPSearchQuery", + "Command": "Submit-PnPSearchQuery -Query \"Title:Intranet*\" -All", + "Id": 1650, "Rank": 3 }, { - "Command": "Submit-PnPSearchQuery -Query \"Title:Intranet*\" -Refiners \"contentclass,FileType(filter=6/0/*)\"", - "Id": 1630, "CommandName": "Submit-PnPSearchQuery", + "Command": "Submit-PnPSearchQuery -Query \"Title:Intranet*\" -Refiners \"contentclass,FileType(filter=6/0/*)\"", + "Id": 1651, "Rank": 4 }, { - "Command": "Submit-PnPSearchQuery -Query \"contentclass:STS_ListItem_DocumentLibrary\" -SelectProperties ComplianceTag,InformationProtectionLabelId -All", - "Id": 1631, "CommandName": "Submit-PnPSearchQuery", + "Command": "Submit-PnPSearchQuery -Query \"contentclass:STS_ListItem_DocumentLibrary\" -SelectProperties ComplianceTag,InformationProtectionLabelId -All", + "Id": 1652, "Rank": 5 }, { - "Command": "Submit-PnPSearchQuery -Query \"contentclass:STS_ListItem_DocumentLibrary\" -SortList @{\"filename\" = \"ascending\"} -All", - "Id": 1632, "CommandName": "Submit-PnPSearchQuery", + "Command": "Submit-PnPSearchQuery -Query \"contentclass:STS_ListItem_DocumentLibrary\" -SortList @{\"filename\" = \"ascending\"} -All", + "Id": 1653, "Rank": 6 }, { - "Command": "Submit-PnPTeamsChannelMessage -Team MyTestTeam -Channel \"My Channel\" -Message \"A new message\"", - "Id": 1633, "CommandName": "Submit-PnPTeamsChannelMessage", + "Command": "Submit-PnPTeamsChannelMessage -Team MyTestTeam -Channel \"My Channel\" -Message \"A new message\"", + "Id": 1654, "Rank": 1 }, { - "Command": "Submit-PnPTeamsChannelMessage -Team MyTestTeam -Channel \"My Channel\" -Message \"A bold new message\" -ContentType Html", - "Id": 1634, "CommandName": "Submit-PnPTeamsChannelMessage", + "Command": "Submit-PnPTeamsChannelMessage -Team MyTestTeam -Channel \"My Channel\" -Message \"A bold new message\" -ContentType Html", + "Id": 1655, "Rank": 2 }, { - "Command": "Sync-PnPAppToTeams -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe", - "Id": 1635, "CommandName": "Sync-PnPAppToTeams", + "Command": "Sync-PnPAppToTeams -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe", + "Id": 1656, "Rank": 1 }, { - "Command": "Sync-PnPSharePointUserProfilesFromAzureActiveDirectory -UserProfilePropertyMapping @{\"HomePhone\"=\"phone\";\"CustomProperty\"=\"DisplayName\"}", - "Id": 1636, "CommandName": "Sync-PnPSharePointUserProfilesFromAzureActiveDirectory", + "Command": "Sync-PnPSharePointUserProfilesFromAzureActiveDirectory -UserProfilePropertyMapping @{\"HomePhone\"=\"phone\";\"CustomProperty\"=\"DisplayName\"}", + "Id": 1657, "Rank": 1 }, { - "Command": "Sync-PnPSharePointUserProfilesFromAzureActiveDirectory -UserProfilePropertyMapping @{\"CostCenter\"=\"extension_b0b5aaa58a0a4287acd826c5b8330e48_CostCenter\"} -Folder \"User Profile Sync\"", - "Id": 1637, "CommandName": "Sync-PnPSharePointUserProfilesFromAzureActiveDirectory", + "Command": "Sync-PnPSharePointUserProfilesFromAzureActiveDirectory -UserProfilePropertyMapping @{\"CostCenter\"=\"extension_b0b5aaa58a0a4287acd826c5b8330e48_CostCenter\"} -Folder \"User Profile Sync\"", + "Id": 1658, "Rank": 2 }, { - "Command": "Sync-PnPSharePointUserProfilesFromAzureActiveDirectory -UserProfilePropertyMapping @{\"CostCenter\"=\"extension_b0b5aaa58a0a4287acd826c5b8330e48_CostCenter\"} -Folder \"User Profile Sync\\Jobs\" -Wait -Verbose", - "Id": 1638, "CommandName": "Sync-PnPSharePointUserProfilesFromAzureActiveDirectory", + "Command": "Sync-PnPSharePointUserProfilesFromAzureActiveDirectory -UserProfilePropertyMapping @{\"CostCenter\"=\"extension_b0b5aaa58a0a4287acd826c5b8330e48_CostCenter\"} -Folder \"User Profile Sync\\Jobs\" -Wait -Verbose", + "Id": 1659, "Rank": 3 }, { - "Command": "Test-PnPListItemIsRecord -List \"Documents\" -Identity 4", - "Id": 1639, "CommandName": "Test-PnPListItemIsRecord", + "Command": "Test-PnPListItemIsRecord -List \"Documents\" -Identity 4", + "Id": 1660, "Rank": 1 }, { - "Command": "Test-PnPMicrosoft365GroupAliasIsUsed -Alias \"MyGroup\"", - "Id": 1640, "CommandName": "Test-PnPMicrosoft365GroupAliasIsUsed", + "Command": "Test-PnPMicrosoft365GroupAliasIsUsed -Alias \"MyGroup\"", + "Id": 1661, "Rank": 1 }, { - "Command": "Test-PnPSite -Identity \"https://contoso.sharepoint.com/sites/marketing\"", - "Id": 1641, "CommandName": "Test-PnPSite", + "Command": "Test-PnPSite -Identity \"https://contoso.sharepoint.com/sites/marketing\"", + "Id": 1662, "Rank": 1 }, { - "Command": "Test-PnPSite -Identity \"https://contoso.sharepoint.com/sites/marketing\" -RuleID \"ee967197-ccbe-4c00-88e4-e6fab81145e1\"", - "Id": 1642, "CommandName": "Test-PnPSite", + "Command": "Test-PnPSite -Identity \"https://contoso.sharepoint.com/sites/marketing\" -RuleID \"ee967197-ccbe-4c00-88e4-e6fab81145e1\"", + "Id": 1663, "Rank": 2 }, { - "Command": "Test-PnPTenantTemplate -Template $myTemplate", - "Id": 1643, "CommandName": "Test-PnPTenantTemplate", + "Command": "Test-PnPTenantTemplate -Template $myTemplate", + "Id": 1664, "Rank": 1 }, { - "Command": "Undo-PnPFileCheckedOut -Url \"/sites/PnP/Shared Documents/Contract.docx\"", - "Id": 1644, "CommandName": "Undo-PnPFileCheckedOut", + "Command": "Undo-PnPFileCheckedOut -Url \"/sites/PnP/Shared Documents/Contract.docx\"", + "Id": 1665, "Rank": 1 }, { - "Command": "Uninstall-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe", - "Id": 1645, "CommandName": "Uninstall-PnPApp", + "Command": "Uninstall-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe", + "Id": 1666, "Rank": 1 }, { - "Command": "Uninstall-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe -Scope Site", - "Id": 1646, "CommandName": "Uninstall-PnPApp", + "Command": "Uninstall-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe -Scope Site", + "Id": 1667, "Rank": 2 }, { - "Command": "Unlock-PnPSensitivityLabelEncryptedFile -Url \"https://contoso.com/sites/Marketing/Shared Documents/Doc1.docx\" -JustificationText \"Need to access file\"", - "Id": 1647, "CommandName": "Unlock-PnPSensitivityLabelEncryptedFile", + "Command": "Unlock-PnPSensitivityLabelEncryptedFile -Url \"https://contoso.com/sites/Marketing/Shared Documents/Doc1.docx\" -JustificationText \"Need to access file\"", + "Id": 1668, "Rank": 1 }, { - "Command": "Unpublish-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe", - "Id": 1648, "CommandName": "Unpublish-PnPApp", + "Command": "Unpublish-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe", + "Id": 1669, "Rank": 1 }, { - "Command": "Unpublish-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe -Scope Site", - "Id": 1649, "CommandName": "Unpublish-PnPApp", + "Command": "Unpublish-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe -Scope Site", + "Id": 1670, "Rank": 2 }, { - "Command": "Unpublish-PnPContentType -ContentType 0x0101", - "Id": 1650, "CommandName": "Unpublish-PnPContentType", + "Command": "Unpublish-PnPContentType -ContentType 0x0101", + "Id": 1671, "Rank": 1 }, { - "Command": "Unpublish-PnPSyntexModel -Model \"Invoice model\" -ListWebUrl \"https://contoso.sharepoint.com/sites/finance\" -List \"Documents\"", - "Id": 1651, "CommandName": "Unpublish-PnPSyntexModel", + "Command": "Unpublish-PnPSyntexModel -Model \"Invoice model\" -ListWebUrl \"https://contoso.sharepoint.com/sites/finance\" -List \"Documents\"", + "Id": 1672, "Rank": 1 }, { - "Command": "Unpublish-PnPSyntexModel -Model \"Invoice model\" -TargetSiteUrl \"https://contoso.sharepoint.com/sites/finance\" -TargetWebServerRelativeUrl \"/sites/finance\" -TargetLibraryServerRelativeUrl \"/sites/finance/shared%20documents\" -Batch $batch", - "Id": 1652, "CommandName": "Unpublish-PnPSyntexModel", + "Command": "Unpublish-PnPSyntexModel -Model \"Invoice model\" -TargetSiteUrl \"https://contoso.sharepoint.com/sites/finance\" -TargetWebServerRelativeUrl \"/sites/finance\" -TargetLibraryServerRelativeUrl \"/sites/finance/shared%20documents\" -Batch $batch", + "Id": 1673, "Rank": 2 }, { - "Command": "Unregister-PnPHubSite -Site \"https://tenant.sharepoint.com/sites/myhubsite\"", - "Id": 1653, "CommandName": "Unregister-PnPHubSite", + "Command": "Unregister-PnPHubSite -Site \"https://tenant.sharepoint.com/sites/myhubsite\"", + "Id": 1674, "Rank": 1 }, { - "Command": "Update-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe", - "Id": 1654, "CommandName": "Update-PnPApp", + "Command": "Update-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe", + "Id": 1675, "Rank": 1 }, { - "Command": "Update-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe -Scope Site", - "Id": 1655, "CommandName": "Update-PnPApp", + "Command": "Update-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe -Scope Site", + "Id": 1676, "Rank": 2 }, { - "Command": "Update-PnPAvailableSiteClassification -Classifications \"HBI\",\"Top Secret\"", - "Id": 1656, "CommandName": "Update-PnPAvailableSiteClassification", + "Command": "Update-PnPAvailableSiteClassification -Classifications \"HBI\",\"Top Secret\"", + "Id": 1677, "Rank": 1 }, { - "Command": "Update-PnPAvailableSiteClassification -DefaultClassification \"LBI\"", - "Id": 1657, "CommandName": "Update-PnPAvailableSiteClassification", + "Command": "Update-PnPAvailableSiteClassification -DefaultClassification \"LBI\"", + "Id": 1678, "Rank": 2 }, { - "Command": "Update-PnPAvailableSiteClassification -UsageGuidelinesUrl https://aka.ms/m365pnp", - "Id": 1658, "CommandName": "Update-PnPAvailableSiteClassification", + "Command": "Update-PnPAvailableSiteClassification -UsageGuidelinesUrl https://aka.ms/m365pnp", + "Id": 1679, "Rank": 3 }, { - "Command": "Update-PnPSiteDesignFromWeb -Identity \"Contoso Project\" -IncludeAll", - "Id": 1659, "CommandName": "Update-PnPSiteDesignFromWeb", + "Command": "Update-PnPSiteDesignFromWeb -Identity \"Contoso Project\" -IncludeAll", + "Id": 1680, "Rank": 1 }, { - "Command": "Update-PnPSiteDesignFromWeb -Identity \"Contoso Project\" -IncludeAll -Lists (\"/lists/Issue list\", \"Shared Documents)", - "Id": 1660, "CommandName": "Update-PnPSiteDesignFromWeb", + "Command": "Update-PnPSiteDesignFromWeb -Identity \"Contoso Project\" -IncludeAll -Lists (\"/lists/Issue list\", \"Shared Documents)", + "Id": 1681, "Rank": 2 }, { - "Command": "Update-PnPSiteDesignFromWeb -Url https://contoso.sharepoint.com/sites/template -Identity \"Contoso Project\" -Lists \"/lists/Issue list\"", - "Id": 1661, "CommandName": "Update-PnPSiteDesignFromWeb", + "Command": "Update-PnPSiteDesignFromWeb -Url https://contoso.sharepoint.com/sites/template -Identity \"Contoso Project\" -Lists \"/lists/Issue list\"", + "Id": 1682, "Rank": 3 }, { - "Command": "Update-PnPTeamsApp -Identity 4efdf392-8225-4763-9e7f-4edeb7f721aa -Path c:\\myapp.zip", - "Id": 1662, "CommandName": "Update-PnPTeamsApp", + "Command": "Update-PnPTeamsApp -Identity 4efdf392-8225-4763-9e7f-4edeb7f721aa -Path c:\\myapp.zip", + "Id": 1683, "Rank": 1 }, { - "Command": "Update-PnPTeamsUser -Team MyTeam -User john@doe.com -Role Owner", - "Id": 1663, "CommandName": "Update-PnPTeamsUser", + "Command": "Update-PnPTeamsUser -Team MyTeam -User john@doe.com -Role Owner", + "Id": 1684, "Rank": 1 }, { - "Command": "Update-PnPTeamsUser -Team MyTeam -User john@doe.com -Role Member", - "Id": 1664, "CommandName": "Update-PnPTeamsUser", + "Command": "Update-PnPTeamsUser -Team MyTeam -User john@doe.com -Role Member", + "Id": 1685, "Rank": 2 }, { - "Command": "Update-PnPTeamsUser -Team a0c0a395-4ba6-4fff-958a-000000506d18 -User john@doe.com -Role Member -Force", - "Id": 1665, "CommandName": "Update-PnPTeamsUser", + "Command": "Update-PnPTeamsUser -Team a0c0a395-4ba6-4fff-958a-000000506d18 -User john@doe.com -Role Member -Force", + "Id": 1686, "Rank": 3 }, { - "Command": "Update-PnPUserType -LoginName jdoe@contoso.com", - "Id": 1666, "CommandName": "Update-PnPUserType", + "Command": "Update-PnPUserType -LoginName jdoe@contoso.com", + "Id": 1687, "Rank": 1 } ] diff --git a/src/Commands/Admin/GetTenantInfo.cs b/src/Commands/Admin/GetTenantInfo.cs index eed560c45..fd60a6ce0 100644 --- a/src/Commands/Admin/GetTenantInfo.cs +++ b/src/Commands/Admin/GetTenantInfo.cs @@ -35,7 +35,7 @@ protected override void ExecuteCmdlet() var requestUrl = BuildRequestUrl(); WriteVerbose($"Making call to {requestUrl} to request tenant information"); - var results = RestHelper.GetAsync(Connection.HttpClient, requestUrl, graphAccessToken).GetAwaiter().GetResult(); + var results = RestHelper.Get(Connection.HttpClient, requestUrl, graphAccessToken); WriteObject(results, true); } diff --git a/src/Commands/Admin/NewContainerType.cs b/src/Commands/Admin/NewContainerType.cs index c4559e543..e04a67204 100644 --- a/src/Commands/Admin/NewContainerType.cs +++ b/src/Commands/Admin/NewContainerType.cs @@ -7,9 +7,10 @@ namespace PnP.PowerShell.Commands.Admin { [Cmdlet(VerbsCommon.New, "PnPContainerType")] - public class NewContainerType : PnPAdminCmdlet,IDynamicParameters + public class NewContainerType : PnPAdminCmdlet, IDynamicParameters { private const string ParameterSet_Standard = "Standard"; + [Parameter(Mandatory = true)] public string ContainerTypeName; @@ -29,6 +30,15 @@ public object GetDynamicParameters() return null; } + // + // NOTICE: The SharePoint API being used in this code is of temporary nature. + // It will be replaced by Microsoft Graph in due time. + // This SharePoint API should not be called directly or implemented into your own tools or software. + // When the Microsoft Graph alternative becomes available, this PnP cmdlet will be rewritten to use it instead. + // So when using this PnP PowerShell cmdlet, the goal is to seemlessly transition to the new API. + // When you would use it in your own code directly, it will stop working at some point in time without prior announcement. + // + protected override void ExecuteCmdlet() { SPContainerTypeProperties sPContainerTypeProperties = new SPContainerTypeProperties(); diff --git a/src/Commands/Admin/PublishCompanyApp.cs b/src/Commands/Admin/PublishCompanyApp.cs index 51a765cef..9ca2e1b94 100644 --- a/src/Commands/Admin/PublishCompanyApp.cs +++ b/src/Commands/Admin/PublishCompanyApp.cs @@ -185,7 +185,7 @@ protected override void ExecuteCmdlet() if (!NoUpload) { var bytes = System.IO.File.ReadAllBytes(System.IO.Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, $"{AppName}.zip")); - TeamsUtility.AddAppAsync(Connection, GraphAccessToken, bytes).GetAwaiter().GetResult(); + TeamsUtility.AddApp(this, Connection, GraphAccessToken, bytes); WriteObject($"Teams app uploaded to teams app Store."); } } diff --git a/src/Commands/Admin/RenameTenantSite.cs b/src/Commands/Admin/RenameTenantSite.cs index 93c4d8216..393a8f23d 100644 --- a/src/Commands/Admin/RenameTenantSite.cs +++ b/src/Commands/Admin/RenameTenantSite.cs @@ -68,7 +68,7 @@ protected override void ExecuteCmdlet() OperationId = Guid.Empty }; - var results = Utilities.REST.RestHelper.PostAsync(HttpClient, $"{AdminContext.Url.TrimEnd('/')}/_api/SiteRenameJobs?api-version=1.4.7", AdminContext, body, false).GetAwaiter().GetResult(); + var results = Utilities.REST.RestHelper.Post(HttpClient, $"{AdminContext.Url.TrimEnd('/')}/_api/SiteRenameJobs?api-version=1.4.7", AdminContext, body, false); if (!Wait.IsPresent) { if (results != null) diff --git a/src/Commands/Admin/SetTenant.cs b/src/Commands/Admin/SetTenant.cs index 48283182d..451a4916d 100644 --- a/src/Commands/Admin/SetTenant.cs +++ b/src/Commands/Admin/SetTenant.cs @@ -469,6 +469,21 @@ public class SetTenant : PnPAdminCmdlet [Parameter(Mandatory = false)] public int? RecycleBinRetentionPeriod { get; set; } + [Parameter(Mandatory = false)] + public bool? IsSharePointAddInsDisabled { get; set; } + + [Parameter(Mandatory = false)] + public SharingScope? CoreDefaultShareLinkScope { private set; get; } + + [Parameter(Mandatory = false)] + public Role? CoreDefaultShareLinkRole { private set; get; } + + [Parameter(Mandatory = false)] + public SharingCapabilities? OneDriveSharingCapability { private set; get; } + + [Parameter(Mandatory = false)] + public string[] GuestSharingGroupAllowListInTenantByPrincipalIdentity { private set; get; } + protected override void ExecuteCmdlet() { AdminContext.Load(Tenant); @@ -1508,6 +1523,41 @@ protected override void ExecuteCmdlet() Tenant.RecycleBinRetentionPeriod = RecycleBinRetentionPeriod.Value; modified = true; } + if (IsSharePointAddInsDisabled.HasValue) + { + Tenant.SharePointAddInsDisabled = IsSharePointAddInsDisabled.Value; + modified = true; + } + if (CoreDefaultShareLinkScope.HasValue) + { + Tenant.CoreDefaultShareLinkScope = CoreDefaultShareLinkScope.Value; + modified = true; + } + if (CoreDefaultShareLinkRole.HasValue) + { + Tenant.CoreDefaultShareLinkRole = CoreDefaultShareLinkRole.Value; + modified = true; + } + if(OneDriveSharingCapability.HasValue) + { + Tenant.ODBSharingCapability = OneDriveSharingCapability.Value; + modified = true; + } + if (GuestSharingGroupAllowListInTenantByPrincipalIdentity !=null) + { + if (GuestSharingGroupAllowListInTenantByPrincipalIdentity.Length > 0) + { + if (!string.IsNullOrEmpty(GuestSharingGroupAllowListInTenantByPrincipalIdentity[0].ToString())) + { + Tenant.GuestSharingGroupAllowListInTenantByPrincipalIdentity = GuestSharingGroupAllowListInTenantByPrincipalIdentity; + } + else + { + Tenant.GuestSharingGroupAllowListInTenantByPrincipalIdentity = new string[0]; + } + } + modified = true; + } if (BlockDownloadFileTypePolicy.HasValue) { if (!BlockDownloadFileTypePolicy.Value) diff --git a/src/Commands/Admin/SetTenantSite.cs b/src/Commands/Admin/SetTenantSite.cs index 0a59ded10..1037a48b5 100644 --- a/src/Commands/Admin/SetTenantSite.cs +++ b/src/Commands/Admin/SetTenantSite.cs @@ -205,6 +205,24 @@ public class SetTenantSite : PnPAdminCmdlet [Parameter(Mandatory = false, ParameterSetName = ParameterSet_PROPERTIES)] public SharingScope LoopDefaultSharingLinkScope; + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_PROPERTIES)] + public bool RestrictContentOrgWideSearch; + + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_PROPERTIES)] + public bool ReadOnlyForUnmanagedDevices; + + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_PROPERTIES)] + public SwitchParameter InheritVersionPolicyFromTenant; + + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_PROPERTIES)] + public bool OverrideSharingCapability; + + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_PROPERTIES)] + public int RequestFilesLinkExpirationInDays; + + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_PROPERTIES)] + public bool RequestFilesLinkEnabled; + [Parameter(Mandatory = false)] public SwitchParameter Wait; @@ -614,6 +632,42 @@ private void SetSiteProperties(Func timeoutFunctio updateRequired = true; } + if (ParameterSpecified(nameof(RestrictContentOrgWideSearch))) + { + props.RestrictContentOrgWideSearch = RestrictContentOrgWideSearch; + updateRequired = true; + } + + if (ParameterSpecified(nameof(InheritVersionPolicyFromTenant))) + { + props.InheritVersionPolicyFromTenant = InheritVersionPolicyFromTenant; + updateRequired = true; + } + + if (ParameterSpecified(nameof(ReadOnlyForUnmanagedDevices))) + { + props.ReadOnlyForUnmanagedDevices = ReadOnlyForUnmanagedDevices; + updateRequired = true; + } + + if (ParameterSpecified(nameof(OverrideSharingCapability))) + { + props.OverrideSharingCapability = OverrideSharingCapability; + updateRequired = true; + } + + if (ParameterSpecified(nameof(RequestFilesLinkExpirationInDays))) + { + props.RequestFilesLinkExpirationInDays = RequestFilesLinkExpirationInDays; + updateRequired = true; + } + + if (ParameterSpecified(nameof(RequestFilesLinkEnabled))) + { + props.RequestFilesLinkEnabled = RequestFilesLinkEnabled; + updateRequired = true; + } + if (updateRequired) { var op = props.Update(); diff --git a/src/Commands/Apps/AddAzureADServicePrincipalAppRole.cs b/src/Commands/Apps/AddAzureADServicePrincipalAppRole.cs index d0b7223c0..3a8b26bf6 100644 --- a/src/Commands/Apps/AddAzureADServicePrincipalAppRole.cs +++ b/src/Commands/Apps/AddAzureADServicePrincipalAppRole.cs @@ -34,7 +34,7 @@ public class AddAzureADServicePrincipalAppRole : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var principal = Principal.GetServicePrincipal(Connection, AccessToken); + var principal = Principal.GetServicePrincipal(this, Connection, AccessToken); if(principal == null) { @@ -47,7 +47,7 @@ protected override void ExecuteCmdlet() if (AppRole.AppRole == null) { - var resource = ParameterSetName == ParameterSet_BYBUILTINTYPE ? ServicePrincipalUtility.GetServicePrincipalByBuiltInType(Connection, AccessToken, BuiltInType) : Resource.GetServicePrincipal(Connection, AccessToken); + var resource = ParameterSetName == ParameterSet_BYBUILTINTYPE ? ServicePrincipalUtility.GetServicePrincipalByBuiltInType(this, Connection, AccessToken, BuiltInType) : Resource.GetServicePrincipal(this, Connection, AccessToken); if (resource == null) { @@ -67,7 +67,7 @@ protected override void ExecuteCmdlet() WriteVerbose($"Adding app role {appRole.Value}: {appRole.DisplayName}"); - var response = ServicePrincipalUtility.AddServicePrincipalRoleAssignment(Connection, AccessToken, principal, appRole); + var response = ServicePrincipalUtility.AddServicePrincipalRoleAssignment(this, Connection, AccessToken, principal, appRole); WriteObject(response, false); } } diff --git a/src/Commands/Apps/GetAzureADAppSitePermission.cs b/src/Commands/Apps/GetAzureADAppSitePermission.cs index 1d8fa3e9e..88980151e 100644 --- a/src/Commands/Apps/GetAzureADAppSitePermission.cs +++ b/src/Commands/Apps/GetAzureADAppSitePermission.cs @@ -52,14 +52,14 @@ protected override void ExecuteCmdlet() var accessToken = AccessToken; // All permissions, first fetch just the Ids as the API works in a weird way that requesting all permissions does not reveal their roles, so we will request all permissions and then request each permission individually so we will also have the roles - var permissions = GraphHelper.GetResultCollectionAsync(Connection, $"https://{Connection.GraphEndPoint}/v1.0/sites/{siteId}/permissions?$select=Id", accessToken).GetAwaiter().GetResult(); + var permissions = GraphHelper.GetResultCollection(this, Connection, $"https://{Connection.GraphEndPoint}/v1.0/sites/{siteId}/permissions?$select=Id", accessToken); if (permissions.Any()) { var results = new List(); foreach (var permission in permissions) { // Request the permission individually so it will include the roles - var detailedApp = GraphHelper.GetAsync(Connection, $"https://{Connection.GraphEndPoint}/v1.0/sites/{siteId}/permissions/{permission.Id}", accessToken).GetAwaiter().GetResult(); + var detailedApp = GraphHelper.Get(this, Connection, $"https://{Connection.GraphEndPoint}/v1.0/sites/{siteId}/permissions/{permission.Id}", accessToken); results.Add(detailedApp.Convert()); } @@ -76,7 +76,7 @@ protected override void ExecuteCmdlet() } else { - var results = GraphHelper.GetAsync(Connection, $"https://{Connection.GraphEndPoint}/v1.0/sites/{siteId}/permissions/{PermissionId}", AccessToken).GetAwaiter().GetResult(); + var results = GraphHelper.Get(this, Connection, $"https://{Connection.GraphEndPoint}/v1.0/sites/{siteId}/permissions/{PermissionId}", AccessToken); WriteObject(results.Convert()); } } diff --git a/src/Commands/Apps/GetAzureADServicePrincipal.cs b/src/Commands/Apps/GetAzureADServicePrincipal.cs index def1f5e0c..60673b766 100644 --- a/src/Commands/Apps/GetAzureADServicePrincipal.cs +++ b/src/Commands/Apps/GetAzureADServicePrincipal.cs @@ -42,19 +42,19 @@ protected override void ExecuteCmdlet() switch (ParameterSetName) { case ParameterSet_BYAPPID: - servicePrincipal = ServicePrincipalUtility.GetServicePrincipalByAppId(Connection, AccessToken, AppId); + servicePrincipal = ServicePrincipalUtility.GetServicePrincipalByAppId(this, Connection, AccessToken, AppId); break; case ParameterSet_BYOBJECTID: - servicePrincipal = ServicePrincipalUtility.GetServicePrincipalByObjectId(Connection, AccessToken, ObjectId); + servicePrincipal = ServicePrincipalUtility.GetServicePrincipalByObjectId(this, Connection, AccessToken, ObjectId); break; case ParameterSet_BYAPPNAME: - servicePrincipal = ServicePrincipalUtility.GetServicePrincipalByAppName(Connection, AccessToken, AppName); + servicePrincipal = ServicePrincipalUtility.GetServicePrincipalByAppName(this, Connection, AccessToken, AppName); break; case ParameterSet_BYBUILTINTYPE: - servicePrincipal = ServicePrincipalUtility.GetServicePrincipalByBuiltInType(Connection, AccessToken, BuiltInType); + servicePrincipal = ServicePrincipalUtility.GetServicePrincipalByBuiltInType(this, Connection, AccessToken, BuiltInType); break; case ParameterSet_ALL: - var servicePrincipals = ServicePrincipalUtility.GetServicePrincipals(Connection, AccessToken, Filter); + var servicePrincipals = ServicePrincipalUtility.GetServicePrincipals(this, Connection, AccessToken, Filter); WriteObject(servicePrincipals, true); return; } diff --git a/src/Commands/Apps/GetAzureADServicePrincipalAssignedAppRole.cs b/src/Commands/Apps/GetAzureADServicePrincipalAssignedAppRole.cs index 28507ba75..3aac860f8 100644 --- a/src/Commands/Apps/GetAzureADServicePrincipalAssignedAppRole.cs +++ b/src/Commands/Apps/GetAzureADServicePrincipalAssignedAppRole.cs @@ -22,7 +22,7 @@ public class GetAzureADServicePrincipalAssignedAppRole : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var principal = Principal.GetServicePrincipal(Connection, AccessToken); + var principal = Principal.GetServicePrincipal(this, Connection, AccessToken); if(principal == null) { @@ -31,7 +31,7 @@ protected override void ExecuteCmdlet() WriteVerbose($"Requesting currently assigned app roles to service principal {principal.DisplayName}"); - var appRoleAssignments = ServicePrincipalUtility.GetServicePrincipalAppRoleAssignmentsByServicePrincipalObjectId(Connection, AccessToken, principal.Id); + var appRoleAssignments = ServicePrincipalUtility.GetServicePrincipalAppRoleAssignmentsByServicePrincipalObjectId(this, Connection, AccessToken, principal.Id); if(ParameterSpecified(nameof(Identity))) { var appRole = Identity.GetAvailableAppRole(Connection, AccessToken, principal); diff --git a/src/Commands/Apps/GetAzureADServicePrincipalAvailableAppRole.cs b/src/Commands/Apps/GetAzureADServicePrincipalAvailableAppRole.cs index 238de01bb..cced88f9b 100644 --- a/src/Commands/Apps/GetAzureADServicePrincipalAvailableAppRole.cs +++ b/src/Commands/Apps/GetAzureADServicePrincipalAvailableAppRole.cs @@ -21,7 +21,7 @@ public class GetAzureADServicePrincipalAvailableAppRole : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var principal = Principal.GetServicePrincipal(Connection, AccessToken); + var principal = Principal.GetServicePrincipal(this, Connection, AccessToken); if(principal == null) { diff --git a/src/Commands/Apps/GrantAzureADAppSitePermission.cs b/src/Commands/Apps/GrantAzureADAppSitePermission.cs index 2372a84e7..234bac4e6 100644 --- a/src/Commands/Apps/GrantAzureADAppSitePermission.cs +++ b/src/Commands/Apps/GrantAzureADAppSitePermission.cs @@ -56,7 +56,7 @@ protected override void ExecuteCmdlet() // Adding a fix for multi-geo issue // https://github.com/pnp/powershell/issues/2801 - var multiGeoFix = Utilities.REST.RestHelper.GetAsync(Connection.HttpClient, $"https://{Connection.GraphEndPoint}/v1.0/sites/{siteId}", AccessToken).GetAwaiter().GetResult(); + var multiGeoFix = Utilities.REST.RestHelper.Get(Connection.HttpClient, $"https://{Connection.GraphEndPoint}/v1.0/sites/{siteId}", AccessToken); // Construct the payload of the Graph request var payload = new @@ -83,7 +83,7 @@ protected override void ExecuteCmdlet() WriteVerbose($"Granting App with Id {AppId} the permission{(payload.roles.Length != 1 ? "s" : "")} {string.Join(',', payload.roles)}"); // Make the Graph Grant request - var result = Utilities.REST.RestHelper.PostAsync(Connection.HttpClient, $"https://{Connection.GraphEndPoint}/v1.0/sites/{siteId}/permissions", AccessToken, payload).GetAwaiter().GetResult(); + var result = Utilities.REST.RestHelper.Post(Connection.HttpClient, $"https://{Connection.GraphEndPoint}/v1.0/sites/{siteId}/permissions", AccessToken, payload); WriteObject(result.Convert()); } } diff --git a/src/Commands/Apps/GrantTenantServicePrincipalPermission.cs b/src/Commands/Apps/GrantTenantServicePrincipalPermission.cs index 1742cedda..ae62a554f 100644 --- a/src/Commands/Apps/GrantTenantServicePrincipalPermission.cs +++ b/src/Commands/Apps/GrantTenantServicePrincipalPermission.cs @@ -26,7 +26,7 @@ protected override void ExecuteCmdlet() { var spoWebAppServicePrincipal = new SPOWebAppServicePrincipal(tenantContext); var appId = spoWebAppServicePrincipal.EnsureProperty(a => a.AppId); - var results = GraphHelper.GetAsync>(Connection, $"/v1.0/servicePrincipals?$filter=appId eq '{appId}'&$select=id", AccessToken).GetAwaiter().GetResult(); + var results = GraphHelper.Get>(this, Connection, $"/v1.0/servicePrincipals?$filter=appId eq '{appId}'&$select=id", AccessToken); if (results.Items.Any()) { var servicePrincipal = results.Items.First(); diff --git a/src/Commands/Apps/RemoveAzureADServicePrincipalAssignedAppRole.cs b/src/Commands/Apps/RemoveAzureADServicePrincipalAssignedAppRole.cs index 19ec31141..1fce57a90 100644 --- a/src/Commands/Apps/RemoveAzureADServicePrincipalAssignedAppRole.cs +++ b/src/Commands/Apps/RemoveAzureADServicePrincipalAssignedAppRole.cs @@ -33,7 +33,7 @@ protected override void ExecuteCmdlet() { if(ParameterSetName == ParameterSet_BYASSIGNEDAPPROLE || ParameterSetName == ParameterSet_BYAPPROLENAME) { - var principal = Principal.GetServicePrincipal(Connection, AccessToken); + var principal = Principal.GetServicePrincipal(this, Connection, AccessToken); if(principal == null) { @@ -46,23 +46,23 @@ protected override void ExecuteCmdlet() { if (ParameterSpecified(nameof(Identity))) { - var appRoleAssignment = Identity.GetAssignedAppRole(Connection, AccessToken, principal.Id); - ServicePrincipalUtility.RemoveServicePrincipalRoleAssignment(Connection, AccessToken, appRoleAssignment); + var appRoleAssignment = Identity.GetAssignedAppRole(this, Connection, AccessToken, principal.Id); + ServicePrincipalUtility.RemoveServicePrincipalRoleAssignment(this, Connection, AccessToken, appRoleAssignment); } else { - ServicePrincipalUtility.RemoveServicePrincipalRoleAssignment(Connection, AccessToken, principal); + ServicePrincipalUtility.RemoveServicePrincipalRoleAssignment(this, Connection, AccessToken, principal); } } else { - ServicePrincipalUtility.RemoveServicePrincipalRoleAssignment(Connection, AccessToken, principal, AppRoleName); + ServicePrincipalUtility.RemoveServicePrincipalRoleAssignment(this, Connection, AccessToken, principal, AppRoleName); } } else { - var appRoleAssignment = Identity.GetAssignedAppRole(Connection, AccessToken); - ServicePrincipalUtility.RemoveServicePrincipalRoleAssignment(Connection, AccessToken, appRoleAssignment); + var appRoleAssignment = Identity.GetAssignedAppRole(this, Connection, AccessToken); + ServicePrincipalUtility.RemoveServicePrincipalRoleAssignment(this, Connection, AccessToken, appRoleAssignment); } } } diff --git a/src/Commands/Apps/RevokeAzureADAppSitePermission.cs b/src/Commands/Apps/RevokeAzureADAppSitePermission.cs index f1a1f3c0c..e4f56d87b 100644 --- a/src/Commands/Apps/RevokeAzureADAppSitePermission.cs +++ b/src/Commands/Apps/RevokeAzureADAppSitePermission.cs @@ -38,7 +38,7 @@ protected override void ExecuteCmdlet() { if (Force || ShouldContinue("Are you sure you want to revoke the permissions?", string.Empty)) { - var results = PnP.PowerShell.Commands.Utilities.REST.RestHelper.DeleteAsync(Connection.HttpClient, $"https://{Connection.GraphEndPoint}/v1.0/sites/{siteId}/permissions/{PermissionId}", AccessToken).GetAwaiter().GetResult(); + var results = PnP.PowerShell.Commands.Utilities.REST.RestHelper.Delete(Connection.HttpClient, $"https://{Connection.GraphEndPoint}/v1.0/sites/{siteId}/permissions/{PermissionId}", AccessToken); } } } diff --git a/src/Commands/Apps/RevokeTenantServicePrincipalPermission.cs b/src/Commands/Apps/RevokeTenantServicePrincipalPermission.cs index 97c167e91..17dece954 100644 --- a/src/Commands/Apps/RevokeTenantServicePrincipalPermission.cs +++ b/src/Commands/Apps/RevokeTenantServicePrincipalPermission.cs @@ -30,7 +30,7 @@ protected override void ExecuteCmdlet() { var spoWebAppServicePrincipal = new SPOWebAppServicePrincipal(tenantContext); var appId = spoWebAppServicePrincipal.EnsureProperty(a => a.AppId); - var results = GraphHelper.GetAsync>(Connection, $"/v1.0/servicePrincipals?$filter=appId eq '{appId}'&$select=id", AccessToken).GetAwaiter().GetResult(); + var results = GraphHelper.Get>(this, Connection, $"/v1.0/servicePrincipals?$filter=appId eq '{appId}'&$select=id", AccessToken); if (results.Items.Any()) { if (Force || ShouldContinue($"Revoke permission {Scope}?", "Continue")) diff --git a/src/Commands/Apps/SetAzureADAppSitePermission.cs b/src/Commands/Apps/SetAzureADAppSitePermission.cs index 4d8f055e4..335c102da 100644 --- a/src/Commands/Apps/SetAzureADAppSitePermission.cs +++ b/src/Commands/Apps/SetAzureADAppSitePermission.cs @@ -48,7 +48,7 @@ protected override void ExecuteCmdlet() roles = Permissions.Select(p => p.ToLower()).ToArray() }; - var results = Utilities.REST.RestHelper.PatchAsync(Connection.HttpClient, $"https://{Connection.GraphEndPoint}/v1.0/sites/{siteId}/permissions/{PermissionId}", AccessToken, payload).GetAwaiter().GetResult(); + var results = Utilities.REST.RestHelper.Patch(Connection.HttpClient, $"https://{Connection.GraphEndPoint}/v1.0/sites/{siteId}/permissions/{PermissionId}", AccessToken, payload); WriteObject(results.Convert()); } } diff --git a/src/Commands/Attributes/RequiredApiPermissions.cs b/src/Commands/Attributes/RequiredApiPermissions.cs index 505557494..3c0c4d721 100644 --- a/src/Commands/Attributes/RequiredApiPermissions.cs +++ b/src/Commands/Attributes/RequiredApiPermissions.cs @@ -2,7 +2,7 @@ namespace PnP.PowerShell.Commands.Attributes { - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public sealed class RequiredMinimalApiPermissions : Attribute { public string[] PermissionScopes { get; set; } diff --git a/src/Commands/AzureAD/AddAzureADGroupMember.cs b/src/Commands/AzureAD/AddAzureADGroupMember.cs index 5c7c33f20..53f169ae1 100644 --- a/src/Commands/AzureAD/AddAzureADGroupMember.cs +++ b/src/Commands/AzureAD/AddAzureADGroupMember.cs @@ -34,7 +34,7 @@ protected override void ExecuteCmdlet() if (Identity != null) { - group = Identity.GetGroup(Connection, AccessToken); + group = Identity.GetGroup(this, Connection, AccessToken); } if (group != null) { @@ -44,14 +44,14 @@ protected override void ExecuteCmdlet() if (userArray.Length > 0) { - Microsoft365GroupsUtility.AddMembersAsync(Connection, new System.Guid(group.Id), userArray, AccessToken, RemoveExisting.ToBool()).GetAwaiter().GetResult(); + ClearOwners.AddMembers(this, Connection, new Guid(group.Id), userArray, AccessToken, RemoveExisting.ToBool()); } var secGroups = Users.Where(x => Guid.TryParse(x, out emptyGuid)).Select(x => emptyGuid).ToArray(); if (secGroups.Length > 0) { - Microsoft365GroupsUtility.AddDirectoryMembersAsync(Connection, new System.Guid(group.Id), secGroups, AccessToken, RemoveExisting.ToBool()).GetAwaiter().GetResult(); + ClearOwners.AddDirectoryMembers(this, Connection, new Guid(group.Id), secGroups, AccessToken, RemoveExisting.ToBool()); } } } diff --git a/src/Commands/AzureAD/AddAzureADGroupOwner.cs b/src/Commands/AzureAD/AddAzureADGroupOwner.cs index 85c7d76d7..8fdd3a5df 100644 --- a/src/Commands/AzureAD/AddAzureADGroupOwner.cs +++ b/src/Commands/AzureAD/AddAzureADGroupOwner.cs @@ -29,7 +29,7 @@ protected override void ExecuteCmdlet() if (Identity != null) { - group = Identity.GetGroup(Connection, AccessToken); + group = Identity.GetGroup(this, Connection, AccessToken); } if (group != null) @@ -41,14 +41,14 @@ protected override void ExecuteCmdlet() if (userArray.Length > 0) { - Microsoft365GroupsUtility.AddOwnersAsync(Connection, new System.Guid(group.Id), userArray, AccessToken, RemoveExisting.ToBool()).GetAwaiter().GetResult(); + ClearOwners.AddOwners(this, Connection, new System.Guid(group.Id), userArray, AccessToken, RemoveExisting.ToBool()); } var secGroups = Users.Where(x => Guid.TryParse(x, out emptyGuid)).Select(x => emptyGuid).ToArray(); if (secGroups.Length > 0) { - Microsoft365GroupsUtility.AddDirectoryOwnersAsync(Connection, new System.Guid(group.Id), secGroups, AccessToken, RemoveExisting.ToBool()).GetAwaiter().GetResult(); + ClearOwners.AddDirectoryOwners(this, Connection, new System.Guid(group.Id), secGroups, AccessToken, RemoveExisting.ToBool()); } } } diff --git a/src/Commands/AzureAD/ClearAzureADGroupMember.cs b/src/Commands/AzureAD/ClearAzureADGroupMember.cs index 5fe5b3ff7..32eb75b8a 100644 --- a/src/Commands/AzureAD/ClearAzureADGroupMember.cs +++ b/src/Commands/AzureAD/ClearAzureADGroupMember.cs @@ -22,16 +22,16 @@ protected override void ExecuteCmdlet() if (Identity != null) { - group = Identity.GetGroup(Connection, AccessToken); + group = Identity.GetGroup(this, Connection, AccessToken); } if (group != null) { - var members = Microsoft365GroupsUtility.GetMembersAsync(Connection, new System.Guid(group.Id), AccessToken).GetAwaiter().GetResult(); + var members = ClearOwners.GetMembers(this, Connection, new System.Guid(group.Id), AccessToken); var membersToBeRemoved = members?.Select(p => p.UserPrincipalName).ToArray(); - Microsoft365GroupsUtility.RemoveMembersAsync(Connection, new System.Guid(group.Id), membersToBeRemoved, AccessToken).GetAwaiter().GetResult(); + ClearOwners.RemoveMembers(this, Connection, new System.Guid(group.Id), membersToBeRemoved, AccessToken); } } } diff --git a/src/Commands/AzureAD/ClearAzureADGroupOwner.cs b/src/Commands/AzureAD/ClearAzureADGroupOwner.cs index cb218e7d8..d542a8c85 100644 --- a/src/Commands/AzureAD/ClearAzureADGroupOwner.cs +++ b/src/Commands/AzureAD/ClearAzureADGroupOwner.cs @@ -22,16 +22,16 @@ protected override void ExecuteCmdlet() if (Identity != null) { - group = Identity.GetGroup(Connection, AccessToken); + group = Identity.GetGroup(this, Connection, AccessToken); } if (group != null) { - var owners = Microsoft365GroupsUtility.GetOwnersAsync(Connection, new System.Guid(group.Id), AccessToken).GetAwaiter().GetResult(); + var owners = ClearOwners.GetOwners(this, Connection, new System.Guid(group.Id), AccessToken); var ownersToBeRemoved = owners?.Select(p => p.UserPrincipalName).ToArray(); - Microsoft365GroupsUtility.RemoveOwnersAsync(Connection, new System.Guid(group.Id), ownersToBeRemoved, AccessToken).GetAwaiter().GetResult(); + ClearOwners.RemoveOwners(this, Connection, new System.Guid(group.Id), ownersToBeRemoved, AccessToken); } } } diff --git a/src/Commands/AzureAD/GetAzureADActivityReportDirectoryAudit.cs b/src/Commands/AzureAD/GetAzureADActivityReportDirectoryAudit.cs index d51fc781c..d13b2bf32 100644 --- a/src/Commands/AzureAD/GetAzureADActivityReportDirectoryAudit.cs +++ b/src/Commands/AzureAD/GetAzureADActivityReportDirectoryAudit.cs @@ -31,12 +31,12 @@ protected override void ExecuteCmdlet() if (ParameterSpecified(nameof(Identity))) { - var auditResults = GraphHelper.GetAsync(Connection, auditLogUrl, AccessToken).GetAwaiter().GetResult(); + var auditResults = GraphHelper.Get(this, Connection, auditLogUrl, AccessToken); WriteObject(auditResults, false); } else { - var auditResults = GraphHelper.GetResultCollectionAsync(Connection, auditLogUrl, AccessToken).GetAwaiter().GetResult(); + var auditResults = GraphHelper.GetResultCollection(this, Connection, auditLogUrl, AccessToken); WriteObject(auditResults, true); } } diff --git a/src/Commands/AzureAD/GetAzureADActivityReportSignIn.cs b/src/Commands/AzureAD/GetAzureADActivityReportSignIn.cs index ff12d4e0b..82387d54a 100644 --- a/src/Commands/AzureAD/GetAzureADActivityReportSignIn.cs +++ b/src/Commands/AzureAD/GetAzureADActivityReportSignIn.cs @@ -35,12 +35,12 @@ protected override void ExecuteCmdlet() if (ParameterSpecified(nameof(Identity))) { - var auditResults = GraphHelper.GetAsync(Connection, signInUrl, AccessToken).GetAwaiter().GetResult(); + var auditResults = GraphHelper.Get(this, Connection, signInUrl, AccessToken); WriteObject(auditResults, false); } else { - var auditResults = GraphHelper.GetResultCollectionAsync(Connection, signInUrl, AccessToken).GetAwaiter().GetResult(); + var auditResults = GraphHelper.GetResultCollection(this, Connection, signInUrl, AccessToken); WriteObject(auditResults, true); } } diff --git a/src/Commands/AzureAD/GetAzureADApp.cs b/src/Commands/AzureAD/GetAzureADApp.cs index 83d2bb701..a6c881a94 100644 --- a/src/Commands/AzureAD/GetAzureADApp.cs +++ b/src/Commands/AzureAD/GetAzureADApp.cs @@ -41,7 +41,7 @@ protected override void ExecuteCmdlet() { "ConsistencyLevel", "eventual" } }; } - var result = GraphHelper.GetResultCollectionAsync(Connection, requestUrl, AccessToken, additionalHeaders: additionalHeaders).GetAwaiter().GetResult(); + var result = GraphHelper.GetResultCollection(this, Connection, requestUrl, AccessToken, additionalHeaders: additionalHeaders); WriteObject(result, true); } } diff --git a/src/Commands/AzureAD/GetAzureADAppPermission.cs b/src/Commands/AzureAD/GetAzureADAppPermission.cs index 7335a966e..03c85d893 100644 --- a/src/Commands/AzureAD/GetAzureADAppPermission.cs +++ b/src/Commands/AzureAD/GetAzureADAppPermission.cs @@ -26,7 +26,7 @@ protected override void ExecuteCmdlet() else { List apps = new List(); - var result = GraphHelper.GetResultCollectionAsync(Connection, "/v1.0/applications", AccessToken).GetAwaiter().GetResult(); + var result = GraphHelper.GetResultCollection(this, Connection, "/v1.0/applications", AccessToken); if (result != null && result.Any()) { apps.AddRange(result.Select(p => ConvertToPSObject(p))); diff --git a/src/Commands/AzureAD/GetAzureADGroup.cs b/src/Commands/AzureAD/GetAzureADGroup.cs index bd754ffc4..25fa1301f 100644 --- a/src/Commands/AzureAD/GetAzureADGroup.cs +++ b/src/Commands/AzureAD/GetAzureADGroup.cs @@ -9,6 +9,7 @@ namespace PnP.PowerShell.Commands.Graph { [Cmdlet(VerbsCommon.Get, "PnPAzureADGroup")] [RequiredMinimalApiPermissions("Group.Read.All")] + [RequiredMinimalApiPermissions("Group.ReadWrite.All")] [Alias("Get-PnPEntraIDGroup")] public class GetAzureADGroup : PnPGraphCmdlet { @@ -19,7 +20,7 @@ protected override void ExecuteCmdlet() { if (Identity != null) { - var group = Identity.GetGroup(Connection, AccessToken); + var group = Identity.GetGroup(this, Connection, AccessToken); if (group != null) { WriteObject(group); @@ -27,7 +28,7 @@ protected override void ExecuteCmdlet() } else { - var groups = AzureADGroupsUtility.GetGroupsAsync(Connection, AccessToken).GetAwaiter().GetResult(); + var groups = AzureADGroupsUtility.GetGroups(this, Connection, AccessToken); if (groups != null) { WriteObject(groups?.OrderBy(m => m.DisplayName), true); diff --git a/src/Commands/AzureAD/GetAzureADGroupMember.cs b/src/Commands/AzureAD/GetAzureADGroupMember.cs index fcd6251a6..81744c965 100644 --- a/src/Commands/AzureAD/GetAzureADGroupMember.cs +++ b/src/Commands/AzureAD/GetAzureADGroupMember.cs @@ -11,6 +11,7 @@ namespace PnP.PowerShell.Commands.Graph { [Cmdlet(VerbsCommon.Get, "PnPAzureADGroupMember")] [RequiredMinimalApiPermissions("Group.Read.All")] + [RequiredMinimalApiPermissions("Group.ReadWrite.All")] [Alias("Get-PnPEntraIDGroupMember")] public class GetAzureADGroupMember : PnPGraphCmdlet { @@ -23,13 +24,13 @@ protected override void ExecuteCmdlet() if (Identity != null) { - group = Identity.GetGroup(Connection, AccessToken); + group = Identity.GetGroup(this, Connection, AccessToken); } if (group != null) { // Get members of the group - var members = Microsoft365GroupsUtility.GetMembersAsync(Connection, new Guid(group.Id), AccessToken).GetAwaiter().GetResult(); + var members = ClearOwners.GetMembers(this, Connection, new Guid(group.Id), AccessToken); WriteObject(members?.OrderBy(m => m.DisplayName), true); } } diff --git a/src/Commands/AzureAD/GetAzureADGroupOwner.cs b/src/Commands/AzureAD/GetAzureADGroupOwner.cs index 2a29ce65e..e9ef15214 100644 --- a/src/Commands/AzureAD/GetAzureADGroupOwner.cs +++ b/src/Commands/AzureAD/GetAzureADGroupOwner.cs @@ -23,13 +23,13 @@ protected override void ExecuteCmdlet() if (Identity != null) { - group = Identity.GetGroup(Connection, AccessToken); + group = Identity.GetGroup(this, Connection, AccessToken); } if (group != null) { // Get Owners of the group - var owners = Microsoft365GroupsUtility.GetOwnersAsync(Connection, new Guid(group.Id), AccessToken).GetAwaiter().GetResult(); + var owners = ClearOwners.GetOwners(this, Connection, new Guid(group.Id), AccessToken); WriteObject(owners?.OrderBy(m => m.DisplayName), true); } } diff --git a/src/Commands/AzureAD/NewAzureADGroup.cs b/src/Commands/AzureAD/NewAzureADGroup.cs index 659bd65da..a4262c8e4 100644 --- a/src/Commands/AzureAD/NewAzureADGroup.cs +++ b/src/Commands/AzureAD/NewAzureADGroup.cs @@ -52,7 +52,7 @@ protected override void ExecuteCmdlet() if (!Force) { - var existingGroup = AzureADGroupsUtility.GetGroupAsync(Connection, MailNickname, AccessToken).GetAwaiter().GetResult(); + var existingGroup = AzureADGroupsUtility.GetGroup(this, Connection, MailNickname, AccessToken); forceCreation = existingGroup == null || ShouldContinue(string.Format(Resources.ForceCreationOfExistingGroup0, MailNickname), Resources.Confirm); } @@ -77,12 +77,12 @@ protected override void ExecuteCmdlet() if (Owners?.Length > 0) { - ownerData = Microsoft365GroupsUtility.GetUsersDataBindValueAsync(Connection, AccessToken, Owners).GetAwaiter().GetResult(); + ownerData = ClearOwners.GetUsersDataBindValue(this, Connection, AccessToken, Owners); postData.Add("owners@odata.bind", ownerData); } if (Members?.Length > 0) { - memberData = Microsoft365GroupsUtility.GetUsersDataBindValueAsync(Connection, AccessToken, Members).GetAwaiter().GetResult(); + memberData = ClearOwners.GetUsersDataBindValue(this, Connection, AccessToken, Members); postData.Add("members@odata.bind", memberData); } @@ -90,7 +90,7 @@ protected override void ExecuteCmdlet() var stringContent = new StringContent(data); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - var groupResult = GraphHelper.PostAsync(Connection, $"v1.0/groups", stringContent, AccessToken).GetAwaiter().GetResult(); + var groupResult = GraphHelper.Post(this, Connection, $"v1.0/groups", stringContent, AccessToken); WriteObject(groupResult); } diff --git a/src/Commands/AzureAD/NewAzureADUserTemporaryAccessPass.cs b/src/Commands/AzureAD/NewAzureADUserTemporaryAccessPass.cs index 861fd84ee..7948f4f17 100644 --- a/src/Commands/AzureAD/NewAzureADUserTemporaryAccessPass.cs +++ b/src/Commands/AzureAD/NewAzureADUserTemporaryAccessPass.cs @@ -28,7 +28,7 @@ protected override void ExecuteCmdlet() { var accessPass = UsersUtility.RequestTemporaryAccessPass( accessToken: AccessToken, - userId: Identity.User?.Id?.ToString() ?? Identity.Upn ?? Identity.UserId, + userId: Identity.User?.Id?.ToString() ?? Identity.Upn ?? (Identity.UserId.HasValue ? Identity.UserId.Value.ToString() : null), startDateTime: StartDateTime, lifeTimeInMinutes: LifeTimeInMinutes, isUsableOnce: IsUsableOnce, azureEnvironment: Connection.AzureEnvironment); diff --git a/src/Commands/AzureAD/RegisterAzureADApp.cs b/src/Commands/AzureAD/RegisterAzureADApp.cs index 612a609e3..08b2ce6d3 100644 --- a/src/Commands/AzureAD/RegisterAzureADApp.cs +++ b/src/Commands/AzureAD/RegisterAzureADApp.cs @@ -17,6 +17,7 @@ using Resources = PnP.PowerShell.Commands.Properties.Resources; using PnP.PowerShell.Commands.Base; using System.Diagnostics; +using System.Dynamic; namespace PnP.PowerShell.Commands.AzureAD { @@ -90,6 +91,15 @@ public class RegisterAzureADApp : BasePSCmdlet, IDynamicParameters [Parameter(Mandatory = false)] public string LogoFilePath; + [Parameter(Mandatory = false)] + public SwitchParameter SkipCertCreation; + + [Parameter(Mandatory = false)] + public string MicrosoftGraphEndPoint; + + [Parameter(Mandatory = false)] + public string EntraIDLoginEndPoint; + protected override void ProcessRecord() { if (ParameterSpecified(nameof(Store)) && !OperatingSystem.IsWindows()) @@ -124,7 +134,7 @@ protected override void ProcessRecord() using (var authenticationManager = new AuthenticationManager()) { - loginEndPoint = authenticationManager.GetAzureADLoginEndPoint(AzureEnvironment); + loginEndPoint = authenticationManager.GetAzureADLoginEndPoint(AzureEnvironment) ?? EntraIDLoginEndPoint; } var permissionScopes = new PermissionScopes(); @@ -195,7 +205,11 @@ protected override void ProcessRecord() if (!string.IsNullOrEmpty(token)) { - var cert = GetCertificate(record); + X509Certificate2 cert = null; + if (!SkipCertCreation) + { + cert = GetCertificate(record); + } var httpClient = Framework.Http.PnPHttpClient.Instance.GetHttpClient(); if (!AppExists(ApplicationName, httpClient, token)) @@ -203,10 +217,13 @@ protected override void ProcessRecord() var azureApp = CreateApp(loginEndPoint, httpClient, token, cert, redirectUri, scopes); record.Properties.Add(new PSVariableProperty(new PSVariable("AzureAppId/ClientId", azureApp.AppId))); - record.Properties.Add(new PSVariableProperty(new PSVariable("Certificate Thumbprint", cert.GetCertHashString()))); - byte[] certPfxData = cert.Export(X509ContentType.Pfx, CertificatePassword); - var base64String = Convert.ToBase64String(certPfxData); - record.Properties.Add(new PSVariableProperty(new PSVariable("Base64Encoded", base64String))); + if (cert != null) + { + record.Properties.Add(new PSVariableProperty(new PSVariable("Certificate Thumbprint", cert.GetCertHashString()))); + byte[] certPfxData = cert.Export(X509ContentType.Pfx, CertificatePassword); + var base64String = Convert.ToBase64String(certPfxData); + record.Properties.Add(new PSVariableProperty(new PSVariable("Base64Encoded", base64String))); + } StartConsentFlow(loginEndPoint, azureApp, redirectUri, token, httpClient, record, messageWriter, scopes); if (ParameterSpecified(nameof(LogoFilePath)) && !string.IsNullOrEmpty(LogoFilePath)) @@ -412,7 +429,7 @@ private string GetAuthToken(CmdletMessageWriter messageWriter) { Task.Factory.StartNew(() => { - token = AzureAuthHelper.AuthenticateDeviceLogin(cancellationTokenSource, messageWriter, NoPopup, AzureEnvironment); + token = AzureAuthHelper.AuthenticateDeviceLogin(cancellationTokenSource, messageWriter, NoPopup, AzureEnvironment, MicrosoftGraphEndPoint); if (token == null) { messageWriter.WriteWarning("Operation cancelled or no token retrieved."); @@ -425,7 +442,7 @@ private string GetAuthToken(CmdletMessageWriter messageWriter) { Task.Factory.StartNew(() => { - token = AzureAuthHelper.AuthenticateInteractive(cancellationTokenSource, messageWriter, NoPopup, AzureEnvironment, Tenant); + token = AzureAuthHelper.AuthenticateInteractive(cancellationTokenSource, messageWriter, NoPopup, AzureEnvironment, Tenant, MicrosoftGraphEndPoint); if (token == null) { messageWriter.WriteWarning("Operation cancelled or no token retrieved."); @@ -449,7 +466,7 @@ private string GetAuthToken(CmdletMessageWriter messageWriter) { throw new PSArgumentException("Password is required or use -DeviceLogin or -Interactive"); } - token = AzureAuthHelper.AuthenticateAsync(Tenant, Username, Password, AzureEnvironment).GetAwaiter().GetResult(); + token = AzureAuthHelper.AuthenticateAsync(Tenant, Username, Password, AzureEnvironment, MicrosoftGraphEndPoint).GetAwaiter().GetResult(); } return token; @@ -531,10 +548,10 @@ private bool AppExists(string appName, HttpClient httpClient, string token) var graphEndpoint = $"https://{AuthenticationManager.GetGraphEndPoint(AzureEnvironment)}"; if (AzureEnvironment == AzureEnvironment.Custom) { - graphEndpoint = Environment.GetEnvironmentVariable("MicrosoftGraphEndPoint", EnvironmentVariableTarget.Process); + graphEndpoint = Environment.GetEnvironmentVariable("MicrosoftGraphEndPoint", EnvironmentVariableTarget.Process) ?? MicrosoftGraphEndPoint; } - var azureApps = RestHelper.GetAsync>(httpClient, $"{graphEndpoint}/v1.0/applications?$filter=displayName eq '{appName}'&$select=Id", token).GetAwaiter().GetResult(); + var azureApps = RestHelper.Get>(httpClient, $"{graphEndpoint}/v1.0/applications?$filter=displayName eq '{appName}'&$select=Id", token); if (azureApps != null && azureApps.Items.Any()) { Host.UI.WriteLine(); @@ -546,16 +563,24 @@ private bool AppExists(string appName, HttpClient httpClient, string token) private AzureADApp CreateApp(string loginEndPoint, HttpClient httpClient, string token, X509Certificate2 cert, string redirectUri, List scopes) { - var expirationDate = cert.NotAfter.ToUniversalTime(); - var startDate = cert.NotBefore.ToUniversalTime(); - var scopesPayload = GetScopesPayload(scopes); - var payload = new + var redirectUris = new List() { $"{loginEndPoint}/common/oauth2/nativeclient", redirectUri }; + if (redirectUri != "http://localhost") + { + redirectUris.Add("http://localhost"); + } + dynamic payload = new ExpandoObject(); + payload.isFallbackPublicClient = true; + payload.displayName = ApplicationName; + payload.signInAudience = "AzureADMyOrg"; + payload.publicClient = new { redirectUris = redirectUris.ToArray() }; + payload.requiredResourceAccess = scopesPayload; + + if (cert != null) { - isFallbackPublicClient = true, - displayName = ApplicationName, - signInAudience = "AzureADMyOrg", - keyCredentials = new[] { + var expirationDate = cert.NotAfter.ToUniversalTime(); + var startDate = cert.NotBefore.ToUniversalTime(); + payload.keyCredentials = new[] { new { customKeyIdentifier = cert.GetCertHashString(), endDateTime = expirationDate, @@ -566,25 +591,43 @@ private AzureADApp CreateApp(string loginEndPoint, HttpClient httpClient, string key = Convert.ToBase64String(cert.GetRawCertData()), displayName = cert.Subject, } - }, - - publicClient = new - { - redirectUris = new[] { - $"{loginEndPoint}/common/oauth2/nativeclient", - redirectUri - } - }, - requiredResourceAccess = scopesPayload - }; + }; + } var graphEndpoint = $"https://{AuthenticationManager.GetGraphEndPoint(AzureEnvironment)}"; if (AzureEnvironment == AzureEnvironment.Custom) { - graphEndpoint = Environment.GetEnvironmentVariable("MicrosoftGraphEndPoint", EnvironmentVariableTarget.Process); + graphEndpoint = Environment.GetEnvironmentVariable("MicrosoftGraphEndPoint", EnvironmentVariableTarget.Process) ?? MicrosoftGraphEndPoint; + } + + var azureApp = RestHelper.Post(httpClient, $"{graphEndpoint}/v1.0/applications", token, payload); + + var retry = true; + var iteration = 0; + while (retry) + { + try + { + // Add redirectURI to support windows broker + dynamic redirectUriPayload = new ExpandoObject(); + redirectUris.Add($"ms-appx-web://microsoft.aad.brokerplugin/{azureApp.AppId}"); + redirectUriPayload.publicClient = new { redirectUris = redirectUris.ToArray() }; + RestHelper.Patch(httpClient, $"{graphEndpoint}/v1.0/applications/{azureApp.Id}", token, redirectUriPayload); + retry = false; + } + + catch (Exception) + { + Thread.Sleep(10000); + iteration++; + } + + if (iteration > 3) // don't try more than 3 times + { + retry = false; + } } - var azureApp = RestHelper.PostAsync(httpClient, $"{graphEndpoint}/v1.0/applications", token, payload).GetAwaiter().GetResult(); if (azureApp != null) { Host.UI.WriteLine(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, $"App {azureApp.DisplayName} with id {azureApp.AppId} created."); @@ -599,7 +642,7 @@ private void StartConsentFlow(string loginEndPoint, AzureADApp azureApp, string var graphEndpoint = $"https://{AuthenticationManager.GetGraphEndPoint(AzureEnvironment)}"; if (AzureEnvironment == AzureEnvironment.Custom) { - graphEndpoint = Environment.GetEnvironmentVariable("MicrosoftGraphEndPoint", EnvironmentVariableTarget.Process); + graphEndpoint = Environment.GetEnvironmentVariable("MicrosoftGraphEndPoint", EnvironmentVariableTarget.Process) ?? MicrosoftGraphEndPoint; } var resource = scopes.FirstOrDefault(s => s.resourceAppId == PermissionScopes.ResourceAppId_Graph) != null ? $"{graphEndpoint}/.default" : "https://microsoft.sharepoint-df.com/.default"; @@ -608,7 +651,7 @@ private void StartConsentFlow(string loginEndPoint, AzureADApp azureApp, string var waitTime = 30; - var progressRecord = new ProgressRecord(1, "Please wait...", $"Waiting {waitTime} seconds to update Azure AD and launch consent flow"); + var progressRecord = new ProgressRecord(1, "Please wait...", $"Waiting {waitTime} seconds to update Entra ID and launch consent flow"); for (var i = 0; i < waitTime; i++) { progressRecord.PercentComplete = Convert.ToInt32((Convert.ToDouble(i) / Convert.ToDouble(waitTime)) * 100); @@ -675,12 +718,12 @@ private void SetLogo(AzureADApp azureApp, string token) { try { - WriteVerbose("Setting the logo for the Azure AD app"); + WriteVerbose("Setting the logo for the EntraID app"); var graphEndpoint = $"https://{AuthenticationManager.GetGraphEndPoint(AzureEnvironment)}"; if (AzureEnvironment == AzureEnvironment.Custom) { - graphEndpoint = Environment.GetEnvironmentVariable("MicrosoftGraphEndPoint", EnvironmentVariableTarget.Process); + graphEndpoint = Environment.GetEnvironmentVariable("MicrosoftGraphEndPoint", EnvironmentVariableTarget.Process) ?? MicrosoftGraphEndPoint; } var endpoint = $"{graphEndpoint}/v1.0/applications/{azureApp.Id}/logo"; @@ -714,9 +757,9 @@ private void SetLogo(AzureADApp azureApp, string token) { var byteArrayContent = new ByteArrayContent(bytes); byteArrayContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(mediaType); - GraphHelper.PutAsync(PnPConnection.Current, endpoint, token, byteArrayContent).GetAwaiter().GetResult(); + GraphHelper.Put(this, PnPConnection.Current, endpoint, token, byteArrayContent); - WriteVerbose("Successfully set the logo for the Azure AD app"); + WriteVerbose("Successfully set the logo for the Entra ID app"); } else { @@ -734,4 +777,4 @@ private void SetLogo(AzureADApp azureApp, string token) } } } -} \ No newline at end of file +} diff --git a/src/Commands/AzureAD/RegisterEntraIDAppForInteractiveLogin.cs b/src/Commands/AzureAD/RegisterEntraIDAppForInteractiveLogin.cs new file mode 100644 index 000000000..bb7307016 --- /dev/null +++ b/src/Commands/AzureAD/RegisterEntraIDAppForInteractiveLogin.cs @@ -0,0 +1,600 @@ +using PnP.Framework; +using PnP.PowerShell.Commands.Model; +using PnP.PowerShell.Commands.Utilities; +using PnP.PowerShell.Commands.Utilities.REST; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Management.Automation; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using OperatingSystem = PnP.PowerShell.Commands.Utilities.OperatingSystem; +using PnP.PowerShell.Commands.Base; +using System.Diagnostics; +using System.Dynamic; + +namespace PnP.PowerShell.Commands.AzureAD +{ + [Cmdlet(VerbsLifecycle.Register, "PnPEntraIDAppForInteractiveLogin")] + public class RegisterEntraIDAppForInteractiveLogin : BasePSCmdlet, IDynamicParameters + { + private CancellationTokenSource cancellationTokenSource; + + [Parameter(Mandatory = true, ParameterSetName = ParameterAttribute.AllParameterSets)] + public string ApplicationName; + + [Parameter(Mandatory = true, ParameterSetName = ParameterAttribute.AllParameterSets)] + public string Tenant; + + [Parameter(Mandatory = false)] + public AzureEnvironment AzureEnvironment = AzureEnvironment.Production; + + [Parameter(Mandatory = true, ParameterSetName = "DeviceLogin")] + public SwitchParameter DeviceLogin; + + [Parameter(Mandatory = false)] + public SwitchParameter NoPopup; + + [Parameter(Mandatory = true, ParameterSetName = ("Interactive"))] + public SwitchParameter Interactive; + + [Parameter(Mandatory = false)] + public string LogoFilePath; + + [Parameter(Mandatory = false)] + public string MicrosoftGraphEndPoint; + + [Parameter(Mandatory = false)] + public string EntraIDLoginEndPoint; + + protected override void ProcessRecord() + { + var redirectUri = "http://localhost"; + // if (ParameterSpecified(nameof(DeviceLogin)) || OperatingSystem.IsMacOS()) + if (ParameterSpecified(nameof(DeviceLogin)) || OperatingSystem.IsMacOS()) + { + redirectUri = "https://pnp.github.io/powershell/consent.html"; + } + + var messageWriter = new CmdletMessageWriter(this); + cancellationTokenSource = new CancellationTokenSource(); + CancellationToken cancellationToken = cancellationTokenSource.Token; + + var loginEndPoint = string.Empty; + + using (var authenticationManager = new AuthenticationManager()) + { + loginEndPoint = authenticationManager.GetAzureADLoginEndPoint(AzureEnvironment) ?? EntraIDLoginEndPoint; + } + + var permissionScopes = new PermissionScopes(); + var scopes = new List(); + if (this.Scopes != null) + { + foreach (var scopeIdentifier in this.Scopes) + { + PermissionScope scope = null; + scope = permissionScopes.GetScope(PermissionScopes.ResourceAppId_Graph, scopeIdentifier.Replace("MSGraph.", ""), "Role"); + if (scope == null) + { + scope = permissionScopes.GetScope(PermissionScopes.ResourceAppId_SPO, scopeIdentifier.Replace("SPO.", ""), "Role"); + } + if (scope == null) + { + scope = permissionScopes.GetScope(PermissionScopes.ResourceAppID_O365Management, scopeIdentifier.Replace("O365.", ""), "Role"); + } + if (scope != null) + { + scopes.Add(scope); + } + } + } + else + { + if (GraphApplicationPermissions != null) + { + foreach (var scopeIdentifier in this.GraphApplicationPermissions) + { + scopes.Add(permissionScopes.GetScope(PermissionScopes.ResourceAppId_Graph, scopeIdentifier, "Role")); + } + } + if (GraphDelegatePermissions != null) + { + foreach (var scopeIdentifier in this.GraphDelegatePermissions) + { + scopes.Add(permissionScopes.GetScope(PermissionScopes.ResourceAppId_Graph, scopeIdentifier, "Scope")); + } + } + if (SharePointApplicationPermissions != null) + { + foreach (var scopeIdentifier in this.SharePointApplicationPermissions) + { + scopes.Add(permissionScopes.GetScope(PermissionScopes.ResourceAppId_SPO, scopeIdentifier, "Role")); + } + } + if (SharePointDelegatePermissions != null) + { + foreach (var scopeIdentifier in this.SharePointDelegatePermissions) + { + scopes.Add(permissionScopes.GetScope(PermissionScopes.ResourceAppId_SPO, scopeIdentifier, "Scope")); + } + } + } + if (!scopes.Any()) + { + messageWriter.WriteWarning("No permissions specified, using default permissions"); + scopes.Add(permissionScopes.GetScope(PermissionScopes.ResourceAppId_SPO, "TermStore.ReadWrite.All", "Scope")); // Delegate + scopes.Add(permissionScopes.GetScope(PermissionScopes.ResourceAppId_SPO, "AllSites.FullControl", "Scope")); // Delegate + scopes.Add(permissionScopes.GetScope(PermissionScopes.ResourceAppId_Graph, "Group.ReadWrite.All", "Scope")); // Delegate + scopes.Add(permissionScopes.GetScope(PermissionScopes.ResourceAppId_SPO, "User.ReadWrite.All", "Scope")); // Delegate + scopes.Add(permissionScopes.GetScope(PermissionScopes.ResourceAppId_Graph, "User.ReadWrite.All", "Scope")); // Delegate + } + var record = new PSObject(); + + string token = GetAuthToken(messageWriter); + + if (!string.IsNullOrEmpty(token)) + { + var httpClient = Framework.Http.PnPHttpClient.Instance.GetHttpClient(); + + if (!AppExists(ApplicationName, httpClient, token)) + { + var azureApp = CreateApp(loginEndPoint, httpClient, token, redirectUri, scopes); + + record.Properties.Add(new PSVariableProperty(new PSVariable("AzureAppId/ClientId", azureApp.AppId))); + + StartConsentFlow(loginEndPoint, azureApp, redirectUri, token, httpClient, record, messageWriter, scopes); + + if (ParameterSpecified(nameof(LogoFilePath)) && !string.IsNullOrEmpty(LogoFilePath)) + { + SetLogo(azureApp, token); + } + } + else + { + throw new PSInvalidOperationException($"The application with name {ApplicationName} already exists."); + } + + } + } + + protected override void StopProcessing() + { + cancellationTokenSource.Cancel(); + } + + private static object GetScopesPayload(List scopes) + { + var resourcePermissions = new List(); + var distinctResources = scopes.GroupBy(s => s.resourceAppId).Select(r => r.First()).ToList(); + foreach (var distinctResource in distinctResources) + { + var id = distinctResource.resourceAppId; + var appResource = new AppResource() { Id = id }; + appResource.ResourceAccess.AddRange(scopes.Where(s => s.resourceAppId == id).ToList()); + resourcePermissions.Add(appResource); + } + return resourcePermissions; + } + + protected IEnumerable Scopes + { + get + { + if (ParameterSpecified(nameof(Scopes)) && MyInvocation.BoundParameters["Scopes"] != null) + { + return MyInvocation.BoundParameters["Scopes"] as string[]; + } + else + { + return null; + } + } + } + + protected IEnumerable GraphApplicationPermissions + { + get + { + if (ParameterSpecified(nameof(GraphApplicationPermissions)) && MyInvocation.BoundParameters[nameof(GraphApplicationPermissions)] != null) + { + return MyInvocation.BoundParameters[nameof(GraphApplicationPermissions)] as string[]; + } + else + { + return null; + } + } + } + + protected IEnumerable GraphDelegatePermissions + { + get + { + if (ParameterSpecified(nameof(GraphDelegatePermissions)) && MyInvocation.BoundParameters[nameof(GraphDelegatePermissions)] != null) + { + return MyInvocation.BoundParameters[nameof(GraphDelegatePermissions)] as string[]; + } + else + { + return null; + } + } + } + + protected IEnumerable SharePointApplicationPermissions + { + get + { + if (ParameterSpecified(nameof(SharePointApplicationPermissions)) && MyInvocation.BoundParameters[nameof(SharePointApplicationPermissions)] != null) + { + return MyInvocation.BoundParameters[nameof(SharePointApplicationPermissions)] as string[]; + } + else + { + return null; + } + } + } + + protected IEnumerable SharePointDelegatePermissions + { + get + { + if (ParameterSpecified(nameof(SharePointDelegatePermissions)) && MyInvocation.BoundParameters[nameof(SharePointDelegatePermissions)] != null) + { + return MyInvocation.BoundParameters[nameof(SharePointDelegatePermissions)] as string[]; + } + else + { + return null; + } + } + } + + protected IEnumerable O365ManagementApplicationPermissions + { + get + { + if (ParameterSpecified(nameof(O365ManagementApplicationPermissions)) && MyInvocation.BoundParameters[nameof(O365ManagementApplicationPermissions)] != null) + { + return MyInvocation.BoundParameters[nameof(O365ManagementApplicationPermissions)] as string[]; + } + else + { + return null; + } + } + } + + protected IEnumerable O365ManagementDelegatePermissions + { + get + { + if (ParameterSpecified(nameof(O365ManagementDelegatePermissions)) && MyInvocation.BoundParameters[nameof(O365ManagementDelegatePermissions)] != null) + { + return MyInvocation.BoundParameters[nameof(O365ManagementDelegatePermissions)] as string[]; + } + else + { + return null; + } + } + } + + public object GetDynamicParameters() + { + // var classAttribute = this.GetType().GetCustomAttributes(false).FirstOrDefault(a => a is PropertyLoadingAttribute); + const string parameterName = "Scopes"; + + var parameterDictionary = new RuntimeDefinedParameterDictionary(); + var attributeCollection = new System.Collections.ObjectModel.Collection(); + + // Scopes + var parameterAttribute = new ParameterAttribute + { + ValueFromPipeline = false, + ValueFromPipelineByPropertyName = false, + Mandatory = false + }; + + attributeCollection.Add(parameterAttribute); + attributeCollection.Add(new ObsoleteAttribute("Use either -GraphApplicationPermissions, -GraphDelegatePermissions, -SharePointApplicationPermissions or -SharePointDelegatePermissions")); + + var identifiers = new PermissionScopes().GetIdentifiers(); + + var validateSetAttribute = new ValidateSetAttribute(identifiers); + attributeCollection.Add(validateSetAttribute); + + var runtimeParameter = new RuntimeDefinedParameter(parameterName, typeof(string[]), attributeCollection); + + parameterDictionary.Add(parameterName, runtimeParameter); + + // Graph + parameterDictionary.Add("GraphApplicationPermissions", GetParameter("GraphApplicationPermissions", PermissionScopes.ResourceAppId_Graph, "Role")); + parameterDictionary.Add("GraphDelegatePermissions", GetParameter("GraphDelegatePermissions", PermissionScopes.ResourceAppId_Graph, "Scope")); + + // SharePoint + parameterDictionary.Add("SharePointApplicationPermissions", GetParameter("SharePointApplicationPermissions", PermissionScopes.ResourceAppId_SPO, "Role")); + parameterDictionary.Add("SharePointDelegatePermissions", GetParameter("SharePointDelegatePermissions", PermissionScopes.ResourceAppId_SPO, "Scope")); + + // O365 Management + parameterDictionary.Add("O365ManagementApplicationPermissions", GetParameter("O365ManagementApplicationPermissions", PermissionScopes.ResourceAppID_O365Management, "Role")); + parameterDictionary.Add("O365ManagementDelegatePermissions", GetParameter("O365ManagementDelegatePermissions", PermissionScopes.ResourceAppID_O365Management, "Scope")); + + return parameterDictionary; + } + + private RuntimeDefinedParameter GetParameter(string parameterName, string resourceAppId, string type) + { + var attributeCollection = new System.Collections.ObjectModel.Collection(); + var parameterAttribute = new ParameterAttribute + { + ValueFromPipeline = false, + ValueFromPipelineByPropertyName = false, + Mandatory = false + }; + attributeCollection.Add(parameterAttribute); + var validateSetAttribute = new ValidateSetAttribute(new PermissionScopes().GetIdentifiers(resourceAppId, type)); + attributeCollection.Add(validateSetAttribute); + var parameter = new RuntimeDefinedParameter(parameterName, typeof(string[]), attributeCollection); + return parameter; + } + + private string GetAuthToken(CmdletMessageWriter messageWriter) + { + var token = string.Empty; + if (DeviceLogin.IsPresent) + { + Task.Factory.StartNew(() => + { + token = AzureAuthHelper.AuthenticateDeviceLogin(cancellationTokenSource, messageWriter, NoPopup, AzureEnvironment, MicrosoftGraphEndPoint); + if (token == null) + { + messageWriter.WriteWarning("Operation cancelled or no token retrieved."); + } + messageWriter.Stop(); + }); + messageWriter.Start(); + } + else if (Interactive.IsPresent) + { + Task.Factory.StartNew(() => + { + token = AzureAuthHelper.AuthenticateInteractive(cancellationTokenSource, messageWriter, NoPopup, AzureEnvironment, Tenant, MicrosoftGraphEndPoint); + if (token == null) + { + messageWriter.WriteWarning("Operation cancelled or no token retrieved."); + } + messageWriter.Stop(); + }); + messageWriter.Start(); + } + + return token; + } + + private bool AppExists(string appName, HttpClient httpClient, string token) + { + Host.UI.Write(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, $"Checking if application '{appName}' does not exist yet..."); + + var graphEndpoint = $"https://{AuthenticationManager.GetGraphEndPoint(AzureEnvironment)}"; + if (AzureEnvironment == AzureEnvironment.Custom) + { + graphEndpoint = Environment.GetEnvironmentVariable("MicrosoftGraphEndPoint", EnvironmentVariableTarget.Process) ?? MicrosoftGraphEndPoint; + } + + var azureApps = RestHelper.Get>(httpClient, $"{graphEndpoint}/v1.0/applications?$filter=displayName eq '{appName}'&$select=Id", token); + if (azureApps != null && azureApps.Items.Any()) + { + Host.UI.WriteLine(); + return true; + } + Host.UI.WriteLine(ConsoleColor.Green, Host.UI.RawUI.BackgroundColor, $"Success. Application '{appName}' can be registered."); + return false; + } + + private AzureADApp CreateApp(string loginEndPoint, HttpClient httpClient, string token, string redirectUri, List scopes) + { + var scopesPayload = GetScopesPayload(scopes); + var redirectUris = new List() { $"{loginEndPoint}/common/oauth2/nativeclient", redirectUri }; + if (redirectUri != "http://localhost") + { + redirectUris.Add("http://localhost"); + } + dynamic payload = new ExpandoObject(); + payload.isFallbackPublicClient = true; + payload.displayName = ApplicationName; + payload.signInAudience = "AzureADMyOrg"; + payload.publicClient = new { redirectUris = redirectUris.ToArray() }; + payload.requiredResourceAccess = scopesPayload; + + var graphEndpoint = $"https://{AuthenticationManager.GetGraphEndPoint(AzureEnvironment)}"; + if (AzureEnvironment == AzureEnvironment.Custom) + { + graphEndpoint = Environment.GetEnvironmentVariable("MicrosoftGraphEndPoint", EnvironmentVariableTarget.Process) ?? MicrosoftGraphEndPoint; + } + + var azureApp = RestHelper.Post(httpClient, $"{graphEndpoint}/v1.0/applications", token, payload); + + var retry = true; + var iteration = 0; + while (retry) + { + try + { + // Add redirectURI to support windows broker + dynamic redirectUriPayload = new ExpandoObject(); + redirectUris.Add($"ms-appx-web://microsoft.aad.brokerplugin/{azureApp.AppId}"); + redirectUriPayload.publicClient = new { redirectUris = redirectUris.ToArray() }; + RestHelper.Patch(httpClient, $"{graphEndpoint}/v1.0/applications/{azureApp.Id}", token, redirectUriPayload); + retry = false; + } + + catch (Exception) + { + Thread.Sleep(10000); + iteration++; + } + + if (iteration > 3) // don't try more than 3 times + { + retry = false; + } + } + + if (azureApp != null) + { + Host.UI.WriteLine(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, $"App {azureApp.DisplayName} with id {azureApp.AppId} created."); + } + return azureApp; + } + + private void StartConsentFlow(string loginEndPoint, AzureADApp azureApp, string redirectUri, string token, HttpClient httpClient, PSObject record, CmdletMessageWriter messageWriter, List scopes) + { + //Host.UI.WriteLine(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, $"Starting consent flow."); + + var graphEndpoint = $"https://{AuthenticationManager.GetGraphEndPoint(AzureEnvironment)}"; + if (AzureEnvironment == AzureEnvironment.Custom) + { + graphEndpoint = Environment.GetEnvironmentVariable("MicrosoftGraphEndPoint", EnvironmentVariableTarget.Process) ?? MicrosoftGraphEndPoint; + } + + var resource = scopes.FirstOrDefault(s => s.resourceAppId == PermissionScopes.ResourceAppId_Graph) != null ? $"{graphEndpoint}/.default" : "https://microsoft.sharepoint-df.com/.default"; + + var consentUrl = $"{loginEndPoint}/{Tenant}/v2.0/adminconsent?client_id={azureApp.AppId}&scope={resource}&redirect_uri={redirectUri}"; + + var waitTime = 30; + + var progressRecord = new ProgressRecord(1, "Please wait...", $"Waiting {waitTime} seconds to update Entra ID and launch consent flow"); + for (var i = 0; i < waitTime; i++) + { + progressRecord.PercentComplete = Convert.ToInt32((Convert.ToDouble(i) / Convert.ToDouble(waitTime)) * 100); + WriteProgress(progressRecord); + Thread.Sleep(1000); + + // Check if CTRL+C has been pressed and if so, abort the wait + if (Stopping) + { + Host.UI.WriteLine("Wait cancelled. You can provide consent manually by navigating to"); + Host.UI.WriteLine(consentUrl); + break; + } + } + progressRecord.RecordType = ProgressRecordType.Completed; + WriteProgress(progressRecord); + + + if (OperatingSystem.IsWindows() && !NoPopup) + { + + if (!Stopping) + { + + if (ParameterSpecified(nameof(Interactive))) + { + using (var authManager = AuthenticationManager.CreateWithInteractiveLogin(azureApp.AppId, (url, port) => + { + BrowserHelper.OpenBrowserForInteractiveLogin(url, port, true, cancellationTokenSource); + }, Tenant, "You successfully provided consent", "You failed to provide consent.", AzureEnvironment)) + { + authManager.GetAccessToken(resource, Microsoft.Identity.Client.Prompt.Consent); + } + } + else + { + BrowserHelper.GetWebBrowserPopup(consentUrl, "Please provide consent", new[] { ("https://pnp.github.io/powershell/consent.html", BrowserHelper.UrlMatchType.StartsWith) }, cancellationTokenSource: cancellationTokenSource, cancelOnClose: false); + } + // Write results + + WriteObject($"App created. You can now connect to your tenant using Connect-PnPOnline -Url -Interactive -ClientId {azureApp.AppId}"); + WriteObject(record); + } + } + else + { + if (OperatingSystem.IsMacOS()) + { + Process.Start("open", consentUrl); + } + else + { + Host.UI.WriteLine(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, $"Open the following URL in a browser window to provide consent. This consent is required in order to use this application.\n\n{consentUrl}"); + } + WriteObject($"App created. You can now connect to your tenant using Connect-PnPOnline -Url -Interactive -ClientId {azureApp.AppId}"); + WriteObject(record); + } + } + + private void SetLogo(AzureADApp azureApp, string token) + { + if (!Path.IsPathRooted(LogoFilePath)) + { + LogoFilePath = Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, LogoFilePath); + } + if (File.Exists(LogoFilePath)) + { + try + { + WriteVerbose("Setting the logo for the EntraID app"); + + var graphEndpoint = $"https://{AuthenticationManager.GetGraphEndPoint(AzureEnvironment)}"; + if (AzureEnvironment == AzureEnvironment.Custom) + { + graphEndpoint = Environment.GetEnvironmentVariable("MicrosoftGraphEndPoint", EnvironmentVariableTarget.Process) ?? MicrosoftGraphEndPoint; + } + + var endpoint = $"{graphEndpoint}/v1.0/applications/{azureApp.Id}/logo"; + + var bytes = File.ReadAllBytes(LogoFilePath); + + var fileInfo = new FileInfo(LogoFilePath); + + var mediaType = string.Empty; + switch (fileInfo.Extension.ToLower()) + { + case ".jpg": + case ".jpeg": + { + mediaType = "image/jpeg"; + break; + } + case ".gif": + { + mediaType = "image/gif"; + break; + } + case ".png": + { + mediaType = "image/png"; + break; + } + } + + if (!string.IsNullOrEmpty(mediaType)) + { + var byteArrayContent = new ByteArrayContent(bytes); + byteArrayContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(mediaType); + GraphHelper.Put(this, PnPConnection.Current, endpoint, token, byteArrayContent); + + WriteVerbose("Successfully set the logo for the Entra ID app"); + } + else + { + throw new Exception("Unrecognized image format. Supported formats are .png, .jpg, .jpeg and .gif"); + } + } + catch (Exception ex) + { + WriteWarning("Something went wrong setting the logo " + ex.Message); + } + } + else + { + WriteWarning("Logo File does not exist, ignoring setting the logo"); + } + } + } +} \ No newline at end of file diff --git a/src/Commands/AzureAD/RegisterManagementShellAccess.cs b/src/Commands/AzureAD/RegisterManagementShellAccess.cs index 92fe61ecc..5212e4e96 100644 --- a/src/Commands/AzureAD/RegisterManagementShellAccess.cs +++ b/src/Commands/AzureAD/RegisterManagementShellAccess.cs @@ -37,6 +37,7 @@ public class RegisterManagementShellAccess : PSCmdlet protected override void ProcessRecord() { + WriteWarning("This cmdlet will provide consent for the PnP Managment Shell Entra ID multi-tenant app. It is strongly recommmended to register your own app in your Entra ID and use that for authentication instead. See the documentation for Register-PnPEntraIDApp."); source = new CancellationTokenSource(); var messageWriter = new CmdletMessageWriter(this); diff --git a/src/Commands/AzureAD/RemoveAzureADApp.cs b/src/Commands/AzureAD/RemoveAzureADApp.cs index fb72e00ee..0e47a25f1 100644 --- a/src/Commands/AzureAD/RemoveAzureADApp.cs +++ b/src/Commands/AzureAD/RemoveAzureADApp.cs @@ -22,7 +22,7 @@ protected override void ExecuteCmdlet() if (Force || ShouldContinue($"Remove app '{app.DisplayName}' with id '{app.Id}'", string.Empty)) { - Utilities.REST.GraphHelper.DeleteAsync(Connection, $"/v1.0/applications/{app.Id}", AccessToken).GetAwaiter().GetResult(); + Utilities.REST.GraphHelper.Delete(this, Connection, $"/v1.0/applications/{app.Id}", AccessToken); } } } diff --git a/src/Commands/AzureAD/RemoveAzureADGroup.cs b/src/Commands/AzureAD/RemoveAzureADGroup.cs index ef4702e46..ddf59589b 100644 --- a/src/Commands/AzureAD/RemoveAzureADGroup.cs +++ b/src/Commands/AzureAD/RemoveAzureADGroup.cs @@ -19,11 +19,11 @@ protected override void ExecuteCmdlet() { if (Identity != null) { - Group group = Identity.GetGroup(Connection, AccessToken); + Group group = Identity.GetGroup(this, Connection, AccessToken); if (group != null) { - Microsoft365GroupsUtility.RemoveGroupAsync(Connection, new System.Guid(group.Id), AccessToken).GetAwaiter().GetResult(); + ClearOwners.RemoveGroup(this, Connection, new System.Guid(group.Id), AccessToken); } } } diff --git a/src/Commands/AzureAD/RemoveAzureADGroupMember.cs b/src/Commands/AzureAD/RemoveAzureADGroupMember.cs index aeadf8f32..3dbf036fb 100644 --- a/src/Commands/AzureAD/RemoveAzureADGroupMember.cs +++ b/src/Commands/AzureAD/RemoveAzureADGroupMember.cs @@ -24,12 +24,12 @@ protected override void ExecuteCmdlet() if (Identity != null) { - group = Identity.GetGroup(Connection, AccessToken); + group = Identity.GetGroup(this, Connection, AccessToken); } if (group != null) { - Microsoft365GroupsUtility.RemoveMembersAsync(Connection, new System.Guid(group.Id), Users, AccessToken).GetAwaiter().GetResult(); + ClearOwners.RemoveMembers(this, Connection, new System.Guid(group.Id), Users, AccessToken); } } } diff --git a/src/Commands/AzureAD/RemoveAzureADGroupOwner.cs b/src/Commands/AzureAD/RemoveAzureADGroupOwner.cs index 552405356..871ec671e 100644 --- a/src/Commands/AzureAD/RemoveAzureADGroupOwner.cs +++ b/src/Commands/AzureAD/RemoveAzureADGroupOwner.cs @@ -24,12 +24,12 @@ protected override void ExecuteCmdlet() if (Identity != null) { - group = Identity.GetGroup(Connection, AccessToken); + group = Identity.GetGroup(this, Connection, AccessToken); } if (group != null) { - Microsoft365GroupsUtility.RemoveOwnersAsync(Connection, new System.Guid(group.Id), Users, AccessToken).GetAwaiter().GetResult(); + ClearOwners.RemoveOwners(this, Connection, new System.Guid(group.Id), Users, AccessToken); } } } diff --git a/src/Commands/AzureAD/RemoveAzureADUser.cs b/src/Commands/AzureAD/RemoveAzureADUser.cs new file mode 100644 index 000000000..119963fba --- /dev/null +++ b/src/Commands/AzureAD/RemoveAzureADUser.cs @@ -0,0 +1,52 @@ +using PnP.PowerShell.Commands.Attributes; +using PnP.PowerShell.Commands.Base; +using PnP.PowerShell.Commands.Base.PipeBinds; +using System.Management.Automation; +using PnP.PowerShell.Commands.Model.AzureAD; +using PnP.PowerShell.Commands.Utilities.REST; + +namespace PnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Remove, "PnPAzureADUser")] + [RequiredMinimalApiPermissions("User.ReadWrite.All")] + [Alias("Remove-PnPEntraIDUser")] + public class RemoveAzureADUser : PnPGraphCmdlet + { + [Parameter(Mandatory = true, ValueFromPipeline = true)] + public AzureADUserPipeBind Identity; + + [Parameter(Mandatory = false)] + public SwitchParameter WhatIf; + + protected override void ExecuteCmdlet() + { + WriteVerbose($"Looking up user provided through the {nameof(Identity)} parameter"); + User user = Identity.GetUser(AccessToken, Connection.AzureEnvironment); + + if (user == null) + { + WriteWarning($"User provided through the {nameof(Identity)} parameter could not be found"); + return; + } + + if(WhatIf.ToBool()) + { + WriteVerbose($"Would delete user with Id {user.Id} if {nameof(WhatIf)} was not present"); + return; + } + + WriteVerbose($"Deleting user with Id {user.Id}"); + + var graphResult = GraphHelper.Delete(this, Connection, $"v1.0/users/{user.Id}", AccessToken); + + if(graphResult.StatusCode == System.Net.HttpStatusCode.NoContent) + { + WriteVerbose("User deleted successfully"); + } + else + { + throw new PSArgumentException("User could not be deleted", nameof(Identity)); + } + } + } +} \ No newline at end of file diff --git a/src/Commands/AzureAD/SetAzureADGroup.cs b/src/Commands/AzureAD/SetAzureADGroup.cs index d7411d400..628284674 100644 --- a/src/Commands/AzureAD/SetAzureADGroup.cs +++ b/src/Commands/AzureAD/SetAzureADGroup.cs @@ -46,7 +46,7 @@ protected override void ExecuteCmdlet() if (Identity != null) { - group = Identity.GetGroup(Connection, AccessToken); + group = Identity.GetGroup(this, Connection, AccessToken); } if (group != null) @@ -77,22 +77,22 @@ protected override void ExecuteCmdlet() if (changed) { - AzureADGroupsUtility.UpdateAsync(Connection, AccessToken, group).GetAwaiter().GetResult(); + AzureADGroupsUtility.Update(this, Connection, AccessToken, group); } if (ParameterSpecified(nameof(Owners))) { - Microsoft365GroupsUtility.UpdateOwnersAsync(Connection, new Guid(group.Id), AccessToken, Owners).GetAwaiter().GetResult(); + ClearOwners.UpdateOwners(this, Connection, new Guid(group.Id), AccessToken, Owners); } if (ParameterSpecified(nameof(Members))) { - Microsoft365GroupsUtility.UpdateMembersAsync(Connection, new Guid(group.Id), AccessToken, Members).GetAwaiter().GetResult(); + ClearOwners.UpdateMembersAsync(this, Connection, new Guid(group.Id), AccessToken, Members); } if (ParameterSpecified(nameof(HideFromAddressLists)) || ParameterSpecified(nameof(HideFromOutlookClients))) { // For this scenario a separate call needs to be made - Utilities.Microsoft365GroupsUtility.SetVisibilityAsync(Connection, AccessToken, new Guid(group.Id), HideFromAddressLists, HideFromOutlookClients).GetAwaiter().GetResult(); + Utilities.ClearOwners.SetVisibility(this, Connection, AccessToken, new Guid(group.Id), HideFromAddressLists, HideFromOutlookClients); } } catch (Exception e) diff --git a/src/Commands/Base/BasePSCmdlet.cs b/src/Commands/Base/BasePSCmdlet.cs index 72de479a7..86065ce01 100644 --- a/src/Commands/Base/BasePSCmdlet.cs +++ b/src/Commands/Base/BasePSCmdlet.cs @@ -41,6 +41,17 @@ public bool ParameterSpecified(string parameterName) return MyInvocation.BoundParameters.ContainsKey(parameterName); } + protected string ErrorActionSetting + { + get + { + if (MyInvocation.BoundParameters.TryGetValue("ErrorAction", out object result)) + return result.ToString() ?? ""; + else + return SessionState.PSVariable.GetValue("ErrorActionPreference")?.ToString() ?? ""; + } + } + protected virtual void ExecuteCmdlet() { } @@ -50,7 +61,7 @@ protected override void ProcessRecord() { ExecuteCmdlet(); } - catch (PnP.PowerShell.Commands.Model.Graph.GraphException gex) + catch (Model.Graph.GraphException gex) { var errorMessage = gex.Error.Message; @@ -58,7 +69,7 @@ protected override void ProcessRecord() { if (!string.IsNullOrEmpty(gex.AccessToken)) { - TokenHandler.ValidateTokenForPermissions(GetType(), gex.AccessToken); + TokenHandler.EnsureRequiredPermissionsAvailableInAccessToken(GetType(), gex.AccessToken); } } if(string.IsNullOrWhiteSpace(errorMessage) && gex.HttpResponse != null && gex.HttpResponse.StatusCode == System.Net.HttpStatusCode.Forbidden) diff --git a/src/Commands/Base/ConnectOnline.cs b/src/Commands/Base/ConnectOnline.cs index 6a62be0e9..80397bee0 100644 --- a/src/Commands/Base/ConnectOnline.cs +++ b/src/Commands/Base/ConnectOnline.cs @@ -9,7 +9,6 @@ using System.IO; using System.Linq; using System.Management.Automation; -using System.Net.Http; using System.Reflection; using System.Security; using System.Security.Cryptography.X509Certificates; @@ -39,6 +38,7 @@ public class ConnectOnline : BasePSCmdlet private const string ParameterSet_INTERACTIVE = "Interactive login for Multi Factor Authentication"; private const string ParameterSet_ENVIRONMENTVARIABLE = "Environment Variable"; private const string ParameterSet_AZUREAD_WORKLOAD_IDENTITY = "Azure AD Workload Identity"; + private const string ParameterSet_OSLOGIN = "OS login"; private const string SPOManagementClientId = "9bc3ab49-b65d-410a-85ad-de819febfddc"; private const string SPOManagementRedirectUri = "https://oauth.spops.microsoft.com/"; @@ -58,6 +58,7 @@ public class ConnectOnline : BasePSCmdlet [Parameter(Mandatory = false, ParameterSetName = ParameterSet_USERASSIGNEDMANAGEDIDENTITYBYPRINCIPALID)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_USERASSIGNEDMANAGEDIDENTITYBYAZURERESOURCEID)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_AZUREAD_WORKLOAD_IDENTITY)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_OSLOGIN, ValueFromPipeline = true)] public SwitchParameter ReturnConnection; [Parameter(Mandatory = false, ParameterSetName = ParameterSet_CREDENTIALS, ValueFromPipeline = true)] @@ -70,7 +71,12 @@ public class ConnectOnline : BasePSCmdlet [Parameter(Mandatory = false, ParameterSetName = ParameterSet_INTERACTIVE, ValueFromPipeline = true)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_ACCESSTOKEN, ValueFromPipeline = true)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_ENVIRONMENTVARIABLE, ValueFromPipeline = true)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_SYSTEMASSIGNEDMANAGEDIDENTITY, ValueFromPipeline = true)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_USERASSIGNEDMANAGEDIDENTITYBYCLIENTID, ValueFromPipeline = true)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_USERASSIGNEDMANAGEDIDENTITYBYPRINCIPALID, ValueFromPipeline = true)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_USERASSIGNEDMANAGEDIDENTITYBYAZURERESOURCEID, ValueFromPipeline = true)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_AZUREAD_WORKLOAD_IDENTITY, ValueFromPipeline = true)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_OSLOGIN, ValueFromPipeline = true)] public SwitchParameter ValidateConnection; [Parameter(Mandatory = true, Position = 0, ParameterSetName = ParameterSet_CREDENTIALS, ValueFromPipeline = true)] @@ -88,6 +94,7 @@ public class ConnectOnline : BasePSCmdlet [Parameter(Mandatory = false, Position = 0, ParameterSetName = ParameterSet_USERASSIGNEDMANAGEDIDENTITYBYAZURERESOURCEID, ValueFromPipeline = true)] [Parameter(Mandatory = true, Position = 0, ParameterSetName = ParameterSet_ENVIRONMENTVARIABLE, ValueFromPipeline = true)] [Parameter(Mandatory = false, Position = 0, ParameterSetName = ParameterSet_AZUREAD_WORKLOAD_IDENTITY, ValueFromPipeline = true)] + [Parameter(Mandatory = true, Position = 0, ParameterSetName = ParameterSet_OSLOGIN, ValueFromPipeline = true)] public string Url; [Parameter(Mandatory = false, ParameterSetName = ParameterSet_CREDENTIALS)] @@ -99,6 +106,7 @@ public class ConnectOnline : BasePSCmdlet [Parameter(Mandatory = false, ParameterSetName = ParameterSet_INTERACTIVE)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_ENVIRONMENTVARIABLE)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_AZUREAD_WORKLOAD_IDENTITY)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_OSLOGIN)] public PnPConnection Connection = PnPConnection.Current; [Parameter(Mandatory = false, ParameterSetName = ParameterSet_CREDENTIALS)] @@ -125,6 +133,7 @@ public class ConnectOnline : BasePSCmdlet [Parameter(Mandatory = false, ParameterSetName = ParameterSet_WEBLOGIN)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_INTERACTIVE)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_ENVIRONMENTVARIABLE)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_OSLOGIN)] public SwitchParameter CreateDrive; [Parameter(Mandatory = false, ParameterSetName = ParameterSet_CREDENTIALS)] @@ -136,6 +145,7 @@ public class ConnectOnline : BasePSCmdlet [Parameter(Mandatory = false, ParameterSetName = ParameterSet_WEBLOGIN)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_INTERACTIVE)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_ENVIRONMENTVARIABLE)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_OSLOGIN)] public string DriveName = "SPO"; [Parameter(Mandatory = true, ParameterSetName = ParameterSet_SPOMANAGEMENT)] @@ -155,6 +165,7 @@ public class ConnectOnline : BasePSCmdlet [Parameter(Mandatory = true, ParameterSetName = ParameterSet_ACSAPPONLY)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_INTERACTIVE)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_DEVICELOGIN)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_OSLOGIN)] [Alias("ApplicationId")] public string ClientId; @@ -167,6 +178,7 @@ public class ConnectOnline : BasePSCmdlet [Parameter(Mandatory = false, ParameterSetName = ParameterSet_INTERACTIVE)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_DEVICELOGIN)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_ENVIRONMENTVARIABLE)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_OSLOGIN)] public string Tenant; [Parameter(Mandatory = false, ParameterSetName = ParameterSet_APPONLYAADCERTIFICATE)] @@ -189,6 +201,11 @@ public class ConnectOnline : BasePSCmdlet [Parameter(Mandatory = false, ParameterSetName = ParameterSet_INTERACTIVE)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_ACCESSTOKEN)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_ENVIRONMENTVARIABLE)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_OSLOGIN)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_SYSTEMASSIGNEDMANAGEDIDENTITY)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_USERASSIGNEDMANAGEDIDENTITYBYCLIENTID)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_USERASSIGNEDMANAGEDIDENTITYBYPRINCIPALID)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_USERASSIGNEDMANAGEDIDENTITYBYAZURERESOURCEID)] public AzureEnvironment AzureEnvironment = AzureEnvironment.Production; // [Parameter(Mandatory = true, ParameterSetName = ParameterSet_APPONLYCLIENTIDCLIENTSECRETAADDOMAIN)] @@ -203,6 +220,7 @@ public class ConnectOnline : BasePSCmdlet [Parameter(Mandatory = false, ParameterSetName = ParameterSet_WEBLOGIN)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_INTERACTIVE)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_ENVIRONMENTVARIABLE)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_OSLOGIN)] public string TenantAdminUrl; [Parameter(Mandatory = true, ParameterSetName = ParameterSet_SYSTEMASSIGNEDMANAGEDIDENTITY)] @@ -233,6 +251,7 @@ public class ConnectOnline : BasePSCmdlet [Parameter(Mandatory = false, ParameterSetName = ParameterSet_WEBLOGIN)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_INTERACTIVE)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_OSLOGIN)] public SwitchParameter ForceAuthentication; [Parameter(Mandatory = true, ParameterSetName = ParameterSet_INTERACTIVE)] @@ -252,6 +271,11 @@ public class ConnectOnline : BasePSCmdlet [Parameter(Mandatory = false, ParameterSetName = ParameterSet_INTERACTIVE)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_ACCESSTOKEN)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_ENVIRONMENTVARIABLE)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_SYSTEMASSIGNEDMANAGEDIDENTITY)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_USERASSIGNEDMANAGEDIDENTITYBYCLIENTID)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_USERASSIGNEDMANAGEDIDENTITYBYPRINCIPALID)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_USERASSIGNEDMANAGEDIDENTITYBYAZURERESOURCEID)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_OSLOGIN)] public string MicrosoftGraphEndPoint; [Parameter(Mandatory = false, ParameterSetName = ParameterSet_CREDENTIALS)] @@ -262,11 +286,19 @@ public class ConnectOnline : BasePSCmdlet [Parameter(Mandatory = false, ParameterSetName = ParameterSet_INTERACTIVE)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_ACCESSTOKEN)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_ENVIRONMENTVARIABLE)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_SYSTEMASSIGNEDMANAGEDIDENTITY)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_USERASSIGNEDMANAGEDIDENTITYBYCLIENTID)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_USERASSIGNEDMANAGEDIDENTITYBYPRINCIPALID)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_USERASSIGNEDMANAGEDIDENTITYBYAZURERESOURCEID)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_OSLOGIN)] public string AzureADLoginEndPoint; [Parameter(Mandatory = true, ParameterSetName = ParameterSet_AZUREAD_WORKLOAD_IDENTITY)] public SwitchParameter AzureADWorkloadIdentity; + [Parameter(Mandatory = true, ParameterSetName = ParameterSet_OSLOGIN)] + public SwitchParameter OSLogin; + protected override void ProcessRecord() { cancellationTokenSource = new CancellationTokenSource(); @@ -289,6 +321,8 @@ protected override void ProcessRecord() /// protected void Connect(ref CancellationToken cancellationToken) { + WriteVerbose($"PnP PowerShell Cmdlets ({new SemanticVersion(Assembly.GetExecutingAssembly().GetName().Version)})"); + if (!string.IsNullOrEmpty(Url)) { Url = Url.TrimEnd('/'); @@ -306,16 +340,19 @@ protected void Connect(ref CancellationToken cancellationToken) { credentials = Credentials.Credential; } - - if (PingHost(new Uri(Url).Host) == false) + + if (ValidateConnection) { - throw new PSArgumentException("Host not reachable"); + if (PingHost(new Uri(Url).Host) == false) + { + throw new PSArgumentException("Host not reachable"); + } } if (AzureEnvironment == AzureEnvironment.Custom) { SetCustomEndpoints(); - } + } // Connect using the used set parameters switch (ParameterSetName) @@ -359,7 +396,10 @@ protected void Connect(ref CancellationToken cancellationToken) case ParameterSet_AZUREAD_WORKLOAD_IDENTITY: newConnection = ConnectAzureADWorkloadIdentity(); break; - } + case ParameterSet_OSLOGIN: + newConnection = ConnectWithOSLogin(); + break; + } // Ensure a connection instance has been created by now if (newConnection == null) @@ -369,8 +409,8 @@ protected void Connect(ref CancellationToken cancellationToken) } // Connection has been established - WriteVerbose($"PnP PowerShell Cmdlets ({new SemanticVersion(Assembly.GetExecutingAssembly().GetName().Version)})"); - + WriteVerbose($"Connected"); + if (newConnection.Url != null) { var hostUri = new Uri(newConnection.Url); @@ -416,11 +456,11 @@ protected void Connect(ref CancellationToken cancellationToken) } // If the ErrorAction is not set to Stop, Ignore or SilentlyContinue throw an exception, otherwise just continue - if (!ParameterSpecified("ErrorAction") || !new [] { "stop", "ignore", "silentlycontinue" }.Contains(MyInvocation.BoundParameters["ErrorAction"].ToString().ToLowerInvariant())) + if (!new[] { "stop", "ignore", "silentlycontinue" }.Contains(ErrorActionSetting.ToLowerInvariant())) { throw new PSInvalidOperationException(errorMessage); } - } + } } if (ReturnConnection) @@ -445,7 +485,6 @@ protected void Connect(ref CancellationToken cancellationToken) SessionState.Drive.New(drive, "Global"); } } - } #region Connect Types @@ -456,6 +495,8 @@ protected void Connect(ref CancellationToken cancellationToken) /// PnPConnection based on the parameters provided in the parameter set private PnPConnection ConnectACSAppOnly() { + WriteVerbose("Connecting using the SharePoint Online Access Control Services(ACS) App-Only"); + CmdletMessageWriter.WriteFormattedMessage(this, new CmdletMessageWriter.Message { Text = "Connecting with Client Secret uses legacy authentication and provides limited functionality. We can for instance not execute requests towards the Microsoft Graph, which limits cmdlets related to Microsoft Teams, Microsoft Planner, Microsoft Flow and Microsoft 365 Groups. You can hide this warning by using Connect-PnPOnline [your parameters] -WarningAction Ignore", Formatted = true, Type = CmdletMessageWriter.MessageType.Warning }); if (Connection?.ClientId == ClientId && Connection?.ClientSecret == ClientSecret && @@ -463,6 +504,9 @@ private PnPConnection ConnectACSAppOnly() { ReuseAuthenticationManager(); } + + WriteVerbose($"Using ClientID {ClientId}"); + return PnPConnection.CreateWithACSAppOnly(new Uri(Url), Realm, ClientId, ClientSecret, TenantAdminUrl, AzureEnvironment); } @@ -472,9 +516,13 @@ private PnPConnection ConnectACSAppOnly() /// PnPConnection based on the parameters provided in the parameter set private PnPConnection ConnectSpoManagement() { + WriteVerbose("Connecting using the SharePoint Online Management Shell App Registration"); + ClientId = SPOManagementClientId; RedirectUri = SPOManagementRedirectUri; + WriteVerbose($"Using ClientID {ClientId}"); + return ConnectCredentials(Credentials?.Credential, InitializationType.SPOManagementShell); } @@ -484,6 +532,8 @@ private PnPConnection ConnectSpoManagement() /// PnPConnection based on the parameters provided in the parameter set private PnPConnection ConnectDeviceLogin() { + WriteVerbose("Connecting using Device-Login"); + var messageWriter = new CmdletMessageWriter(this); PnPConnection connection = null; var uri = new Uri(Url); @@ -508,13 +558,25 @@ private PnPConnection ConnectDeviceLogin() { ReuseAuthenticationManager(); } - - var clientId = PnPConnection.PnPManagementShellClientId; + var clientId = ""; if (ParameterSpecified(nameof(ClientId))) { clientId = ClientId; } - + else + { + var environmentAppId = Environment.GetEnvironmentVariable("ENTRAID_APP_ID") ?? Environment.GetEnvironmentVariable("ENTRAID_CLIENT_ID") ?? Environment.GetEnvironmentVariable("AZURE_CLIENT_ID"); + if (!string.IsNullOrEmpty(environmentAppId)) + { + clientId = environmentAppId; + } + else + { + clientId = PnPConnection.PnPManagementShellClientId; + CmdletMessageWriter.WriteFormattedMessage(this, new CmdletMessageWriter.Message { Text = "You are authenticating using the PnP Management Shell multi-tenant App Id. It is strongly recommended to register your own Entra ID App for authentication. See the documentation for Register-PnPEntraIDApp.", Formatted = true, Type = CmdletMessageWriter.MessageType.Warning }); + } + } + var returnedConnection = PnPConnection.CreateWithDeviceLogin(clientId, Url, Tenant, LaunchBrowser, messageWriter, AzureEnvironment, cancellationTokenSource); connection = returnedConnection; messageWriter.Finished = true; @@ -535,6 +597,9 @@ private PnPConnection ConnectDeviceLogin() /// PnPConnection based on the parameters provided in the parameter set private PnPConnection ConnectAppOnlyWithCertificate() { + WriteVerbose("Connecting using Entra ID App-Only using a certificate"); + WriteVerbose($"Using ClientID {ClientId}"); + if (ParameterSpecified(nameof(CertificatePath))) { if (!Path.IsPathRooted(CertificatePath)) @@ -554,6 +619,7 @@ private PnPConnection ConnectAppOnlyWithCertificate() { ReuseAuthenticationManager(); } + return PnPConnection.CreateWithCert(new Uri(Url), ClientId, Tenant, TenantAdminUrl, AzureEnvironment, certificate, true); } else if (ParameterSpecified(nameof(CertificateBase64Encoded))) @@ -603,6 +669,8 @@ private PnPConnection ConnectAppOnlyWithCertificate() /// PnPConnection based on the parameters provided in the parameter set private PnPConnection ConnectAccessToken() { + WriteVerbose("Connecting using a provided Access Token"); + return PnPConnection.CreateWithAccessToken(!string.IsNullOrEmpty(Url) ? new Uri(Url) : null, AccessToken, TenantAdminUrl); } @@ -612,6 +680,8 @@ private PnPConnection ConnectAccessToken() /// PnPConnection based on credentials authentication private PnPConnection ConnectCredentials(PSCredential credentials, InitializationType initializationType = InitializationType.Credentials) { + WriteVerbose("Connecting using username and password"); + if (!CurrentCredentials && credentials == null) { credentials = GetCredentials(); @@ -629,7 +699,16 @@ private PnPConnection ConnectCredentials(PSCredential credentials, Initializatio } if (ClientId == null) { - ClientId = PnPConnection.PnPManagementShellClientId; + var environmentAppId = Environment.GetEnvironmentVariable("ENTRAID_APP_ID") ?? Environment.GetEnvironmentVariable("ENTRAID_CLIENT_ID") ?? Environment.GetEnvironmentVariable("AZURE_CLIENT_ID"); + if (!string.IsNullOrEmpty(environmentAppId)) + { + ClientId = environmentAppId; + } + else + { + ClientId = PnPConnection.PnPManagementShellClientId; + CmdletMessageWriter.WriteFormattedMessage(this, new CmdletMessageWriter.Message { Text = "You are authenticating using the PnP Management Shell multi-tenant App Id. It is strongly recommended to register your own Entra ID App for authentication. See the documentation for Register-PnPEntraIDApp.", Formatted = true, Type = CmdletMessageWriter.MessageType.Warning }); + } } if (Connection?.ClientId == ClientId) @@ -640,7 +719,7 @@ private PnPConnection ConnectCredentials(PSCredential credentials, Initializatio ReuseAuthenticationManager(); } } - + WriteVerbose($"Using ClientID {ClientId}"); return PnPConnection.CreateWithCredentials(this, new Uri(Url), credentials, CurrentCredentials, @@ -652,13 +731,17 @@ private PnPConnection ConnectCredentials(PSCredential credentials, Initializatio private PnPConnection ConnectManagedIdentity() { - WriteVerbose("Connecting using Managed Identity"); + WriteVerbose("Connecting using an Azure Managed Identity"); + + WriteVerbose($"ClientID: {UserAssignedManagedIdentityClientId}"); return PnPConnection.CreateWithManagedIdentity(this, Url, TenantAdminUrl, UserAssignedManagedIdentityObjectId, UserAssignedManagedIdentityClientId, UserAssignedManagedIdentityAzureResourceId); } private PnPConnection ConnectWebLogin() { - WriteWarning("Consider using -Interactive instead, which provides better functionality. See the documentation at https://pnp.github.io/powershell/cmdlets/Connect-PnPOnline.html#interactive-login-for-multi-factor-authentication"); + WriteVerbose("Connecting using WebLogin"); + WriteWarning("Consider using -Interactive instead, which provides better functionality. See the documentation at https://pnp.github.io/powershell/cmdlets/Connect-PnPOnline.html#interactive-for-multi-factor-authentication"); + if (Utilities.OperatingSystem.IsWindows()) { if (!string.IsNullOrWhiteSpace(RelativeUrl)) @@ -678,9 +761,20 @@ private PnPConnection ConnectWebLogin() private PnPConnection ConnectInteractive() { + WriteVerbose("Connecting using Interactive login"); + if (ClientId == null) { - ClientId = PnPConnection.PnPManagementShellClientId; + var environmentAppId = Environment.GetEnvironmentVariable("ENTRAID_APP_ID") ?? Environment.GetEnvironmentVariable("ENTRAID_CLIENT_ID") ?? Environment.GetEnvironmentVariable("AZURE_CLIENT_ID"); + if (!string.IsNullOrEmpty(environmentAppId)) + { + ClientId = environmentAppId; + } + else + { + ClientId = PnPConnection.PnPManagementShellClientId; + CmdletMessageWriter.WriteFormattedMessage(this, new CmdletMessageWriter.Message { Text = "Connecting with -Interactive uses the PnP Management Shell multi-tenant App Id for authentication. It is strongly recommended to register your own Entra ID App for authentication. See the documentation for Register-PnPEntraIDAppForInteractiveLogin.", Formatted = true, Type = CmdletMessageWriter.MessageType.Warning }); + } } if (Connection?.ClientId == ClientId && Connection?.ConnectionMethod == ConnectionMethod.Credentials) { @@ -689,16 +783,20 @@ private PnPConnection ConnectInteractive() ReuseAuthenticationManager(); } } - return PnPConnection.CreateWithInteractiveLogin(new Uri(Url.ToLower()), ClientId, TenantAdminUrl, LaunchBrowser, AzureEnvironment, cancellationTokenSource, ForceAuthentication, Tenant); + WriteVerbose($"Using ClientID {ClientId}"); + + return PnPConnection.CreateWithInteractiveLogin(new Uri(Url.ToLower()), ClientId, TenantAdminUrl, LaunchBrowser, AzureEnvironment, cancellationTokenSource, ForceAuthentication, Tenant, false); } private PnPConnection ConnectEnvironmentVariable(InitializationType initializationType = InitializationType.EnvironmentVariable) { - string username = Environment.GetEnvironmentVariable("AZURE_USERNAME"); - string password = Environment.GetEnvironmentVariable("AZURE_PASSWORD"); - string azureClientId = Environment.GetEnvironmentVariable("AZURE_CLIENT_ID"); - string azureCertificatePath = Environment.GetEnvironmentVariable("AZURE_CLIENT_CERTIFICATE_PATH"); - string azureCertPassword = Environment.GetEnvironmentVariable("AZURE_CLIENT_CERTIFICATE_PASSWORD"); + WriteVerbose("Connecting using information from environment variables"); + + string username = Environment.GetEnvironmentVariable("AZURE_USERNAME") ?? Environment.GetEnvironmentVariable("ENTRAID_USERNAME"); + string password = Environment.GetEnvironmentVariable("AZURE_PASSWORD") ?? Environment.GetEnvironmentVariable("ENTRAID_PASSWORD"); + string azureClientId = Environment.GetEnvironmentVariable("AZURE_CLIENT_ID") ?? Environment.GetEnvironmentVariable("ENTRAID_APP_ID") ?? Environment.GetEnvironmentVariable("ENTRAID_CLIENT_ID"); + string azureCertificatePath = Environment.GetEnvironmentVariable("AZURE_CLIENT_CERTIFICATE_PATH") ?? Environment.GetEnvironmentVariable("ENTRAID_APP_CERTIFICATE_PATH") ?? Environment.GetEnvironmentVariable("ENTRAID_CLIENT_CERTIFICATE_PATH"); + string azureCertPassword = Environment.GetEnvironmentVariable("AZURE_CLIENT_CERTIFICATE_PASSWORD") ?? Environment.GetEnvironmentVariable("ENTRAID_APP_CERTIFICATE_PASSWORD") ?? Environment.GetEnvironmentVariable("ENTRAID_CLIENT_CERTIFICATE_PASSWORD"); if (!string.IsNullOrEmpty(azureCertificatePath) && !string.IsNullOrEmpty(azureCertPassword)) { @@ -732,6 +830,9 @@ private PnPConnection ConnectEnvironmentVariable(InitializationType initializati { ReuseAuthenticationManager(); } + + WriteVerbose($"ClientID: {azureClientId}"); + return PnPConnection.CreateWithCert(new Uri(Url), azureClientId, Tenant, TenantAdminUrl, AzureEnvironment, certificate, true); } @@ -740,6 +841,7 @@ private PnPConnection ConnectEnvironmentVariable(InitializationType initializati if (string.IsNullOrEmpty(azureClientId)) { azureClientId = PnPConnection.PnPManagementShellClientId; + CmdletMessageWriter.WriteFormattedMessage(this, new CmdletMessageWriter.Message { Text = "You are authenticating using the PnP Management Shell multi-tenant App Id. It is strongly recommended to register your own Entra ID App for authentication. See the documentation for Register-PnPEntraIDApp.", Formatted = true, Type = CmdletMessageWriter.MessageType.Warning }); } SecureString secPassword = StringToSecureString(password); @@ -753,6 +855,7 @@ private PnPConnection ConnectEnvironmentVariable(InitializationType initializati ReuseAuthenticationManager(); } } + WriteVerbose($"ClientID: {azureClientId}"); return PnPConnection.CreateWithCredentials(this, new Uri(Url), credentials, @@ -769,9 +872,35 @@ private PnPConnection ConnectEnvironmentVariable(InitializationType initializati private PnPConnection ConnectAzureADWorkloadIdentity() { WriteVerbose("Connecting using Azure AD Workload Identity"); + return PnPConnection.CreateWithAzureADWorkloadIdentity(this, Url, TenantAdminUrl); } + private PnPConnection ConnectWithOSLogin() + { + WriteVerbose("Connecting using Web Account Manager (WAM)"); + + if (ClientId == null) + { + var environmentAppId = Environment.GetEnvironmentVariable("ENTRAID_APP_ID") ?? Environment.GetEnvironmentVariable("ENTRAID_CLIENT_ID") ?? Environment.GetEnvironmentVariable("AZURE_CLIENT_ID"); + if (!string.IsNullOrEmpty(environmentAppId)) + { + ClientId = environmentAppId; + } + } + if (Connection?.ClientId == ClientId && Connection?.ConnectionMethod == ConnectionMethod.Credentials) + { + if (IsSameOrAdminHost(new Uri(Url), new Uri(Connection.Url))) + { + ReuseAuthenticationManager(); + } + } + + WriteVerbose($"Using ClientID {ClientId}"); + + return PnPConnection.CreateWithInteractiveLogin(new Uri(Url.ToLower()), ClientId, TenantAdminUrl, LaunchBrowser, AzureEnvironment, cancellationTokenSource, ForceAuthentication, Tenant, true); + } + #endregion #region Helper methods @@ -897,4 +1026,4 @@ private void SetCustomEndpoints() #endregion } -} +} \ No newline at end of file diff --git a/src/Commands/Base/GetAccessToken.cs b/src/Commands/Base/GetAccessToken.cs index bc41d4257..02b2d0296 100644 --- a/src/Commands/Base/GetAccessToken.cs +++ b/src/Commands/Base/GetAccessToken.cs @@ -1,5 +1,5 @@ -using PnP.PowerShell.Commands.Attributes; -using PnP.PowerShell.Commands.Enums; +using PnP.PowerShell.Commands.Enums; +using PnP.PowerShell.Commands.Utilities.Auth; using System; using System.Management.Automation; @@ -48,7 +48,7 @@ protected override void ExecuteCmdlet() accessTokenValue = TokenHandler.GetAccessToken(this, rootUrl + "/.default", Connection); break; case ResourceTypeName.ARM: - accessTokenValue = TokenHandler.GetAccessToken(this, "https://management.azure.com/.default", Connection); + accessTokenValue = TokenHandler.GetAccessToken(this, ARMEndpoint.GetARMEndpoint(Connection), Connection); break; } } diff --git a/src/Commands/Base/GetDiagnostics.cs b/src/Commands/Base/GetDiagnostics.cs index 65b9a3184..67460b73c 100644 --- a/src/Commands/Base/GetDiagnostics.cs +++ b/src/Commands/Base/GetDiagnostics.cs @@ -81,7 +81,7 @@ void FillLastException(Diagnostics result) var correlationId = string.Empty; if (exception.Exception.Data.Contains("CorrelationId")) { - correlationId = exception.Exception.Data["CorrelationId"].ToString(); + correlationId = exception.Exception.Data["CorrelationId"]?.ToString(); } var timeStampUtc = DateTime.MinValue; if (exception.Exception.Data.Contains("TimeStampUtc")) diff --git a/src/Commands/Base/PipeBinds/AzureADAppPipeBind.cs b/src/Commands/Base/PipeBinds/AzureADAppPipeBind.cs index abe9d3b76..909d7cfdc 100644 --- a/src/Commands/Base/PipeBinds/AzureADAppPipeBind.cs +++ b/src/Commands/Base/PipeBinds/AzureADAppPipeBind.cs @@ -1,7 +1,6 @@ using System; using System.Linq; using System.Management.Automation; -using System.Net.Http; using PnP.PowerShell.Commands.Model; using PnP.PowerShell.Commands.Utilities.REST; @@ -33,20 +32,20 @@ public AzureADApp GetApp(BasePSCmdlet cmdlet, PnPConnection connection, string a { if (_id != Guid.Empty) { - var results = Utilities.REST.GraphHelper.GetAsync>(connection, $"/v1.0/applications?$filter=appId eq '{_id}'", accessToken).GetAwaiter().GetResult(); + var results = GraphHelper.Get>(cmdlet, connection, $"/v1.0/applications?$filter=appId eq '{_id}'", accessToken); if (results != null && results.Items.Any()) { return results.Items.First(); } else { - return Utilities.REST.GraphHelper.GetAsync(connection, $"/v1.0/applications/{_id}", accessToken).GetAwaiter().GetResult(); + return GraphHelper.Get(cmdlet, connection, $"/v1.0/applications/{_id}", accessToken); } } if (!string.IsNullOrEmpty(_name)) { - var results = Utilities.REST.GraphHelper.GetAsync>(connection, $"/v1.0/applications?$filter=displayName eq '{_name}'", accessToken).GetAwaiter().GetResult(); + var results = GraphHelper.Get>(cmdlet, connection, $"/v1.0/applications?$filter=displayName eq '{_name}'", accessToken); if (results != null && results.Items.Any()) { return results.Items.First(); diff --git a/src/Commands/Base/PipeBinds/AzureADGroupPipeBind.cs b/src/Commands/Base/PipeBinds/AzureADGroupPipeBind.cs index 2cca1e448..277cbd4e8 100644 --- a/src/Commands/Base/PipeBinds/AzureADGroupPipeBind.cs +++ b/src/Commands/Base/PipeBinds/AzureADGroupPipeBind.cs @@ -1,6 +1,7 @@ using PnP.PowerShell.Commands.Model.AzureAD; using PnP.PowerShell.Commands.Utilities; using System; +using System.Management.Automation; using Group = PnP.PowerShell.Commands.Model.Graph.Group; namespace PnP.PowerShell.Commands.Base.PipeBinds @@ -39,20 +40,20 @@ public AzureADGroupPipeBind(string input) public string GroupId => (_groupId); - public Group GetGroup(PnPConnection connection, string accessToken) + public Group GetGroup(Cmdlet cmdlet, PnPConnection connection, string accessToken) { Group group = null; if (Group != null) { - group = AzureADGroupsUtility.GetGroupAsync(connection, new Guid(Group.Id), accessToken).GetAwaiter().GetResult(); + group = AzureADGroupsUtility.GetGroup(cmdlet, connection, new Guid(Group.Id), accessToken); } else if (!string.IsNullOrEmpty(GroupId)) { - group = AzureADGroupsUtility.GetGroupAsync(connection, new Guid(GroupId), accessToken).GetAwaiter().GetResult(); + group = AzureADGroupsUtility.GetGroup(cmdlet, connection, new Guid(GroupId), accessToken); } else if (!string.IsNullOrEmpty(DisplayName)) { - group = AzureADGroupsUtility.GetGroupAsync(connection, DisplayName, accessToken).GetAwaiter().GetResult(); + group = AzureADGroupsUtility.GetGroup(cmdlet, connection, DisplayName, accessToken); } if (group != null) { diff --git a/src/Commands/Base/PipeBinds/AzureADUserPipeBind.cs b/src/Commands/Base/PipeBinds/AzureADUserPipeBind.cs index 466b4f373..28ed4ee97 100644 --- a/src/Commands/Base/PipeBinds/AzureADUserPipeBind.cs +++ b/src/Commands/Base/PipeBinds/AzureADUserPipeBind.cs @@ -11,7 +11,7 @@ namespace PnP.PowerShell.Commands.Base.PipeBinds public class AzureADUserPipeBind { private readonly User _user; - private readonly string _userId; + private readonly Guid? _userId; private readonly string _upn; public AzureADUserPipeBind() @@ -28,7 +28,7 @@ public AzureADUserPipeBind(string input) Guid idValue; if (Guid.TryParse(input, out idValue)) { - _userId = input; + _userId = idValue; } else { @@ -49,7 +49,7 @@ public AzureADUserPipeBind(string input) /// /// GUID of the user account /// - public string UserId => _userId; + public Guid? UserId => _userId; /// /// Tries to return the User instace based on the information this pipe has available @@ -63,13 +63,13 @@ public User GetUser(string accessToken, AzureEnvironment azureEnvironment = Azur { return _user; } - if (_userId != null) + if (_userId.HasValue) { - return User.CreateFrom(PnP.Framework.Graph.UsersUtility.GetUser(accessToken, _userId, azureEnvironment: azureEnvironment)); + return User.CreateFrom(Framework.Graph.UsersUtility.GetUser(accessToken, _userId.Value, azureEnvironment: azureEnvironment)); } if (_upn != null) { - return User.CreateFrom(PnP.Framework.Graph.UsersUtility.GetUser(accessToken, WebUtility.UrlEncode(_upn), azureEnvironment: azureEnvironment)); + return User.CreateFrom(Framework.Graph.UsersUtility.GetUser(accessToken, WebUtility.UrlEncode(_upn), azureEnvironment: azureEnvironment)); } return null; } diff --git a/src/Commands/Base/PipeBinds/FilePipeBind.cs b/src/Commands/Base/PipeBinds/FilePipeBind.cs new file mode 100644 index 000000000..f6f1da273 --- /dev/null +++ b/src/Commands/Base/PipeBinds/FilePipeBind.cs @@ -0,0 +1,139 @@ +using System; +using Microsoft.SharePoint.Client; +using System.Management.Automation; +using PnP.Core.Model.SharePoint; +using PnP.Core.Services; + +namespace PnP.PowerShell.Commands.Base.PipeBinds +{ + public sealed class FilePipeBind + { + #region Properties + + public Guid? Id { get; private set; } + public File File { get; private set; } + public IFile CoreFile { get; private set; } + public ListItem ListItem { get; private set; } + public string ServerRelativeUrl { get; private set; } + + #endregion + + #region Constructors + + public FilePipeBind() + { + } + + public FilePipeBind(Guid id) + { + Id = id; + } + + public FilePipeBind(ListItem listItem) + { + ListItem = listItem; + } + + public FilePipeBind(File file) + { + File = file; + } + + public FilePipeBind(IFile coreFile) + { + CoreFile = coreFile; + } + + public FilePipeBind(string id) + { + if (Guid.TryParse(id, out Guid fileGuid)) + { + Id = fileGuid; + } + else + { + ServerRelativeUrl = id; + } + } + + #endregion + + #region Methods + + internal IFile GetCoreFile(PnPContext context, Cmdlet cmdlet = null) + { + if(CoreFile != null) + { + cmdlet?.WriteVerbose("File determined based on CoreFile instance"); + return CoreFile; + } + + if (File != null) + { + cmdlet?.WriteVerbose("File will be retrieved based on CSOM File instance"); + File.EnsureProperties(f => f.UniqueId); + return context.Web.GetFileById(File.UniqueId); + } + + if (ListItem != null) + { + cmdlet?.WriteVerbose("File will be retrieved based on CSOM ListItem instance"); + ListItem.EnsureProperties(i => i.File, i => i.File.UniqueId); + return !ListItem.File.ServerObjectIsNull() ? context.Web.GetFileById(ListItem.File.UniqueId) : null; + } + + if (Id.HasValue) + { + cmdlet?.WriteVerbose("File will be retrieved based on file id"); + return context.Web.GetFileById(Id.Value); + } + + if (!string.IsNullOrEmpty(ServerRelativeUrl)) + { + cmdlet?.WriteVerbose("File will be retrieved based on server relative url"); + return context.Web.GetFileByServerRelativeUrl(ServerRelativeUrl); + } + + throw new PSInvalidOperationException("No information available to retrieve file"); + } + + internal File GetFile(ClientContext context, Cmdlet cmdlet = null) + { + if (File != null) + { + cmdlet?.WriteVerbose("File determined based on CSOM File instance"); + return File; + } + + if (CoreFile != null) + { + cmdlet?.WriteVerbose("File will be retrieved based on PnP Core File instance"); + CoreFile.EnsureProperties(f => f.UniqueId); + return context.Web.GetFileById(File.UniqueId); + } + + if (ListItem != null) + { + cmdlet?.WriteVerbose("File will be retrieved based on CSOM ListItem instance"); + ListItem.EnsureProperties(i => i.File); + return context.Web.GetFileById(ListItem.File.UniqueId); + } + + if (Id.HasValue) + { + cmdlet?.WriteVerbose("File will be retrieved based on file id"); + return context.Web.GetFileById(Id.Value); + } + + if (!string.IsNullOrEmpty(ServerRelativeUrl)) + { + cmdlet?.WriteVerbose("File will be retrieved based on server relative url"); + return context.Web.GetFileByServerRelativeUrl(ServerRelativeUrl); + } + + throw new PSInvalidOperationException("No information available to retrieve file"); + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Commands/Base/PipeBinds/GraphAdditionalHeadersPipeBind.cs b/src/Commands/Base/PipeBinds/GraphAdditionalHeadersPipeBind.cs new file mode 100644 index 000000000..d4b650087 --- /dev/null +++ b/src/Commands/Base/PipeBinds/GraphAdditionalHeadersPipeBind.cs @@ -0,0 +1,37 @@ +using PnP.Framework.Graph.Model; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace PnP.PowerShell.Commands.Base.PipeBinds +{ + public class GraphAdditionalHeadersPipeBind + { + private Dictionary Headers; + + public GraphAdditionalHeadersPipeBind(Hashtable hashtable) + { + Headers = hashtable.Cast().ToDictionary(kvp => (string)kvp.Key, kvp => (string)kvp.Value); + } + + public GraphAdditionalHeadersPipeBind(Dictionary dictionary) + { + Headers = dictionary; + } + + internal Dictionary GetHeaders(bool consistencyLevelEventualPresent) + { + if (consistencyLevelEventualPresent) + { + if (Headers == null) + { + Headers = new Dictionary(); + } + Headers.Remove("ConsistencyLevel"); + Headers.Add("ConsistencyLevel", "eventual"); + } + return Headers; + } + } +} diff --git a/src/Commands/Base/PipeBinds/Microsoft365GroupPipeBind.cs b/src/Commands/Base/PipeBinds/Microsoft365GroupPipeBind.cs index 31a56ea96..a13aaadf3 100644 --- a/src/Commands/Base/PipeBinds/Microsoft365GroupPipeBind.cs +++ b/src/Commands/Base/PipeBinds/Microsoft365GroupPipeBind.cs @@ -44,25 +44,25 @@ public Microsoft365GroupPipeBind(Guid guid) public Guid GroupId => _groupId; - public Microsoft365Group GetGroup(PnPConnection connection, string accessToken, bool includeSite, bool includeOwners, bool detailed, bool includeSensitivityLabels) + public Microsoft365Group GetGroup(Cmdlet cmdlet, PnPConnection connection, string accessToken, bool includeSite, bool includeOwners, bool detailed, bool includeSensitivityLabels) { Microsoft365Group group = null; if (Group != null) { - group = Microsoft365GroupsUtility.GetGroupAsync(connection, _group.Id.Value, accessToken, includeSite, includeOwners, detailed, includeSensitivityLabels).GetAwaiter().GetResult(); + group = ClearOwners.GetGroup(cmdlet, connection, _group.Id.Value, accessToken, includeSite, includeOwners, detailed, includeSensitivityLabels); } else if (_groupId != Guid.Empty) { - group = Microsoft365GroupsUtility.GetGroupAsync(connection, _groupId, accessToken, includeSite, includeOwners, detailed, includeSensitivityLabels).GetAwaiter().GetResult(); + group = ClearOwners.GetGroup(cmdlet, connection, _groupId, accessToken, includeSite, includeOwners, detailed, includeSensitivityLabels); } else if (!string.IsNullOrEmpty(DisplayName)) { - group = Microsoft365GroupsUtility.GetGroupAsync(connection, DisplayName, accessToken, includeSite, includeOwners, detailed, includeSensitivityLabels).GetAwaiter().GetResult(); + group = ClearOwners.GetGroup(cmdlet, connection, DisplayName, accessToken, includeSite, includeOwners, detailed, includeSensitivityLabels); } return group; } - public Guid GetGroupId(PnPConnection connection, string accessToken) + public Guid GetGroupId(Cmdlet cmdlet, PnPConnection connection, string accessToken) { if (Group != null) { @@ -74,7 +74,7 @@ public Guid GetGroupId(PnPConnection connection, string accessToken) } else if (!string.IsNullOrEmpty(DisplayName)) { - var group = Microsoft365GroupsUtility.GetGroupAsync(connection, DisplayName, accessToken, false, false, false, false).GetAwaiter().GetResult(); + var group = ClearOwners.GetGroup(cmdlet, connection, DisplayName, accessToken, false, false, false, false); if (group != null) { return group.Id.Value; @@ -83,24 +83,24 @@ public Guid GetGroupId(PnPConnection connection, string accessToken) throw new PSInvalidOperationException("Group not found"); } - public Microsoft365Group GetDeletedGroup(PnPConnection connection, string accessToken) + public Microsoft365Group GetDeletedGroup(Cmdlet cmdlet, PnPConnection connection, string accessToken) { if (_group != null) { - return Microsoft365GroupsUtility.GetDeletedGroupAsync(connection, _group.Id.Value, accessToken).GetAwaiter().GetResult(); + return ClearOwners.GetDeletedGroup(cmdlet, connection, _group.Id.Value, accessToken); } else if (_groupId != Guid.Empty) { - return Microsoft365GroupsUtility.GetDeletedGroupAsync(connection, _groupId, accessToken).GetAwaiter().GetResult(); + return ClearOwners.GetDeletedGroup(cmdlet, connection, _groupId, accessToken); } else if (!string.IsNullOrEmpty(_displayName)) { - return Microsoft365GroupsUtility.GetDeletedGroupAsync(connection, _displayName, accessToken).GetAwaiter().GetResult(); + return ClearOwners.GetDeletedGroup(cmdlet, connection, _displayName, accessToken); } return null; } - public Guid GetDeletedGroupId(PnPConnection connection, string accessToken) + public Guid GetDeletedGroupId(Cmdlet cmdlet, PnPConnection connection, string accessToken) { if (_group != null) { @@ -112,7 +112,7 @@ public Guid GetDeletedGroupId(PnPConnection connection, string accessToken) } else if (!string.IsNullOrEmpty(_displayName)) { - var group = Microsoft365GroupsUtility.GetDeletedGroupAsync(connection, _displayName, accessToken).GetAwaiter().GetResult(); + var group = ClearOwners.GetDeletedGroup(cmdlet, connection, _displayName, accessToken); if (group != null) { return group.Id.Value; diff --git a/src/Commands/Base/PipeBinds/PlannerBucketPipeBind.cs b/src/Commands/Base/PipeBinds/PlannerBucketPipeBind.cs index c4c796e29..405a70123 100644 --- a/src/Commands/Base/PipeBinds/PlannerBucketPipeBind.cs +++ b/src/Commands/Base/PipeBinds/PlannerBucketPipeBind.cs @@ -34,7 +34,7 @@ public string GetId() } } - public PlannerBucket GetBucket(PnPConnection connection, string accessToken, string planId) + public PlannerBucket GetBucket(Cmdlet cmdlet, PnPConnection connection, string accessToken, string planId) { // first try to get the bucket by id if (_bucket != null) @@ -45,7 +45,7 @@ public PlannerBucket GetBucket(PnPConnection connection, string accessToken, str { try { - var buckets = PlannerUtility.GetBucketsAsync(connection, accessToken, planId).GetAwaiter().GetResult(); + var buckets = PlannerUtility.GetBuckets(cmdlet, connection, accessToken, planId); if (buckets != null) { PlannerBucket bucket = null; diff --git a/src/Commands/Base/PipeBinds/PlannerGroupPipeBind.cs b/src/Commands/Base/PipeBinds/PlannerGroupPipeBind.cs index 4f308d30d..3dea50bb0 100644 --- a/src/Commands/Base/PipeBinds/PlannerGroupPipeBind.cs +++ b/src/Commands/Base/PipeBinds/PlannerGroupPipeBind.cs @@ -38,7 +38,7 @@ public PlannerGroupPipeBind(Model.Graph.Group group) _id = group.Id; } - public string GetGroupId(PnPConnection connection, string accessToken) + public string GetGroupId(Cmdlet cmdlet, PnPConnection connection, string accessToken) { if (!string.IsNullOrEmpty(_id)) { @@ -46,7 +46,7 @@ public string GetGroupId(PnPConnection connection, string accessToken) } else { - var collection = GraphHelper.GetAsync>(connection, $"v1.0/groups?$filter=mailNickname eq '{_stringValue}'&$select=Id", accessToken).GetAwaiter().GetResult(); + var collection = GraphHelper.Get>(cmdlet, connection, $"v1.0/groups?$filter=mailNickname eq '{_stringValue}'&$select=Id", accessToken); if (collection != null && collection.Items.Any()) { return collection.Items.First().Id; @@ -54,7 +54,7 @@ public string GetGroupId(PnPConnection connection, string accessToken) else { // find the team by displayName - var byDisplayNamecollection = GraphHelper.GetAsync>(connection, $"v1.0/groups?$filter=displayName eq '{_stringValue}'&$select=Id", accessToken).GetAwaiter().GetResult(); + var byDisplayNamecollection = GraphHelper.Get>(cmdlet, connection, $"v1.0/groups?$filter=displayName eq '{_stringValue}'&$select=Id", accessToken); if (byDisplayNamecollection != null && byDisplayNamecollection.Items.Any()) { if (byDisplayNamecollection.Items.Count() == 1) diff --git a/src/Commands/Base/PipeBinds/PlannerPlanPipeBind.cs b/src/Commands/Base/PipeBinds/PlannerPlanPipeBind.cs index ada835a7f..d6e1f57e5 100644 --- a/src/Commands/Base/PipeBinds/PlannerPlanPipeBind.cs +++ b/src/Commands/Base/PipeBinds/PlannerPlanPipeBind.cs @@ -1,6 +1,5 @@ using System.Linq; using System.Management.Automation; -using System.Threading.Tasks; using PnP.PowerShell.Commands.Model.Graph; using PnP.PowerShell.Commands.Model.Planner; using PnP.PowerShell.Commands.Utilities; @@ -25,7 +24,7 @@ public PlannerPlanPipeBind(PlannerPlan plan) _plan = plan; } - public async Task GetPlanAsync(PnPConnection connection, string accessToken, string groupId, bool resolveIdentities) + public PlannerPlan GetPlan(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, bool resolveIdentities) { if (_plan != null) { @@ -34,11 +33,11 @@ public async Task GetPlanAsync(PnPConnection connection, string acc // first try to get the plan by id try { - return await PlannerUtility.GetPlanAsync(connection, accessToken, _id, resolveIdentities); + return PlannerUtility.GetPlan(cmdlet, connection, accessToken, _id, resolveIdentities); } catch (GraphException) { - var plans = await PlannerUtility.GetPlansAsync(connection, accessToken, groupId, resolveIdentities); + var plans = PlannerUtility.GetPlans(cmdlet,connection, accessToken, groupId, resolveIdentities); if (plans != null && plans.Any()) { var collection = plans.Where(p => p.Title.Equals(_id)); @@ -55,7 +54,7 @@ public async Task GetPlanAsync(PnPConnection connection, string acc return null; } - public async Task GetIdAsync(PnPConnection connection, string accessToken, string groupId) + public string GetId(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId) { if (_plan != null) { @@ -64,12 +63,12 @@ public async Task GetIdAsync(PnPConnection connection, string accessToke // first try to get the plan by id try { - var plan = await PlannerUtility.GetPlanAsync(connection, accessToken, _id, false); + var plan = PlannerUtility.GetPlan(cmdlet, connection, accessToken, _id, false); return plan.Id; } catch (GraphException) { - var plans = await PlannerUtility.GetPlansAsync(connection, accessToken, groupId, false); + var plans = PlannerUtility.GetPlans(cmdlet, connection, accessToken, groupId, false); if (plans != null && plans.Any()) { var collection = plans.Where(p => p.Title.Equals(_id)); @@ -85,6 +84,5 @@ public async Task GetIdAsync(PnPConnection connection, string accessToke } return null; } - } } diff --git a/src/Commands/Base/PipeBinds/PlannerRosterPipeBind.cs b/src/Commands/Base/PipeBinds/PlannerRosterPipeBind.cs index dcc8f9a4e..7d876df59 100644 --- a/src/Commands/Base/PipeBinds/PlannerRosterPipeBind.cs +++ b/src/Commands/Base/PipeBinds/PlannerRosterPipeBind.cs @@ -1,4 +1,4 @@ -using System.Threading.Tasks; +using System.Management.Automation; using PnP.PowerShell.Commands.Model.Planner; using PnP.PowerShell.Commands.Utilities; @@ -22,13 +22,13 @@ public PlannerRosterPipeBind(PlannerRoster roster) _roster = roster; } - public async Task GetPlannerRosterAsync(PnPConnection connection, string accessToken) + public PlannerRoster GetPlannerRoster(Cmdlet cmdlet, PnPConnection connection, string accessToken) { if (_roster != null) { return _roster; } - return await PlannerUtility.GetRosterAsync(connection, accessToken, _id); + return PlannerUtility.GetRoster(cmdlet, connection, accessToken, _id); } } } diff --git a/src/Commands/Base/PipeBinds/SearchExternalConnectionPipeBind.cs b/src/Commands/Base/PipeBinds/SearchExternalConnectionPipeBind.cs new file mode 100644 index 000000000..5360c7645 --- /dev/null +++ b/src/Commands/Base/PipeBinds/SearchExternalConnectionPipeBind.cs @@ -0,0 +1,39 @@ +using System.Management.Automation; + +namespace PnP.PowerShell.Commands.Base.PipeBinds +{ + public class SearchExternalConnectionPipeBind + { + private readonly Model.Graph.MicrosoftSearch.ExternalConnection _searchExternalConnection; + private readonly string _identity; + + public SearchExternalConnectionPipeBind() + { + _searchExternalConnection = null; + _identity = null; + } + + public SearchExternalConnectionPipeBind(Model.Graph.MicrosoftSearch.ExternalConnection searchExternalConnection) + { + _searchExternalConnection = searchExternalConnection; + } + + public SearchExternalConnectionPipeBind(string identity) + { + _identity = identity; + } + + public Model.Graph.MicrosoftSearch.ExternalConnection GetExternalConnection(PSCmdlet cmdlet, PnPConnection connection, string accessToken) + { + if(_searchExternalConnection != null) + { + return _searchExternalConnection; + } + else + { + var externalConnectionResult = Utilities.REST.GraphHelper.Get(cmdlet, connection, $"v1.0/external/connections/{_identity}", accessToken); + return externalConnectionResult; + } + } + } +} diff --git a/src/Commands/Base/PipeBinds/SensitivityLabelPipeBind.cs b/src/Commands/Base/PipeBinds/SensitivityLabelPipeBind.cs index 767942e61..8dda2ae68 100644 --- a/src/Commands/Base/PipeBinds/SensitivityLabelPipeBind.cs +++ b/src/Commands/Base/PipeBinds/SensitivityLabelPipeBind.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Management.Automation; namespace PnP.PowerShell.Commands.Base.PipeBinds { @@ -60,7 +61,7 @@ public SensitivityLabelPipeBind(Model.Graph.Purview.InformationProtectionLabel l /// Connection that can be used to query Microsoft Graph for the available sensitivity labels /// Access Token to use to authenticate to Microsoft Graph /// The the sensitivity label that matches the name set in this pipebind or NULL if no match found - public Model.Graph.Purview.InformationProtectionLabel GetLabelByNameThroughGraph(PnPConnection connection, string accesstoken) + public Model.Graph.Purview.InformationProtectionLabel GetLabelByNameThroughGraph(Cmdlet cmdlet, PnPConnection connection, string accesstoken) { if (string.IsNullOrEmpty(_labelName)) return null; @@ -74,7 +75,7 @@ public Model.Graph.Purview.InformationProtectionLabel GetLabelByNameThroughGraph url = "/beta/me/security/informationProtection/sensitivityLabels"; } - var availableLabels = Utilities.REST.GraphHelper.GetResultCollectionAsync(connection, $"https://{connection.GraphEndPoint}/{url}", accesstoken).GetAwaiter().GetResult(); + var availableLabels = Utilities.REST.GraphHelper.GetResultCollection(cmdlet, connection, $"https://{connection.GraphEndPoint}/{url}", accesstoken); return availableLabels.FirstOrDefault(l => l.Name == _labelName); } } diff --git a/src/Commands/Base/PipeBinds/ServicePrincipalAssignedAppRoleBind.cs b/src/Commands/Base/PipeBinds/ServicePrincipalAssignedAppRoleBind.cs index 04e63dd5f..ce1d5fdf7 100644 --- a/src/Commands/Base/PipeBinds/ServicePrincipalAssignedAppRoleBind.cs +++ b/src/Commands/Base/PipeBinds/ServicePrincipalAssignedAppRoleBind.cs @@ -2,6 +2,7 @@ using PnP.PowerShell.Commands.Utilities; using System; using System.Linq; +using System.Management.Automation; namespace PnP.PowerShell.Commands.Base.PipeBinds { @@ -31,7 +32,7 @@ public ServicePrincipalAssignedAppRoleBind(AzureADServicePrincipalAppRoleAssignm public string Id => _id; public AzureADServicePrincipalAppRoleAssignment AppRoleAssignment => _appRoleAssignment; - internal AzureADServicePrincipalAppRoleAssignment GetAssignedAppRole(PnPConnection connection, string accesstoken, string servicePrincipalObjectId = null) + internal AzureADServicePrincipalAppRoleAssignment GetAssignedAppRole(Cmdlet cmdlet, PnPConnection connection, string accesstoken, string servicePrincipalObjectId = null) { AzureADServicePrincipalAppRoleAssignment appRoleAssignment = null; @@ -42,7 +43,7 @@ internal AzureADServicePrincipalAppRoleAssignment GetAssignedAppRole(PnPConnecti { throw new ArgumentNullException(nameof(servicePrincipalObjectId), $"{nameof(servicePrincipalObjectId)} is required when the {GetType()} is created based on an Id"); } - appRoleAssignment = ServicePrincipalUtility.GetServicePrincipalAppRoleAssignmentsByServicePrincipalObjectId(connection, accesstoken, servicePrincipalObjectId, _id).FirstOrDefault(); + appRoleAssignment = ServicePrincipalUtility.GetServicePrincipalAppRoleAssignmentsByServicePrincipalObjectId(cmdlet, connection, accesstoken, servicePrincipalObjectId, _id).FirstOrDefault(); } return appRoleAssignment; diff --git a/src/Commands/Base/PipeBinds/ServicePrincipalPipeBind.cs b/src/Commands/Base/PipeBinds/ServicePrincipalPipeBind.cs index 093e63e2b..25ec04f24 100644 --- a/src/Commands/Base/PipeBinds/ServicePrincipalPipeBind.cs +++ b/src/Commands/Base/PipeBinds/ServicePrincipalPipeBind.cs @@ -1,6 +1,7 @@ using PnP.PowerShell.Commands.Model.AzureAD; using PnP.PowerShell.Commands.Utilities; using System; +using System.Management.Automation; namespace PnP.PowerShell.Commands.Base.PipeBinds { @@ -38,11 +39,11 @@ public ServicePrincipalPipeBind(AzureADServicePrincipal servicePrincipal) public Guid? Id => _id; public AzureADServicePrincipal ServicePrincipal => _servicePrincipal; - internal AzureADServicePrincipal GetServicePrincipal(PnPConnection connection, string accesstoken) + internal AzureADServicePrincipal GetServicePrincipal(Cmdlet cmdlet, PnPConnection connection, string accesstoken) { if(_servicePrincipal != null) return _servicePrincipal; - if(!string.IsNullOrEmpty(_displayName)) return ServicePrincipalUtility.GetServicePrincipalByAppName(connection, accesstoken, _displayName); - if(_id.HasValue) return ServicePrincipalUtility.GetServicePrincipalByObjectId(connection, accesstoken, _id.Value) ?? ServicePrincipalUtility.GetServicePrincipalByAppId(connection, accesstoken, _id.Value); + if(!string.IsNullOrEmpty(_displayName)) return ServicePrincipalUtility.GetServicePrincipalByAppName(cmdlet, connection, accesstoken, _displayName); + if(_id.HasValue) return ServicePrincipalUtility.GetServicePrincipalByObjectId(cmdlet, connection, accesstoken, _id.Value) ?? ServicePrincipalUtility.GetServicePrincipalByAppId(cmdlet, connection, accesstoken, _id.Value); return null; } } diff --git a/src/Commands/Base/PipeBinds/SitePipeBind.cs b/src/Commands/Base/PipeBinds/SitePipeBind.cs index 2058881c8..6ee2bae73 100644 --- a/src/Commands/Base/PipeBinds/SitePipeBind.cs +++ b/src/Commands/Base/PipeBinds/SitePipeBind.cs @@ -70,7 +70,7 @@ public Guid GetSiteIdThroughGraph(PnPConnection connection, string accesstoken) { var uri = new Uri(_url); - var result = Utilities.REST.RestHelper.GetAsync(connection.HttpClient, $"https://{connection.GraphEndPoint}/v1.0/sites/{uri.Host}:{uri.LocalPath}", accesstoken).GetAwaiter().GetResult(); + var result = Utilities.REST.RestHelper.Get(connection.HttpClient, $"https://{connection.GraphEndPoint}/v1.0/sites/{uri.Host}:{uri.LocalPath}", accesstoken); if (!string.IsNullOrEmpty(result)) { var resultElement = JsonSerializer.Deserialize(result); diff --git a/src/Commands/Base/PipeBinds/TeamsAppPipeBind.cs b/src/Commands/Base/PipeBinds/TeamsAppPipeBind.cs index 3cbde28a7..c9e463618 100644 --- a/src/Commands/Base/PipeBinds/TeamsAppPipeBind.cs +++ b/src/Commands/Base/PipeBinds/TeamsAppPipeBind.cs @@ -3,7 +3,6 @@ using System; using System.Linq; using System.Management.Automation; -using System.Net.Http; namespace PnP.PowerShell.Commands.Base.PipeBinds { @@ -38,18 +37,18 @@ public TeamsAppPipeBind(string input) public string StringValue => _stringValue; - public TeamApp GetApp(PnPConnection connection, string accessToken) + public TeamApp GetApp(Cmdlet cmdlet, PnPConnection connection, string accessToken) { if (Id != Guid.Empty) { - var collection = GraphHelper.GetAsync>(connection, $"v1.0/appCatalogs/teamsApps?$filter=id eq '{_id}'", accessToken).GetAwaiter().GetResult(); + var collection = GraphHelper.Get>(cmdlet, connection, $"v1.0/appCatalogs/teamsApps?$filter=id eq '{_id}'", accessToken); if (collection != null && collection.Items.Any()) { return collection.Items.First(); } else { - collection = GraphHelper.GetAsync>(connection, $"v1.0/appCatalogs/teamsApps?$filter=externalId eq '{_id}'", accessToken).GetAwaiter().GetResult(); + collection = GraphHelper.Get>(cmdlet, connection, $"v1.0/appCatalogs/teamsApps?$filter=externalId eq '{_id}'", accessToken); if (collection != null && collection.Items.Any()) { return collection.Items.First(); @@ -58,7 +57,7 @@ public TeamApp GetApp(PnPConnection connection, string accessToken) } else { - var collection = GraphHelper.GetAsync>(connection, $"v1.0/appCatalogs/teamsApps?$filter=displayName eq '{_stringValue}'", accessToken).GetAwaiter().GetResult(); + var collection = GraphHelper.Get>(cmdlet, connection, $"v1.0/appCatalogs/teamsApps?$filter=displayName eq '{_stringValue}'", accessToken); if (collection != null && collection.Items.Any()) { if (collection.Items.Count() == 1) diff --git a/src/Commands/Base/PipeBinds/TeamsChannelMemberPipeBind.cs b/src/Commands/Base/PipeBinds/TeamsChannelMemberPipeBind.cs index 76a21c806..ea28cfb65 100644 --- a/src/Commands/Base/PipeBinds/TeamsChannelMemberPipeBind.cs +++ b/src/Commands/Base/PipeBinds/TeamsChannelMemberPipeBind.cs @@ -2,6 +2,7 @@ using PnP.PowerShell.Commands.Utilities; using System; using System.Linq; +using System.Management.Automation; using System.Net.Http; using System.Threading.Tasks; @@ -40,7 +41,7 @@ public TeamsChannelMemberPipeBind(TeamChannelMember membership) _membership = membership; } - public async Task GetIdAsync(PnPConnection Connection, string accessToken, string groupId, string channelId) + public string GetId(Cmdlet cmdlet, PnPConnection Connection, string accessToken, string groupId, string channelId) { if (!string.IsNullOrEmpty(_id)) { @@ -52,7 +53,7 @@ public async Task GetIdAsync(PnPConnection Connection, string accessToke return _membership.Id; } - var memberships = await TeamsUtility.GetChannelMembersAsync(Connection, accessToken, groupId, channelId); + var memberships = TeamsUtility.GetChannelMembers(cmdlet, Connection, accessToken, groupId, channelId); if (!string.IsNullOrEmpty(_userUpn)) { return memberships.FirstOrDefault(m => _userUpn.Equals(m.Email, StringComparison.OrdinalIgnoreCase))?.Id; @@ -61,7 +62,7 @@ public async Task GetIdAsync(PnPConnection Connection, string accessToke return memberships.FirstOrDefault(m => !string.IsNullOrEmpty(m.UserId) && _userId.Equals(m.UserId, StringComparison.OrdinalIgnoreCase))?.Id; } - public async Task GetMembershipAsync(PnPConnection Connection, string accessToken, string groupId, string channelId) + public TeamChannelMember GetMembership(Cmdlet cmdlet, PnPConnection Connection, string accessToken, string groupId, string channelId) { if (_membership != null) { @@ -70,10 +71,10 @@ public async Task GetMembershipAsync(PnPConnection Connection if (!string.IsNullOrEmpty(_id)) { - return await TeamsUtility.GetChannelMemberAsync(Connection, accessToken, groupId, channelId, _id); + return TeamsUtility.GetChannelMember(cmdlet, Connection, accessToken, groupId, channelId, _id); } - var memberships = await TeamsUtility.GetChannelMembersAsync(Connection, accessToken, groupId, channelId); + var memberships = TeamsUtility.GetChannelMembers(cmdlet, Connection, accessToken, groupId, channelId); if (!string.IsNullOrEmpty(_userUpn)) { return memberships.FirstOrDefault(m => _userUpn.Equals(m.Email, StringComparison.OrdinalIgnoreCase)); diff --git a/src/Commands/Base/PipeBinds/TeamsChannelPipeBind.cs b/src/Commands/Base/PipeBinds/TeamsChannelPipeBind.cs index e5944a526..c7be15c26 100644 --- a/src/Commands/Base/PipeBinds/TeamsChannelPipeBind.cs +++ b/src/Commands/Base/PipeBinds/TeamsChannelPipeBind.cs @@ -2,7 +2,7 @@ using PnP.PowerShell.Commands.Utilities; using System; using System.Linq; -using System.Net.Http; +using System.Management.Automation; namespace PnP.PowerShell.Commands.Base.PipeBinds { @@ -36,7 +36,7 @@ public TeamsChannelPipeBind(Model.Teams.TeamChannel channel) public string Id => _id; - public string GetId(PnPConnection connection, string accessToken, string groupId) + public string GetId(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId) { if (!string.IsNullOrEmpty(_id)) { @@ -44,21 +44,21 @@ public string GetId(PnPConnection connection, string accessToken, string groupId } else { - var channels = TeamsUtility.GetChannelsAsync(accessToken, connection, groupId).GetAwaiter().GetResult(); + var channels = TeamsUtility.GetChannels(cmdlet, accessToken, connection, groupId); return channels.FirstOrDefault(c => c.DisplayName.Equals(_displayName, StringComparison.OrdinalIgnoreCase))?.Id; } } - public TeamChannel GetChannel(PnPConnection connection, string accessToken, string groupId, bool useBeta = false) + public TeamChannel GetChannel(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, bool useBeta = false) { if (!string.IsNullOrEmpty(_id)) { - var channel = TeamsUtility.GetChannelAsync(accessToken, connection, groupId, _id, useBeta).GetAwaiter().GetResult(); + var channel = TeamsUtility.GetChannel(cmdlet, accessToken, connection, groupId, _id, useBeta); return channel; } else { - var channels = TeamsUtility.GetChannelsAsync(accessToken, connection, groupId, useBeta).GetAwaiter().GetResult(); + var channels = TeamsUtility.GetChannels(cmdlet, accessToken, connection, groupId, useBeta); if (channels != null && channels.Any()) { return channels.FirstOrDefault(c => c.DisplayName.Equals(_displayName, StringComparison.OrdinalIgnoreCase)); diff --git a/src/Commands/Base/PipeBinds/TeamsTabPipeBind.cs b/src/Commands/Base/PipeBinds/TeamsTabPipeBind.cs index 17f6b1a72..0c0c00a7d 100644 --- a/src/Commands/Base/PipeBinds/TeamsTabPipeBind.cs +++ b/src/Commands/Base/PipeBinds/TeamsTabPipeBind.cs @@ -47,10 +47,10 @@ public TeamTab GetTab(BasePSCmdlet cmdlet, PnPConnection Connection, string acce } else { - var tab = TeamsUtility.GetTabAsync(accessToken, Connection, groupId, channelId, _id).GetAwaiter().GetResult(); + var tab = TeamsUtility.GetTab(cmdlet, accessToken, Connection, groupId, channelId, _id); if (string.IsNullOrEmpty(tab.Id)) { - var tabs = TeamsUtility.GetTabsAsync(accessToken, Connection, groupId, channelId).GetAwaiter().GetResult(); + var tabs = TeamsUtility.GetTabs(cmdlet, accessToken, Connection, groupId, channelId); if (tabs != null) { // find the tab by id diff --git a/src/Commands/Base/PipeBinds/TeamsTagPipeBind.cs b/src/Commands/Base/PipeBinds/TeamsTagPipeBind.cs index 643e9e8f7..9646f8b69 100644 --- a/src/Commands/Base/PipeBinds/TeamsTagPipeBind.cs +++ b/src/Commands/Base/PipeBinds/TeamsTagPipeBind.cs @@ -2,7 +2,7 @@ using PnP.PowerShell.Commands.Utilities; using System; using System.Linq; -using System.Net.Http; +using System.Management.Automation; namespace PnP.PowerShell.Commands.Base.PipeBinds { @@ -24,9 +24,9 @@ public TeamsTagPipeBind(TeamTag tag) } - public TeamTag GetTag(PnPConnection connection, string accessToken, string groupId) + public TeamTag GetTag(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId) { - var tags = TeamsUtility.GetTagsAsync(accessToken, connection, groupId).GetAwaiter().GetResult(); + var tags = TeamsUtility.GetTags(cmdlet, accessToken, connection, groupId); if (tags != null && tags.Any()) { return tags.FirstOrDefault(c => c.Id.Equals(_id, StringComparison.OrdinalIgnoreCase)); diff --git a/src/Commands/Base/PipeBinds/TeamsTeamPipeBind.cs b/src/Commands/Base/PipeBinds/TeamsTeamPipeBind.cs index 929ddb41e..089cb53a2 100644 --- a/src/Commands/Base/PipeBinds/TeamsTeamPipeBind.cs +++ b/src/Commands/Base/PipeBinds/TeamsTeamPipeBind.cs @@ -46,7 +46,7 @@ public TeamsTeamPipeBind(Guid id) _id = id.ToString(); } - public string GetGroupId(PnPConnection connection, string accessToken) + public string GetGroupId(Cmdlet cmdlet, PnPConnection connection, string accessToken) { if (!string.IsNullOrEmpty(_id)) { @@ -54,7 +54,7 @@ public string GetGroupId(PnPConnection connection, string accessToken) } else { - var collection = GraphHelper.GetAsync>(connection, $"v1.0/groups?$filter=(resourceProvisioningOptions/Any(x:x eq 'Team') and mailNickname eq '{UrlUtilities.UrlEncode(_stringValue)}')&$select=Id", accessToken).GetAwaiter().GetResult(); + var collection = GraphHelper.Get>(cmdlet, connection, $"v1.0/groups?$filter=(resourceProvisioningOptions/Any(x:x eq 'Team') and mailNickname eq '{UrlUtilities.UrlEncode(_stringValue)}')&$select=Id", accessToken); if (collection != null && collection.Items.Any()) { return collection.Items.First().Id; @@ -62,7 +62,7 @@ public string GetGroupId(PnPConnection connection, string accessToken) else { // find the team by displayName - var byDisplayNamecollection = GraphHelper.GetAsync>(connection, $"v1.0/groups?$filter=(resourceProvisioningOptions/Any(x:x eq 'Team') and displayName eq '{UrlUtilities.UrlEncode(_stringValue)}')&$select=Id", accessToken).GetAwaiter().GetResult(); + var byDisplayNamecollection = GraphHelper.Get>(cmdlet, connection, $"v1.0/groups?$filter=(resourceProvisioningOptions/Any(x:x eq 'Team') and displayName eq '{UrlUtilities.UrlEncode(_stringValue)}')&$select=Id", accessToken); if (byDisplayNamecollection != null && byDisplayNamecollection.Items.Any()) { if (byDisplayNamecollection.Items.Count() == 1) @@ -79,22 +79,22 @@ public string GetGroupId(PnPConnection connection, string accessToken) } } - public Team GetTeam(PnPConnection connection, string accessToken) + public Team GetTeam(Cmdlet cmdlet, PnPConnection connection, string accessToken) { try { if (!string.IsNullOrEmpty(_id)) { - return GraphHelper.GetAsync(connection, $"v1.0/teams/{_id}", accessToken, false).GetAwaiter().GetResult(); + return GraphHelper.Get(cmdlet, connection, $"v1.0/teams/{_id}", accessToken, false); } else { - var collection = GraphHelper.GetAsync>(connection, $"v1.0/groups?$filter=(resourceProvisioningOptions/Any(x:x eq 'Team') and displayName eq '{_stringValue}')&$select=Id", accessToken).GetAwaiter().GetResult(); + var collection = GraphHelper.Get>(cmdlet, connection, $"v1.0/groups?$filter=(resourceProvisioningOptions/Any(x:x eq 'Team') and displayName eq '{_stringValue}')&$select=Id", accessToken); if (collection != null && collection.Items.Any()) { if (collection.Items.Count() == 1) { - return GraphHelper.GetAsync(connection, $"v1.0/teams/{collection.Items.First().Id}", accessToken, false).GetAwaiter().GetResult(); + return GraphHelper.Get(cmdlet, connection, $"v1.0/teams/{collection.Items.First().Id}", accessToken, false); } else { @@ -103,10 +103,10 @@ public Team GetTeam(PnPConnection connection, string accessToken) } else { - collection = GraphHelper.GetAsync>(connection, $"v1.0/groups?$filter=(resourceProvisioningOptions/Any(x:x eq 'Team') and mailNickname eq '{_stringValue}')&$select=Id", accessToken).GetAwaiter().GetResult(); + collection = GraphHelper.Get>(cmdlet, connection, $"v1.0/groups?$filter=(resourceProvisioningOptions/Any(x:x eq 'Team') and mailNickname eq '{_stringValue}')&$select=Id", accessToken); if (collection != null && collection.Items.Count() == 1) { - return GraphHelper.GetAsync(connection, $"v1.0/teams/{collection.Items.First().Id}", accessToken, false).GetAwaiter().GetResult(); + return GraphHelper.Get(cmdlet, connection, $"v1.0/teams/{collection.Items.First().Id}", accessToken, false); } } } diff --git a/src/Commands/Base/PnPAzureManagementApiCmdlet.cs b/src/Commands/Base/PnPAzureManagementApiCmdlet.cs index e1866a4ea..9f35c58fe 100644 --- a/src/Commands/Base/PnPAzureManagementApiCmdlet.cs +++ b/src/Commands/Base/PnPAzureManagementApiCmdlet.cs @@ -1,6 +1,6 @@ using System.Management.Automation; using Microsoft.SharePoint.Client; -using PnP.PowerShell.Commands.Model; +using PnP.PowerShell.Commands.Utilities.Auth; namespace PnP.PowerShell.Commands.Base { @@ -10,35 +10,12 @@ namespace PnP.PowerShell.Commands.Base public abstract class PnPAzureManagementApiCmdlet : PnPConnectedCmdlet { /// - /// Returns an Access Token for the Azure Management API, if available, otherwise NULL + /// Returns an Access Token for the Microsoft Office Management API, if available, otherwise NULL /// - public string AccessToken - { - get - { - if (Connection != null) - { - if (Connection.ConnectionMethod == ConnectionMethod.ManagedIdentity) - { - return TokenHandler.GetManagedIdentityTokenAsync(this, Connection.HttpClient, "https://management.azure.com", Connection.UserAssignedManagedIdentityObjectId, Connection.UserAssignedManagedIdentityClientId, Connection.UserAssignedManagedIdentityAzureResourceId).GetAwaiter().GetResult(); - } - else if (Connection.ConnectionMethod == ConnectionMethod.AzureADWorkloadIdentity) - { - return TokenHandler.GetAzureADWorkloadIdentityTokenAsync(this, "https://management.azure.com/.default").GetAwaiter().GetResult(); - } - else - { - if (Connection.Context != null) - { - return TokenHandler.GetAccessToken(this, "https://management.azure.com/.default", Connection); - } - } - } - WriteVerbose("Unable to acquire token for resource: https://management.azure.com/"); - return null; - } - } + public string AccessToken => TokenHandler.GetAccessToken(this, ARMEndpoint.GetARMEndpoint(Connection), Connection); + public string PowerAppsServiceAccessToken => TokenHandler.GetAccessToken(this,"https://service.powerapps.com/.default",Connection); + protected override void BeginProcessing() { base.BeginProcessing(); @@ -49,6 +26,6 @@ protected override void BeginProcessing() throw new PSInvalidOperationException("This cmdlet not work with a WebLogin/Cookie based connection towards SharePoint."); } } - } + } } } \ No newline at end of file diff --git a/src/Commands/Base/PnPConnectedCmdlet.cs b/src/Commands/Base/PnPConnectedCmdlet.cs index 6888f0597..6dfaf093e 100644 --- a/src/Commands/Base/PnPConnectedCmdlet.cs +++ b/src/Commands/Base/PnPConnectedCmdlet.cs @@ -62,12 +62,12 @@ protected override void ProcessRecord() string errorMessage; switch (ex) { - case PnP.PowerShell.Commands.Model.Graph.GraphException gex: - errorMessage = $"{gex.HttpResponse.ReasonPhrase} ({(int)gex.HttpResponse.StatusCode}): {gex.Error.Message}"; + case Model.Graph.GraphException gex: + errorMessage = $"{gex.HttpResponse.ReasonPhrase} ({(int)gex.HttpResponse.StatusCode}): {(gex.Error != null ? gex.Error.Message : gex.HttpResponse.Content.ReadAsStringAsync().Result)}"; break; - case PnP.Core.SharePointRestServiceException rex: - errorMessage = (rex.Error as PnP.Core.SharePointRestError).Message; + case Core.SharePointRestServiceException rex: + errorMessage = (rex.Error as Core.SharePointRestError).Message; break; case System.Reflection.TargetInvocationException tex: @@ -86,8 +86,8 @@ protected override void ProcessRecord() errorMessage = innermostException.Message; } break; - case PnP.Core.MicrosoftGraphServiceException pgex: - errorMessage = (pgex.Error as PnP.Core.MicrosoftGraphError).Message; + case Core.MicrosoftGraphServiceException pgex: + errorMessage = (pgex.Error as Core.MicrosoftGraphError).Message; break; default: @@ -96,7 +96,7 @@ protected override void ProcessRecord() } // If the ErrorAction is not set to Stop, Ignore or SilentlyContinue throw an exception, otherwise just continue - if (!ParameterSpecified("ErrorAction") || !(new [] { "stop", "ignore", "silentlycontinue" }.Contains(MyInvocation.BoundParameters["ErrorAction"].ToString().ToLowerInvariant()))) + if (!(new [] { "stop", "ignore", "silentlycontinue" }.Contains(ErrorActionSetting.ToLowerInvariant()))) { throw new PSInvalidOperationException(errorMessage); } @@ -107,7 +107,7 @@ protected override void ProcessRecord() } // With ErrorAction:Ignore, the $Error variable should not be populated with the error, otherwise it should - if (!ParameterSpecified("ErrorAction") || !(new[] { "ignore" }.Contains(MyInvocation.BoundParameters["ErrorAction"].ToString().ToLowerInvariant()))) + if (!new[] { "ignore" }.Contains(ErrorActionSetting.ToLowerInvariant())) { ex.Data["CorrelationId"] = Connection.Context.TraceCorrelationId; ex.Data["TimeStampUtc"] = DateTime.UtcNow; diff --git a/src/Commands/Base/PnPConnection.cs b/src/Commands/Base/PnPConnection.cs index db018126d..6a4acf849 100644 --- a/src/Commands/Base/PnPConnection.cs +++ b/src/Commands/Base/PnPConnection.cs @@ -141,7 +141,6 @@ internal PnPContext PnPContext /// If applicable, will return the object/principal ID of the User Assigned Managed Identity that is being used for this connection /// public string UserAssignedManagedIdentityObjectId { get; set; } - /// /// If applicable, will return the client ID of the User Assigned Managed Identity that is being used for this connection /// @@ -150,7 +149,7 @@ internal PnPContext PnPContext /// /// If applicable, will return the Azure Resource ID of the User Assigned Managed Identity that is being used for this connection /// - public string UserAssignedManagedIdentityAzureResourceId { get; set; } + public string UserAssignedManagedIdentityAzureResourceId { get; set; } /// /// Type of Azure cloud to connect to @@ -397,7 +396,7 @@ internal static PnPConnection CreateWithManagedIdentity(Cmdlet cmdlet, string ur ManagedIdentityType managedIdentityType = ManagedIdentityType.SystemAssigned; string managedIdentityUserAssignedIdentifier = null; - if(!string.IsNullOrEmpty(userAssignedManagedIdentityObjectId)) + if (!string.IsNullOrEmpty(userAssignedManagedIdentityObjectId)) { managedIdentityType = ManagedIdentityType.UserAssignedByObjectId; managedIdentityUserAssignedIdentifier = userAssignedManagedIdentityObjectId; @@ -414,14 +413,13 @@ internal static PnPConnection CreateWithManagedIdentity(Cmdlet cmdlet, string ur } // Ensure if its not a System Assigned Managed Identity, that we an identifier pointing to the user assigned Managed Identity - if(managedIdentityType != ManagedIdentityType.SystemAssigned && string.IsNullOrEmpty(managedIdentityUserAssignedIdentifier)) + if (managedIdentityType != ManagedIdentityType.SystemAssigned && string.IsNullOrEmpty(managedIdentityUserAssignedIdentifier)) { throw new InvalidOperationException("Unable to use a User Assigned Managed Identity without passing in an identifier for the User Assigned Managed Identity."); } // Set up the AuthenticationManager in PnP Framework to use a Managed Identity context using var authManager = new Framework.AuthenticationManager(endPoint, identityHeader, managedIdentityType, managedIdentityUserAssignedIdentifier); - PnPClientContext context = null; ConnectionType connectionType = ConnectionType.O365; if (url != null) @@ -538,7 +536,8 @@ internal static PnPConnection CreateWithCredentials(Cmdlet cmdlet, Uri url, PSCr { ConnectionMethod = Model.ConnectionMethod.Credentials, AzureEnvironment = azureEnvironment, - Tenant = tenantId + Tenant = tenantId, + ClientId = clientId }; } else @@ -572,6 +571,7 @@ internal static PnPConnection CreateWithCredentials(Cmdlet cmdlet, Uri url, PSCr { ConnectionMethod = Model.ConnectionMethod.Credentials, AzureEnvironment = azureEnvironment, + ClientId = clientId }; } @@ -625,7 +625,7 @@ internal static PnPConnection CreateWithWeblogin(Uri url, string tenantAdminUrl, } } - internal static PnPConnection CreateWithInteractiveLogin(Uri uri, string clientId, string tenantAdminUrl, bool launchBrowser, AzureEnvironment azureEnvironment, CancellationTokenSource cancellationTokenSource, bool forceAuthentication, string tenant) + internal static PnPConnection CreateWithInteractiveLogin(Uri uri, string clientId, string tenantAdminUrl, bool launchBrowser, AzureEnvironment azureEnvironment, CancellationTokenSource cancellationTokenSource, bool forceAuthentication, string tenant, bool enableLoginWithWAM) { PnP.Framework.AuthenticationManager authManager = null; if (PnPConnection.CachedAuthenticationManager != null && !forceAuthentication) @@ -642,7 +642,7 @@ internal static PnPConnection CreateWithInteractiveLogin(Uri uri, string clientI tenant, successMessageHtml: $"You successfully authenticated with PnP PowerShell. Feel free to close this {(launchBrowser ? "tab" : "window")}.", failureMessageHtml: $"You did not authenticate with PnP PowerShell. Feel free to close this browser {(launchBrowser ? "tab" : "window")}.", - azureEnvironment: azureEnvironment); + azureEnvironment: azureEnvironment, useWAM: enableLoginWithWAM); } using (authManager) { @@ -676,7 +676,7 @@ internal static PnPConnection CreateWithInteractiveLogin(Uri uri, string clientI /// Url to the SharePoint Online Admin Center site to connect to /// Instantiated PnPConnection internal static PnPConnection CreateWithAzureADWorkloadIdentity(Cmdlet cmdlet, string url, string tenantAdminUrl) - { + { string defaultResource = "https://graph.microsoft.com/.default"; if (url != null) { @@ -707,7 +707,6 @@ internal static PnPConnection CreateWithAzureADWorkloadIdentity(Cmdlet cmdlet, s } var connection = new PnPConnection(context, connectionType, null, url != null ? url.ToString() : null, tenantAdminUrl, PnPPSVersionTag, InitializationType.AzureADWorkloadIdentity); - return connection; } } @@ -733,11 +732,11 @@ private PnPConnection(ClientContext context, InitializeTelemetry(context, initializationType); var connectionMethod = ConnectionMethod.Credentials; - if(initializationType == InitializationType.AzureADWorkloadIdentity) + if (initializationType == InitializationType.AzureADWorkloadIdentity) { connectionMethod = ConnectionMethod.AzureADWorkloadIdentity; } - else if(initializationType == InitializationType.ManagedIdentity) + else if (initializationType == InitializationType.ManagedIdentity) { connectionMethod = ConnectionMethod.ManagedIdentity; } diff --git a/src/Commands/Base/PnPGraphCmdlet.cs b/src/Commands/Base/PnPGraphCmdlet.cs index 1f7535d0f..38697aa49 100644 --- a/src/Commands/Base/PnPGraphCmdlet.cs +++ b/src/Commands/Base/PnPGraphCmdlet.cs @@ -1,7 +1,6 @@ using Microsoft.Graph; using Microsoft.SharePoint.Client; using PnP.Core.Services; -using PnP.PowerShell.Commands.Model; using System.Management.Automation; using System.Net.Http.Headers; using System.Threading.Tasks; @@ -40,39 +39,7 @@ protected override void BeginProcessing() /// /// Returns an Access Token for the Microsoft Graph API, if available, otherwise NULL /// - public string AccessToken - { - get - { - if (Connection != null) - { - if (Connection.ConnectionMethod == ConnectionMethod.ManagedIdentity) - { - WriteVerbose("Acquiring token for resource " + Connection.GraphEndPoint + " using Managed Identity"); - var accessToken = TokenHandler.GetManagedIdentityTokenAsync(this, Connection.HttpClient, $"https://{Connection.GraphEndPoint}/", Connection.UserAssignedManagedIdentityObjectId, Connection.UserAssignedManagedIdentityClientId, Connection.UserAssignedManagedIdentityAzureResourceId).GetAwaiter().GetResult(); - - return accessToken; - } - else if (Connection.ConnectionMethod == ConnectionMethod.AzureADWorkloadIdentity) - { - WriteVerbose("Acquiring token for resource " + Connection.GraphEndPoint + " using Azure AD Workload Identity"); - var accessToken = TokenHandler.GetAzureADWorkloadIdentityTokenAsync(this, $"https://{Connection.GraphEndPoint}/.default").GetAwaiter().GetResult(); - - return accessToken; - } - else - { - if (Connection.Context != null) - { - var accessToken = TokenHandler.GetAccessToken(this, $"https://{Connection.GraphEndPoint}/.default", Connection); - return accessToken; - } - } - } - WriteVerbose("Unable to acquire token for resource " + Connection.GraphEndPoint); - return null; - } - } + public string AccessToken => TokenHandler.GetAccessToken(this, $"https://{Connection.GraphEndPoint}/.default", Connection); internal GraphServiceClient ServiceClient { diff --git a/src/Commands/Base/PnPOfficeManagementApiCmdlet.cs b/src/Commands/Base/PnPOfficeManagementApiCmdlet.cs index 095f3591e..b8ca053ef 100644 --- a/src/Commands/Base/PnPOfficeManagementApiCmdlet.cs +++ b/src/Commands/Base/PnPOfficeManagementApiCmdlet.cs @@ -13,17 +13,7 @@ public abstract class PnPOfficeManagementApiCmdlet : PnPConnectedCmdlet /// /// Returns an Access Token for the Microsoft Office Management API, if available, otherwise NULL /// - public string AccessToken - { - get - { - if (Connection?.Context != null) - { - return TokenHandler.GetAccessToken(this, "https://manage.office.com/.default", Connection); - } - return null; - } - } + public string AccessToken => TokenHandler.GetAccessToken(this, "https://manage.office.com/.default", Connection); protected override void BeginProcessing() { diff --git a/src/Commands/Base/PnPSharePointCmdlet.cs b/src/Commands/Base/PnPSharePointCmdlet.cs index cf53177b1..df69979c5 100644 --- a/src/Commands/Base/PnPSharePointCmdlet.cs +++ b/src/Commands/Base/PnPSharePointCmdlet.cs @@ -40,13 +40,7 @@ protected string AccessToken { if (Connection != null) { - if (Connection.ConnectionMethod == ConnectionMethod.ManagedIdentity) - { - var resourceUri = new Uri(Connection.Url); - var defaultResource = $"{resourceUri.Scheme}://{resourceUri.Authority}"; - return TokenHandler.GetManagedIdentityTokenAsync(this, HttpClient, defaultResource, Connection.UserAssignedManagedIdentityObjectId, Connection.UserAssignedManagedIdentityClientId, Connection.UserAssignedManagedIdentityAzureResourceId).GetAwaiter().GetResult(); - } - else if (Connection.ConnectionMethod == ConnectionMethod.AzureADWorkloadIdentity) + if (Connection.ConnectionMethod == ConnectionMethod.AzureADWorkloadIdentity) { var resourceUri = new Uri(Connection.Url); var defaultResource = $"{resourceUri.Scheme}://{resourceUri.Authority}/.default"; @@ -80,11 +74,7 @@ public string GraphAccessToken { get { - if (Connection?.ConnectionMethod == ConnectionMethod.ManagedIdentity) - { - return TokenHandler.GetManagedIdentityTokenAsync(this, HttpClient, $"https://{Connection.GraphEndPoint}/", Connection.UserAssignedManagedIdentityObjectId, Connection.UserAssignedManagedIdentityClientId, Connection.UserAssignedManagedIdentityAzureResourceId).GetAwaiter().GetResult(); - } - else if (Connection?.ConnectionMethod == ConnectionMethod.AzureADWorkloadIdentity) + if (Connection?.ConnectionMethod == ConnectionMethod.AzureADWorkloadIdentity) { return TokenHandler.GetAzureADWorkloadIdentityTokenAsync(this, $"https://{Connection.GraphEndPoint}/.default").GetAwaiter().GetResult(); } diff --git a/src/Commands/Base/TokenHandling.cs b/src/Commands/Base/TokenHandler.cs similarity index 60% rename from src/Commands/Base/TokenHandling.cs rename to src/Commands/Base/TokenHandler.cs index 46fabbd8b..e845498f0 100644 --- a/src/Commands/Base/TokenHandling.cs +++ b/src/Commands/Base/TokenHandler.cs @@ -1,6 +1,8 @@ -using Microsoft.Identity.Client; +using AngleSharp.Text; +using Microsoft.Identity.Client; using Microsoft.SharePoint.Client; using PnP.PowerShell.Commands.Attributes; +using PnP.PowerShell.Commands.Model; using System; using System.IdentityModel.Tokens.Jwt; using System.Linq; @@ -11,6 +13,9 @@ namespace PnP.PowerShell.Commands.Base { + /// + /// Helper classes around oAuth Token Evaluation + /// internal static class TokenHandler { /// @@ -27,7 +32,7 @@ internal static Enums.IdType RetrieveTokenType(string token) // Check if the token contains an idType if (idType == null) return Enums.IdType.Unknown; - + // Parse the idType to the corresponding enum value return idType.Value.ToLowerInvariant() switch { @@ -38,104 +43,160 @@ internal static Enums.IdType RetrieveTokenType(string token) } /// - /// Extracts the oAuth JWT token to compare the permissions in it (roles) with the required permissions for the cmdlet provided through an attribute + /// Returns the permission scopes of the oAuth JWT token being passed in + /// + /// The oAuth JWT token + /// String array containing the scopes + internal static string[] ReturnScopes(string accessToken) + { + var decodedToken = new JwtSecurityToken(accessToken); + + // The scopes can either be stored in the roles or scp claim, so we examine both + var scopes = decodedToken.Claims.Where(c => c.Type == "roles" || c.Type == "scp").SelectMany(r => r.Value.Split(" ")); + return scopes.ToArray(); + } + + /// + /// Ensures the oAuth JWT token holds the permissions in it (roles) that match with with the required permissions for the cmdlet provided through the attributes on the cmdlet /// /// The cmdlet that will be executed. Used to check for the permissions attribute. - /// The oAuth JWT token that needs to be validated for its roles + /// The oAuth JWT token that needs to be validated for its roles + /// Have this function throw an exception if the required permissions in the permission attribute do not match with the available permissions in the access token (true). Defaults to false. /// Thrown if the permissions set through the permissions attribute do not match the roles in the JWT token - internal static void ValidateTokenForPermissions(Type cmdletType, string token) + internal static void EnsureRequiredPermissionsAvailableInAccessToken(Type cmdletType, string accessToken) { - string[] requiredScopes = null; - var requiredScopesAttribute = (RequiredMinimalApiPermissions)Attribute.GetCustomAttribute(cmdletType, typeof(RequiredMinimalApiPermissions)); - if (requiredScopesAttribute != null) + var permissionEvaluationResponses = AccessTokenPermissionValidationResponse.EvaluatePermissions(cmdletType, accessToken); + foreach (var permissionEvaluationResponse in permissionEvaluationResponses) + { + if (permissionEvaluationResponse.RequiredPermissionsPresent) return; + } + var missingPermissions = permissionEvaluationResponses.Select(r => r.MissingPermissions); + throw new PSArgumentException($"Authorization Denied: Token used does not contain permission scope{(missingPermissions.Count() != 1 ? "s" : "")} for one or more of these permissions: {string.Concat(missingPermissions, ", ")}"); + } + + /// + /// Returns an oAuth JWT access token + /// + /// Cmdlet for which the token is requested + /// Audience to retrieve the token for + /// The connection to use to make the token calls + /// oAuth JWT token + /// Thrown if retrieval of the token fails + internal static string GetAccessToken(Cmdlet cmdlet, string audience, PnPConnection connection) + { + if (connection == null) return null; + + string accessToken = null; + if (connection.ConnectionMethod == ConnectionMethod.AzureADWorkloadIdentity) { - requiredScopes = requiredScopesAttribute.PermissionScopes; + cmdlet.WriteVerbose("Acquiring token for resource " + connection.GraphEndPoint + " using Azure AD Workload Identity"); + accessToken = GetAzureADWorkloadIdentityTokenAsync(cmdlet, $"{audience.TrimEnd('/')}/.default").GetAwaiter().GetResult(); } - if (requiredScopes?.Length > 0) + else { - var decodedToken = new JwtSecurityToken(token); - var roles = decodedToken.Claims.FirstOrDefault(c => c.Type == "roles"); - if (roles != null) + if (connection.Context != null) { - foreach (var permission in requiredScopes) + var contextSettings = connection.Context.GetContextSettings(); + var authManager = contextSettings.AuthenticationManager; + if (authManager != null) { - if (!roles.Value.ToLower().Contains(permission.ToLower())) + if (contextSettings.Type == Framework.Utilities.Context.ClientContextType.SharePointACSAppOnly) { - throw new PSArgumentException($"Authorization Denied: Token used does not contain permission scope '{permission}'"); + // When connected using ACS, we cannot get a token for another endpoint + throw new PSInvalidOperationException("Trying to get a token for a different endpoint while being connected through an ACS token is not possible. Please connect differently."); } - } - } - roles = decodedToken.Claims.FirstOrDefault(c => c.Type == "scp"); - if (roles != null) - { - foreach (var permission in requiredScopes) - { - if (!roles.Value.ToLower().Contains(permission.ToLower())) + + accessToken = authManager.GetAccessToken(audience); + var currentScopes = ReturnScopes(accessToken); + + var scopesPresent = false; + + if (cmdlet != null && cmdlet.GetType() != null) { - throw new PSArgumentException($"Authorization Denied: Token used does not contain permission scope '{permission}'"); + var requiredListedScopes = (RequiredMinimalApiPermissions[])Attribute.GetCustomAttributes(cmdlet.GetType(), typeof(RequiredMinimalApiPermissions)); + // assume these are 'or' + if (requiredListedScopes != null) + { + foreach (var requiredListedScope in requiredListedScopes) + { + var matchedScopes = 0; + // check if scopes are present + foreach (var permission in requiredListedScope.PermissionScopes) + { + if (currentScopes.Contains(permission, StringComparison.InvariantCultureIgnoreCase)) + { + matchedScopes++; + } + } + if (matchedScopes == requiredListedScope.PermissionScopes.Length) + { + scopesPresent = true; + var requiredScopes = requiredListedScope.PermissionScopes; + if (contextSettings.Type != Framework.Utilities.Context.ClientContextType.AzureADCertificate) + { + accessToken = authManager.GetAccessTokenAsync(requiredScopes).GetAwaiter().GetResult(); + // we have a match, jump out of the loop + break; + } + } + } + + if (!scopesPresent) + { + var requiredScopes = requiredListedScopes.Length > 0 ? requiredListedScopes.First().PermissionScopes : null; + + if (contextSettings.Type == Framework.Utilities.Context.ClientContextType.AzureADCertificate) + { + requiredScopes = new[] { audience }; // override for app only + } + if (requiredScopes == null && !string.IsNullOrEmpty(audience)) + { + requiredScopes = new[] { audience }; + } + + cmdlet.WriteVerbose($"Acquiring oAuth token for {(requiredScopes.Length != 1 ? requiredScopes.Length + " " : "")}permission scope{(requiredScopes.Length != 1 ? "s" : "")} {string.Join(", ", requiredScopes)}"); + accessToken = authManager.GetAccessTokenAsync(requiredScopes).GetAwaiter().GetResult(); + + // Retrieve the scopes from the access token + var scopes = ReturnScopes(accessToken); + + // Perform logging on the scopes in the retrieved access token + if (scopes.Length > 0) + { + cmdlet.WriteVerbose($"Access token acquired containing the following {(scopes.Length != 1 ? scopes.Length + " " : "")}{RetrieveTokenType(accessToken).ToString().ToLowerInvariant()} scope{(scopes.Length == 1 ? "" : "s")}: {string.Join(", ", scopes)}"); + } + else + { + cmdlet.WriteVerbose($"No scopes could be determined from the access token"); + } + } + } } } } } - } - - internal static string GetAccessToken(Cmdlet cmdlet, string appOnlyDefaultScope, PnPConnection connection) - { - var contextSettings = connection.Context.GetContextSettings(); - var authManager = contextSettings.AuthenticationManager; - if (authManager != null) + if (string.IsNullOrEmpty(accessToken)) { - if (contextSettings.Type == Framework.Utilities.Context.ClientContextType.SharePointACSAppOnly) - { - // When connected using ACS, we cannot get a token for another endpoint - throw new PSInvalidOperationException("Trying to get a token for a different endpoint while being connected through an ACS token is not possible. Please connect differently."); - } - - string[] requiredScopes = null; - RequiredMinimalApiPermissions requiredScopesAttribute = null; - if (cmdlet != null && cmdlet.GetType() != null) - { - requiredScopesAttribute = (RequiredMinimalApiPermissions)Attribute.GetCustomAttribute(cmdlet.GetType(), typeof(RequiredMinimalApiPermissions)); - } - if (requiredScopesAttribute != null) - { - requiredScopes = requiredScopesAttribute.PermissionScopes; - } - if (contextSettings.Type == Framework.Utilities.Context.ClientContextType.AzureADCertificate) - { - requiredScopes = new[] { appOnlyDefaultScope }; // override for app only - } - if (requiredScopes == null && !string.IsNullOrEmpty(appOnlyDefaultScope)) - { - requiredScopes = new[] { appOnlyDefaultScope }; - } - - cmdlet.WriteVerbose($"Acquiring oAuth token for {(requiredScopes.Length != 1 ? requiredScopes.Length + " " : "")}permission scope{(requiredScopes.Length != 1 ? "s" : "")} {string.Join(",", requiredScopes)}"); - var accessToken = authManager.GetAccessTokenAsync(requiredScopes).GetAwaiter().GetResult(); - cmdlet.WriteVerbose($"Access token acquired"); - return accessToken; + cmdlet.WriteVerbose($"Unable to acquire token for resource {connection.GraphEndPoint}"); + return null; } - return null; - } - internal static string GetAccessTokenforPowerPlatformSolutions(Cmdlet cmdlet, PnPConnection connection, string enviormentBaseUrl) - { - var contextSettings = connection.Context.GetContextSettings(); - var authManager = contextSettings.AuthenticationManager; - if (authManager != null) + var permissionEvaluations = AccessTokenPermissionValidationResponse.EvaluatePermissions(cmdlet.GetType(), accessToken); + var permissionsInPlace = false; + foreach (var permissionEvaluation in permissionEvaluations) { - if (contextSettings.Type == Framework.Utilities.Context.ClientContextType.SharePointACSAppOnly) + if (permissionEvaluation.MissingPermissions.Length == 0) { - // When connected using ACS, we cannot get a token for another endpoint - throw new PSInvalidOperationException("Trying to get a token for a different endpoint while being connected through an ACS token is not possible. Please connect differently."); + permissionsInPlace = true; + break; } - string[] requiredScopes = new string[1] { enviormentBaseUrl + "/.default" }; - cmdlet.WriteVerbose($"Acquiring oAuth token for {(requiredScopes.Length != 1 ? requiredScopes.Length + " " : "")}permission scope{(requiredScopes.Length != 1 ? "s" : "")} {string.Join(",", requiredScopes)}"); - var accessToken = authManager.GetAccessTokenAsync(requiredScopes).GetAwaiter().GetResult(); - cmdlet.WriteVerbose($"Access token acquired for PowerPlatformSolutions: {accessToken}"); - return accessToken; } - return null; + if (!permissionsInPlace) + { + cmdlet.WriteVerbose($"The currect access token might not have the required permissions to execute this cmdlet. Required are one or more of the following: {string.Join(", ", permissionEvaluations.Select(p => string.Join(", ", p.MissingPermissions)))}"); + } + + return accessToken; } /// @@ -302,10 +363,13 @@ internal static async Task GetAzureADWorkloadIdentityTokenAsync(Cmdlet c var clientID = Environment.GetEnvironmentVariable("AZURE_CLIENT_ID"); var tokenPath = Environment.GetEnvironmentVariable("AZURE_FEDERATED_TOKEN_FILE"); var tenantID = Environment.GetEnvironmentVariable("AZURE_TENANT_ID"); + var host = Environment.GetEnvironmentVariable("AZURE_AUTHORITY_HOST"); var _confidentialClientApp = ConfidentialClientApplicationBuilder.Create(clientID) - .WithClientAssertion(ReadJWTFromFS(tokenPath)) - .WithTenantId(tenantID).Build(); + .WithAuthority(host, tenantID) + .WithClientAssertion(() => ReadJWTFromFS(tokenPath)) + .WithCacheOptions(CacheOptions.EnableSharedCacheOptions) + .Build(); AuthenticationResult result = null; try @@ -328,7 +392,7 @@ internal static async Task GetAzureADWorkloadIdentityTokenAsync(Cmdlet c throw new PSInvalidOperationException(ex.Message); } catch (MsalServiceException ex) - { + { // Some other generic exception throw new PSInvalidOperationException(ex.Message); } diff --git a/src/Commands/Diagnostic/MeasurePnPWeb.cs b/src/Commands/Diagnostic/MeasurePnPWeb.cs index e05e83dd2..4f5dcd4e6 100644 --- a/src/Commands/Diagnostic/MeasurePnPWeb.cs +++ b/src/Commands/Diagnostic/MeasurePnPWeb.cs @@ -17,6 +17,7 @@ public class MeasurePnPWeb : PnPSharePointCmdlet [Parameter(Mandatory = false, ValueFromPipeline = true, Position = 0)] public WebPipeBind Identity; + [Alias("Recurse")] [Parameter(Mandatory = false)] public SwitchParameter Recursive; diff --git a/src/Commands/DocumentSets/AddDocumentSet.cs b/src/Commands/DocumentSets/AddDocumentSet.cs index ed173a2cc..ee11c3afe 100644 --- a/src/Commands/DocumentSets/AddDocumentSet.cs +++ b/src/Commands/DocumentSets/AddDocumentSet.cs @@ -19,6 +19,9 @@ public class AddDocumentSet : PnPWebCmdlet [ValidateNotNullOrEmpty] public string Name; + [Parameter(Mandatory = false)] + public FolderPipeBind Folder; + [Parameter(Mandatory = true)] [ValidateNotNullOrEmpty] public ContentTypePipeBind ContentType; @@ -42,11 +45,45 @@ protected override void ExecuteCmdlet() throw new PSArgumentException($"Content type '{ContentType}' does not inherit from the base Document Set content type. Document Set content type IDs start with 0x120D520"); } + var targetFolder = list.RootFolder; + + if (Folder != null) + { + // Create the folder if it doesn't exist + targetFolder = EnsureFolder(); + } + // Create the document set - var result = DocumentSet.Create(ClientContext, list.RootFolder, Name, listContentType.Id); + var result = DocumentSet.Create(ClientContext, targetFolder, Name, listContentType.Id); ClientContext.ExecuteQueryRetry(); WriteObject(result.Value); } + + /// + /// Ensures the folder to which the document set is to be created exists. Changed from using the EnsureFolder implementation in PnP Framework as that requires at least member rights to the entire site to work. + /// + /// The folder to which the document set needs to be created + private Folder EnsureFolder() + { + // First try to get the folder if it exists already. This avoids an Access Denied exception if the current user doesn't have Full Control access at Web level + CurrentWeb.EnsureProperty(w => w.ServerRelativeUrl); + + Folder folder = null; + try + { + folder = Folder.GetFolder(CurrentWeb); + folder.EnsureProperties(f => f.ServerRelativeUrl); + return folder; + } + // Exception will be thrown if the folder does not exist yet on SharePoint + catch (ServerException serverEx) when (serverEx.ServerErrorCode == -2147024894) + { + // Try to create the folder + folder = CurrentWeb.EnsureFolder(CurrentWeb.RootFolder, Folder.ServerRelativeUrl); + folder.EnsureProperties(f => f.ServerRelativeUrl); + return folder; + } + } } } \ No newline at end of file diff --git a/src/Commands/Enums/SearchExternalConnectionState.cs b/src/Commands/Enums/SearchExternalConnectionState.cs new file mode 100644 index 000000000..0077d6469 --- /dev/null +++ b/src/Commands/Enums/SearchExternalConnectionState.cs @@ -0,0 +1,29 @@ +namespace PnP.PowerShell.Commands.Enums +{ + /// + /// Contains the possible states of an external connection + /// + /// + public enum SearchExternalConnectionState : short + { + /// + /// Connection is in draft state + /// + Draft = 0, + + /// + /// Connection is ready to be used + /// + Ready = 1, + + /// + /// Connection can no longer be used + /// + Obsolete = 2, + + /// + /// Too many connections have been created on the tenant + /// + LimitExceeded = 3 + } +} diff --git a/src/Commands/Enums/SearchExternalSchemaPropertyLabel.cs b/src/Commands/Enums/SearchExternalSchemaPropertyLabel.cs new file mode 100644 index 000000000..058597d8a --- /dev/null +++ b/src/Commands/Enums/SearchExternalSchemaPropertyLabel.cs @@ -0,0 +1,59 @@ +namespace PnP.PowerShell.Commands.Enums +{ + /// + /// Contains the possible well-known tags that can be assigned to properties in the schema definition of an external search connection to make Microsoft Search understand its content better + /// + /// + public enum SearchExternalSchemaPropertyLabel : short + { + /// + /// Property represents the title of the item + /// + Title, + + /// + /// Property represents a link to the item + /// + Url, + + /// + /// Property represents the author of the item + /// + CreatedBy, + + /// + /// Property represents the last person who modified the item + /// + LastModifiedBy, + + /// + /// Property represents the authors of the item + /// + Authors, + + /// + /// Property represents the date and time the item was created + /// + CreatedDateTime, + + /// + /// Property represents the date and time the item was last modified + /// + LastModifiedDateTime, + + /// + /// Property represents the name of the file + /// + FileName, + + /// + /// Property represents the extension of the file + /// + FileExtension, + + /// + /// Property represents the icon to be shown with the item + /// + IconUrl + } +} diff --git a/src/Commands/Enums/SearchExternalSchemaPropertyType.cs b/src/Commands/Enums/SearchExternalSchemaPropertyType.cs new file mode 100644 index 000000000..cf6ac73c3 --- /dev/null +++ b/src/Commands/Enums/SearchExternalSchemaPropertyType.cs @@ -0,0 +1,54 @@ +namespace PnP.PowerShell.Commands.Enums +{ + /// + /// Contains the possible types of properties in the schema definition of an external search connection + /// + /// + public enum SearchExternalSchemaPropertyType : short + { + /// + /// Property contains a text value + /// + String, + + /// + /// Property contains a numeric value + /// + Int64, + + /// + /// Property contains a floating point value + /// + Double, + + /// + /// Property contains a date and time value + /// + DateTime, + + /// + /// Property contains a boolean value + /// + Boolean, + + /// + /// Property contains a collection of text values + /// + StringCollection, + + /// + /// Property contains a collection of numeric values + /// + Int64Collection, + + /// + /// Property contains a collection of floating point values + /// + DoubleCollection, + + /// + /// Property contains a collection of date and time values + /// + DateTimeCollection + } +} diff --git a/src/Commands/Files/GetFolder.cs b/src/Commands/Files/GetFolder.cs index 7c14c9e9c..13eb3872f 100644 --- a/src/Commands/Files/GetFolder.cs +++ b/src/Commands/Files/GetFolder.cs @@ -15,8 +15,8 @@ public class GetFolder : PnPWebRetrievalsCmdlet private const string ParameterSet_FOLDERSINCURRENTWEB = "Folders in current Web"; private const string ParameterSet_CURRENTWEBROOTFOLDER = "Root folder of the current Web"; private const string ParameterSet_LISTROOTFOLDER = "Root folder of a list"; - private const string ParameterSet_FOLDERSINLIST = "Folders In List"; - private const string ParameterSet_FOLDERBYURL = "Folder by url"; + private const string ParameterSet_FOLDERSINLIST = "Folders In List"; + private const string ParameterSet_FOLDERBYURL = "Folder by url"; [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = ParameterSet_FOLDERBYURL)] [Alias("RelativeUrl")] @@ -32,94 +32,112 @@ public class GetFolder : PnPWebRetrievalsCmdlet [Parameter(Mandatory = true, Position = 1, ParameterSetName = ParameterSet_CURRENTWEBROOTFOLDER)] public SwitchParameter CurrentWebRootFolder; + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_FOLDERBYURL)] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_LISTROOTFOLDER)] + public SwitchParameter AsListItem; + protected override void ExecuteCmdlet() { DefaultRetrievalExpressions = new Expression>[] { f => f.ServerRelativeUrl, f => f.Name, f => f.TimeLastModified, f => f.ItemCount }; Folder folder = null; - switch(ParameterSetName) + switch (ParameterSetName) { case ParameterSet_FOLDERSINCURRENTWEB: - { - WriteVerbose("Getting all folders in the root of the current web"); - ClientContext.Load(CurrentWeb, w => w.Folders.IncludeWithDefaultProperties(RetrievalExpressions)); - ClientContext.ExecuteQueryRetry(); - WriteObject(CurrentWeb.Folders, true); - break; - } + { + WriteVerbose("Getting all folders in the root of the current web"); + ClientContext.Load(CurrentWeb, w => w.Folders.IncludeWithDefaultProperties(RetrievalExpressions)); + ClientContext.ExecuteQueryRetry(); + WriteObject(CurrentWeb.Folders, true); + break; + } case ParameterSet_CURRENTWEBROOTFOLDER: - { - WriteVerbose("Getting root folder of the current web"); - folder = CurrentWeb.RootFolder; - - ReturnFolderProperties(folder); - break; - } + { + WriteVerbose("Getting root folder of the current web"); + folder = CurrentWeb.RootFolder; + + ReturnFolderProperties(folder); + break; + } case ParameterSet_LISTROOTFOLDER: - { - WriteVerbose("Getting root folder of the provided list"); - var list = ListRootFolder.GetList(CurrentWeb); - folder = list.RootFolder; - - ReturnFolderProperties(folder); - break; - } + { + WriteVerbose("Getting root folder of the provided list"); + var list = ListRootFolder.GetList(CurrentWeb); + folder = list.RootFolder; + + ReturnFolderProperties(folder); + break; + } case ParameterSet_FOLDERSINLIST: - { - // Gets the provided list + { + // Gets the provided list #pragma warning disable CS0618 // Type or member is obsolete - var list = List.GetList(CurrentWeb); + var list = List.GetList(CurrentWeb); #pragma warning restore CS0618 // Type or member is obsolete - // Query for all folders in the list - CamlQuery query = CamlQuery.CreateAllFoldersQuery(); - do - { - // Execute the query. It will retrieve all properties of the folders. Refraining to using the RetrievalExpressions would cause a tremendous increased load on SharePoint as it would have to execute a query per list item which would be less efficient, especially on lists with many folders, than just getting all properties directly - ListItemCollection listItems = list.GetItems(query); - ClientContext.Load(listItems, item => item.Include(t => t.Folder), item => item.ListItemCollectionPosition); - ClientContext.ExecuteQueryRetry(); - - // Take all the folders from the resulting list items and put them in a list to return - var folders = new List(listItems.Count); - foreach (ListItem listItem in listItems) + // Query for all folders in the list + CamlQuery query = CamlQuery.CreateAllFoldersQuery(); + do { - var listFolder = listItem.Folder; - listFolder.EnsureProperties(RetrievalExpressions); - folders.Add(listFolder); - } - - WriteObject(folders, true); - - query.ListItemCollectionPosition = listItems.ListItemCollectionPosition; - } while (query.ListItemCollectionPosition != null); - break; - } + // Execute the query. It will retrieve all properties of the folders. Refraining to using the RetrievalExpressions would cause a tremendous increased load on SharePoint as it would have to execute a query per list item which would be less efficient, especially on lists with many folders, than just getting all properties directly + ListItemCollection listItems = list.GetItems(query); + ClientContext.Load(listItems, item => item.Include(t => t.Folder), item => item.ListItemCollectionPosition); + ClientContext.ExecuteQueryRetry(); + + // Take all the folders from the resulting list items and put them in a list to return + var folders = new List(listItems.Count); + foreach (ListItem listItem in listItems) + { + var listFolder = listItem.Folder; + listFolder.EnsureProperties(RetrievalExpressions); + folders.Add(listFolder); + } + + WriteObject(folders, true); + + query.ListItemCollectionPosition = listItems.ListItemCollectionPosition; + } while (query.ListItemCollectionPosition != null); + break; + } case ParameterSet_FOLDERBYURL: - { - WriteVerbose("Getting folder at the provided url"); - var webServerRelativeUrl = CurrentWeb.EnsureProperty(w => w.ServerRelativeUrl); - if (!Url.StartsWith(webServerRelativeUrl, StringComparison.OrdinalIgnoreCase)) { - Url = UrlUtility.Combine(webServerRelativeUrl, Url); + WriteVerbose("Getting folder at the provided url"); + var webServerRelativeUrl = CurrentWeb.EnsureProperty(w => w.ServerRelativeUrl); + if (!Url.StartsWith(webServerRelativeUrl, StringComparison.OrdinalIgnoreCase)) + { + Url = UrlUtility.Combine(webServerRelativeUrl, Url); + } + folder = CurrentWeb.GetFolderByServerRelativePath(ResourcePath.FromDecodedUrl(Url)); + + ReturnFolderProperties(folder); + break; } - folder = CurrentWeb.GetFolderByServerRelativePath(ResourcePath.FromDecodedUrl(Url)); - - ReturnFolderProperties(folder); - break; - } } } private void ReturnFolderProperties(Folder folder) { WriteVerbose("Retrieving folder properties"); - folder?.EnsureProperties(RetrievalExpressions); - WriteObject(folder, false); + + if (AsListItem.IsPresent) + { + folder?.EnsureProperties(RetrievalExpressions); + folder?.EnsureProperties(f => f.Exists, f => f.ListItemAllFields); + if (folder.Exists) + { + WriteObject(folder.ListItemAllFields); + } + } + else + { + folder?.EnsureProperties(RetrievalExpressions); + WriteObject(folder, false); + } + } } } diff --git a/src/Commands/Files/GetFolderItem.cs b/src/Commands/Files/GetFolderItem.cs index 57f4728e2..123b6364d 100644 --- a/src/Commands/Files/GetFolderItem.cs +++ b/src/Commands/Files/GetFolderItem.cs @@ -30,6 +30,7 @@ public class GetFolderItem : PnPWebCmdlet [Parameter(Mandatory = false)] public string ItemName = string.Empty; + [Alias("Recurse")] [Parameter(Mandatory = false)] public SwitchParameter Recursive; diff --git a/src/Commands/Files/SetFolderPermission.cs b/src/Commands/Files/SetFolderPermission.cs index 65f86b962..60b17aed9 100644 --- a/src/Commands/Files/SetFolderPermission.cs +++ b/src/Commands/Files/SetFolderPermission.cs @@ -56,15 +56,17 @@ protected override void ExecuteCmdlet() if (folder == null) { WriteError(new ErrorRecord(new Exception("Folder not found"), "1", ErrorCategory.ObjectNotFound, null)); + return; } // Ensure we have access to the ListItemAllFields property of the folder folder.EnsureProperty(f => f.ListItemAllFields); // Validate that the ListItemAllFields contains the Id which represents the ListItem ID equivallent for this folder - if (folder.ListItemAllFields.Id <= 0) + if (folder.ListItemAllFields.ServerObjectIsNull.GetValueOrDefault(true) || folder.ListItemAllFields.Id <= 0) { WriteError(new ErrorRecord(new Exception("ListItemId on folder not found"), "1", ErrorCategory.InvalidData, null)); + return; } // Get the list item which is the equivallent of the folder diff --git a/src/Commands/Graph/InvokeGraphMethod.cs b/src/Commands/Graph/InvokeGraphMethod.cs index 4f22f8bde..428f6837d 100644 --- a/src/Commands/Graph/InvokeGraphMethod.cs +++ b/src/Commands/Graph/InvokeGraphMethod.cs @@ -9,6 +9,7 @@ using System.Net.Http.Headers; using System.Text.Json.Serialization; using System.IO; +using PnP.PowerShell.Commands.Base.PipeBinds; namespace PnP.PowerShell.Commands.Base { @@ -59,31 +60,31 @@ public string Url [Parameter(Mandatory = false, ParameterSetName = ParameterSet_TOSTREAM)] public string ContentType = "application/json"; - IDictionary additionalHeaders = null; - + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_TOFILE)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_TOCONSOLE)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_TOSTREAM)] - public IDictionary AdditionalHeaders - { - get - { - if (ConsistencyLevelEventual.IsPresent) - { - if (additionalHeaders == null) - { - additionalHeaders = new Dictionary(); - } - additionalHeaders.Remove("ConsistencyLevel"); - additionalHeaders.Add("ConsistencyLevel", "eventual"); - } - return additionalHeaders; - } - set - { - additionalHeaders = value; - } - } + public GraphAdditionalHeadersPipeBind AdditionalHeaders; + // public IDictionary AdditionalHeaders + // { + // get + // { + // if (ConsistencyLevelEventual.IsPresent) + // { + // if (additionalHeaders == null) + // { + // additionalHeaders = new Dictionary(); + // } + // additionalHeaders.Remove("ConsistencyLevel"); + // additionalHeaders.Add("ConsistencyLevel", "eventual"); + // } + // return additionalHeaders; + // } + // set + // { + // additionalHeaders = value; + // } + // } [Parameter(Mandatory = false, ParameterSetName = ParameterSet_TOFILE)] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_TOCONSOLE)] @@ -167,13 +168,13 @@ private void SendRequest() } throw new NotSupportedException($"method [{Method}] not supported"); } - catch (PnP.PowerShell.Commands.Model.Graph.GraphException gex) + catch (Model.Graph.GraphException gex) { if (gex.Error.Code == "Authorization_RequestDenied") { if (!string.IsNullOrEmpty(gex.AccessToken)) { - TokenHandler.ValidateTokenForPermissions(GetType(), gex.AccessToken); + TokenHandler.EnsureRequiredPermissionsAvailableInAccessToken(GetType(), gex.AccessToken); } } throw new PSInvalidOperationException(gex.Error.Message); @@ -209,7 +210,7 @@ private void WriteGraphResult(string result) private void GetRequestWithPaging() { - var result = GraphHelper.GetAsync(Connection, Url, AccessToken, AdditionalHeaders).GetAwaiter().GetResult(); + var result = GraphHelper.Get(this, Connection, Url, AccessToken, AdditionalHeaders?.GetHeaders(ConsistencyLevelEventual.IsPresent)); if (Raw.IsPresent) { WriteObject(result); @@ -233,7 +234,7 @@ private void GetRequestWithPaging() break; } var nextLink = nextLinkProperty.ToString(); - result = GraphHelper.GetAsync(Connection, nextLink, AccessToken, AdditionalHeaders).GetAwaiter().GetResult(); + result = GraphHelper.Get(this, Connection, nextLink, AccessToken, AdditionalHeaders?.GetHeaders(ConsistencyLevelEventual.IsPresent)); element = JsonSerializer.Deserialize(result); dynamic nextObj = Deserialize(element); if (nextObj != null && nextObj.value != null && (nextObj.value is List)) @@ -259,35 +260,35 @@ private void GetRequestWithPaging() private void GetRequestWithoutPaging() { WriteVerbose($"Sending HTTP GET to {Url}"); - using var response = GraphHelper.GetResponseAsync(Connection, Url, AccessToken).GetAwaiter().GetResult(); + using var response = GraphHelper.GetResponse(this, Connection, Url, AccessToken); HandleResponse(response); } private void PostRequest() { WriteVerbose($"Sending HTTP POST to {Url}"); - var response = GraphHelper.PostAsync(Connection, Url, AccessToken, GetHttpContent(), AdditionalHeaders).GetAwaiter().GetResult(); + var response = GraphHelper.Post(this, Connection, Url, AccessToken, GetHttpContent(), AdditionalHeaders?.GetHeaders(ConsistencyLevelEventual.IsPresent)); HandleResponse(response); } private void PutRequest() { WriteVerbose($"Sending HTTP PUT to {Url}"); - var response = GraphHelper.PutAsync(Connection, Url, AccessToken, GetHttpContent(), AdditionalHeaders).GetAwaiter().GetResult(); + var response = GraphHelper.Put(this, Connection, Url, AccessToken, GetHttpContent(), AdditionalHeaders?.GetHeaders(ConsistencyLevelEventual.IsPresent)); HandleResponse(response); } private void PatchRequest() { WriteVerbose($"Sending HTTP PATCH to {Url}"); - var response = GraphHelper.PatchAsync(Connection, AccessToken, GetHttpContent(), Url, AdditionalHeaders).GetAwaiter().GetResult(); + var response = GraphHelper.Patch(this, Connection, AccessToken, GetHttpContent(), Url, AdditionalHeaders?.GetHeaders(ConsistencyLevelEventual.IsPresent)); HandleResponse(response); } private void DeleteRequest() { WriteVerbose($"Sending HTTP DELETE to {Url}"); - var response = GraphHelper.DeleteAsync(Connection, Url, AccessToken, AdditionalHeaders).GetAwaiter().GetResult(); + var response = GraphHelper.Delete(this, Connection, Url, AccessToken, AdditionalHeaders?.GetHeaders(ConsistencyLevelEventual.IsPresent)); HandleResponse(response); } @@ -308,7 +309,7 @@ private void HandleResponse(HttpResponseMessage response) { WriteVerbose($"Writing {responseStreamForFile.Length} bytes response to {OutFile}"); - using (var fileStream = new System.IO.FileStream(OutFile, System.IO.FileMode.Create, System.IO.FileAccess.Write)) + using (var fileStream = new FileStream(OutFile, FileMode.Create, FileAccess.Write)) { responseStreamForFile.CopyTo(fileStream); fileStream.Close(); @@ -321,7 +322,7 @@ private void HandleResponse(HttpResponseMessage response) WriteVerbose($"Writing {responseStream.Length} bytes response to outputstream"); - var memoryStream = new System.IO.MemoryStream(); + var memoryStream = new MemoryStream(); responseStream.CopyTo(memoryStream); memoryStream.Position = 0; diff --git a/src/Commands/Lists/ClearDefaultColumnValues.cs b/src/Commands/Lists/ClearDefaultColumnValues.cs index df9464a82..1a27600f4 100644 --- a/src/Commands/Lists/ClearDefaultColumnValues.cs +++ b/src/Commands/Lists/ClearDefaultColumnValues.cs @@ -25,51 +25,53 @@ public class ClearDefaultColumnValues : PnPWebCmdlet protected override void ExecuteCmdlet() { - List list = null; - if (List != null) - { - list = List.GetList(CurrentWeb); - } - if (list != null) + List list = List.GetList(CurrentWeb); + + if (list.BaseTemplate == (int)ListTemplateType.DocumentLibrary || list.BaseTemplate == (int)ListTemplateType.WebPageLibrary || list.BaseTemplate == (int)ListTemplateType.PictureLibrary) { - if (list.BaseTemplate == (int)ListTemplateType.DocumentLibrary || list.BaseTemplate == (int)ListTemplateType.WebPageLibrary || list.BaseTemplate == (int)ListTemplateType.PictureLibrary) + Field field = null; + // Get the field + if (Field.Field != null) { - Field field = null; - // Get the field - if (Field.Field != null) - { - field = Field.Field; + field = Field.Field; - ClientContext.Load(field); - ClientContext.ExecuteQueryRetry(); + ClientContext.Load(field); + ClientContext.ExecuteQueryRetry(); - field.EnsureProperties(f => f.TypeAsString, f => f.InternalName); - } - else if (Field.Id != Guid.Empty) - { - field = list.Fields.GetById(Field.Id); - ClientContext.Load(field, f => f.InternalName, f => f.TypeAsString); - ClientContext.ExecuteQueryRetry(); - } - else if (!string.IsNullOrEmpty(Field.Name)) - { - field = list.Fields.GetByInternalNameOrTitle(Field.Name); - ClientContext.Load(field, f => f.InternalName, f => f.TypeAsString); - ClientContext.ExecuteQueryRetry(); - } - if (field != null) + field.EnsureProperties(f => f.TypeAsString, f => f.InternalName); + } + else if (Field.Id != Guid.Empty) + { + field = list.Fields.GetById(Field.Id); + ClientContext.Load(field, f => f.InternalName, f => f.TypeAsString); + ClientContext.ExecuteQueryRetry(); + } + else if (!string.IsNullOrEmpty(Field.Name)) + { + field = list.Fields.GetByInternalNameOrTitle(Field.Name); + ClientContext.Load(field, f => f.InternalName, f => f.TypeAsString); + ClientContext.ExecuteQueryRetry(); + } + if (field != null) + { + // Folder must be the relative path to the library with "/" prefix + if (Folder != null && !Folder.StartsWith("/")) { - IDefaultColumnValue defaultColumnValue = field.GetDefaultColumnValueFromField(ClientContext, Folder, new string[0]); - list.ClearDefaultColumnValues(new List() { defaultColumnValue }); + Folder = $"/{Folder}"; } + + IDefaultColumnValue defaultColumnValue = field.GetDefaultColumnValueFromField(ClientContext, Folder, new string[0]); + list.ClearDefaultColumnValues(new List() { defaultColumnValue }); } else { - WriteWarning("List is not a document library"); + throw new PSArgumentException("Field not found", nameof(Field)); } - + } + else + { + WriteWarning("List is not a document library"); } } } - } diff --git a/src/Commands/Lists/CopyList.cs b/src/Commands/Lists/CopyList.cs index 85c0b5e95..c41b942b8 100644 --- a/src/Commands/Lists/CopyList.cs +++ b/src/Commands/Lists/CopyList.cs @@ -62,7 +62,7 @@ protected override void ExecuteCmdlet() // Generate a site script from the list that needs to be copied WriteVerbose($"Generating script from list at {SourceListUrl}"); - var generatedScript = RestHelper.PostAsync>(Connection.HttpClient, $"{Connection.Url}/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteScriptFromList()", ClientContext, new { listUrl = SourceListUrl}).GetAwaiter().GetResult(); + var generatedScript = RestHelper.Post>(Connection.HttpClient, $"{Connection.Url}/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteScriptFromList()", ClientContext, new { listUrl = SourceListUrl}); // Take the site script of the list to copy var script = generatedScript.Content; @@ -94,7 +94,7 @@ protected override void ExecuteCmdlet() // Execute site script on destination site so the list will be created WriteVerbose($"Executing site script to site at {DestinationWebUrl}"); - var actionResults = RestHelper.PostAsync>(Connection.HttpClient, $"{DestinationWebUrl}/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.ExecuteTemplateScript()", ClientContext, new { script = script}).GetAwaiter().GetResult(); + var actionResults = RestHelper.Post>(Connection.HttpClient, $"{DestinationWebUrl}/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.ExecuteTemplateScript()", ClientContext, new { script = script}); // Ensure site script actions have been executed if(actionResults.Items.Count() == 0) diff --git a/src/Commands/Lists/SetDefaultColumnValues.cs b/src/Commands/Lists/SetDefaultColumnValues.cs index 1db0961a1..03dc36c56 100644 --- a/src/Commands/Lists/SetDefaultColumnValues.cs +++ b/src/Commands/Lists/SetDefaultColumnValues.cs @@ -26,56 +26,54 @@ public class SetDefaultColumnValues : PnPWebCmdlet protected override void ExecuteCmdlet() { - List list = null; - if (List != null) - { - list = List.GetList(CurrentWeb); - } - if (list != null) + List list = List.GetList(CurrentWeb); + + if (list.BaseTemplate == (int)ListTemplateType.DocumentLibrary || list.BaseTemplate == (int)ListTemplateType.WebPageLibrary || list.BaseTemplate == (int)ListTemplateType.PictureLibrary) { - if (list.BaseTemplate == (int)ListTemplateType.DocumentLibrary || list.BaseTemplate == (int)ListTemplateType.WebPageLibrary || list.BaseTemplate == (int)ListTemplateType.PictureLibrary) + Field field = null; + // Get the field + if (Field.Field != null) { - Field field = null; - // Get the field - if (Field.Field != null) - { - field = Field.Field; + field = Field.Field; - ClientContext.Load(field); - ClientContext.ExecuteQueryRetry(); + ClientContext.Load(field); + ClientContext.ExecuteQueryRetry(); - field.EnsureProperties(f => f.TypeAsString, f => f.InternalName); - } - else if (Field.Id != Guid.Empty) - { - field = list.Fields.GetById(Field.Id); - ClientContext.Load(field, f => f.InternalName, f => f.TypeAsString); - ClientContext.ExecuteQueryRetry(); - } - else if (!string.IsNullOrEmpty(Field.Name)) - { - field = list.Fields.GetByInternalNameOrTitle(Field.Name); - ClientContext.Load(field, f => f.InternalName, f => f.TypeAsString); - ClientContext.ExecuteQueryRetry(); - } - if (field != null) + field.EnsureProperties(f => f.TypeAsString, f => f.InternalName); + } + else if (Field.Id != Guid.Empty) + { + field = list.Fields.GetById(Field.Id); + ClientContext.Load(field, f => f.InternalName, f => f.TypeAsString); + ClientContext.ExecuteQueryRetry(); + } + else if (!string.IsNullOrEmpty(Field.Name)) + { + field = list.Fields.GetByInternalNameOrTitle(Field.Name); + ClientContext.Load(field, f => f.InternalName, f => f.TypeAsString); + ClientContext.ExecuteQueryRetry(); + } + if (field != null) + { + if (!string.IsNullOrEmpty(Folder)) { - if (!string.IsNullOrEmpty(Folder)) + if (Folder.IndexOfAny(new[] { '#', '%' }) > -1) { - if (Folder.IndexOfAny(new[] { '#', '%' }) > -1) - { - throw new PSArgumentException("Due to limitations of SharePoint Online, setting a default column value on a folder with special characters is not supported"); - } + throw new PSArgumentException("Due to limitations of SharePoint Online, setting a default column value on a folder with special characters is not supported"); } - IDefaultColumnValue defaultColumnValue = field.GetDefaultColumnValueFromField(ClientContext, Folder, Value); - list.SetDefaultColumnValues(new List() { defaultColumnValue }); } + IDefaultColumnValue defaultColumnValue = field.GetDefaultColumnValueFromField(ClientContext, Folder, Value); + list.SetDefaultColumnValues(new List() { defaultColumnValue }); } else { - WriteWarning("List is not a document library"); + throw new PSArgumentException("Field not found", nameof(Field)); } } + else + { + WriteWarning("List is not a document library"); + } } } } diff --git a/src/Commands/Lists/SetList.cs b/src/Commands/Lists/SetList.cs index 618ea4ee1..11f167f20 100644 --- a/src/Commands/Lists/SetList.cs +++ b/src/Commands/Lists/SetList.cs @@ -387,7 +387,7 @@ protected override void ExecuteCmdlet() if (!string.IsNullOrEmpty(DefaultSensitivityLabelForLibrary.LabelName)) { WriteVerbose($"Looking up sensitivity label id by label name '{DefaultSensitivityLabelForLibrary.LabelName}'"); - var label = DefaultSensitivityLabelForLibrary.GetLabelByNameThroughGraph(Connection, GraphAccessToken); + var label = DefaultSensitivityLabelForLibrary.GetLabelByNameThroughGraph(this, Connection, GraphAccessToken); if (label == null || !label.Id.HasValue) { diff --git a/src/Commands/ManagementApi/GetUnifiedAuditLog.cs b/src/Commands/ManagementApi/GetUnifiedAuditLog.cs index 20ae5ee66..cf698bf9d 100644 --- a/src/Commands/ManagementApi/GetUnifiedAuditLog.cs +++ b/src/Commands/ManagementApi/GetUnifiedAuditLog.cs @@ -57,7 +57,7 @@ protected string ContentTypeString private IEnumerable GetSubscriptions() { var url = $"{ApiUrl}/subscriptions/list"; - return GraphHelper.GetAsync>(Connection, url, AccessToken).GetAwaiter().GetResult(); + return GraphHelper.Get>(this, Connection, url, AccessToken); } private void EnsureSubscription(string contentType) @@ -66,7 +66,7 @@ private void EnsureSubscription(string contentType) var subscription = subscriptions.FirstOrDefault(s => s.ContentType == contentType); if (subscription == null) { - subscription = GraphHelper.PostAsync(Connection, $"{ApiUrl}/subscriptions/start?contentType={contentType}&PublisherIdentifier={TenantId}", AccessToken).GetAwaiter().GetResult(); + subscription = GraphHelper.Post(this, Connection, $"{ApiUrl}/subscriptions/start?contentType={contentType}&PublisherIdentifier={TenantId}", AccessToken); if (!subscription.Status.Equals("enabled", StringComparison.OrdinalIgnoreCase)) { throw new Exception($"Cannot enable subscription for {contentType}"); @@ -88,20 +88,20 @@ protected override void ExecuteCmdlet() url += $"&endTime={EndTime:yyyy-MM-ddTHH:mm:ss}"; } - List subscriptionContents = new List(); - var subscriptionResponse = GraphHelper.GetResponseAsync(Connection, url, AccessToken).GetAwaiter().GetResult(); + List subscriptionContents = new(); + var subscriptionResponse = GraphHelper.GetResponse(this, Connection, url, AccessToken); var content = subscriptionResponse.Content.ReadAsStringAsync().GetAwaiter().GetResult(); if (subscriptionResponse.IsSuccessStatusCode) { - subscriptionContents.AddRange(System.Text.Json.JsonSerializer.Deserialize>(content, new System.Text.Json.JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase })); + subscriptionContents.AddRange(collection: JsonSerializer.Deserialize>(content, new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase })); while (subscriptionResponse.Headers.Contains("NextPageUri")) { - subscriptionResponse = GraphHelper.GetResponseAsync(Connection, subscriptionResponse.Headers.GetValues("NextPageUri").First(), AccessToken).GetAwaiter().GetResult(); + subscriptionResponse = GraphHelper.GetResponse(this, Connection, subscriptionResponse.Headers.GetValues("NextPageUri").First(), AccessToken); if (subscriptionResponse.IsSuccessStatusCode) { content = subscriptionResponse.Content.ReadAsStringAsync().GetAwaiter().GetResult(); - subscriptionContents.AddRange(System.Text.Json.JsonSerializer.Deserialize>(content)); + subscriptionContents.AddRange(collection: JsonSerializer.Deserialize>(content)); } } } @@ -115,7 +115,7 @@ protected override void ExecuteCmdlet() { foreach (var subscriptionContent in subscriptionContents) { - var logs = GraphHelper.GetAsync>(Connection, subscriptionContent.ContentUri, AccessToken, false).GetAwaiter().GetResult(); + var logs = GraphHelper.Get>(this, Connection, subscriptionContent.ContentUri, AccessToken, false); WriteObject(logs, true); } } diff --git a/src/Commands/Microsoft365Groups/AddMicrosoft365GroupMember.cs b/src/Commands/Microsoft365Groups/AddMicrosoft365GroupMember.cs index cf78c16e5..36c7b7da5 100644 --- a/src/Commands/Microsoft365Groups/AddMicrosoft365GroupMember.cs +++ b/src/Commands/Microsoft365Groups/AddMicrosoft365GroupMember.cs @@ -21,7 +21,7 @@ public class AddMicrosoft365GroupMember : PnPGraphCmdlet protected override void ExecuteCmdlet() { - Microsoft365GroupsUtility.AddMembersAsync(Connection, Identity.GetGroupId(Connection, AccessToken), Users, AccessToken, RemoveExisting).GetAwaiter().GetResult(); + ClearOwners.AddMembers(this, Connection, Identity.GetGroupId(this, Connection, AccessToken), Users, AccessToken, RemoveExisting); } } } \ No newline at end of file diff --git a/src/Commands/Microsoft365Groups/AddMicrosoft365GroupOwner.cs b/src/Commands/Microsoft365Groups/AddMicrosoft365GroupOwner.cs index 4d214c822..8329c5928 100644 --- a/src/Commands/Microsoft365Groups/AddMicrosoft365GroupOwner.cs +++ b/src/Commands/Microsoft365Groups/AddMicrosoft365GroupOwner.cs @@ -21,7 +21,7 @@ public class AddMicrosoft365GroupOwner : PnPGraphCmdlet protected override void ExecuteCmdlet() { - Microsoft365GroupsUtility.AddOwnersAsync(Connection, Identity.GetGroupId(Connection, AccessToken), Users, AccessToken, RemoveExisting).GetAwaiter().GetResult(); + ClearOwners.AddOwners(this, Connection, Identity.GetGroupId(this, Connection, AccessToken), Users, AccessToken, RemoveExisting); } } } \ No newline at end of file diff --git a/src/Commands/Microsoft365Groups/ClearMicrosoft365GroupMember.cs b/src/Commands/Microsoft365Groups/ClearMicrosoft365GroupMember.cs index 64191033c..0a9cd52fe 100644 --- a/src/Commands/Microsoft365Groups/ClearMicrosoft365GroupMember.cs +++ b/src/Commands/Microsoft365Groups/ClearMicrosoft365GroupMember.cs @@ -15,7 +15,7 @@ public class ClearMicrosoft365GroupMember : PnPGraphCmdlet protected override void ExecuteCmdlet() { - Microsoft365GroupsUtility.ClearMembersAsync(Connection, Identity.GetGroupId(Connection, AccessToken), AccessToken).GetAwaiter().GetResult(); + ClearOwners.ClearMembers(this, Connection, Identity.GetGroupId(this, Connection, AccessToken), AccessToken); } } } \ No newline at end of file diff --git a/src/Commands/Microsoft365Groups/ClearMicrosoft365GroupOwner.cs b/src/Commands/Microsoft365Groups/ClearMicrosoft365GroupOwner.cs index 6ca4bbdbc..357758176 100644 --- a/src/Commands/Microsoft365Groups/ClearMicrosoft365GroupOwner.cs +++ b/src/Commands/Microsoft365Groups/ClearMicrosoft365GroupOwner.cs @@ -16,9 +16,9 @@ public class ClearMicrosoft365GroupOwner : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Identity.GetGroupId(Connection, AccessToken); - Microsoft365GroupsUtility.ClearOwnersAsync(Connection, groupId, AccessToken).GetAwaiter().GetResult(); - var owners = Microsoft365GroupsUtility.GetOwnersAsync(Connection, groupId, AccessToken).GetAwaiter().GetResult(); + var groupId = Identity.GetGroupId(this, Connection, AccessToken); + ClearOwners.ClearOwnersAsync(this, Connection, groupId, AccessToken); + var owners = ClearOwners.GetOwners(this, Connection, groupId, AccessToken); if (owners != null && owners.Any()) { WriteWarning($"Clearing all owners is not possible as there will always have to be at least one owner. To changed the owners with new owners use Set-PnPMicrosoft365GroupOwner -Identity {groupId} -Owners \"newowner@domain.com\""); diff --git a/src/Commands/Microsoft365Groups/GetDeletedMicrosoft365Group.cs b/src/Commands/Microsoft365Groups/GetDeletedMicrosoft365Group.cs index 867715daa..48d00c3e4 100644 --- a/src/Commands/Microsoft365Groups/GetDeletedMicrosoft365Group.cs +++ b/src/Commands/Microsoft365Groups/GetDeletedMicrosoft365Group.cs @@ -9,6 +9,7 @@ namespace PnP.PowerShell.Commands.Microsoft365Groups { [Cmdlet(VerbsCommon.Get, "PnPDeletedMicrosoft365Group")] [RequiredMinimalApiPermissions("Group.Read.All")] + [RequiredMinimalApiPermissions("Group.ReadWrite.All")] public class GetDeletedMicrosoft365Group : PnPGraphCmdlet { [Parameter(Mandatory = false)] @@ -18,11 +19,11 @@ protected override void ExecuteCmdlet() { if (Identity != null) { - WriteObject(Identity.GetDeletedGroup(Connection, AccessToken)); + WriteObject(Identity.GetDeletedGroup(this, Connection, AccessToken)); } else { - var groups = Microsoft365GroupsUtility.GetDeletedGroupsAsync(Connection, AccessToken).GetAwaiter().GetResult(); + var groups = ClearOwners.GetDeletedGroups(this, Connection, AccessToken); WriteObject(groups.OrderBy(g => g.DisplayName), true); } } diff --git a/src/Commands/Microsoft365Groups/GetExpiringMicrosoft365Group.cs b/src/Commands/Microsoft365Groups/GetExpiringMicrosoft365Group.cs index 7ae65379a..afa791e02 100644 --- a/src/Commands/Microsoft365Groups/GetExpiringMicrosoft365Group.cs +++ b/src/Commands/Microsoft365Groups/GetExpiringMicrosoft365Group.cs @@ -23,7 +23,7 @@ public class GetExpiringMicrosoft365Group : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var expiringGroups = Microsoft365GroupsUtility.GetExpiringGroupAsync(Connection, AccessToken, Limit, IncludeSiteUrl, IncludeOwners).GetAwaiter().GetResult(); + var expiringGroups = ClearOwners.GetExpiringGroup(this, Connection, AccessToken, Limit, IncludeSiteUrl, IncludeOwners); WriteObject(expiringGroups.OrderBy(p => p.DisplayName), true); } diff --git a/src/Commands/Microsoft365Groups/GetMicrosoft365Group.cs b/src/Commands/Microsoft365Groups/GetMicrosoft365Group.cs index fbb3dcd48..dd3e4e78e 100644 --- a/src/Commands/Microsoft365Groups/GetMicrosoft365Group.cs +++ b/src/Commands/Microsoft365Groups/GetMicrosoft365Group.cs @@ -10,6 +10,7 @@ namespace PnP.PowerShell.Commands.Microsoft365Groups { [Cmdlet(VerbsCommon.Get, "PnPMicrosoft365Group")] [RequiredMinimalApiPermissions("Group.Read.All")] + [RequiredMinimalApiPermissions("Group.ReadWrite.All")] public class GetMicrosoft365Group : PnPGraphCmdlet { [Parameter(Mandatory = false)] @@ -36,12 +37,12 @@ protected override void ExecuteCmdlet() if (Identity != null) { - var group = Identity.GetGroup(Connection, AccessToken, includeSiteUrl, IncludeOwners, Detailed.ToBool(), IncludeSensitivityLabels); + var group = Identity.GetGroup(this, Connection, AccessToken, includeSiteUrl, IncludeOwners, Detailed.ToBool(), IncludeSensitivityLabels); WriteObject(group); } else { - var groups = Microsoft365GroupsUtility.GetGroupsAsync(Connection, AccessToken, includeSiteUrl, IncludeOwners, Filter, IncludeSensitivityLabels).GetAwaiter().GetResult(); + var groups = ClearOwners.GetGroups(this, Connection, AccessToken, includeSiteUrl, IncludeOwners, Filter, IncludeSensitivityLabels); WriteObject(groups.OrderBy(p => p.DisplayName), true); } diff --git a/src/Commands/Microsoft365Groups/GetMicrosoft365GroupEndpoint.cs b/src/Commands/Microsoft365Groups/GetMicrosoft365GroupEndpoint.cs index 52380b267..859ff060f 100644 --- a/src/Commands/Microsoft365Groups/GetMicrosoft365GroupEndpoint.cs +++ b/src/Commands/Microsoft365Groups/GetMicrosoft365GroupEndpoint.cs @@ -11,6 +11,7 @@ namespace PnP.PowerShell.Commands.Microsoft365Groups { [Cmdlet(VerbsCommon.Get, "PnPMicrosoft365GroupEndpoint")] [RequiredMinimalApiPermissions("Group.Read.All")] + [RequiredMinimalApiPermissions("Group.ReadWrite.All")] public class GetMicrosoft365GroupEndpoint : PnPGraphCmdlet { [Parameter(Mandatory = false, ValueFromPipeline = true, Position = 0)] @@ -22,7 +23,7 @@ protected override void ExecuteCmdlet() if (ParameterSpecified(nameof(Identity))) { WriteVerbose($"Defining Microsoft 365 Group based on {nameof(Identity)} parameter"); - groupId = Identity.GetGroupId(Connection, AccessToken); + groupId = Identity.GetGroupId(this, Connection, AccessToken); } else { @@ -43,7 +44,7 @@ protected override void ExecuteCmdlet() } WriteVerbose($"Requesting endpoints of Microsoft 365 Group with Id {groupId}"); - var endpoints = GraphHelper.GetResultCollectionAsync(Connection, $"/beta/groups/{groupId}/endpoints", AccessToken).GetAwaiter().GetResult(); + var endpoints = GraphHelper.GetResultCollection(this, Connection, $"/beta/groups/{groupId}/endpoints", AccessToken); WriteVerbose($"{endpoints.Count()} endpoint(s) found in total"); WriteObject(endpoints, true); } diff --git a/src/Commands/Microsoft365Groups/GetMicrosoft365GroupMember.cs b/src/Commands/Microsoft365Groups/GetMicrosoft365GroupMember.cs index 9974527ff..fb68c559d 100644 --- a/src/Commands/Microsoft365Groups/GetMicrosoft365GroupMember.cs +++ b/src/Commands/Microsoft365Groups/GetMicrosoft365GroupMember.cs @@ -10,6 +10,7 @@ namespace PnP.PowerShell.Commands.Microsoft365Groups [Cmdlet(VerbsCommon.Get, "PnPMicrosoft365GroupMember")] [Alias("Get-PnPMicrosoft365GroupMembers")] [RequiredMinimalApiPermissions("Group.Read.All")] + [RequiredMinimalApiPermissions("Group.ReadWrite.All")] public class GetMicrosoft365GroupMember : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true)] @@ -17,7 +18,7 @@ public class GetMicrosoft365GroupMember : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var members = Microsoft365GroupsUtility.GetMembersAsync(Connection, Identity.GetGroupId(Connection, AccessToken), AccessToken).GetAwaiter().GetResult(); + var members = ClearOwners.GetMembers(this, Connection, Identity.GetGroupId(this, Connection, AccessToken), AccessToken); WriteObject(members?.OrderBy(m => m.DisplayName), true); } } diff --git a/src/Commands/Microsoft365Groups/GetMicrosoft365GroupOwner.cs b/src/Commands/Microsoft365Groups/GetMicrosoft365GroupOwner.cs index 487b7aa9f..a9bcac0b9 100644 --- a/src/Commands/Microsoft365Groups/GetMicrosoft365GroupOwner.cs +++ b/src/Commands/Microsoft365Groups/GetMicrosoft365GroupOwner.cs @@ -10,6 +10,7 @@ namespace PnP.PowerShell.Commands.Microsoft365Groups [Cmdlet(VerbsCommon.Get, "PnPMicrosoft365GroupOwner")] [Alias("Get-PnPMicrosoft365GroupOwners")] [RequiredMinimalApiPermissions("Group.Read.All")] + [RequiredMinimalApiPermissions("Group.ReadWrite.All")] public class GetMicrosoft365GroupOwner : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true)] @@ -17,7 +18,7 @@ public class GetMicrosoft365GroupOwner : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var owners = Microsoft365GroupsUtility.GetOwnersAsync(Connection, Identity.GetGroupId(Connection, AccessToken), AccessToken).GetAwaiter().GetResult(); + var owners = ClearOwners.GetOwners(this, Connection, Identity.GetGroupId(this, Connection, AccessToken), AccessToken); WriteObject(owners?.OrderBy(o => o.DisplayName), true); } } diff --git a/src/Commands/Microsoft365Groups/GetMicrosoft365GroupSettingTemplates.cs b/src/Commands/Microsoft365Groups/GetMicrosoft365GroupSettingTemplates.cs index cc110f0a3..4ccc9d188 100644 --- a/src/Commands/Microsoft365Groups/GetMicrosoft365GroupSettingTemplates.cs +++ b/src/Commands/Microsoft365Groups/GetMicrosoft365GroupSettingTemplates.cs @@ -7,6 +7,7 @@ namespace PnP.PowerShell.Commands.Microsoft365Groups { [Cmdlet(VerbsCommon.Get, "PnPMicrosoft365GroupSettingTemplates")] [RequiredMinimalApiPermissions("Directory.Read.All")] + [RequiredMinimalApiPermissions("Directory.ReadWrite.All")] public class GetMicrosoft365GroupSettingTemplates : PnPGraphCmdlet { [Parameter(Mandatory = false)] @@ -16,12 +17,12 @@ protected override void ExecuteCmdlet() { if (Identity != null) { - var groupSettingTemplate = Microsoft365GroupsUtility.GetGroupTemplateSettingsAsync(Connection, AccessToken, Identity).GetAwaiter().GetResult(); + var groupSettingTemplate = ClearOwners.GetGroupTemplateSettings(this, Connection, AccessToken, Identity); WriteObject(groupSettingTemplate); } else { - var groupSettingTemplates = Microsoft365GroupsUtility.GetGroupTemplateSettingsAsync(Connection, AccessToken).GetAwaiter().GetResult(); + var groupSettingTemplates = ClearOwners.GetGroupTemplateSettings(this, Connection, AccessToken); WriteObject(groupSettingTemplates?.Value, true); } } diff --git a/src/Commands/Microsoft365Groups/GetMicrosoft365GroupSettings.cs b/src/Commands/Microsoft365Groups/GetMicrosoft365GroupSettings.cs index 79aeda295..8c1784aeb 100644 --- a/src/Commands/Microsoft365Groups/GetMicrosoft365GroupSettings.cs +++ b/src/Commands/Microsoft365Groups/GetMicrosoft365GroupSettings.cs @@ -2,13 +2,13 @@ using PnP.PowerShell.Commands.Base; using PnP.PowerShell.Commands.Base.PipeBinds; using PnP.PowerShell.Commands.Utilities; -using System; using System.Management.Automation; namespace PnP.PowerShell.Commands.Microsoft365Groups { [Cmdlet(VerbsCommon.Get, "PnPMicrosoft365GroupSettings")] [RequiredMinimalApiPermissions("Directory.Read.All")] + [RequiredMinimalApiPermissions("Directory.ReadWrite.All")] public class GetMicrosoft365GroupSettings : PnPGraphCmdlet { [Parameter(Mandatory = false)] @@ -18,13 +18,13 @@ protected override void ExecuteCmdlet() { if (Identity != null) { - var groupId = Identity.GetGroupId(Connection, AccessToken); - var groupSettings = Microsoft365GroupsUtility.GetGroupSettingsAsync(Connection, AccessToken, groupId.ToString()).GetAwaiter().GetResult(); + var groupId = Identity.GetGroupId(this, Connection, AccessToken); + var groupSettings = ClearOwners.GetGroupSettings(this, Connection, AccessToken, groupId.ToString()); WriteObject(groupSettings?.Value, true); } else { - var groupSettings = Microsoft365GroupsUtility.GetGroupSettingsAsync(Connection, AccessToken).GetAwaiter().GetResult(); + var groupSettings = ClearOwners.GetGroupSettings(this, Connection, AccessToken); WriteObject(groupSettings?.Value, true); } } diff --git a/src/Commands/Microsoft365Groups/GetMicrosoft365GroupTeam.cs b/src/Commands/Microsoft365Groups/GetMicrosoft365GroupTeam.cs index 1fd2843df..e368ee6d8 100644 --- a/src/Commands/Microsoft365Groups/GetMicrosoft365GroupTeam.cs +++ b/src/Commands/Microsoft365Groups/GetMicrosoft365GroupTeam.cs @@ -11,6 +11,7 @@ namespace PnP.PowerShell.Commands.Microsoft365Groups { [Cmdlet(VerbsCommon.Get, "PnPMicrosoft365GroupTeam")] [RequiredMinimalApiPermissions("Group.Read.All")] + [RequiredMinimalApiPermissions("Group.ReadWrite.All")] public class GetMicrosoft365GroupTeam : PnPGraphCmdlet { [Parameter(Mandatory = false, ValueFromPipeline = true, Position = 0)] @@ -22,7 +23,7 @@ protected override void ExecuteCmdlet() if (ParameterSpecified(nameof(Identity))) { WriteVerbose($"Defining Microsoft 365 Group based on {nameof(Identity)} parameter"); - groupId = Identity.GetGroupId(Connection, AccessToken); + groupId = Identity.GetGroupId(this, Connection, AccessToken); } else { @@ -43,7 +44,7 @@ protected override void ExecuteCmdlet() } WriteVerbose($"Requesting endpoints of Microsoft 365 Group with Id {groupId}"); - var endpoints = GraphHelper.GetResultCollectionAsync(Connection, $"/beta/groups/{groupId}/endpoints", AccessToken).GetAwaiter().GetResult(); + var endpoints = GraphHelper.GetResultCollection(this, Connection, $"/beta/groups/{groupId}/endpoints", AccessToken); WriteVerbose($"{endpoints.Count()} endpoint(s) found in total"); var yammerEndpoint = endpoints.Where(e => e.ProviderName.Equals("Microsoft Teams", StringComparison.InvariantCultureIgnoreCase)); diff --git a/src/Commands/Microsoft365Groups/GetMicrosoft365GroupYammerCommunity.cs b/src/Commands/Microsoft365Groups/GetMicrosoft365GroupYammerCommunity.cs index d5eb3b9a4..c9ad4583e 100644 --- a/src/Commands/Microsoft365Groups/GetMicrosoft365GroupYammerCommunity.cs +++ b/src/Commands/Microsoft365Groups/GetMicrosoft365GroupYammerCommunity.cs @@ -11,6 +11,7 @@ namespace PnP.PowerShell.Commands.Microsoft365Groups { [Cmdlet(VerbsCommon.Get, "PnPMicrosoft365GroupYammerCommunity")] [RequiredMinimalApiPermissions("Group.Read.All")] + [RequiredMinimalApiPermissions("Group.ReadWrite.All")] public class GetMicrosoft365GroupYammerCommunity : PnPGraphCmdlet { [Parameter(Mandatory = false, ValueFromPipeline = true, Position = 0)] @@ -22,7 +23,7 @@ protected override void ExecuteCmdlet() if (ParameterSpecified(nameof(Identity))) { WriteVerbose($"Defining Microsoft 365 Group based on {nameof(Identity)} parameter"); - groupId = Identity.GetGroupId(Connection, AccessToken); + groupId = Identity.GetGroupId(this, Connection, AccessToken); } else { @@ -43,7 +44,7 @@ protected override void ExecuteCmdlet() } WriteVerbose($"Requesting endpoints of Microsoft 365 Group with Id {groupId}"); - var endpoints = GraphHelper.GetResultCollectionAsync(Connection, $"/beta/groups/{groupId}/endpoints", AccessToken).GetAwaiter().GetResult(); + var endpoints = GraphHelper.GetResultCollection(this, Connection, $"/beta/groups/{groupId}/endpoints", AccessToken); WriteVerbose($"{endpoints.Count()} endpoint(s) found in total"); var yammerEndpoint = endpoints.Where(e => e.ProviderName.Equals("Yammer", StringComparison.InvariantCultureIgnoreCase)); diff --git a/src/Commands/Microsoft365Groups/NewMicrosoft365Group.cs b/src/Commands/Microsoft365Groups/NewMicrosoft365Group.cs index face3ed1c..9d17c80bb 100644 --- a/src/Commands/Microsoft365Groups/NewMicrosoft365Group.cs +++ b/src/Commands/Microsoft365Groups/NewMicrosoft365Group.cs @@ -101,7 +101,7 @@ protected override void ExecuteCmdlet() if (!Force) { - var candidate = Microsoft365GroupsUtility.GetGroupAsync(Connection, MailNickname, AccessToken, false, false, false, false).GetAwaiter().GetResult(); + var candidate = ClearOwners.GetGroup(this, Connection, MailNickname, AccessToken, false, false, false, false); forceCreation = candidate == null || ShouldContinue($"The Microsoft 365 Group '{MailNickname} already exists. Do you want to create a new one?", Properties.Resources.Confirm); } else @@ -173,14 +173,14 @@ protected override void ExecuteCmdlet() } } - var group = Microsoft365GroupsUtility.CreateAsync(Connection, AccessToken, newGroup, CreateTeam, LogoPath, Owners, Members, HideFromAddressLists, HideFromOutlookClients, Labels).GetAwaiter().GetResult(); + var group = ClearOwners.Create(this, Connection, AccessToken, newGroup, CreateTeam, LogoPath, Owners, Members, HideFromAddressLists, HideFromOutlookClients, Labels); if (ParameterSpecified(nameof(HideFromAddressLists)) || ParameterSpecified(nameof(HideFromOutlookClients))) { - Microsoft365GroupsUtility.SetVisibilityAsync(Connection, AccessToken, group.Id.Value, HideFromAddressLists, HideFromOutlookClients).GetAwaiter().GetResult(); + ClearOwners.SetVisibility(this, Connection, AccessToken, group.Id.Value, HideFromAddressLists, HideFromOutlookClients); } - var updatedGroup = Microsoft365GroupsUtility.GetGroupAsync(Connection, group.Id.Value, AccessToken, true, false, false, true).GetAwaiter().GetResult(); + var updatedGroup = ClearOwners.GetGroup(this, Connection, group.Id.Value, AccessToken, true, false, false, true); WriteObject(updatedGroup); } diff --git a/src/Commands/Microsoft365Groups/NewMicrosoft365GroupSettings.cs b/src/Commands/Microsoft365Groups/NewMicrosoft365GroupSettings.cs index 0fecf5f04..cc20ef35a 100644 --- a/src/Commands/Microsoft365Groups/NewMicrosoft365GroupSettings.cs +++ b/src/Commands/Microsoft365Groups/NewMicrosoft365GroupSettings.cs @@ -30,17 +30,17 @@ protected override void ExecuteCmdlet() { if (Identity != null) { - var groupId = Identity.GetGroupId(Connection, AccessToken); + var groupId = Identity.GetGroupId(this, Connection, AccessToken); var groupSettingObject = GroupSettingsObject(); - var responseValue = Microsoft365GroupsUtility.CreateGroupSetting(Connection, AccessToken, groupId.ToString(), groupSettingObject).GetAwaiter().GetResult(); + var responseValue = ClearOwners.CreateGroupSetting(this, Connection, AccessToken, groupId.ToString(), groupSettingObject).GetAwaiter().GetResult(); WriteObject(responseValue); } else { var groupSettingObject = GroupSettingsObject(); - var responseValue = Microsoft365GroupsUtility.CreateGroupSetting(Connection, AccessToken, groupSettingObject).GetAwaiter().GetResult(); + var responseValue = ClearOwners.CreateGroupSetting(this, Connection, AccessToken, groupSettingObject).GetAwaiter().GetResult(); WriteObject(responseValue); } } diff --git a/src/Commands/Microsoft365Groups/RemoveDeletedMicrosoft365Group.cs b/src/Commands/Microsoft365Groups/RemoveDeletedMicrosoft365Group.cs index 0231bc3f2..b5d3a8cd6 100644 --- a/src/Commands/Microsoft365Groups/RemoveDeletedMicrosoft365Group.cs +++ b/src/Commands/Microsoft365Groups/RemoveDeletedMicrosoft365Group.cs @@ -15,7 +15,7 @@ public class RemoveDeletedMicrosoft365Group : PnPGraphCmdlet protected override void ExecuteCmdlet() { - Microsoft365GroupsUtility.PermanentlyDeleteDeletedGroupAsync(Connection, Identity.GetDeletedGroupId(Connection, AccessToken), AccessToken).GetAwaiter().GetResult(); + ClearOwners.PermanentlyDeleteDeletedGroup(this, Connection, Identity.GetDeletedGroupId(this, Connection, AccessToken), AccessToken); } } } \ No newline at end of file diff --git a/src/Commands/Microsoft365Groups/RemoveMicrosoft365Group.cs b/src/Commands/Microsoft365Groups/RemoveMicrosoft365Group.cs index dc6590a66..00c868ce5 100644 --- a/src/Commands/Microsoft365Groups/RemoveMicrosoft365Group.cs +++ b/src/Commands/Microsoft365Groups/RemoveMicrosoft365Group.cs @@ -15,7 +15,7 @@ public class RemoveMicrosoft365Group : PnPGraphCmdlet protected override void ExecuteCmdlet() { - Microsoft365GroupsUtility.RemoveGroupAsync(Connection, Identity.GetGroupId(Connection, AccessToken), AccessToken).GetAwaiter().GetResult(); + ClearOwners.RemoveGroup(this, Connection, Identity.GetGroupId(this, Connection, AccessToken), AccessToken); } } } \ No newline at end of file diff --git a/src/Commands/Microsoft365Groups/RemoveMicrosoft365GroupMember.cs b/src/Commands/Microsoft365Groups/RemoveMicrosoft365GroupMember.cs index c1f3f5ffb..b147d905e 100644 --- a/src/Commands/Microsoft365Groups/RemoveMicrosoft365GroupMember.cs +++ b/src/Commands/Microsoft365Groups/RemoveMicrosoft365GroupMember.cs @@ -18,7 +18,7 @@ public class RemoveMicrosoft365GroupMember : PnPGraphCmdlet protected override void ExecuteCmdlet() { - Microsoft365GroupsUtility.RemoveMembersAsync(Connection, Identity.GetGroupId(Connection, AccessToken), Users, AccessToken).GetAwaiter().GetResult(); + ClearOwners.RemoveMembers(this, Connection, Identity.GetGroupId(this, Connection, AccessToken), Users, AccessToken); } } } \ No newline at end of file diff --git a/src/Commands/Microsoft365Groups/RemoveMicrosoft365GroupOwner.cs b/src/Commands/Microsoft365Groups/RemoveMicrosoft365GroupOwner.cs index 3e8633ba6..7a3648307 100644 --- a/src/Commands/Microsoft365Groups/RemoveMicrosoft365GroupOwner.cs +++ b/src/Commands/Microsoft365Groups/RemoveMicrosoft365GroupOwner.cs @@ -18,7 +18,7 @@ public class RemoveMicrosoft365GroupOwner : PnPGraphCmdlet protected override void ExecuteCmdlet() { - Microsoft365GroupsUtility.RemoveOwnersAsync(Connection, Identity.GetGroupId(Connection, AccessToken), Users, AccessToken).GetAwaiter().GetResult(); + ClearOwners.RemoveOwners(this, Connection, Identity.GetGroupId(this, Connection, AccessToken), Users, AccessToken); } } } \ No newline at end of file diff --git a/src/Commands/Microsoft365Groups/RemoveMicrosoft365GroupPhoto.cs b/src/Commands/Microsoft365Groups/RemoveMicrosoft365GroupPhoto.cs index f60e714ba..80731cb38 100644 --- a/src/Commands/Microsoft365Groups/RemoveMicrosoft365GroupPhoto.cs +++ b/src/Commands/Microsoft365Groups/RemoveMicrosoft365GroupPhoto.cs @@ -18,10 +18,10 @@ public class RemoveMicrosoft365GroupPicture : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var group = Identity.GetGroup(Connection, AccessToken, false, false, false, false); + var group = Identity.GetGroup(this, Connection, AccessToken, false, false, false, false); if (group != null) { - var response = Microsoft365GroupsUtility.DeletePhotoAsync(Connection, AccessToken, group.Id.Value).GetAwaiter().GetResult(); + var response = ClearOwners.DeletePhoto(this, Connection, AccessToken, group.Id.Value); if (!response.IsSuccessStatusCode) { if (GraphHelper.TryGetGraphException(response, out GraphException ex)) diff --git a/src/Commands/Microsoft365Groups/RemoveMicrosoft365GroupSettings.cs b/src/Commands/Microsoft365Groups/RemoveMicrosoft365GroupSettings.cs index 731d78a09..160fbd616 100644 --- a/src/Commands/Microsoft365Groups/RemoveMicrosoft365GroupSettings.cs +++ b/src/Commands/Microsoft365Groups/RemoveMicrosoft365GroupSettings.cs @@ -20,12 +20,12 @@ protected override void ExecuteCmdlet() { if (Group != null) { - var groupId = Group.GetGroupId(Connection, AccessToken); - Microsoft365GroupsUtility.RemoveGroupSetting(Connection, AccessToken, Identity, groupId.ToString()).GetAwaiter().GetResult(); + var groupId = Group.GetGroupId(this, Connection, AccessToken); + ClearOwners.RemoveGroupSetting(this, Connection, AccessToken, Identity, groupId.ToString()); } else { - Microsoft365GroupsUtility.RemoveGroupSetting(Connection, AccessToken, Identity).GetAwaiter().GetResult(); + ClearOwners.RemoveGroupSetting(this, Connection, AccessToken, Identity); } } } diff --git a/src/Commands/Microsoft365Groups/ResetMicrosoft365GroupExpiration.cs b/src/Commands/Microsoft365Groups/ResetMicrosoft365GroupExpiration.cs index ce52db7dd..8a62a7a29 100644 --- a/src/Commands/Microsoft365Groups/ResetMicrosoft365GroupExpiration.cs +++ b/src/Commands/Microsoft365Groups/ResetMicrosoft365GroupExpiration.cs @@ -15,7 +15,7 @@ public class ResetMicrosoft365GroupExpiration : PnPGraphCmdlet protected override void ExecuteCmdlet() { - Microsoft365GroupsUtility.RenewAsync(Connection, AccessToken, Identity.GetGroupId(Connection, AccessToken)).GetAwaiter().GetResult(); + ClearOwners.Renew(this, Connection, AccessToken, Identity.GetGroupId(this, Connection, AccessToken)); } } } \ No newline at end of file diff --git a/src/Commands/Microsoft365Groups/RestoreDeletedMicrosoft365Group.cs b/src/Commands/Microsoft365Groups/RestoreDeletedMicrosoft365Group.cs index b5fdaf2ec..f96f7d466 100644 --- a/src/Commands/Microsoft365Groups/RestoreDeletedMicrosoft365Group.cs +++ b/src/Commands/Microsoft365Groups/RestoreDeletedMicrosoft365Group.cs @@ -15,7 +15,7 @@ public class RestoreDeletedMicrosoft365Group : PnPGraphCmdlet protected override void ExecuteCmdlet() { - WriteObject(Microsoft365GroupsUtility.RestoreDeletedGroupAsync(Connection, Identity.GetDeletedGroupId(Connection, AccessToken), AccessToken).GetAwaiter().GetResult()); + WriteObject(ClearOwners.RestoreDeletedGroup(this, Connection, Identity.GetDeletedGroupId(this, Connection, AccessToken), AccessToken)); } } } \ No newline at end of file diff --git a/src/Commands/Microsoft365Groups/SetMicrosoft365Group.cs b/src/Commands/Microsoft365Groups/SetMicrosoft365Group.cs index d65a39278..b5ea5be19 100644 --- a/src/Commands/Microsoft365Groups/SetMicrosoft365Group.cs +++ b/src/Commands/Microsoft365Groups/SetMicrosoft365Group.cs @@ -62,7 +62,7 @@ public class SetMicrosoft365Group : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var group = Identity.GetGroup(Connection, AccessToken, false, false, false, false); + var group = Identity.GetGroup(this, Connection, AccessToken, false, false, false, false); if (group != null) { @@ -99,7 +99,7 @@ protected override void ExecuteCmdlet() if (changed) { WriteVerbose("Updating Microsoft 365 Group properties in Microsoft Graph"); - group = Microsoft365GroupsUtility.UpdateAsync(Connection, AccessToken, group).GetAwaiter().GetResult(); + group = ClearOwners.Update(this, Connection, AccessToken, group); } if (ParameterSpecified(nameof(AllowExternalSenders)) && AllowExternalSenders.HasValue) @@ -127,17 +127,17 @@ protected override void ExecuteCmdlet() if (exchangeOnlinePropertiesChanged) { WriteVerbose("Updating Microsoft 365 Group Exchange Online properties through Microsoft Graph"); - group = Microsoft365GroupsUtility.UpdateExchangeOnlineSettingAsync(Connection, group.Id.Value, AccessToken, group).GetAwaiter().GetResult(); + group = ClearOwners.UpdateExchangeOnlineSetting(this, Connection, group.Id.Value, AccessToken, group); } if (ParameterSpecified(nameof(Owners))) { - Microsoft365GroupsUtility.UpdateOwnersAsync(Connection, group.Id.Value, AccessToken, Owners).GetAwaiter().GetResult(); + ClearOwners.UpdateOwners(this, Connection, group.Id.Value, AccessToken, Owners); } if (ParameterSpecified(nameof(Members))) { - Microsoft365GroupsUtility.UpdateMembersAsync(Connection, group.Id.Value, AccessToken, Members).GetAwaiter().GetResult(); + ClearOwners.UpdateMembersAsync(this, Connection, group.Id.Value, AccessToken, Members); } if (ParameterSpecified(nameof(LogoPath))) @@ -146,14 +146,14 @@ protected override void ExecuteCmdlet() { LogoPath = Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, LogoPath); } - Microsoft365GroupsUtility.UploadLogoAsync(Connection, AccessToken, group.Id.Value, LogoPath).GetAwaiter().GetResult(); + ClearOwners.UploadLogoAsync(this, Connection, AccessToken, group.Id.Value, LogoPath); } if (ParameterSpecified(nameof(CreateTeam))) { if (!group.ResourceProvisioningOptions.Contains("Team")) { - Microsoft365GroupsUtility.CreateTeamAsync(Connection, AccessToken, group.Id.Value).GetAwaiter().GetResult(); + ClearOwners.CreateTeam(this, Connection, AccessToken, group.Id.Value); } else { @@ -164,7 +164,7 @@ protected override void ExecuteCmdlet() if (ParameterSpecified(nameof(HideFromAddressLists)) || ParameterSpecified(nameof(HideFromOutlookClients))) { // For this scenario a separate call needs to be made - Microsoft365GroupsUtility.SetVisibilityAsync(Connection, AccessToken, group.Id.Value, HideFromAddressLists, HideFromOutlookClients).GetAwaiter().GetResult(); + ClearOwners.SetVisibility(this, Connection, AccessToken, group.Id.Value, HideFromAddressLists, HideFromOutlookClients); } var assignedLabels = new List(); @@ -183,7 +183,7 @@ protected override void ExecuteCmdlet() }); } } - Microsoft365GroupsUtility.SetSensitivityLabelsAsync(Connection, AccessToken, group.Id.Value, assignedLabels).GetAwaiter().GetResult(); + ClearOwners.SetSensitivityLabels(this, Connection, AccessToken, group.Id.Value, assignedLabels); } else { diff --git a/src/Commands/Microsoft365Groups/SetMicrosoft365GroupSettings.cs b/src/Commands/Microsoft365Groups/SetMicrosoft365GroupSettings.cs index 58a51b95a..6b30bae2e 100644 --- a/src/Commands/Microsoft365Groups/SetMicrosoft365GroupSettings.cs +++ b/src/Commands/Microsoft365Groups/SetMicrosoft365GroupSettings.cs @@ -26,15 +26,15 @@ protected override void ExecuteCmdlet() { if (Group != null) { - var groupId = Group.GetGroupId(Connection, AccessToken); + var groupId = Group.GetGroupId(this, Connection, AccessToken); var groupSettingObject = GroupSettingsObject(); - Microsoft365GroupsUtility.UpdateGroupSetting(Connection, AccessToken, Identity, groupId.ToString(), groupSettingObject).GetAwaiter().GetResult(); + ClearOwners.UpdateGroupSetting(this, Connection, AccessToken, Identity, groupId.ToString(), groupSettingObject).GetAwaiter().GetResult(); } else { var groupSettingObject = GroupSettingsObject(); - Microsoft365GroupsUtility.UpdateGroupSetting(Connection, AccessToken, Identity, groupSettingObject).GetAwaiter().GetResult(); + ClearOwners.UpdateGroupSetting(this, Connection, AccessToken, Identity, groupSettingObject).GetAwaiter().GetResult(); } } diff --git a/src/Commands/Model/AccessTokenPermissionValidationResponse.cs b/src/Commands/Model/AccessTokenPermissionValidationResponse.cs new file mode 100644 index 000000000..0a237b987 --- /dev/null +++ b/src/Commands/Model/AccessTokenPermissionValidationResponse.cs @@ -0,0 +1,87 @@ +using PnP.PowerShell.Commands.Attributes; +using PnP.PowerShell.Commands.Base; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PnP.PowerShell.Commands.Model +{ + /// + /// Model to evaluate and reply to an access token permission validation when cross checking it with the required permissions for a cmdlet + /// + public class AccessTokenPermissionValidationResponse + { + #region Properties + + /// + /// Indicates if the permissions required for the Cmdlet are present in the access token + /// + public bool RequiredPermissionsPresent { get; set; } + + /// + /// List of permissions that are missing in the access token + /// + public string[] MissingPermissions { get; set; } + + /// + /// List of permissions that are required for the Cmdlet to run + /// + public string[] RequiredPermissions { get; set; } + + #endregion + + #region Methods + + /// + /// Extracts the oAuth JWT token to compare the permissions in it (roles) with the required permissions for the cmdlet provided through an attribute + /// + /// The cmdlet that will be executed. Used to check for the permissions attribute. + /// The oAuth JWT token that needs to be validated for its roles + /// instance containing the results of the evaluation + internal static List EvaluatePermissions(Type cmdletType, string accessToken) + { + var responses = new List(); + + string[] requiredScopes = null; + var attributes = (RequiredMinimalApiPermissions[])Attribute.GetCustomAttributes(cmdletType, typeof(RequiredMinimalApiPermissions)); + + foreach (var requiredScopesAttribute in attributes) + { + + if (requiredScopesAttribute != null) + { + requiredScopes = requiredScopesAttribute.PermissionScopes; + } + + // Ensure there are permission attributes present on the cmdlet, otherwise we have nothing to compare it against + if (requiredScopes == null || requiredScopes.Length == 0) + { + responses.Add(new AccessTokenPermissionValidationResponse + { + RequiredPermissionsPresent = true, + MissingPermissions = Array.Empty(), + RequiredPermissions = Array.Empty() + }); + } + else + { + // Retrieve the scopes we have in our AccessToken + var scopes = TokenHandler.ReturnScopes(accessToken); + + var missingScopes = requiredScopes.Where(rs => !scopes.Contains(rs)).ToArray(); + + responses.Add(new AccessTokenPermissionValidationResponse + { + RequiredPermissionsPresent = missingScopes.Length == 0, + RequiredPermissions = requiredScopes, + MissingPermissions = missingScopes + }); + + } + + } + return responses; + #endregion + } + } +} \ No newline at end of file diff --git a/src/Commands/Model/Graph/MicrosoftSearch/ExternalConnection.cs b/src/Commands/Model/Graph/MicrosoftSearch/ExternalConnection.cs new file mode 100644 index 000000000..3dd69321c --- /dev/null +++ b/src/Commands/Model/Graph/MicrosoftSearch/ExternalConnection.cs @@ -0,0 +1,42 @@ +using System.Text.Json.Serialization; + +namespace PnP.PowerShell.Commands.Model.Graph.MicrosoftSearch; + +/// +/// Defines a connection to an external datasource used by Microsoft Search +/// +/// +public class ExternalConnection +{ + /// + /// Unique identifier of the external connection + /// + [JsonPropertyName("id")] + public string Id { get; set; } + + /// + /// Name of the external connection + /// + [JsonPropertyName("name")] + public string Name { get; set; } + + /// + /// Description of the external connection + /// + [JsonPropertyName("description")] + public string Description { get; set; } + + /// + /// The configuration on the external connection + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("configuration")] + public ExternalConnectionConfiguration Configuration { get; set; } + + /// + /// The state of the external connection + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("state")] + public Enums.SearchExternalConnectionState? State { get; set; } +} \ No newline at end of file diff --git a/src/Commands/Model/Graph/MicrosoftSearch/ExternalConnectionConfiguration.cs b/src/Commands/Model/Graph/MicrosoftSearch/ExternalConnectionConfiguration.cs new file mode 100644 index 000000000..55cc7fcb4 --- /dev/null +++ b/src/Commands/Model/Graph/MicrosoftSearch/ExternalConnectionConfiguration.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace PnP.PowerShell.Commands.Model.Graph.MicrosoftSearch; + +/// +/// Defines the configuration of an external connection used by Microsoft Search +/// +/// +public class ExternalConnectionConfiguration +{ + /// + /// A collection of application IDs for registered Microsoft Entra apps that are allowed to manage the externalConnection and to index content in the externalConnection + /// + [JsonPropertyName("authorizedAppIds")] + public string[] AuthorizedAppIds { get; set; } +} \ No newline at end of file diff --git a/src/Commands/Model/Graph/MicrosoftSearch/ExternalSchema.cs b/src/Commands/Model/Graph/MicrosoftSearch/ExternalSchema.cs new file mode 100644 index 000000000..f15dd6e0e --- /dev/null +++ b/src/Commands/Model/Graph/MicrosoftSearch/ExternalSchema.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace PnP.PowerShell.Commands.Model.Graph.MicrosoftSearch; + +/// +/// Defines a schema for a connection to an external datasource used by Microsoft Search +/// +/// +public class ExternalSchema +{ + /// + /// Schema base type. Do not modify. + /// + [JsonPropertyName("baseType")] + public string BaseType { get; } = "microsoft.graph.externalItem"; + + /// + /// Properties in the schema of the external connection defining which information is available on the external items + /// + [JsonPropertyName("properties")] + public List Properties { get; set; } +} \ No newline at end of file diff --git a/src/Commands/Model/Graph/MicrosoftSearch/ExternalSchemaProperty.cs b/src/Commands/Model/Graph/MicrosoftSearch/ExternalSchemaProperty.cs new file mode 100644 index 000000000..651df7239 --- /dev/null +++ b/src/Commands/Model/Graph/MicrosoftSearch/ExternalSchemaProperty.cs @@ -0,0 +1,58 @@ +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace PnP.PowerShell.Commands.Model.Graph.MicrosoftSearch; + +/// +/// Defines a schema property for a connection to an external datasource used by Microsoft Search +/// +/// +public class ExternalSchemaProperty +{ + /// + /// Name of the schema property + /// + [JsonPropertyName("name")] + public string Name { get; set; } + + /// + /// A set of aliases or a friendly name for the property. Maximum 32 characters. Only alphanumeric characters allowed. For example, each string may not contain control characters, whitespace, or any of the following: :, ;, ,, (, ), [, ], {, }, %, $, +, !, *, =, &, ?, @, #, \, ~, ', ", <, >, `, ^. Optional. + /// + [JsonPropertyName("aliases")] + public string[] Aliases { get; set; } + + /// + /// Specifies if the property is queryable. Queryable properties can be used in Keyword Query Language (KQL) queries. Optional. + /// + [JsonPropertyName("isQueryable")] + public bool IsQueryable { get; set; } + + /// + /// Specifies if the property is refinable. Refinable properties can be used to filter search results in the Search API and add a refiner control in the Microsoft Search user experience. Optional. + /// + [JsonPropertyName("isRefinable")] + public bool IsRefinable { get; set; } + + /// + /// Specifies if the property is retrievable. Retrievable properties are returned in the result set when items are returned by the search API. Retrievable properties are also available to add to the display template used to render search results. Optional. + /// + [JsonPropertyName("isRetrievable")] + public bool IsRetrievable { get; set; } + + /// + /// Specifies if the property is searchable. Only properties of type String or StringCollection can be searchable. Nonsearchable properties aren't added to the search index. Optional. + /// + [JsonPropertyName("isSearchable")] + public bool IsSearchable { get; set; } + + /// + /// Specifies the type of information stored in the property. Required. + /// + [JsonPropertyName("type")] + public Enums.SearchExternalSchemaPropertyType? Type { get; set; } + + /// + /// Specifies the labels to tag the property with to make Microsoft Search better understand the data. Optional. + /// + public List Labels { get; set; } +} \ No newline at end of file diff --git a/src/Commands/Model/Graph/OperationStatus.cs b/src/Commands/Model/Graph/OperationStatus.cs new file mode 100644 index 000000000..da5026914 --- /dev/null +++ b/src/Commands/Model/Graph/OperationStatus.cs @@ -0,0 +1,29 @@ +using System; +using Newtonsoft.Json; + +namespace PnP.PowerShell.Commands.Model.Graph +{ + /// + /// Model for an operation status in Microsoft Graph + /// + public class OperationStatus + { + /// + /// Unique identifier of the operation + /// + [JsonProperty("id")] + public Guid? Id { get; set; } + + /// + /// The status of the operation + /// + [JsonProperty("status")] + public string Status { get; set; } + + /// + /// The error message, if anything went wrong + /// + [JsonProperty("error")] + public string Error { get; set; } + } +} diff --git a/src/Commands/Model/SPOSite.cs b/src/Commands/Model/SPOSite.cs index 158b84e4e..1063030c0 100644 --- a/src/Commands/Model/SPOSite.cs +++ b/src/Commands/Model/SPOSite.cs @@ -83,23 +83,25 @@ public class SPOSite public Role DefaultShareLinkRole { get; set; } public SharingScope LoopDefaultSharingLinkScope { get; set; } public string ArchiveStatus { get; set; } - public bool EnableAutoExpirationVersionTrim { get; set; } + public bool EnableAutoExpirationVersionTrim { get; set; } public int ExpireVersionsAfterDays { get; set; } public bool InheritVersionPolicyFromTenant { get; set; } public bool IsGroupOwnerSiteAdmin { get; set; } public bool ListsShowHeaderAndNavigation { get; set; } public int LockReason { get; set; } - public bool LoopOverrideSharingCapability { get; set; } - public SharingCapabilities LoopSharingCapability { get; set; } public int MajorVersionLimit { get; set; } public int MajorWithMinorVersionsLimit { get; set; } public bool RestrictedAccessControl { get; set; } public Guid[] RestrictedAccessControlGroups { get; set; } - public Guid[] RestrictedAccessControlGroupsToAdd { get; set; } + public Guid[] RestrictedAccessControlGroupsToAdd { get; set; } public Guid[] RestrictedAccessControlGroupsToRemove { get; set; } public RestrictedToRegion RestrictedToRegion { get; set; } public bool SetOwnerWithoutUpdatingSecondaryAdmin { get; set; } + public bool RestrictContentOrgWideSearch { get; set; } + public bool ReadOnlyForUnmanagedDevices { get; set; } + public SiteUserInfoVisibilityPolicyValue OverrideBlockUserInfoVisibility { get; set; } + public bool OverrideSharingCapability { get; set; } #endregion @@ -163,7 +165,7 @@ public SPOSite(SiteProperties props, bool? disableSharingForNonOwnersStatus) StorageUsageCurrent = props.StorageUsage; TeamsChannelType = props.TeamsChannelType; Template = props.Template; - Title = props.Title; + Title = props.Title; WebsCount = props.WebsCount; Url = props.Url; InformationBarrierMode = props.IBMode; @@ -183,8 +185,6 @@ public SPOSite(SiteProperties props, bool? disableSharingForNonOwnersStatus) IsGroupOwnerSiteAdmin = props.IsGroupOwnerSiteAdmin; ListsShowHeaderAndNavigation = props.ListsShowHeaderAndNavigation; LockReason = props.LockReason; - LoopOverrideSharingCapability = props.LoopOverrideSharingCapability; - LoopSharingCapability = props.LoopSharingCapability; MajorVersionLimit = props.MajorVersionLimit; MajorWithMinorVersionsLimit = props.MajorWithMinorVersionsLimit; RestrictedAccessControl = props.RestrictedAccessControl; @@ -192,7 +192,11 @@ public SPOSite(SiteProperties props, bool? disableSharingForNonOwnersStatus) RestrictedAccessControlGroupsToAdd = props.RestrictedAccessControlGroupsToAdd; RestrictedAccessControlGroupsToRemove = props.RestrictedAccessControlGroupsToRemove; RestrictedToRegion = props.RestrictedToRegion; - SetOwnerWithoutUpdatingSecondaryAdmin = props.SetOwnerWithoutUpdatingSecondaryAdmin; + SetOwnerWithoutUpdatingSecondaryAdmin = props.SetOwnerWithoutUpdatingSecondaryAdmin; + RestrictContentOrgWideSearch = props.RestrictContentOrgWideSearch; + ReadOnlyForUnmanagedDevices = props.ReadOnlyForUnmanagedDevices; + OverrideSharingCapability = props.OverrideSharingCapability; + OverrideBlockUserInfoVisibility = props.OverrideBlockUserInfoVisibility; } } } \ No newline at end of file diff --git a/src/Commands/Model/SPOTenant.cs b/src/Commands/Model/SPOTenant.cs index c31e48fc8..0bac35231 100644 --- a/src/Commands/Model/SPOTenant.cs +++ b/src/Commands/Model/SPOTenant.cs @@ -59,7 +59,7 @@ public class SPOTenant public bool BccExternalSharingInvitations { private set; get; } - public string BccExternalSharingInvitationsList { private set; get; } + public string BccExternalSharingInvitationsList { private set; get; } public bool PublicCdnEnabled { private set; get; } @@ -189,13 +189,13 @@ public class SPOTenant public bool? ShowPeoplePickerGroupSuggestionsForIB { private set; get; } public bool? InformationBarriersSuspension { private set; get; } - + public bool? IBImplicitGroupBased { private set; get; } public bool? AppBypassInformationBarriers { private set; get; } public InformationBarriersMode? DefaultOneDriveInformationBarrierMode { private set; get; } - + public SharingCapabilities? CoreSharingCapability { private set; get; } public bool? EnableVersionExpirationSetting { private set; get; } @@ -235,14 +235,21 @@ public class SPOTenant public SharingState? AllowAnonymousMeetingParticipantsToAccessWhiteboards { private set; get; } public SharingScope? OneDriveDefaultShareLinkScope { private set; get; } - + public Role? OneDriveDefaultShareLinkRole { private set; get; } - + public bool? OneDriveDefaultLinkToExistingAccess { private set; get; } - + public SharingState? OneDriveBlockGuestsAsSiteAdmin { private set; get; } public int? RecycleBinRetentionPeriod { private set; get; } + + public bool? EnableAIPIntegration { private set; get; } + public SharingScope? CoreDefaultShareLinkScope { private set; get; } + public Role? CoreDefaultShareLinkRole { private set; get; } + public bool? SharePointAddInsDisabled { private set; get; } + public SharingCapabilities? OneDriveSharingCapability { private set; get; } + public string[] GuestSharingGroupAllowListInTenantByPrincipalIdentity { private set; get; } #endregion public SPOTenant(Tenant tenant, ClientContext clientContext) @@ -300,7 +307,7 @@ public SPOTenant(Tenant tenant, ClientContext clientContext) { UseFindPeopleInPeoplePicker = false; } - + try { RequireAnonymousLinksExpireInDays = tenant.RequireAnonymousLinksExpireInDays; @@ -699,11 +706,11 @@ public SPOTenant(Tenant tenant, ClientContext clientContext) OneDriveRequestFilesLinkExpirationInDays = tenant.OneDriveRequestFilesLinkExpirationInDays; BusinessConnectivityServiceDisabled = tenant.BusinessConnectivityServiceDisabled; - try + try { EnableSensitivityLabelForPDF = tenant.EnableSensitivityLabelForPDF; } - catch + catch { EnableSensitivityLabelForPDF = false; } @@ -742,7 +749,7 @@ public SPOTenant(Tenant tenant, ClientContext clientContext) try { - if (tenant.DefaultODBMode != null) + if (tenant.DefaultODBMode != null) { DefaultOneDriveInformationBarrierMode = Enum.Parse(tenant.DefaultODBMode); } @@ -752,30 +759,36 @@ public SPOTenant(Tenant tenant, ClientContext clientContext) } - try{CoreSharingCapability = tenant.CoreSharingCapability;}catch{} - try{EnableVersionExpirationSetting = tenant.EnableVersionExpirationSetting;}catch{} - try{BlockUserInfoVisibilityInOneDrive = tenant.BlockUserInfoVisibilityInOneDrive;}catch{} - try{AllowOverrideForBlockUserInfoVisibility = tenant.AllowOverrideForBlockUserInfoVisibility;}catch{} - try{AllowEveryoneExceptExternalUsersClaimInPrivateSite = tenant.AllowEveryoneExceptExternalUsersClaimInPrivateSite;}catch{} - try{AllowSensitivityLabelOnRecords = tenant.AllowSensitivityLabelOnRecords;}catch{} - try{AnyoneLinkTrackUsers = tenant.AnyoneLinkTrackUsers;}catch{} - try{AIBuilderEnabled = tenant.AIBuilderEnabled;}catch{} - try{EnableSiteArchive = tenant.EnableSiteArchive;}catch{} - try{ESignatureEnabled = tenant.ESignatureEnabled;}catch{} - try{BlockUserInfoVisibilityInSharePoint = tenant.BlockUserInfoVisibilityInSharePoint;}catch{} - try{OneDriveLoopDefaultSharingLinkScope = tenant.OneDriveLoopDefaultSharingLinkScope;}catch{} - try{CoreLoopDefaultSharingLinkScope = tenant.CoreLoopDefaultSharingLinkScope;}catch{} - try{OneDriveLoopSharingCapability = tenant.OneDriveLoopSharingCapability;}catch{} - try{CoreLoopSharingCapability = tenant.CoreLoopSharingCapability;}catch{} - try{OneDriveLoopDefaultSharingLinkRole = tenant.OneDriveLoopDefaultSharingLinkRole;}catch{} - try{CoreLoopDefaultSharingLinkRole = tenant.CoreLoopDefaultSharingLinkRole;}catch{} - try{IsCollabMeetingNotesFluidEnabled = tenant.IsCollabMeetingNotesFluidEnabled;}catch{} - try{AllowAnonymousMeetingParticipantsToAccessWhiteboards = tenant.AllowAnonymousMeetingParticipantsToAccessWhiteboards;}catch{} - try{OneDriveDefaultShareLinkScope = tenant.OneDriveDefaultShareLinkScope;}catch{} - try{OneDriveDefaultShareLinkRole = tenant.OneDriveDefaultShareLinkRole;}catch{} - try{OneDriveDefaultLinkToExistingAccess = tenant.OneDriveDefaultLinkToExistingAccess;}catch{} - try{OneDriveBlockGuestsAsSiteAdmin = tenant.OneDriveBlockGuestsAsSiteAdmin;}catch{} - try{RecycleBinRetentionPeriod = tenant.RecycleBinRetentionPeriod;}catch{} + try { CoreSharingCapability = tenant.CoreSharingCapability; } catch { } + try { EnableVersionExpirationSetting = tenant.EnableVersionExpirationSetting; } catch { } + try { BlockUserInfoVisibilityInOneDrive = tenant.BlockUserInfoVisibilityInOneDrive; } catch { } + try { AllowOverrideForBlockUserInfoVisibility = tenant.AllowOverrideForBlockUserInfoVisibility; } catch { } + try { AllowEveryoneExceptExternalUsersClaimInPrivateSite = tenant.AllowEveryoneExceptExternalUsersClaimInPrivateSite; } catch { } + try { AllowSensitivityLabelOnRecords = tenant.AllowSensitivityLabelOnRecords; } catch { } + try { AnyoneLinkTrackUsers = tenant.AnyoneLinkTrackUsers; } catch { } + try { AIBuilderEnabled = tenant.AIBuilderEnabled; } catch { } + try { EnableSiteArchive = tenant.EnableSiteArchive; } catch { } + try { ESignatureEnabled = tenant.ESignatureEnabled; } catch { } + try { BlockUserInfoVisibilityInSharePoint = tenant.BlockUserInfoVisibilityInSharePoint; } catch { } + try { OneDriveLoopDefaultSharingLinkScope = tenant.OneDriveLoopDefaultSharingLinkScope; } catch { } + try { CoreLoopDefaultSharingLinkScope = tenant.CoreLoopDefaultSharingLinkScope; } catch { } + try { OneDriveLoopSharingCapability = tenant.OneDriveLoopSharingCapability; } catch { } + try { CoreLoopSharingCapability = tenant.CoreLoopSharingCapability; } catch { } + try { OneDriveLoopDefaultSharingLinkRole = tenant.OneDriveLoopDefaultSharingLinkRole; } catch { } + try { CoreLoopDefaultSharingLinkRole = tenant.CoreLoopDefaultSharingLinkRole; } catch { } + try { IsCollabMeetingNotesFluidEnabled = tenant.IsCollabMeetingNotesFluidEnabled; } catch { } + try { AllowAnonymousMeetingParticipantsToAccessWhiteboards = tenant.AllowAnonymousMeetingParticipantsToAccessWhiteboards; } catch { } + try { OneDriveDefaultShareLinkScope = tenant.OneDriveDefaultShareLinkScope; } catch { } + try { OneDriveDefaultShareLinkRole = tenant.OneDriveDefaultShareLinkRole; } catch { } + try { OneDriveDefaultLinkToExistingAccess = tenant.OneDriveDefaultLinkToExistingAccess; } catch { } + try { OneDriveBlockGuestsAsSiteAdmin = tenant.OneDriveBlockGuestsAsSiteAdmin; } catch { } + try { RecycleBinRetentionPeriod = tenant.RecycleBinRetentionPeriod; } catch { } + try { EnableAIPIntegration = tenant.EnableAIPIntegration; } catch { } + try { CoreDefaultShareLinkScope = tenant.CoreDefaultShareLinkScope; } catch { } + try { CoreDefaultShareLinkRole = tenant.CoreDefaultShareLinkRole; } catch { } + try { SharePointAddInsDisabled = tenant.SharePointAddInsDisabled; } catch { } + try { OneDriveSharingCapability = tenant.ODBSharingCapability; } catch { } + try { GuestSharingGroupAllowListInTenantByPrincipalIdentity = tenant.GuestSharingGroupAllowListInTenantByPrincipalIdentity?.ToArray(); } catch { } } } } diff --git a/src/Commands/Model/SPOTenantInternalSetting.cs b/src/Commands/Model/SPOTenantInternalSetting.cs index 1e298c1fe..d2296298e 100644 --- a/src/Commands/Model/SPOTenantInternalSetting.cs +++ b/src/Commands/Model/SPOTenantInternalSetting.cs @@ -46,7 +46,7 @@ public SPOTenantInternalSetting(Tenant tenant, ClientContext clientContext) private void initSPOTenantInternalSetting(ClientContext clientContext) { var httpClient = PnP.Framework.Http.PnPHttpClient.Instance.GetHttpClient(clientContext); - var internalSettingsData = Utilities.REST.RestHelper.GetAsync(httpClient, $"{clientContext.Url}_api/SPOInternalUseOnly.TenantAdminSettings", clientContext.GetAccessToken(), false).GetAwaiter().GetResult(); + var internalSettingsData = Utilities.REST.RestHelper.Get(httpClient, $"{clientContext.Url}_api/SPOInternalUseOnly.TenantAdminSettings", clientContext.GetAccessToken(), false); SitePagesEnabled = internalSettingsData.SitePagesEnabled.Value; DisableSelfServiceSiteCreation = internalSettingsData.DisableSelfServiceSiteCreation.Value; diff --git a/src/Commands/Model/Teams/TeamsChannelFilesFolder.cs b/src/Commands/Model/Teams/TeamsChannelFilesFolder.cs index 458088762..1b7d961e5 100644 --- a/src/Commands/Model/Teams/TeamsChannelFilesFolder.cs +++ b/src/Commands/Model/Teams/TeamsChannelFilesFolder.cs @@ -12,7 +12,7 @@ public partial class TeamsChannelFilesFolder public DateTime lastModifiedDateTime { get; set; } public string name { get; set; } public string webUrl { get; set; } - public int size { get; set; } + public long size { get; set; } public TeamChannelParentReference parentReference { get; set; } public TeamChannelFileSystemInfo fileSystemInfo { get; set; } public TeamChannelFolder folder { get; set; } diff --git a/src/Commands/Navigation/AddNavigationNode.cs b/src/Commands/Navigation/AddNavigationNode.cs index 2f76db37d..f91bcafa9 100644 --- a/src/Commands/Navigation/AddNavigationNode.cs +++ b/src/Commands/Navigation/AddNavigationNode.cs @@ -122,7 +122,7 @@ protected override void ExecuteCmdlet() { // Retrieve the menu definition and save it back again. This step is needed to enforce some properties of the menu to be shown, such as the audience targeting. CurrentWeb.EnsureProperties(w => w.Url); - var menuState = Utilities.REST.RestHelper.GetAsync(Connection.HttpClient, $"{CurrentWeb.Url}/_api/navigation/MenuState", ClientContext.GetAccessToken(), false).GetAwaiter().GetResult(); + var menuState = Utilities.REST.RestHelper.Get(Connection.HttpClient, $"{CurrentWeb.Url}/_api/navigation/MenuState", ClientContext.GetAccessToken(), false); var currentItem = menuState?.Nodes?.Select(node => SearchNodeById(node, addedNode.Id)) .FirstOrDefault(result => result != null); @@ -136,7 +136,7 @@ protected override void ExecuteCmdlet() } var payload = JsonSerializer.Serialize(menuState); - Utilities.REST.RestHelper.PostAsync(Connection.HttpClient, $"{CurrentWeb.Url}/_api/navigation/SaveMenuState", ClientContext, @"{ ""menuState"": " + payload + "}", "application/json", "application/json;odata=nometadata").GetAwaiter().GetResult(); + Utilities.REST.RestHelper.Post(Connection.HttpClient, $"{CurrentWeb.Url}/_api/navigation/SaveMenuState", ClientContext, @"{ ""menuState"": " + payload + "}", "application/json", "application/json;odata=nometadata"); } else { diff --git a/src/Commands/Pages/DisablePageScheduling.cs b/src/Commands/Pages/DisablePageScheduling.cs index 8dcb27d39..4407cf0fe 100644 --- a/src/Commands/Pages/DisablePageScheduling.cs +++ b/src/Commands/Pages/DisablePageScheduling.cs @@ -10,7 +10,7 @@ public class DisablePageScheduling : PnPWebCmdlet protected override void ExecuteCmdlet() { var pagesList = PagesUtility.GetModernPagesLibrary(PnPContext.Web); - Utilities.REST.RestHelper.PostAsync(Connection.HttpClient, $"{PnPContext.Web.Url}/_api/sitepages/pagesinlib(guid'{pagesList.Id}')/setscheduling(false)", ClientContext, null, "application/json", "application/json;odata=nometadata").GetAwaiter().GetResult(); + Utilities.REST.RestHelper.Post(Connection.HttpClient, $"{PnPContext.Web.Url}/_api/sitepages/pagesinlib(guid'{pagesList.Id}')/setscheduling(false)", ClientContext, null, "application/json", "application/json;odata=nometadata"); } } } diff --git a/src/Commands/Pages/EnablePageScheduling.cs b/src/Commands/Pages/EnablePageScheduling.cs index 2edb52b38..3280e7490 100644 --- a/src/Commands/Pages/EnablePageScheduling.cs +++ b/src/Commands/Pages/EnablePageScheduling.cs @@ -10,7 +10,7 @@ public class EnablePageScheduling : PnPWebCmdlet protected override void ExecuteCmdlet() { var pagesList = PagesUtility.GetModernPagesLibrary(PnPContext.Web); - Utilities.REST.RestHelper.PostAsync(Connection.HttpClient, $"{PnPContext.Web.Url}/_api/sitepages/pagesinlib(guid'{pagesList.Id}')/setscheduling(true)", ClientContext, null, "application/json", "application/json;odata=nometadata").GetAwaiter().GetResult(); + Utilities.REST.RestHelper.Post(Connection.HttpClient, $"{PnPContext.Web.Url}/_api/sitepages/pagesinlib(guid'{pagesList.Id}')/setscheduling(true)", ClientContext, null, "application/json", "application/json;odata=nometadata"); } } } diff --git a/src/Commands/Pages/ExportPage.cs b/src/Commands/Pages/ExportPage.cs index 60984d3a3..4c6236de0 100644 --- a/src/Commands/Pages/ExportPage.cs +++ b/src/Commands/Pages/ExportPage.cs @@ -31,6 +31,8 @@ public class ExportPage : PnPWebCmdlet protected override void ProcessRecord() { + _ = Identity.GetPage(Connection) ?? throw new Exception($"Page '{Identity?.Name}' does not exist"); + ExtractConfiguration extractConfiguration = null; if (ParameterSpecified(nameof(Configuration))) { diff --git a/src/Commands/Pages/GetPageSchedulingEnabled.cs b/src/Commands/Pages/GetPageSchedulingEnabled.cs index 499f307ac..f79dfd222 100644 --- a/src/Commands/Pages/GetPageSchedulingEnabled.cs +++ b/src/Commands/Pages/GetPageSchedulingEnabled.cs @@ -20,7 +20,7 @@ protected override void ExecuteCmdlet() } }; - var results = Utilities.REST.RestHelper.PostAsync(Connection.HttpClient, $"{PnPContext.Web.Url}/_api/web/lists(guid'{pagesList.Id}')/RenderListDataAsStream", ClientContext, payload, false).GetAwaiter().GetResult(); + var results = Utilities.REST.RestHelper.Post(Connection.HttpClient, $"{PnPContext.Web.Url}/_api/web/lists(guid'{pagesList.Id}')/RenderListDataAsStream", ClientContext, payload, false); var frameworkClientInfo = results.GetProperty("SPFrameworkClientInfo"); var pageContextJson = frameworkClientInfo.GetProperty("PageContextJson"); diff --git a/src/Commands/Planner/AddPlannerBucket.cs b/src/Commands/Planner/AddPlannerBucket.cs index 5dd7ea442..d0a879b23 100644 --- a/src/Commands/Planner/AddPlannerBucket.cs +++ b/src/Commands/Planner/AddPlannerBucket.cs @@ -28,14 +28,14 @@ protected override void ExecuteCmdlet() { if (ParameterSetName == ParameterName_BYGROUP) { - var groupId = Group.GetGroupId(Connection, AccessToken); + var groupId = Group.GetGroupId(this, Connection, AccessToken); if (groupId != null) { - var planId = Plan.GetIdAsync(Connection, AccessToken, groupId).GetAwaiter().GetResult(); + var planId = Plan.GetId(this, Connection, AccessToken, groupId); if (planId != null) { - WriteObject(PlannerUtility.CreateBucketAsync(Connection, AccessToken, Name, planId).GetAwaiter().GetResult(), true); + WriteObject(PlannerUtility.CreateBucket(this, Connection, AccessToken, Name, planId), true); } else { @@ -49,7 +49,7 @@ protected override void ExecuteCmdlet() } else if (ParameterSetName == ParameterName_BYPLANID) { - WriteObject(PlannerUtility.CreateBucketAsync(Connection, AccessToken, Name, PlanId).GetAwaiter().GetResult(), true); + WriteObject(PlannerUtility.CreateBucket(this, Connection, AccessToken, Name, PlanId), true); } } } diff --git a/src/Commands/Planner/AddPlannerRoster.cs b/src/Commands/Planner/AddPlannerRoster.cs index 24118ee1f..c9291a8de 100644 --- a/src/Commands/Planner/AddPlannerRoster.cs +++ b/src/Commands/Planner/AddPlannerRoster.cs @@ -11,7 +11,7 @@ public class AddPlannerRoster : PnPGraphCmdlet { protected override void ExecuteCmdlet() { - PlannerUtility.CreateRosterAsync(Connection, AccessToken).GetAwaiter().GetResult(); + PlannerUtility.CreateRoster(this, Connection, AccessToken); } } } \ No newline at end of file diff --git a/src/Commands/Planner/AddPlannerRosterMember.cs b/src/Commands/Planner/AddPlannerRosterMember.cs index adb7c8b74..4fcde918c 100644 --- a/src/Commands/Planner/AddPlannerRosterMember.cs +++ b/src/Commands/Planner/AddPlannerRosterMember.cs @@ -18,14 +18,14 @@ public class AddPlannerRosterMember : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var roster = Identity.GetPlannerRosterAsync(Connection, AccessToken).GetAwaiter().GetResult(); + var roster = Identity.GetPlannerRoster(this, Connection, AccessToken); if(roster == null) { throw new PSArgumentException("Provided Planner Roster could not be found", nameof(Identity)); } - PlannerUtility.AddRosterMemberAsync(Connection, AccessToken, roster.Id, User).GetAwaiter().GetResult(); + PlannerUtility.AddRosterMember(this, Connection, AccessToken, roster.Id, User); } } } \ No newline at end of file diff --git a/src/Commands/Planner/AddPlannerTask.cs b/src/Commands/Planner/AddPlannerTask.cs index 18cc32d7e..5a0786a12 100644 --- a/src/Commands/Planner/AddPlannerTask.cs +++ b/src/Commands/Planner/AddPlannerTask.cs @@ -51,6 +51,9 @@ public class AddPlannerTask : PnPGraphCmdlet [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets)] public string[] AssignedTo; + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets)] + public SwitchParameter OutputTask; + protected override void ExecuteCmdlet() { PlannerTask createdTask; @@ -94,7 +97,7 @@ protected override void ExecuteCmdlet() var chunks = BatchUtility.Chunk(AssignedTo, 20); foreach (var chunk in chunks) { - var userIds = BatchUtility.GetPropertyBatchedAsync(Connection, AccessToken, chunk.ToArray(), "/users/{0}", "id").GetAwaiter().GetResult(); + var userIds = BatchUtility.GetPropertyBatched(this, Connection, AccessToken, chunk.ToArray(), "/users/{0}", "id"); foreach (var userId in userIds) { newTask.Assignments.Add(userId.Value, new TaskAssignment()); @@ -105,32 +108,32 @@ protected override void ExecuteCmdlet() // By Group if (ParameterSetName == ParameterName_BYGROUP) { - var groupId = Group.GetGroupId(Connection, AccessToken); + var groupId = Group.GetGroupId(this, Connection, AccessToken); if (groupId == null) { throw new PSArgumentException("Group not found", nameof(Group)); } - var planId = Plan.GetIdAsync(Connection, AccessToken, groupId).GetAwaiter().GetResult(); + var planId = Plan.GetId(this, Connection, AccessToken, groupId); if (planId == null) { throw new PSArgumentException("Plan not found", nameof(Plan)); } newTask.PlanId = planId; - var bucket = Bucket.GetBucket(Connection, AccessToken, planId); + var bucket = Bucket.GetBucket(this, Connection, AccessToken, planId); if (bucket == null) { throw new PSArgumentException("Bucket not found", nameof(Bucket)); } newTask.BucketId = bucket.Id; - createdTask = PlannerUtility.AddTaskAsync(Connection, AccessToken, newTask).GetAwaiter().GetResult(); + createdTask = PlannerUtility.AddTask(this, Connection, AccessToken, newTask); } // By PlanId else { - var bucket = Bucket.GetBucket(Connection, AccessToken, PlanId); + var bucket = Bucket.GetBucket(this, Connection, AccessToken, PlanId); if (bucket == null) { throw new PSArgumentException("Bucket not found", nameof(Bucket)); @@ -139,13 +142,19 @@ protected override void ExecuteCmdlet() newTask.PlanId = PlanId; newTask.BucketId = bucket.Id; - createdTask = PlannerUtility.AddTaskAsync(Connection, AccessToken, newTask).GetAwaiter().GetResult(); + createdTask = PlannerUtility.AddTask(this, Connection, AccessToken, newTask); } if (ParameterSpecified(nameof(Description))) { - var existingTaskDetails = PlannerUtility.GetTaskDetailsAsync(Connection, AccessToken, createdTask.Id, false).GetAwaiter().GetResult(); - PlannerUtility.UpdateTaskDetailsAsync(Connection, AccessToken, existingTaskDetails, Description).GetAwaiter().GetResult(); + var existingTaskDetails = PlannerUtility.GetTaskDetails(this, Connection, AccessToken, createdTask.Id, false); + PlannerUtility.UpdateTaskDetails(this, Connection, AccessToken, existingTaskDetails, Description); + createdTask.HasDescription = true; + } + + if(OutputTask.IsPresent) + { + WriteObject(createdTask); } } } diff --git a/src/Commands/Planner/GetPlannerBucket.cs b/src/Commands/Planner/GetPlannerBucket.cs index e4bcbe386..b57421e3c 100644 --- a/src/Commands/Planner/GetPlannerBucket.cs +++ b/src/Commands/Planner/GetPlannerBucket.cs @@ -8,6 +8,7 @@ namespace PnP.PowerShell.Commands.Planner { [Cmdlet(VerbsCommon.Get, "PnPPlannerBucket")] [RequiredMinimalApiPermissions("Group.Read.All")] + [RequiredMinimalApiPermissions("Group.ReadWrite.All")] public class GetPlannerBucket : PnPGraphCmdlet { private const string ParameterName_BYGROUP = "By Group"; @@ -29,19 +30,19 @@ protected override void ExecuteCmdlet() { if (ParameterSetName == ParameterName_BYGROUP) { - var groupId = Group.GetGroupId(Connection, AccessToken); + var groupId = Group.GetGroupId(this, Connection, AccessToken); if (groupId != null) { - var planId = Plan.GetIdAsync(Connection, AccessToken, groupId).GetAwaiter().GetResult(); + var planId = Plan.GetId(this, Connection, AccessToken, groupId); if (planId != null) { if (!ParameterSpecified(nameof(Identity))) { - WriteObject(PlannerUtility.GetBucketsAsync(Connection, AccessToken, planId).GetAwaiter().GetResult(), true); + WriteObject(PlannerUtility.GetBuckets(this, Connection, AccessToken, planId), true); } else { - WriteObject(Identity.GetBucket(Connection, AccessToken, planId)); + WriteObject(Identity.GetBucket(this, Connection, AccessToken, planId)); } } else @@ -56,7 +57,7 @@ protected override void ExecuteCmdlet() } else { - WriteObject(PlannerUtility.GetBucketsAsync(Connection, AccessToken, PlanId).GetAwaiter().GetResult(), true); + WriteObject(PlannerUtility.GetBuckets(this, Connection, AccessToken, PlanId), true); } } } diff --git a/src/Commands/Planner/GetPlannerConfiguration.cs b/src/Commands/Planner/GetPlannerConfiguration.cs index c16ddfa7e..789214967 100644 --- a/src/Commands/Planner/GetPlannerConfiguration.cs +++ b/src/Commands/Planner/GetPlannerConfiguration.cs @@ -11,7 +11,7 @@ public class GetPlannerConfiguration : PnPGraphCmdlet { protected override void ExecuteCmdlet() { - var result = PlannerUtility.GetPlannerConfigAsync(Connection, AccessToken).GetAwaiter().GetResult(); + var result = PlannerUtility.GetPlannerConfig(this, Connection, AccessToken); WriteObject(result); } } diff --git a/src/Commands/Planner/GetPlannerPlan.cs b/src/Commands/Planner/GetPlannerPlan.cs index cedca0801..3da55cb0e 100644 --- a/src/Commands/Planner/GetPlannerPlan.cs +++ b/src/Commands/Planner/GetPlannerPlan.cs @@ -7,7 +7,12 @@ namespace PnP.PowerShell.Commands.Planner { [Cmdlet(VerbsCommon.Get, "PnPPlannerPlan")] - [RequiredMinimalApiPermissions("Group.Read.All")] + [RequiredMinimalApiPermissions("Tasks.Read")] + [RequiredMinimalApiPermissions("Group.Read.All")] + [RequiredMinimalApiPermissions("Tasks.Read.All")] + [RequiredMinimalApiPermissions("Tasks.ReadWrite.All")] + [RequiredMinimalApiPermissions("Tasks.ReadWrite.All")] + [RequiredMinimalApiPermissions("Group.ReadWrite.All")] public class GetPlannerPlan : PnPGraphCmdlet { private const string ParameterName_BYGROUP = "By Group"; @@ -29,16 +34,16 @@ protected override void ExecuteCmdlet() { if (ParameterSetName == ParameterName_BYGROUP) { - var groupId = Group.GetGroupId(Connection, AccessToken); + var groupId = Group.GetGroupId(this, Connection, AccessToken); if (groupId != null) { if (ParameterSpecified(nameof(Identity))) { - WriteObject(Identity.GetPlanAsync(Connection, AccessToken, groupId, ResolveIdentities).GetAwaiter().GetResult()); + WriteObject(Identity.GetPlan(this, Connection, AccessToken, groupId, ResolveIdentities)); } else { - WriteObject(PlannerUtility.GetPlansAsync(Connection, AccessToken, groupId, ResolveIdentities).GetAwaiter().GetResult(), true); + WriteObject(PlannerUtility.GetPlans(this, Connection, AccessToken, groupId, ResolveIdentities), true); } } else @@ -48,7 +53,7 @@ protected override void ExecuteCmdlet() } else { - WriteObject(PlannerUtility.GetPlanAsync(Connection, AccessToken, Id, ResolveIdentities).GetAwaiter().GetResult()); + WriteObject(PlannerUtility.GetPlan(this, Connection, AccessToken, Id, ResolveIdentities)); } } } diff --git a/src/Commands/Planner/GetPlannerRosterMember.cs b/src/Commands/Planner/GetPlannerRosterMember.cs index 19d3741e8..686b5ac36 100644 --- a/src/Commands/Planner/GetPlannerRosterMember.cs +++ b/src/Commands/Planner/GetPlannerRosterMember.cs @@ -15,14 +15,14 @@ public class GetPlannerRosterMember : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var roster = Identity.GetPlannerRosterAsync(Connection, AccessToken).GetAwaiter().GetResult(); + var roster = Identity.GetPlannerRoster(this, Connection, AccessToken); if(roster == null) { throw new PSArgumentException("Provided Planner Roster could not be found", nameof(Identity)); } - PlannerUtility.GetRosterMembersAsync(Connection, AccessToken, roster.Id).GetAwaiter().GetResult(); + PlannerUtility.GetRosterMembers(this, Connection, AccessToken, roster.Id); } } } \ No newline at end of file diff --git a/src/Commands/Planner/GetPlannerRosterPlan.cs b/src/Commands/Planner/GetPlannerRosterPlan.cs index 785975f82..c71da2b81 100644 --- a/src/Commands/Planner/GetPlannerRosterPlan.cs +++ b/src/Commands/Planner/GetPlannerRosterPlan.cs @@ -8,6 +8,8 @@ namespace PnP.PowerShell.Commands.Planner { [Cmdlet(VerbsCommon.Get, "PnPPlannerRosterPlan", DefaultParameterSetName = ParameterSet_BYROSTER)] [RequiredMinimalApiPermissions("Tasks.Read")] + [RequiredMinimalApiPermissions("Tasks.ReadWrite")] + public class GetPlannerRosterPlan : PnPGraphCmdlet { private const string ParameterSet_BYUSER = "Get by user"; @@ -24,16 +26,16 @@ protected override void ExecuteCmdlet() switch (ParameterSetName) { case ParameterSet_BYUSER: - WriteObject(PlannerUtility.GetRosterPlansByUserAsync(Connection, AccessToken, User).GetAwaiter().GetResult(), true); + WriteObject(PlannerUtility.GetRosterPlansByUser(this, Connection, AccessToken, User), true); break; - + case ParameterSet_BYROSTER: - var plannerRoster = Identity.GetPlannerRosterAsync(Connection, AccessToken).GetAwaiter().GetResult(); + var plannerRoster = Identity.GetPlannerRoster(this, Connection, AccessToken); if (plannerRoster == null) { throw new PSArgumentException($"Planner Roster provided through {nameof(Identity)} could not be found", nameof(Identity)); } - WriteObject(PlannerUtility.GetRosterPlansByRosterAsync(Connection, AccessToken, plannerRoster.Id).GetAwaiter().GetResult(), true); + WriteObject(PlannerUtility.GetRosterPlansByRoster(this, Connection, AccessToken, plannerRoster.Id), true); break; } } diff --git a/src/Commands/Planner/GetPlannerTask.cs b/src/Commands/Planner/GetPlannerTask.cs index ee82bbc71..c77cb5b72 100644 --- a/src/Commands/Planner/GetPlannerTask.cs +++ b/src/Commands/Planner/GetPlannerTask.cs @@ -8,6 +8,7 @@ namespace PnP.PowerShell.Commands.Planner { [Cmdlet(VerbsCommon.Get, "PnPPlannerTask")] [RequiredMinimalApiPermissions("Group.Read.All")] + [RequiredMinimalApiPermissions("Group.ReadWrite.All")] public class GetPlannerTask : PnPGraphCmdlet { private const string ParameterSetName_BYGROUP = "By Group"; @@ -40,13 +41,13 @@ protected override void ExecuteCmdlet() { if (ParameterSetName == ParameterSetName_BYGROUP) { - var groupId = Group.GetGroupId(Connection, AccessToken); + var groupId = Group.GetGroupId(this, Connection, AccessToken); if (groupId != null) { - var planId = Plan.GetIdAsync(Connection, AccessToken, groupId).GetAwaiter().GetResult(); + var planId = Plan.GetId(this, Connection, AccessToken, groupId); if (planId != null) { - WriteObject(PlannerUtility.GetTasksAsync(Connection, AccessToken, planId, ResolveUserDisplayNames).GetAwaiter().GetResult(), true); + WriteObject(PlannerUtility.GetTasks(this, Connection, AccessToken, planId, ResolveUserDisplayNames), true); } else { @@ -60,15 +61,15 @@ protected override void ExecuteCmdlet() } else if (ParameterSetName == ParameterSetName_BYPLANID) { - WriteObject(PlannerUtility.GetTasksAsync(Connection, AccessToken, PlanId, ResolveUserDisplayNames).GetAwaiter().GetResult(), true); + WriteObject(PlannerUtility.GetTasks(this, Connection, AccessToken, PlanId, ResolveUserDisplayNames), true); } else if (ParameterSetName == ParameterSetName_BYBUCKET) { - WriteObject(PlannerUtility.GetBucketTasksAsync(Connection, AccessToken, Bucket.GetId(), ResolveUserDisplayNames).GetAwaiter().GetResult(), true); + WriteObject(PlannerUtility.GetBucketTasks(this, Connection, AccessToken, Bucket.GetId(), ResolveUserDisplayNames), true); } else if (ParameterSetName == ParameterSetName_BYTASKID) { - WriteObject(PlannerUtility.GetTaskAsync(Connection, AccessToken, TaskId, ResolveUserDisplayNames, IncludeDetails).GetAwaiter().GetResult()); + WriteObject(PlannerUtility.GetTask(this, Connection, AccessToken, TaskId, ResolveUserDisplayNames, IncludeDetails)); } } } diff --git a/src/Commands/Planner/GetPlannerUserPolicy.cs b/src/Commands/Planner/GetPlannerUserPolicy.cs index 078305557..b753c429b 100644 --- a/src/Commands/Planner/GetPlannerUserPolicy.cs +++ b/src/Commands/Planner/GetPlannerUserPolicy.cs @@ -13,7 +13,7 @@ public class GetPlannerUserPolicy : PnPGraphCmdlet public string Identity; protected override void ExecuteCmdlet() { - var result = PlannerUtility.GetPlannerUserPolicyAsync(Connection, AccessToken, Identity).GetAwaiter().GetResult(); + var result = PlannerUtility.GetPlannerUserPolicy(this, Connection, AccessToken, Identity); WriteObject(result); } } diff --git a/src/Commands/Planner/NewPlannerPlan.cs b/src/Commands/Planner/NewPlannerPlan.cs index 959fd3021..17a0d3a7c 100644 --- a/src/Commands/Planner/NewPlannerPlan.cs +++ b/src/Commands/Planner/NewPlannerPlan.cs @@ -7,7 +7,9 @@ namespace PnP.PowerShell.Commands.Planner { [Cmdlet(VerbsCommon.New, "PnPPlannerPlan")] - [RequiredMinimalApiPermissions("Group.ReadWrite.All")] + [RequiredMinimalApiPermissions("Tasks.ReadWrite")] + [RequiredMinimalApiPermissions("Tasks.ReadWrite.All")] + [RequiredMinimalApiPermissions("Group.ReadWrite.All")] public class NewPlannerPlan : PnPGraphCmdlet { [Parameter(Mandatory = true, HelpMessage = "Specify the group id of the plans to retrieve.")] @@ -17,10 +19,10 @@ public class NewPlannerPlan : PnPGraphCmdlet public string Title; protected override void ExecuteCmdlet() { - var groupId = Group.GetGroupId(Connection, AccessToken); + var groupId = Group.GetGroupId(this, Connection, AccessToken); if (groupId != null) { - WriteObject(PlannerUtility.CreatePlanAsync(Connection, AccessToken, groupId, Title).GetAwaiter().GetResult()); + WriteObject(PlannerUtility.CreatePlan(this, Connection, AccessToken, groupId, Title)); } else { diff --git a/src/Commands/Planner/RemovePlannerBucket.cs b/src/Commands/Planner/RemovePlannerBucket.cs index 6c5ab9bf6..7220384b9 100644 --- a/src/Commands/Planner/RemovePlannerBucket.cs +++ b/src/Commands/Planner/RemovePlannerBucket.cs @@ -28,19 +28,19 @@ protected override void ExecuteCmdlet() { if (ParameterSetName == ParameterName_BYNAME) { - var groupId = Group.GetGroupId(Connection, AccessToken); + var groupId = Group.GetGroupId(this, Connection, AccessToken); if (groupId != null) { - var planId = Plan.GetIdAsync(Connection, AccessToken, groupId).GetAwaiter().GetResult(); + var planId = Plan.GetId(this, Connection, AccessToken, groupId); if (planId != null) { - var bucket = Identity.GetBucket(Connection, AccessToken, planId); + var bucket = Identity.GetBucket(this, Connection, AccessToken, planId); if (bucket != null) { if (ShouldProcess($"Remove bucket '{bucket.Name}'")) { - PlannerUtility.RemoveBucketAsync(Connection, AccessToken, bucket.Id).GetAwaiter().GetResult(); + PlannerUtility.RemoveBucket(this, Connection, AccessToken, bucket.Id); } } else @@ -60,12 +60,12 @@ protected override void ExecuteCmdlet() } else if (ParameterSetName == ParameterName_BYBUCKETID) { - var bucket = Identity.GetBucket(Connection, AccessToken, BucketId); + var bucket = Identity.GetBucket(this, Connection, AccessToken, BucketId); if (bucket != null) { if (ShouldProcess($"Remove bucket '{bucket.Name}'")) { - PlannerUtility.RemoveBucketAsync(Connection, AccessToken, BucketId).GetAwaiter().GetResult(); + PlannerUtility.RemoveBucket(this, Connection, AccessToken, BucketId); } } else diff --git a/src/Commands/Planner/RemovePlannerPlan.cs b/src/Commands/Planner/RemovePlannerPlan.cs index b12e1fc62..1332cf453 100644 --- a/src/Commands/Planner/RemovePlannerPlan.cs +++ b/src/Commands/Planner/RemovePlannerPlan.cs @@ -1,5 +1,4 @@ using System.Management.Automation; -using Microsoft.Graph; using PnP.PowerShell.Commands.Attributes; using PnP.PowerShell.Commands.Base; using PnP.PowerShell.Commands.Base.PipeBinds; @@ -8,6 +7,8 @@ namespace PnP.PowerShell.Commands.Planner { [Cmdlet(VerbsCommon.Remove, "PnPPlannerPlan", SupportsShouldProcess = true)] + [RequiredMinimalApiPermissions("Tasks.ReadWrite")] + [RequiredMinimalApiPermissions("Tasks.ReadWrite.All")] [RequiredMinimalApiPermissions("Group.ReadWrite.All")] public class RemovePlannerPlan : PnPGraphCmdlet { @@ -19,15 +20,15 @@ public class RemovePlannerPlan : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Group.GetGroupId(Connection, AccessToken); + var groupId = Group.GetGroupId(this, Connection, AccessToken); if (groupId != null) { - var planId = Identity.GetIdAsync(Connection, AccessToken, groupId).GetAwaiter().GetResult(); + var planId = Identity.GetId(this, Connection, AccessToken, groupId); if (!string.IsNullOrEmpty(planId)) { if (ShouldProcess($"Delete plan with id {planId}")) { - PlannerUtility.DeletePlanAsync(Connection, AccessToken, planId).GetAwaiter().GetResult(); + PlannerUtility.DeletePlan(this, Connection, AccessToken, planId); } } else diff --git a/src/Commands/Planner/RemovePlannerRoster.cs b/src/Commands/Planner/RemovePlannerRoster.cs index 45cf1d816..08b955d99 100644 --- a/src/Commands/Planner/RemovePlannerRoster.cs +++ b/src/Commands/Planner/RemovePlannerRoster.cs @@ -15,14 +15,14 @@ public class RemovePlannerRoster : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var roster = Identity.GetPlannerRosterAsync(Connection, AccessToken).GetAwaiter().GetResult(); + var roster = Identity.GetPlannerRoster(this, Connection, AccessToken); if(roster == null) { throw new PSArgumentException("Provided Planner Roster could not be found", nameof(Identity)); } - PlannerUtility.DeleteRosterAsync(Connection, AccessToken, roster.Id).GetAwaiter().GetResult(); + PlannerUtility.DeleteRoster(this, Connection, AccessToken, roster.Id); } } } \ No newline at end of file diff --git a/src/Commands/Planner/RemovePlannerRosterMember.cs b/src/Commands/Planner/RemovePlannerRosterMember.cs index 35c5fa6e6..3e6140ca1 100644 --- a/src/Commands/Planner/RemovePlannerRosterMember.cs +++ b/src/Commands/Planner/RemovePlannerRosterMember.cs @@ -18,14 +18,14 @@ public class RemovePlannerRosterMember : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var roster = Identity.GetPlannerRosterAsync(Connection, AccessToken).GetAwaiter().GetResult(); + var roster = Identity.GetPlannerRoster(this, Connection, AccessToken); if(roster == null) { throw new PSArgumentException("Provided Planner Roster could not be found", nameof(Identity)); } - PlannerUtility.RemoveRosterMemberAsync(Connection, AccessToken, roster.Id, User).GetAwaiter().GetResult(); + PlannerUtility.RemoveRosterMember(this, Connection, AccessToken, roster.Id, User); } } } \ No newline at end of file diff --git a/src/Commands/Planner/RemovePlannerTask.cs b/src/Commands/Planner/RemovePlannerTask.cs index c3216161b..1825176e9 100644 --- a/src/Commands/Planner/RemovePlannerTask.cs +++ b/src/Commands/Planner/RemovePlannerTask.cs @@ -15,7 +15,7 @@ public class RemovePlannerTask : PnPGraphCmdlet protected override void ExecuteCmdlet() { - PlannerUtility.DeleteTaskAsync(Connection, AccessToken, Task.Id).GetAwaiter().GetResult(); + PlannerUtility.DeleteTask(this, Connection, AccessToken, Task.Id); } } } \ No newline at end of file diff --git a/src/Commands/Planner/SetPlannerBucket.cs b/src/Commands/Planner/SetPlannerBucket.cs index 7c6a35a9a..1e3e0d22e 100644 --- a/src/Commands/Planner/SetPlannerBucket.cs +++ b/src/Commands/Planner/SetPlannerBucket.cs @@ -33,17 +33,17 @@ protected override void ExecuteCmdlet() { if (ParameterSetName == ParameterName_BYGROUP) { - var groupId = Group.GetGroupId(Connection, AccessToken); + var groupId = Group.GetGroupId(this, Connection, AccessToken); if (groupId != null) { - var planId = Plan.GetIdAsync(Connection, AccessToken, groupId).GetAwaiter().GetResult(); + var planId = Plan.GetId(this, Connection, AccessToken, groupId); if (planId != null) { - var bucket = Bucket.GetBucket(Connection, AccessToken, planId); + var bucket = Bucket.GetBucket(this, Connection, AccessToken, planId); if (bucket != null) { - WriteObject(PlannerUtility.UpdateBucketAsync(Connection, AccessToken, Name, bucket.Id).GetAwaiter().GetResult()); + WriteObject(PlannerUtility.UpdateBucket(this, Connection, AccessToken, Name, bucket.Id)); } else { @@ -62,10 +62,10 @@ protected override void ExecuteCmdlet() } else { - var bucket = Bucket.GetBucket(Connection, AccessToken, PlanId); + var bucket = Bucket.GetBucket(this, Connection, AccessToken, PlanId); if (bucket != null) { - WriteObject(PlannerUtility.UpdateBucketAsync(Connection, AccessToken, Name, bucket.Id).GetAwaiter().GetResult()); + WriteObject(PlannerUtility.UpdateBucket(this, Connection, AccessToken, Name, bucket.Id)); } else { diff --git a/src/Commands/Planner/SetPlannerConfiguration.cs b/src/Commands/Planner/SetPlannerConfiguration.cs index 9c36e2b56..1c36f49c7 100644 --- a/src/Commands/Planner/SetPlannerConfiguration.cs +++ b/src/Commands/Planner/SetPlannerConfiguration.cs @@ -29,7 +29,7 @@ public class SetPlannerConfiguration : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var result = PlannerUtility.SetPlannerConfigAsync(Connection, AccessToken, IsPlannerAllowed, AllowCalendarSharing, AllowTenantMoveWithDataLoss, AllowTenantMoveWithDataMigration, AllowRosterCreation, AllowPlannerMobilePushNotifications).GetAwaiter().GetResult(); + var result = PlannerUtility.SetPlannerConfig(this, Connection, AccessToken, IsPlannerAllowed, AllowCalendarSharing, AllowTenantMoveWithDataLoss, AllowTenantMoveWithDataMigration, AllowRosterCreation, AllowPlannerMobilePushNotifications); WriteObject(result); } } diff --git a/src/Commands/Planner/SetPlannerPlan.cs b/src/Commands/Planner/SetPlannerPlan.cs index bf8c69efc..6a6cc1981 100644 --- a/src/Commands/Planner/SetPlannerPlan.cs +++ b/src/Commands/Planner/SetPlannerPlan.cs @@ -7,6 +7,8 @@ namespace PnP.PowerShell.Commands.Graph { [Cmdlet(VerbsCommon.Set, "PnPPlannerPlan")] + [RequiredMinimalApiPermissions("Tasks.ReadWrite")] + [RequiredMinimalApiPermissions("Tasks.ReadWrite.All")] [RequiredMinimalApiPermissions("Group.ReadWrite.All")] public class SetPlannerPlan : PnPGraphCmdlet { @@ -29,13 +31,13 @@ protected override void ExecuteCmdlet() { if (ParameterSetName == ParameterName_BYGROUP) { - var groupId = Group.GetGroupId(Connection, AccessToken); + var groupId = Group.GetGroupId(this, Connection, AccessToken); if (groupId != null) { - var plan = Plan.GetPlanAsync(Connection, AccessToken, groupId, false).GetAwaiter().GetResult(); + var plan = Plan.GetPlan(this, Connection, AccessToken, groupId, false); if (plan != null) { - WriteObject(PlannerUtility.UpdatePlanAsync(Connection, AccessToken, plan, Title).GetAwaiter().GetResult()); + WriteObject(PlannerUtility.UpdatePlan(this, Connection, AccessToken, plan, Title)); } else { @@ -49,10 +51,10 @@ protected override void ExecuteCmdlet() } else { - var plan = PlannerUtility.GetPlanAsync(Connection, AccessToken, PlanId, false).GetAwaiter().GetResult(); + var plan = PlannerUtility.GetPlan(this, Connection, AccessToken, PlanId, false); if (plan != null) { - WriteObject(PlannerUtility.UpdatePlanAsync(Connection, AccessToken, plan, Title).GetAwaiter().GetResult()); + WriteObject(PlannerUtility.UpdatePlan(this, Connection, AccessToken, plan, Title)); } else { diff --git a/src/Commands/Planner/SetPlannerTask.cs b/src/Commands/Planner/SetPlannerTask.cs index e83fa65d2..8834186b9 100644 --- a/src/Commands/Planner/SetPlannerTask.cs +++ b/src/Commands/Planner/SetPlannerTask.cs @@ -43,7 +43,7 @@ public class SetPlannerTask : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var existingTask = PlannerUtility.GetTaskAsync(Connection, AccessToken, TaskId, false, false).GetAwaiter().GetResult(); + var existingTask = PlannerUtility.GetTask(this, Connection, AccessToken, TaskId, false, false); if (existingTask != null) { var plannerTask = new PlannerTask(); @@ -53,7 +53,7 @@ protected override void ExecuteCmdlet() } if (ParameterSpecified(nameof(Bucket))) { - var bucket = Bucket.GetBucket(Connection, AccessToken, existingTask.PlanId); + var bucket = Bucket.GetBucket(this, Connection, AccessToken, existingTask.PlanId); if (bucket != null) { plannerTask.BucketId = bucket.Id; @@ -90,7 +90,7 @@ protected override void ExecuteCmdlet() var chunks = BatchUtility.Chunk(AssignedTo, 20); foreach (var chunk in chunks) { - var userIds = BatchUtility.GetPropertyBatchedAsync(Connection, AccessToken, chunk.ToArray(), "/users/{0}", "id").GetAwaiter().GetResult(); + var userIds = BatchUtility.GetPropertyBatched(this, Connection, AccessToken, chunk.ToArray(), "/users/{0}", "id"); foreach (var userId in userIds) { plannerTask.Assignments.Add(userId.Value, new TaskAssignment()); @@ -106,12 +106,12 @@ protected override void ExecuteCmdlet() } - PlannerUtility.UpdateTaskAsync(Connection, AccessToken, existingTask, plannerTask).GetAwaiter().GetResult(); + PlannerUtility.UpdateTask(this, Connection, AccessToken, existingTask, plannerTask); if (ParameterSpecified(nameof(Description))) { - var existingTaskDetails = PlannerUtility.GetTaskDetailsAsync(Connection, AccessToken, TaskId, false).GetAwaiter().GetResult(); - PlannerUtility.UpdateTaskDetailsAsync(Connection, AccessToken, existingTaskDetails, Description).GetAwaiter().GetResult(); + var existingTaskDetails = PlannerUtility.GetTaskDetails(this, Connection, AccessToken, TaskId, false); + PlannerUtility.UpdateTaskDetails(this, Connection, AccessToken, existingTaskDetails, Description); } } else diff --git a/src/Commands/Planner/SetPlannerUserPolicy.cs b/src/Commands/Planner/SetPlannerUserPolicy.cs index fb2062bab..61717caf8 100644 --- a/src/Commands/Planner/SetPlannerUserPolicy.cs +++ b/src/Commands/Planner/SetPlannerUserPolicy.cs @@ -17,7 +17,7 @@ public class SetPlannerUserPolicy : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var result = PlannerUtility.SetPlannerUserPolicyAsync(Connection, AccessToken, Identity, BlockDeleteTasksNotCreatedBySelf).GetAwaiter().GetResult(); + var result = PlannerUtility.SetPlannerUserPolicy(this, Connection, AccessToken, Identity, BlockDeleteTasksNotCreatedBySelf); WriteObject(result); } } diff --git a/src/Commands/PnP.PowerShell.csproj b/src/Commands/PnP.PowerShell.csproj index 7328b06d2..f4cf286bf 100644 --- a/src/Commands/PnP.PowerShell.csproj +++ b/src/Commands/PnP.PowerShell.csproj @@ -56,30 +56,31 @@ - + + - - + + - - + + - - + + - - + + - + - + diff --git a/src/Commands/PowerPlatform/Environment/GetPowerPlatformCustomConnector.cs b/src/Commands/PowerPlatform/Environment/GetPowerPlatformCustomConnector.cs index 0f079ea80..a997070d2 100644 --- a/src/Commands/PowerPlatform/Environment/GetPowerPlatformCustomConnector.cs +++ b/src/Commands/PowerPlatform/Environment/GetPowerPlatformCustomConnector.cs @@ -35,7 +35,7 @@ protected override void ExecuteCmdlet() } else { - var environments = GraphHelper.GetResultCollectionAsync(Connection, baseUrl + "/providers/Microsoft.ProcessSimple/environments?api-version=2016-11-01", AccessToken).GetAwaiter().GetResult(); + var environments = GraphHelper.GetResultCollection(this, Connection, baseUrl + "/providers/Microsoft.ProcessSimple/environments?api-version=2016-11-01", AccessToken); environmentName = environments.FirstOrDefault(e => e.Properties.IsDefault.HasValue && e.Properties.IsDefault == true)?.Name; if (string.IsNullOrEmpty(environmentName)) @@ -52,14 +52,14 @@ protected override void ExecuteCmdlet() WriteVerbose($"Retrieving specific Custom Connector with the provided name '{appName}' within the environment '{environmentName}'"); - var result = GraphHelper.GetAsync(Connection, $"{powerAppsUrl}/providers/Microsoft.PowerApps{(AsAdmin ? "/scopes/admin/environments/" + environmentName : "")}/apis/{appName}?api-version=2016-11-01&$filter=environment eq '{environmentName}' and isCustomApi eq 'True'", AccessToken).GetAwaiter().GetResult(); + var result = GraphHelper.Get(this, Connection, $"{powerAppsUrl}/providers/Microsoft.PowerApps{(AsAdmin ? "/scopes/admin/environments/" + environmentName : "")}/apis/{appName}?api-version=2016-11-01&$filter=environment eq '{environmentName}' and isCustomApi eq 'True'", PowerAppsServiceAccessToken); WriteObject(result, false); } else { WriteVerbose($"Retrieving all Connectors within environment '{environmentName}'"); - var connectors = GraphHelper.GetResultCollectionAsync(Connection, $"{powerAppsUrl}/providers/Microsoft.PowerApps/apis?api-version=2016-11-01&$filter=environment eq '{environmentName}' and isCustomApi eq 'True'", AccessToken).GetAwaiter().GetResult(); + var connectors = GraphHelper.GetResultCollection(this, Connection, $"{powerAppsUrl}/providers/Microsoft.PowerApps/apis?api-version=2016-11-01&$filter=environment eq '{environmentName}' and isCustomApi eq 'True'", PowerAppsServiceAccessToken); WriteObject(connectors, true); } } diff --git a/src/Commands/PowerPlatform/Environment/GetPowerPlatformEnvironment.cs b/src/Commands/PowerPlatform/Environment/GetPowerPlatformEnvironment.cs index 0bdb71a88..be501c4f3 100644 --- a/src/Commands/PowerPlatform/Environment/GetPowerPlatformEnvironment.cs +++ b/src/Commands/PowerPlatform/Environment/GetPowerPlatformEnvironment.cs @@ -23,7 +23,7 @@ public class GetPowerPlatformEnvironment : PnPAzureManagementApiCmdlet protected override void ExecuteCmdlet() { string baseUrl = PowerPlatformUtility.GetPowerAutomateEndpoint(Connection.AzureEnvironment); - var environments = GraphHelper.GetResultCollectionAsync(Connection, baseUrl + "/providers/Microsoft.ProcessSimple/environments?api-version=2016-11-01", AccessToken).GetAwaiter().GetResult(); + var environments = GraphHelper.GetResultCollection(this, Connection, baseUrl + "/providers/Microsoft.ProcessSimple/environments?api-version=2016-11-01", AccessToken); if(ParameterSpecified(nameof(IsDefault)) && IsDefault.ToBool()) { diff --git a/src/Commands/PowerPlatform/Environment/GetPowerPlatformSolution.cs b/src/Commands/PowerPlatform/Environment/GetPowerPlatformSolution.cs index 4bf9e7a98..d4f25a302 100644 --- a/src/Commands/PowerPlatform/Environment/GetPowerPlatformSolution.cs +++ b/src/Commands/PowerPlatform/Environment/GetPowerPlatformSolution.cs @@ -23,7 +23,7 @@ protected override void ExecuteCmdlet() string environmentName = null; string dynamicsScopeUrl = null; string baseUrl = PowerPlatformUtility.GetPowerAutomateEndpoint(Connection.AzureEnvironment); - var environments = GraphHelper.GetResultCollectionAsync(Connection, $"{baseUrl}/providers/Microsoft.ProcessSimple/environments?api-version=2016-11-01", AccessToken).GetAwaiter().GetResult(); + var environments = GraphHelper.GetResultCollection(this, Connection, $"{baseUrl}/providers/Microsoft.ProcessSimple/environments?api-version=2016-11-01", AccessToken); if (ParameterSpecified(nameof(Environment))) { environmentName = Environment.GetName().ToLower(); @@ -42,7 +42,7 @@ protected override void ExecuteCmdlet() WriteVerbose($"Using default environment as retrieved '{environmentName}'"); } - string accessTokenForGettingSolutions = TokenHandler.GetAccessTokenforPowerPlatformSolutions(this, Connection, dynamicsScopeUrl); + string accessTokenForGettingSolutions = TokenHandler.GetAccessToken(this, $"{dynamicsScopeUrl}/.default", Connection); if (ParameterSpecified(nameof(Name))) { @@ -51,14 +51,14 @@ protected override void ExecuteCmdlet() WriteVerbose($"Retrieving specific solution with the provided name '{solutionName}' within the environment '{environmentName}'"); var requestUrl = dynamicsScopeUrl + "/api/data/v9.0/solutions?$filter=isvisible eq true and friendlyname eq '" + solutionName + "'&$expand=publisherid&api-version=9.1"; - var solution = GraphHelper.GetResultCollectionAsync(Connection, requestUrl, accessTokenForGettingSolutions).GetAwaiter().GetResult(); + var solution = GraphHelper.GetResultCollection(this, Connection, requestUrl, accessTokenForGettingSolutions); WriteObject(solution, false); } else { WriteVerbose($"Retrieving all Solutions within environment '{environmentName}'"); var requestUrl = dynamicsScopeUrl + "/api/data/v9.0/solutions?$filter=isvisible eq true&$expand=publisherid($select=friendlyname)&api-version=9.1"; - var solutions = GraphHelper.GetResultCollectionAsync(Connection, requestUrl, accessTokenForGettingSolutions).GetAwaiter().GetResult(); + var solutions = GraphHelper.GetResultCollection(this, Connection, requestUrl, accessTokenForGettingSolutions); WriteObject(solutions, true); } } diff --git a/src/Commands/PowerPlatform/PowerApps/ExportPowerApp.cs b/src/Commands/PowerPlatform/PowerApps/ExportPowerApp.cs index 54e5e0746..d1a4b38a7 100644 --- a/src/Commands/PowerPlatform/PowerApps/ExportPowerApp.cs +++ b/src/Commands/PowerPlatform/PowerApps/ExportPowerApp.cs @@ -69,7 +69,7 @@ protected override void ExecuteCmdlet() var environmentName = Environment.GetName(); var appName = Identity.GetName(); - var wrapper = PowerAppsUtility.GetWrapper(Connection.HttpClient, environmentName, AccessToken, appName, Connection.AzureEnvironment).GetAwaiter().GetResult(); + var wrapper = PowerAppsUtility.GetWrapper(Connection.HttpClient, environmentName, AccessToken, appName, Connection.AzureEnvironment); if (wrapper.Status == Model.PowerPlatform.PowerApp.Enums.PowerAppExportStatus.Succeeded) { diff --git a/src/Commands/PowerPlatform/PowerApps/GetPowerApp.cs b/src/Commands/PowerPlatform/PowerApps/GetPowerApp.cs index 5ea7b5f2f..868757067 100644 --- a/src/Commands/PowerPlatform/PowerApps/GetPowerApp.cs +++ b/src/Commands/PowerPlatform/PowerApps/GetPowerApp.cs @@ -34,7 +34,7 @@ protected override void ExecuteCmdlet() else { string baseUrl = PowerPlatformUtility.GetPowerAutomateEndpoint(Connection.AzureEnvironment); - var environments = GraphHelper.GetResultCollectionAsync(Connection, baseUrl + "/providers/Microsoft.ProcessSimple/environments?api-version=2016-11-01", AccessToken).GetAwaiter().GetResult(); + var environments = GraphHelper.GetResultCollection(this, Connection, baseUrl + "/providers/Microsoft.ProcessSimple/environments?api-version=2016-11-01", AccessToken); environmentName = environments.FirstOrDefault(e => e.Properties.IsDefault.HasValue && e.Properties.IsDefault == true)?.Name; if(string.IsNullOrEmpty(environmentName)) @@ -51,7 +51,7 @@ protected override void ExecuteCmdlet() WriteVerbose($"Retrieving specific PowerApp with the provided name '{appName}' within the environment '{environmentName}'"); - var result = GraphHelper.GetAsync(Connection, $"{powerAppsUrl}/providers/Microsoft.PowerApps{(AsAdmin ? "/scopes/admin/environments/" + environmentName : "")}/apps/{appName}?api-version=2016-11-01", AccessToken).GetAwaiter().GetResult(); + var result = GraphHelper.Get(this, Connection, $"{powerAppsUrl}/providers/Microsoft.PowerApps{(AsAdmin ? "/scopes/admin/environments/" + environmentName : "")}/apps/{appName}?api-version=2016-11-01", PowerAppsServiceAccessToken); WriteObject(result, false); } @@ -59,7 +59,7 @@ protected override void ExecuteCmdlet() { WriteVerbose($"Retrieving all PowerApps within environment '{environmentName}'"); - var apps = GraphHelper.GetResultCollectionAsync(Connection, $"{powerAppsUrl}/providers/Microsoft.PowerApps/apps?api-version=2016-11-01&$filter=environment eq '{environmentName}'", AccessToken).GetAwaiter().GetResult(); + var apps = GraphHelper.GetResultCollection(this, Connection, $"{powerAppsUrl}/providers/Microsoft.PowerApps/apps?api-version=2016-11-01&$filter=environment eq '{environmentName}'", PowerAppsServiceAccessToken); WriteObject(apps, true); } } diff --git a/src/Commands/PowerPlatform/PowerAutomate/AddFlowOwner.cs b/src/Commands/PowerPlatform/PowerAutomate/AddFlowOwner.cs index 000fc2b9d..648d9b382 100644 --- a/src/Commands/PowerPlatform/PowerAutomate/AddFlowOwner.cs +++ b/src/Commands/PowerPlatform/PowerAutomate/AddFlowOwner.cs @@ -83,7 +83,7 @@ protected override void ExecuteCmdlet() WriteVerbose($"Assigning user {Role} permissions to flow {flowName} in environment {environmentName}"); string baseUrl = PowerPlatformUtility.GetPowerAutomateEndpoint(Connection.AzureEnvironment); - RestHelper.PostAsync(Connection.HttpClient, $"{baseUrl}/providers/Microsoft.ProcessSimple{(AsAdmin ? "/scopes/admin" : "")}/environments/{environmentName}/flows/{flowName}/modifyPermissions?api-version=2016-11-01", AccessToken, payload).GetAwaiter().GetResult(); + RestHelper.Post(Connection.HttpClient, $"{baseUrl}/providers/Microsoft.ProcessSimple{(AsAdmin ? "/scopes/admin" : "")}/environments/{environmentName}/flows/{flowName}/modifyPermissions?api-version=2016-11-01", AccessToken, payload); } } } diff --git a/src/Commands/PowerPlatform/PowerAutomate/DisableFlow.cs b/src/Commands/PowerPlatform/PowerAutomate/DisableFlow.cs index 45b1ea769..aec590f24 100644 --- a/src/Commands/PowerPlatform/PowerAutomate/DisableFlow.cs +++ b/src/Commands/PowerPlatform/PowerAutomate/DisableFlow.cs @@ -23,7 +23,7 @@ protected override void ExecuteCmdlet() var environmentName = Environment.GetName(); var flowName = Identity.GetName(); string baseUrl = PowerPlatformUtility.GetPowerAutomateEndpoint(Connection.AzureEnvironment); - RestHelper.PostAsync(Connection.HttpClient, $"{baseUrl}/providers/Microsoft.ProcessSimple{(AsAdmin ? "/scopes/admin" : "")}/environments/{environmentName}/flows/{flowName}/stop?api-version=2016-11-01", AccessToken).GetAwaiter().GetResult(); + RestHelper.Post(Connection.HttpClient, $"{baseUrl}/providers/Microsoft.ProcessSimple{(AsAdmin ? "/scopes/admin" : "")}/environments/{environmentName}/flows/{flowName}/stop?api-version=2016-11-01", AccessToken); } } } \ No newline at end of file diff --git a/src/Commands/PowerPlatform/PowerAutomate/EnableFlow.cs b/src/Commands/PowerPlatform/PowerAutomate/EnableFlow.cs index 02ede1d49..da8cf2300 100644 --- a/src/Commands/PowerPlatform/PowerAutomate/EnableFlow.cs +++ b/src/Commands/PowerPlatform/PowerAutomate/EnableFlow.cs @@ -23,7 +23,7 @@ protected override void ExecuteCmdlet() var environmentName = Environment.GetName(); var flowName = Identity.GetName(); string baseUrl = PowerPlatformUtility.GetPowerAutomateEndpoint(Connection.AzureEnvironment); - RestHelper.PostAsync(Connection.HttpClient, $"{baseUrl}/providers/Microsoft.ProcessSimple{(AsAdmin ? "/scopes/admin" : "")}/environments/{environmentName}/flows/{flowName}/start?api-version=2016-11-01", AccessToken).GetAwaiter().GetResult(); + RestHelper.Post(Connection.HttpClient, $"{baseUrl}/providers/Microsoft.ProcessSimple{(AsAdmin ? "/scopes/admin" : "")}/environments/{environmentName}/flows/{flowName}/start?api-version=2016-11-01", AccessToken); } } } \ No newline at end of file diff --git a/src/Commands/PowerPlatform/PowerAutomate/ExportFlow.cs b/src/Commands/PowerPlatform/PowerAutomate/ExportFlow.cs index bf8085f3c..73a08cdfd 100644 --- a/src/Commands/PowerPlatform/PowerAutomate/ExportFlow.cs +++ b/src/Commands/PowerPlatform/PowerAutomate/ExportFlow.cs @@ -78,7 +78,7 @@ protected override void ExecuteCmdlet() } }; string baseUrl = PowerPlatformUtility.GetBapEndpoint(Connection.AzureEnvironment); - var wrapper = RestHelper.PostAsync(Connection.HttpClient, $"{baseUrl}/providers/Microsoft.BusinessAppPlatform/environments/{environmentName}/listPackageResources?api-version=2016-11-01", AccessToken, payload: postData).GetAwaiter().GetResult(); + var wrapper = RestHelper.Post(Connection.HttpClient, $"{baseUrl}/providers/Microsoft.BusinessAppPlatform/environments/{environmentName}/listPackageResources?api-version=2016-11-01", AccessToken, payload: postData); if (wrapper.Status == Model.PowerPlatform.PowerAutomate.Enums.FlowExportStatus.Succeeded) { @@ -111,7 +111,7 @@ protected override void ExecuteCmdlet() resources = wrapper.Resources }; - var resultElement = RestHelper.PostAsync(Connection.HttpClient, $"{baseUrl}/providers/Microsoft.BusinessAppPlatform/environments/{environmentName}/exportPackage?api-version=2016-11-01", AccessToken, payload: exportPostData).GetAwaiter().GetResult(); + var resultElement = RestHelper.Post(Connection.HttpClient, $"{baseUrl}/providers/Microsoft.BusinessAppPlatform/environments/{environmentName}/exportPackage?api-version=2016-11-01", AccessToken, payload: exportPostData); if (resultElement.TryGetProperty("status", out JsonElement statusElement)) { if (statusElement.GetString() == "Succeeded") @@ -164,7 +164,7 @@ protected override void ExecuteCmdlet() else { string baseUrl = PowerPlatformUtility.GetPowerAutomateEndpoint(Connection.AzureEnvironment); - var json = RestHelper.PostAsync(Connection.HttpClient, $"{baseUrl}/providers/Microsoft.ProcessSimple/environments/{environmentName}/flows/{flowName}/exportToARMTemplate?api-version=2016-11-01", AccessToken).GetAwaiter().GetResult(); + var json = RestHelper.Post(Connection.HttpClient, $"{baseUrl}/providers/Microsoft.ProcessSimple/environments/{environmentName}/flows/{flowName}/exportToARMTemplate?api-version=2016-11-01", AccessToken); WriteObject(json); } } diff --git a/src/Commands/PowerPlatform/PowerAutomate/GetFlow.cs b/src/Commands/PowerPlatform/PowerAutomate/GetFlow.cs index d6e664f20..9e53b76f0 100644 --- a/src/Commands/PowerPlatform/PowerAutomate/GetFlow.cs +++ b/src/Commands/PowerPlatform/PowerAutomate/GetFlow.cs @@ -41,7 +41,7 @@ protected override void ExecuteCmdlet() } else { - var environments = GraphHelper.GetResultCollectionAsync(Connection, baseUrl + "/providers/Microsoft.ProcessSimple/environments?api-version=2016-11-01", AccessToken).GetAwaiter().GetResult(); + var environments = GraphHelper.GetResultCollection(this, Connection, baseUrl + "/providers/Microsoft.ProcessSimple/environments?api-version=2016-11-01", AccessToken); environmentName = environments.FirstOrDefault(e => e.Properties.IsDefault.HasValue && e.Properties.IsDefault == true)?.Name; if(string.IsNullOrEmpty(environmentName)) @@ -58,7 +58,7 @@ protected override void ExecuteCmdlet() WriteVerbose($"Retrieving specific Power Automate Flow with the provided name '{flowName}' within the environment '{environmentName}'"); - var result = GraphHelper.GetAsync(Connection, baseUrl + $"/providers/Microsoft.ProcessSimple{(AsAdmin ? "/scopes/admin" : "")}/environments/{environmentName}/flows/{flowName}?api-version=2016-11-01", AccessToken).GetAwaiter().GetResult(); + var result = GraphHelper.Get(this, Connection, baseUrl + $"/providers/Microsoft.ProcessSimple{(AsAdmin ? "/scopes/admin" : "")}/environments/{environmentName}/flows/{flowName}?api-version=2016-11-01", AccessToken); WriteObject(result, false); } else @@ -81,7 +81,9 @@ protected override void ExecuteCmdlet() WriteVerbose($"Retrieving all Power Automate Flows within environment '{environmentName}'{(filter != null ? $" with filter '{filter}'" : "")}"); - var flows = GraphHelper.GetResultCollectionAsync(Connection, baseUrl + $"/providers/Microsoft.ProcessSimple{(AsAdmin ? "/scopes/admin" : "")}/environments/{environmentName}/flows?api-version=2016-11-01{(filter != null ? $"&$filter={filter}" : "")}", AccessToken).GetAwaiter().GetResult(); + var flowUrl = $"{baseUrl}/providers/Microsoft.ProcessSimple{(AsAdmin ? "/scopes/admin" : "")}/environments/{environmentName}/{(AsAdmin ? "v2" : "")}/flows?api-version=2016-11-01{(filter != null ? $"&$filter={filter}" : "")}"; + var flows = GraphHelper.GetResultCollection(this, Connection, flowUrl, AccessToken); + WriteObject(flows, true); } diff --git a/src/Commands/PowerPlatform/PowerAutomate/GetFlowOwner.cs b/src/Commands/PowerPlatform/PowerAutomate/GetFlowOwner.cs index 49052bb67..ab68e25d4 100644 --- a/src/Commands/PowerPlatform/PowerAutomate/GetFlowOwner.cs +++ b/src/Commands/PowerPlatform/PowerAutomate/GetFlowOwner.cs @@ -34,7 +34,7 @@ protected override void ExecuteCmdlet() } string baseUrl = PowerPlatformUtility.GetPowerAutomateEndpoint(Connection.AzureEnvironment); - var flowOwners = GraphHelper.GetResultCollectionAsync(Connection, $"{baseUrl}/providers/Microsoft.ProcessSimple{(AsAdmin ? "/scopes/admin" : "")}/environments/{environmentName}/flows/{flowName}/permissions?api-version=2016-11-01", AccessToken).GetAwaiter().GetResult(); + var flowOwners = GraphHelper.GetResultCollection(this, Connection, $"{baseUrl}/providers/Microsoft.ProcessSimple{(AsAdmin ? "/scopes/admin" : "")}/environments/{environmentName}/flows/{flowName}/permissions?api-version=2016-11-01", AccessToken); WriteObject(flowOwners, true); } } diff --git a/src/Commands/PowerPlatform/PowerAutomate/GetFlowRun.cs b/src/Commands/PowerPlatform/PowerAutomate/GetFlowRun.cs index d499a9682..98a5caab1 100644 --- a/src/Commands/PowerPlatform/PowerAutomate/GetFlowRun.cs +++ b/src/Commands/PowerPlatform/PowerAutomate/GetFlowRun.cs @@ -37,12 +37,12 @@ protected override void ExecuteCmdlet() if (ParameterSpecified(nameof(Identity))) { var flowRunName = Identity.GetName(); - var flowRun = GraphHelper.GetAsync(Connection, $"{baseUrl}/providers/Microsoft.ProcessSimple/environments/{environmentName}/flows/{flowName}/runs/{flowRunName}?api-version=2016-11-01", AccessToken).GetAwaiter().GetResult(); + var flowRun = GraphHelper.Get(this, Connection, $"{baseUrl}/providers/Microsoft.ProcessSimple/environments/{environmentName}/flows/{flowName}/runs/{flowRunName}?api-version=2016-11-01", AccessToken); WriteObject(flowRun, false); } else { - var flowRuns = GraphHelper.GetResultCollectionAsync(Connection, $"{baseUrl}/providers/Microsoft.ProcessSimple/environments/{environmentName}/flows/{flowName}/runs?api-version=2016-11-01", AccessToken).GetAwaiter().GetResult(); + var flowRuns = GraphHelper.GetResultCollection(this, Connection, $"{baseUrl}/providers/Microsoft.ProcessSimple/environments/{environmentName}/flows/{flowName}/runs?api-version=2016-11-01", AccessToken); WriteObject(flowRuns, true); } } diff --git a/src/Commands/PowerPlatform/PowerAutomate/RemoveFlow.cs b/src/Commands/PowerPlatform/PowerAutomate/RemoveFlow.cs index f54bb3530..c02b4e9ac 100644 --- a/src/Commands/PowerPlatform/PowerAutomate/RemoveFlow.cs +++ b/src/Commands/PowerPlatform/PowerAutomate/RemoveFlow.cs @@ -40,10 +40,10 @@ protected override void ExecuteCmdlet() { // Had to add this because DELETE doesn't throw error if invalid Flow Id or Name is provided WriteVerbose($"Retrieving Flow with name {flowName} in environment ${environmentName}"); - var result = GraphHelper.GetAsync(Connection, $"{baseUrl}/providers/Microsoft.ProcessSimple{(AsAdmin ? "/scopes/admin" : "")}/environments/{environmentName}/flows/{flowName}?api-version=2016-11-01", AccessToken).GetAwaiter().GetResult(); + var result = GraphHelper.Get(this, Connection, $"{baseUrl}/providers/Microsoft.ProcessSimple{(AsAdmin ? "/scopes/admin" : "")}/environments/{environmentName}/flows/{flowName}?api-version=2016-11-01", AccessToken); if (result != null) { - RestHelper.DeleteAsync(Connection.HttpClient, $"{baseUrl}/providers/Microsoft.ProcessSimple{(AsAdmin ? "/scopes/admin" : "")}/environments/{environmentName}/flows/{flowName}?api-version=2016-11-01", AccessToken).GetAwaiter().GetResult(); + RestHelper.Delete(Connection.HttpClient, $"{baseUrl}/providers/Microsoft.ProcessSimple{(AsAdmin ? "/scopes/admin" : "")}/environments/{environmentName}/flows/{flowName}?api-version=2016-11-01", AccessToken); WriteVerbose($"Flow with name {flowName} deleted"); } } @@ -54,7 +54,7 @@ protected override void ExecuteCmdlet() } else { - RestHelper.DeleteAsync(Connection.HttpClient, $"{baseUrl}/providers/Microsoft.ProcessSimple{(AsAdmin ? "/scopes/admin" : "")}/environments/{environmentName}/flows/{flowName}?api-version=2016-11-01", AccessToken).GetAwaiter().GetResult(); + RestHelper.Delete(Connection.HttpClient, $"{baseUrl}/providers/Microsoft.ProcessSimple{(AsAdmin ? "/scopes/admin" : "")}/environments/{environmentName}/flows/{flowName}?api-version=2016-11-01", AccessToken); WriteVerbose($"Flow with name {flowName} deleted"); } } diff --git a/src/Commands/PowerPlatform/PowerAutomate/RemoveFlowOwner.cs b/src/Commands/PowerPlatform/PowerAutomate/RemoveFlowOwner.cs index 19f445573..cfec6f584 100644 --- a/src/Commands/PowerPlatform/PowerAutomate/RemoveFlowOwner.cs +++ b/src/Commands/PowerPlatform/PowerAutomate/RemoveFlowOwner.cs @@ -77,7 +77,7 @@ protected override void ExecuteCmdlet() { string baseUrl = PowerPlatformUtility.GetPowerAutomateEndpoint(Connection.AzureEnvironment); WriteVerbose($"Removing user {user.Id.Value} permissions from flow {flowName} in environment {environmentName}"); - RestHelper.PostAsync(Connection.HttpClient, $"{baseUrl}/providers/Microsoft.ProcessSimple{(AsAdmin ? "/scopes/admin" : "")}/environments/{environmentName}/flows/{flowName}/modifyPermissions?api-version=2016-11-01", AccessToken, payload).GetAwaiter().GetResult(); + RestHelper.Post(Connection.HttpClient, $"{baseUrl}/providers/Microsoft.ProcessSimple{(AsAdmin ? "/scopes/admin" : "")}/environments/{environmentName}/flows/{flowName}/modifyPermissions?api-version=2016-11-01", AccessToken, payload); } } } diff --git a/src/Commands/PowerPlatform/PowerAutomate/RestartFlowRun.cs b/src/Commands/PowerPlatform/PowerAutomate/RestartFlowRun.cs index 7bd2ce1b9..c4ea783de 100644 --- a/src/Commands/PowerPlatform/PowerAutomate/RestartFlowRun.cs +++ b/src/Commands/PowerPlatform/PowerAutomate/RestartFlowRun.cs @@ -48,8 +48,8 @@ protected override void ExecuteCmdlet() if (!Force && !ShouldContinue($"Restart flow run with name '{flowRunName}'?", Resources.Confirm)) return; - var triggers = GraphHelper.GetResultCollectionAsync(Connection, $"{baseUrl}/providers/Microsoft.ProcessSimple/environments/{environmentName}/flows/{flowName}/triggers?api-version=2016-11-01", AccessToken).GetAwaiter().GetResult(); - RestHelper.PostAsync(Connection.HttpClient, $"{baseUrl}/providers/Microsoft.ProcessSimple/environments/{environmentName}/flows/{flowName}/triggers/{triggers.First().Name}/histories/{flowRunName}/resubmit?api-version=2016-11-01", AccessToken).GetAwaiter().GetResult(); + var triggers = GraphHelper.GetResultCollection(this, Connection, $"{baseUrl}/providers/Microsoft.ProcessSimple/environments/{environmentName}/flows/{flowName}/triggers?api-version=2016-11-01", AccessToken); + RestHelper.Post(Connection.HttpClient, $"{baseUrl}/providers/Microsoft.ProcessSimple/environments/{environmentName}/flows/{flowName}/triggers/{triggers.First().Name}/histories/{flowRunName}/resubmit?api-version=2016-11-01", AccessToken); } } } diff --git a/src/Commands/PowerPlatform/PowerAutomate/StopFlowRun.cs b/src/Commands/PowerPlatform/PowerAutomate/StopFlowRun.cs index d1a457650..b8c9afef5 100644 --- a/src/Commands/PowerPlatform/PowerAutomate/StopFlowRun.cs +++ b/src/Commands/PowerPlatform/PowerAutomate/StopFlowRun.cs @@ -45,7 +45,7 @@ protected override void ExecuteCmdlet() if (Force || ShouldContinue($"Stop flow run with name '{flowRunName}'?", Resources.Confirm)) { string baseUrl = PowerPlatformUtility.GetPowerAutomateEndpoint(Connection.AzureEnvironment); - RestHelper.PostAsync(Connection.HttpClient, $"{baseUrl}/providers/Microsoft.ProcessSimple/environments/{environmentName}/flows/{flowName}/runs/{flowRunName}/cancel?api-version=2016-11-01", AccessToken).GetAwaiter().GetResult(); + RestHelper.Post(Connection.HttpClient, $"{baseUrl}/providers/Microsoft.ProcessSimple/environments/{environmentName}/flows/{flowName}/runs/{flowRunName}/cancel?api-version=2016-11-01", AccessToken); } } } diff --git a/src/Commands/Principals/ExportUserInfo.cs b/src/Commands/Principals/ExportUserInfo.cs index 3889d67b0..e9441e860 100644 --- a/src/Commands/Principals/ExportUserInfo.cs +++ b/src/Commands/Principals/ExportUserInfo.cs @@ -33,7 +33,7 @@ protected override void ExecuteCmdlet() AdminContext.Load(site); AdminContext.ExecuteQueryRetry(); var normalizedUserName = UrlUtilities.UrlEncode($"i:0#.f|membership|{LoginName}"); - var results = RestHelper.GetAsync>(this.HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/GetSPUserInformation(accountName=@a,siteId=@b)?@a='{normalizedUserName}'&@b='{site.Id}'", AdminContext, false).GetAwaiter().GetResult(); + var results = RestHelper.Get>(this.HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/GetSPUserInformation(accountName=@a,siteId=@b)?@a='{normalizedUserName}'&@b='{site.Id}'", AdminContext, false); var record = new PSObject(); foreach (var item in results.Items) { diff --git a/src/Commands/Principals/RemoveUserInfo.cs b/src/Commands/Principals/RemoveUserInfo.cs index 8bfbee16e..adea1bc1e 100644 --- a/src/Commands/Principals/RemoveUserInfo.cs +++ b/src/Commands/Principals/RemoveUserInfo.cs @@ -39,11 +39,11 @@ protected override void ExecuteCmdlet() RestResultCollection results = null; if (!ParameterSpecified(nameof(RedactName))) { - results = RestHelper.PostAsync>(HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/RemoveSPUserInformation(accountName=@a,siteId=@b)?@a='{normalizedUserName}'&@b='{site.Id}'", this.AccessToken, false).GetAwaiter().GetResult(); + results = RestHelper.Post>(HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/RemoveSPUserInformation(accountName=@a,siteId=@b)?@a='{normalizedUserName}'&@b='{site.Id}'", this.AccessToken, false); } else { - results = RestHelper.PostAsync>(HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/RemoveSPUserInformation(accountName=@a,siteId=@b,redactName=@c)?@a='{normalizedUserName}'&@b='{site.Id}'&@c='{RedactName}'", this.AccessToken, false).GetAwaiter().GetResult(); + results = RestHelper.Post>(HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/RemoveSPUserInformation(accountName=@a,siteId=@b,redactName=@c)?@a='{normalizedUserName}'&@b='{site.Id}'&@c='{RedactName}'", this.AccessToken, false); } var record = new PSObject(); foreach (var item in results.Items) diff --git a/src/Commands/Provisioning/Site/AddListFoldersToSiteTemplate.cs b/src/Commands/Provisioning/Site/AddListFoldersToSiteTemplate.cs index cbfa80295..103418d9f 100644 --- a/src/Commands/Provisioning/Site/AddListFoldersToSiteTemplate.cs +++ b/src/Commands/Provisioning/Site/AddListFoldersToSiteTemplate.cs @@ -27,6 +27,7 @@ public class AddListFoldersToSiteTemplate : PnPWebCmdlet [Parameter(Mandatory = true, Position = 2)] public ListPipeBind List; + [Alias("Recurse")] [Parameter(Mandatory = false, Position = 4)] public SwitchParameter Recursive; @@ -62,8 +63,8 @@ protected override void ExecuteCmdlet() var tokenParser = new Framework.Provisioning.ObjectHandlers.TokenParser(ClientContext.Web, template); //We will remove a list if it's found so we can get the list - ListInstance listInstance = template.Lists.Find(l => tokenParser.ParseString(l.Title) == spList.Title); - + ListInstance listInstance = template.Lists.Find(l => tokenParser.ParseString(l.Title) == spList.Title); + if (listInstance == null) { throw new ApplicationException("List does not exist in the template file."); @@ -158,6 +159,10 @@ private PnP.Framework.Provisioning.Model.Folder GetFolder(Microsoft.SharePoint.C var roleBindings = roleAssignment.RoleDefinitionBindings; foreach (var roleBinding in roleBindings) { + if (roleBinding.Name == "Limited Access") + { + continue; + } retFolder.Security.RoleAssignments.Add(new PnP.Framework.Provisioning.Model.RoleAssignment() { Principal = principalName, RoleDefinition = roleBinding.Name }); } } diff --git a/src/Commands/Purview/GetAvailableSensitivityLabel.cs b/src/Commands/Purview/GetAvailableSensitivityLabel.cs index bd171bf87..87cf8bd1d 100644 --- a/src/Commands/Purview/GetAvailableSensitivityLabel.cs +++ b/src/Commands/Purview/GetAvailableSensitivityLabel.cs @@ -49,12 +49,12 @@ protected override void ExecuteCmdlet() { url += $"/{Identity}"; - var labels = GraphHelper.GetAsync(Connection, url, AccessToken).GetAwaiter().GetResult(); + var labels = GraphHelper.Get(this, Connection, url, AccessToken); WriteObject(labels, false); } else { - var labels = GraphHelper.GetResultCollectionAsync(Connection, url, AccessToken).GetAwaiter().GetResult(); + var labels = GraphHelper.GetResultCollection(this, Connection, url, AccessToken); WriteObject(labels, true); } } diff --git a/src/Commands/Purview/GetTenantRetentionLabel.cs b/src/Commands/Purview/GetTenantRetentionLabel.cs index 1efc898af..016dcd915 100644 --- a/src/Commands/Purview/GetTenantRetentionLabel.cs +++ b/src/Commands/Purview/GetTenantRetentionLabel.cs @@ -26,12 +26,12 @@ protected override void ExecuteCmdlet() { url += $"/{Identity}"; - var labels = GraphHelper.GetAsync(Connection, url, AccessToken).GetAwaiter().GetResult(); + var labels = GraphHelper.Get(this, Connection, url, AccessToken); WriteObject(labels, false); } else { - var labels = GraphHelper.GetResultCollectionAsync(Connection, url, AccessToken).GetAwaiter().GetResult(); + var labels = GraphHelper.GetResultCollection(this, Connection, url, AccessToken); WriteObject(labels, true); } } diff --git a/src/Commands/Purview/RemoveSiteSensitivityLabel.cs b/src/Commands/Purview/RemoveSiteSensitivityLabel.cs index 964c684c8..0f0bc359d 100644 --- a/src/Commands/Purview/RemoveSiteSensitivityLabel.cs +++ b/src/Commands/Purview/RemoveSiteSensitivityLabel.cs @@ -29,7 +29,7 @@ protected override void ExecuteCmdlet() WriteVerbose($"Trying to remove the Microsoft Purview sensitivity label from the Microsoft 365 Group with Id {ClientContext.Site.GroupId} behind the current site {Connection.Url}"); var stringContent = new StringContent(JsonSerializer.Serialize(new { assignedLabels = new [] { new { labelId = "" }}})); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - GraphHelper.PatchAsync(Connection, GraphAccessToken, stringContent, $"beta/groups/{ClientContext.Site.GroupId}").GetAwaiter().GetResult();; + GraphHelper.Patch(this, Connection, GraphAccessToken, stringContent, $"beta/groups/{ClientContext.Site.GroupId}"); } else { diff --git a/src/Commands/Purview/SetSiteSensitivityLabel.cs b/src/Commands/Purview/SetSiteSensitivityLabel.cs index e799f47b6..8aa899d24 100644 --- a/src/Commands/Purview/SetSiteSensitivityLabel.cs +++ b/src/Commands/Purview/SetSiteSensitivityLabel.cs @@ -23,7 +23,7 @@ protected override void ExecuteCmdlet() // Look up the sensitivity label Guid with the provided name WriteVerbose($"Passed in label '{Identity}' is a name, going to try to lookup its Id"); - var label = GraphHelper.GetResultCollectionAsync(Connection, $"/beta/{(Connection.ConnectionMethod == Model.ConnectionMethod.AzureADAppOnly ? "" : "me/")}informationProtection/policy/labels?$filter=name eq '{Identity}'", GraphAccessToken).GetAwaiter().GetResult(); + var label = GraphHelper.GetResultCollection(this, Connection, $"/beta/{(Connection.ConnectionMethod == Model.ConnectionMethod.AzureADAppOnly ? "" : "me/")}informationProtection/policy/labels?$filter=name eq '{Identity}'", GraphAccessToken); if(label == null || label.Count() == 0) { throw new PSArgumentException($"No Microsoft Purview sensitivity label with the provided name '{Identity}' could be found", nameof(Identity)); @@ -55,7 +55,7 @@ protected override void ExecuteCmdlet() WriteVerbose($"Trying to set the Microsoft 365 Group with Id {ClientContext.Site.GroupId} behind the current site {Connection.Url} to Microsoft Purview sensitivity label with Id {sensitivityLabelId}"); var stringContent = new StringContent(JsonSerializer.Serialize(new { assignedLabels = new [] { new { labelId = sensitivityLabelId }}})); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - GraphHelper.PatchAsync(Connection, GraphAccessToken, stringContent, $"beta/groups/{ClientContext.Site.GroupId}").GetAwaiter().GetResult();; + GraphHelper.Patch(this, Connection, GraphAccessToken, stringContent, $"beta/groups/{ClientContext.Site.GroupId}"); } else { diff --git a/src/Commands/Search/GetSearchExternalConnection.cs b/src/Commands/Search/GetSearchExternalConnection.cs new file mode 100644 index 000000000..bb57058e6 --- /dev/null +++ b/src/Commands/Search/GetSearchExternalConnection.cs @@ -0,0 +1,39 @@ +using System.Management.Automation; +using PnP.PowerShell.Commands.Base; +using PnP.PowerShell.Commands.Attributes; +using System.Collections.Generic; + +namespace PnP.PowerShell.Commands.Search +{ + [Cmdlet(VerbsCommon.Get, "PnPSearchExternalConnection")] + [RequiredMinimalApiPermissions("ExternalConnection.ReadWrite.OwnedBy")] + [OutputType(typeof(IEnumerable))] + [OutputType(typeof(Model.Graph.MicrosoftSearch.ExternalConnection))] + public class GetSearchExternalConnection : PnPGraphCmdlet + { + [Parameter(Mandatory = false)] + public string Identity; + + protected override void ExecuteCmdlet() + { + var graphApiUrl = $"v1.0/external/connections"; + + if(ParameterSpecified(nameof(Identity))) + { + graphApiUrl += $"/{Identity}"; + + WriteVerbose($"Retrieving external connection with Identity '{Identity}'"); + + var externalConnectionResult = Utilities.REST.GraphHelper.Get(this, Connection, graphApiUrl, AccessToken); + WriteObject(externalConnectionResult, false); + } + else + { + WriteVerbose("Retrieving all external connections"); + + var externalConnectionResults = Utilities.REST.GraphHelper.GetResultCollection(this, Connection, graphApiUrl, AccessToken); + WriteObject(externalConnectionResults, true); + } + } + } +} \ No newline at end of file diff --git a/src/Commands/Search/GetSearchExternalSchema.cs b/src/Commands/Search/GetSearchExternalSchema.cs new file mode 100644 index 000000000..49af6ade5 --- /dev/null +++ b/src/Commands/Search/GetSearchExternalSchema.cs @@ -0,0 +1,24 @@ +using System.Management.Automation; +using PnP.PowerShell.Commands.Base; +using PnP.PowerShell.Commands.Base.PipeBinds; +using PnP.PowerShell.Commands.Attributes; + +namespace PnP.PowerShell.Commands.Search +{ + [Cmdlet(VerbsCommon.Get, "PnPSearchExternalSchema")] + [RequiredMinimalApiPermissions("ExternalConnection.ReadWrite.OwnedBy")] + [OutputType(typeof(Model.Graph.MicrosoftSearch.ExternalSchema))] + public class GetSearchExternalSchema : PnPGraphCmdlet + { + [Parameter(Mandatory = true, ValueFromPipeline = true, Position = 0)] + public SearchExternalConnectionPipeBind ConnectionId; + + protected override void ExecuteCmdlet() + { + var searchExternalConnection = ConnectionId.GetExternalConnection(this, Connection, AccessToken); + var graphApiUrl = $"v1.0/external/connections/{searchExternalConnection.Id}/schema"; + var result = Utilities.REST.GraphHelper.Get(this, Connection, graphApiUrl, AccessToken); + WriteObject(result, false); + } + } +} \ No newline at end of file diff --git a/src/Commands/Search/NewSearchExternalConnection.cs b/src/Commands/Search/NewSearchExternalConnection.cs new file mode 100644 index 000000000..ebb3765f4 --- /dev/null +++ b/src/Commands/Search/NewSearchExternalConnection.cs @@ -0,0 +1,53 @@ +using System.Management.Automation; +using PnP.PowerShell.Commands.Base; +using PnP.PowerShell.Commands.Attributes; +using System.Net.Http.Json; + +namespace PnP.PowerShell.Commands.Search +{ + [Cmdlet(VerbsCommon.New, "PnPSearchExternalConnection")] + [RequiredMinimalApiPermissions("ExternalConnection.ReadWrite.OwnedBy")] + [OutputType(typeof(Model.Graph.MicrosoftSearch.ExternalConnection))] + public class NewSearchExternalConnection : PnPGraphCmdlet + { + [Parameter(Mandatory = true)] + [ValidateLength(3, 32)] + public string Identity; + + [Parameter(Mandatory = true)] + [ValidateLength(1, 128)] + public string Name; + + [Parameter(Mandatory = false)] + public string Description; + + [Parameter(Mandatory = false)] + public string[] AuthorizedAppIds; + protected override void ExecuteCmdlet() + { + var bodyContent = new Model.Graph.MicrosoftSearch.ExternalConnection + { + Id = Identity, + Name = Name, + Description = Description + }; + + if(ParameterSpecified(nameof(AuthorizedAppIds))) + { + bodyContent.Configuration = new() { + AuthorizedAppIds = AuthorizedAppIds + }; + } + + var jsonContent = JsonContent.Create(bodyContent); + WriteVerbose($"Constructed payload: {jsonContent.ReadAsStringAsync().GetAwaiter().GetResult()}"); + + var graphApiUrl = $"v1.0/external/connections"; + var results = Utilities.REST.GraphHelper.Post(this, Connection, graphApiUrl, AccessToken, jsonContent); + var resultsContent = results.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var externalConnectionResult = System.Text.Json.JsonSerializer.Deserialize(resultsContent); + + WriteObject(externalConnectionResult, false); + } + } +} \ No newline at end of file diff --git a/src/Commands/Search/RemoveSearchExternalConnection.cs b/src/Commands/Search/RemoveSearchExternalConnection.cs new file mode 100644 index 000000000..d7ce3b03d --- /dev/null +++ b/src/Commands/Search/RemoveSearchExternalConnection.cs @@ -0,0 +1,21 @@ +using System.Management.Automation; +using PnP.PowerShell.Commands.Base; +using PnP.PowerShell.Commands.Attributes; +using PnP.PowerShell.Commands.Base.PipeBinds; + +namespace PnP.PowerShell.Commands.Search +{ + [Cmdlet(VerbsCommon.Remove, "PnPSearchExternalConnection")] + [RequiredMinimalApiPermissions("ExternalConnection.ReadWrite.OwnedBy")] + public class RemoveSearchExternalConnection : PnPGraphCmdlet + { + [Parameter(Mandatory = true, ValueFromPipeline = true, Position = 0)] + public SearchExternalConnectionPipeBind Identity; + + protected override void ExecuteCmdlet() + { + var externalConnection = Identity.GetExternalConnection(this, Connection, AccessToken); + Utilities.REST.GraphHelper.Delete(this, Connection, $"v1.0/external/connections/{externalConnection.Id}", AccessToken); + } + } +} \ No newline at end of file diff --git a/src/Commands/Search/SetSearchExternalConnection.cs b/src/Commands/Search/SetSearchExternalConnection.cs new file mode 100644 index 000000000..3794f098d --- /dev/null +++ b/src/Commands/Search/SetSearchExternalConnection.cs @@ -0,0 +1,49 @@ +using System.Management.Automation; +using PnP.PowerShell.Commands.Base; +using PnP.PowerShell.Commands.Attributes; +using System.Net.Http.Json; +using System.Text.Json; +using PnP.PowerShell.Commands.Base.PipeBinds; + +namespace PnP.PowerShell.Commands.Search +{ + [Cmdlet(VerbsCommon.Set, "PnPSearchExternalConnection")] + [RequiredMinimalApiPermissions("ExternalConnection.ReadWrite.OwnedBy")] + public class SetSearchExternalConnection : PnPGraphCmdlet + { + [Parameter(Mandatory = true, ValueFromPipeline = true, Position = 0)] + public SearchExternalConnectionPipeBind Identity; + + [Parameter(Mandatory = false)] + [ValidateLength(1, 128)] + public string Name; + + [Parameter(Mandatory = false)] + public string Description; + + [Parameter(Mandatory = false)] + public string[] AuthorizedAppIds; + protected override void ExecuteCmdlet() + { + var bodyContent = new Model.Graph.MicrosoftSearch.ExternalConnection + { + Name = Name, + Description = Description + }; + + if(ParameterSpecified(nameof(AuthorizedAppIds))) + { + bodyContent.Configuration = new() { + AuthorizedAppIds = AuthorizedAppIds + }; + } + + var jsonContent = JsonContent.Create(bodyContent, null, new JsonSerializerOptions { DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull }); + WriteVerbose($"Constructed payload: {jsonContent.ReadAsStringAsync().GetAwaiter().GetResult()}"); + + var externalConnection = Identity.GetExternalConnection(this, Connection, AccessToken); + var graphApiUrl = $"v1.0/external/connections/{externalConnection.Id}"; + Utilities.REST.GraphHelper.Patch(this, Connection, AccessToken, jsonContent, graphApiUrl); + } + } +} \ No newline at end of file diff --git a/src/Commands/Search/SetSearchExternalItem.cs b/src/Commands/Search/SetSearchExternalItem.cs index 7a1a8f734..5f3f3b5df 100644 --- a/src/Commands/Search/SetSearchExternalItem.cs +++ b/src/Commands/Search/SetSearchExternalItem.cs @@ -13,10 +13,10 @@ namespace PnP.PowerShell.Commands.Search [Cmdlet(VerbsCommon.Set, "PnPSearchExternalItem")] [RequiredMinimalApiPermissions("ExternalItem.ReadWrite.All")] [OutputType(typeof(Model.Graph.MicrosoftSearch.ExternalItem))] - public class AddSearchExternalItem : PnPGraphCmdlet + public class SetSearchExternalItem : PnPGraphCmdlet { - [Parameter(Mandatory = true)] - public string ConnectionId; + [Parameter(Mandatory = true, ValueFromPipeline = true, Position = 0)] + public SearchExternalConnectionPipeBind ConnectionId; [Parameter(Mandatory = true)] [ValidateLength(1,128)] @@ -105,20 +105,10 @@ protected override void ExecuteCmdlet() var jsonContent = JsonContent.Create(bodyContent); WriteVerbose($"Constructed payload: {jsonContent.ReadAsStringAsync().GetAwaiter().GetResult()}"); - var graphApiUrl = $"v1.0/external/connections/{ConnectionId}/items/{ItemId}"; - WriteVerbose($"Calling Graph API at {graphApiUrl}"); - - var results = Utilities.REST.GraphHelper.PutAsync(Connection, graphApiUrl, AccessToken, jsonContent).GetAwaiter().GetResult(); - - WriteVerbose($"Graph API responded with HTTP {results.StatusCode} {results.ReasonPhrase}"); - - var resultsContent = results.Content.ReadAsStringAsync().GetAwaiter().GetResult(); - - WriteVerbose($"Graph API responded with payload: {resultsContent}"); - - var externalItemResult = System.Text.Json.JsonSerializer.Deserialize(resultsContent); - - WriteObject(externalItemResult, false); + var searchExternalConnection = ConnectionId.GetExternalConnection(this, Connection, AccessToken); + var graphApiUrl = $"v1.0/external/connections/{searchExternalConnection.Id}/items/{ItemId}"; + var results = Utilities.REST.GraphHelper.Put(this, Connection, graphApiUrl, AccessToken, jsonContent); + WriteObject(results, false); } private List GetUserAcls(AzureADUserPipeBind[] users, Enums.SearchExternalItemAclAccessType accessType) @@ -128,7 +118,7 @@ protected override void ExecuteCmdlet() foreach (var user in users) { - var userAclId = user.UserId ?? user.GetUser(AccessToken)?.Id.Value.ToString(); + var userAclId = user.UserId.HasValue ? user.UserId.Value.ToString() : user.GetUser(AccessToken)?.Id.Value.ToString(); acls.Add(new Model.Graph.MicrosoftSearch.ExternalItemAcl { @@ -148,7 +138,7 @@ protected override void ExecuteCmdlet() foreach (var group in groups) { - var userAclId = group.GroupId ?? group.GetGroup(Connection, AccessToken)?.Id; + var userAclId = group.GroupId ?? group.GetGroup(this, Connection, AccessToken)?.Id; acls.Add(new Model.Graph.MicrosoftSearch.ExternalItemAcl { diff --git a/src/Commands/Search/SetSearchExternalSchema.cs b/src/Commands/Search/SetSearchExternalSchema.cs new file mode 100644 index 000000000..9f8200152 --- /dev/null +++ b/src/Commands/Search/SetSearchExternalSchema.cs @@ -0,0 +1,101 @@ +using System.Management.Automation; +using PnP.PowerShell.Commands.Base; +using PnP.PowerShell.Commands.Base.PipeBinds; +using PnP.PowerShell.Commands.Attributes; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System; + +namespace PnP.PowerShell.Commands.Search +{ + [Cmdlet(VerbsCommon.Set, "PnPSearchExternalSchema")] + [RequiredMinimalApiPermissions("ExternalConnection.ReadWrite.OwnedBy")] + [OutputType(typeof(string))] + public class SetSearchExternalSchema : PnPGraphCmdlet + { + const string ParamSet_TextualSchema = "By textual schema"; + const string ParamSet_SchemaInstance = "By schema instance"; + + [Parameter(Mandatory = true, ValueFromPipeline = true, Position = 0, ParameterSetName = ParamSet_TextualSchema)] + [Parameter(Mandatory = true, ValueFromPipeline = true, Position = 0, ParameterSetName = ParamSet_SchemaInstance)] + public SearchExternalConnectionPipeBind ConnectionId; + + [Parameter(Mandatory = true, ParameterSetName = ParamSet_TextualSchema)] + public string SchemaAsText; + + [Parameter(Mandatory = true, ParameterSetName = ParamSet_SchemaInstance)] + public Model.Graph.MicrosoftSearch.ExternalSchema Schema; + + [Parameter(Mandatory = false, ParameterSetName = ParamSet_TextualSchema)] + [Parameter(Mandatory = false, ParameterSetName = ParamSet_SchemaInstance)] + public SwitchParameter Wait; + + [Parameter(Mandatory = false, ParameterSetName = ParamSet_TextualSchema)] + [Parameter(Mandatory = false, ParameterSetName = ParamSet_SchemaInstance)] + public short? OperationStatusPollingInterval = 30; + + protected override void ExecuteCmdlet() + { + var searchExternalConnection = ConnectionId.GetExternalConnection(this, Connection, AccessToken); + + switch(ParameterSetName) + { + case ParamSet_TextualSchema: + WriteVerbose("Parsing schema from textual representation"); + break; + case ParamSet_SchemaInstance: + WriteVerbose("Using provided schema instance"); + SchemaAsText = System.Text.Json.JsonSerializer.Serialize(Schema); + break; + } + + var jsonContent = new StringContent(SchemaAsText); + WriteVerbose($"Constructed payload: {jsonContent.ReadAsStringAsync().GetAwaiter().GetResult()}"); + + var graphApiUrl = $"v1.0/external/connections/{searchExternalConnection.Id}/schema"; + var results = Utilities.REST.GraphHelper.Patch(this, Connection, AccessToken, jsonContent, graphApiUrl); + + WriteVerbose("Trying to retrieve location header from response which can be used to poll for the status of the schema operation"); + if(results.Headers.TryGetValues("Location", out var location) && location.Any()) + { + var schemaOperationStatusUrl = location.FirstOrDefault(); + WriteVerbose("Schema update has been scheduled"); + + if(Wait.ToBool()) + { + WriteVerbose($"Waiting for schema operation to complete by polling {schemaOperationStatusUrl}"); + + do + { + WriteVerbose("Polling schema operation status"); + var schemaOperationResult = Utilities.REST.GraphHelper.Get(this, Connection, schemaOperationStatusUrl, AccessToken); + + if(!string.IsNullOrEmpty(schemaOperationResult.Status)) + { + if (schemaOperationResult.Status.ToLowerInvariant() == "completed") + { + WriteVerbose("Schema operation has completed"); + break; + } + else + { + WriteVerbose($"Schema operation still in progress with status {schemaOperationResult.Status}"); + } + } + + WriteVerbose($"Waiting for {OperationStatusPollingInterval.GetValueOrDefault(30)} seconds before polling again"); + Thread.Sleep(TimeSpan.FromSeconds(OperationStatusPollingInterval.GetValueOrDefault(30))); + } + while (true); + } + + WriteObject(schemaOperationStatusUrl, false); + } + else + { + WriteVerbose("No valid Location header found in response"); + } + } + } +} \ No newline at end of file diff --git a/src/Commands/Security/GetFileSharingLink.cs b/src/Commands/Security/GetFileSharingLink.cs index 36679342a..9dde2a87a 100644 --- a/src/Commands/Security/GetFileSharingLink.cs +++ b/src/Commands/Security/GetFileSharingLink.cs @@ -1,33 +1,56 @@ -using PnP.Framework.Utilities; +using PnP.Core.Model.Security; +using PnP.Core.Model.SharePoint; +using PnP.Framework.Utilities; +using System; using System.Management.Automation; +using PnP.PowerShell.Commands.Base.PipeBinds; namespace PnP.PowerShell.Commands.Security -{ +{ [Cmdlet(VerbsCommon.Get, "PnPFileSharingLink")] + [OutputType(typeof(IGraphPermissionCollection))] public class GetFileSharingLink : PnPWebCmdlet { - [Parameter(Mandatory = true)] + private const string ParameterSet_BYFILEURL = "By file url"; + private const string ParameterSet_BYIDENTITY = "By identity"; + + [Obsolete("Use Identity parameter instead")] + [Parameter(Mandatory = true, ParameterSetName = ParameterSet_BYFILEURL)] public string FileUrl; + [Parameter(Mandatory = true, ValueFromPipeline = true, ParameterSetName = ParameterSet_BYIDENTITY)] + public FilePipeBind Identity; + protected override void ExecuteCmdlet() { - var serverRelativeUrl = string.Empty; - var ctx = Connection.PnPContext; - - ctx.Web.EnsureProperties(w => w.ServerRelativeUrl); + IFile file; - if (!FileUrl.ToLower().StartsWith(ctx.Web.ServerRelativeUrl.ToLower())) + if (ParameterSpecified(nameof(Identity))) { - serverRelativeUrl = UrlUtility.Combine(ctx.Web.ServerRelativeUrl, FileUrl); + file = Identity.GetCoreFile(PnPContext, this); } else { - serverRelativeUrl = FileUrl; - } + var serverRelativeUrl = string.Empty; + var ctx = Connection.PnPContext; + + ctx.Web.EnsureProperties(w => w.ServerRelativeUrl); - var file = ctx.Web.GetFileByServerRelativeUrl(serverRelativeUrl); +#pragma warning disable CS0618 + if (!FileUrl.ToLower().StartsWith(ctx.Web.ServerRelativeUrl.ToLower())) + { + serverRelativeUrl = UrlUtility.Combine(ctx.Web.ServerRelativeUrl, FileUrl); + } + else + { + serverRelativeUrl = FileUrl; + } +#pragma warning restore CS0618 + file = ctx.Web.GetFileByServerRelativeUrl(serverRelativeUrl); + } - var sharingLinks = file.GetShareLinks(); + WriteVerbose("Retrieving file sharing details from Microsoft Graph"); + var sharingLinks = file?.GetShareLinks(); WriteObject(sharingLinks?.RequestedItems, true); } diff --git a/src/Commands/ServiceHealth/GetMessageCenterAnnouncement.cs b/src/Commands/ServiceHealth/GetMessageCenterAnnouncement.cs index ae541ce7c..3ed8be76e 100644 --- a/src/Commands/ServiceHealth/GetMessageCenterAnnouncement.cs +++ b/src/Commands/ServiceHealth/GetMessageCenterAnnouncement.cs @@ -16,11 +16,11 @@ protected override void ExecuteCmdlet() { if (ParameterSpecified(nameof(Identity))) { - WriteObject(ServiceHealthUtility.GetServiceUpdateMessageByIdAsync(Identity, Connection, AccessToken).GetAwaiter().GetResult(), false); + WriteObject(ServiceHealthUtility.GetServiceUpdateMessageById(this, Identity, Connection, AccessToken), false); } else { - WriteObject(ServiceHealthUtility.GetServiceUpdateMessagesAsync(Connection, AccessToken).GetAwaiter().GetResult(), true); + WriteObject(ServiceHealthUtility.GetServiceUpdateMessages(this, Connection, AccessToken), true); } } } diff --git a/src/Commands/ServiceHealth/GetServiceCurrentHealth.cs b/src/Commands/ServiceHealth/GetServiceCurrentHealth.cs index 360bbbf4e..56d74adc4 100644 --- a/src/Commands/ServiceHealth/GetServiceCurrentHealth.cs +++ b/src/Commands/ServiceHealth/GetServiceCurrentHealth.cs @@ -16,11 +16,11 @@ protected override void ExecuteCmdlet() { if (ParameterSpecified(nameof(Identity))) { - WriteObject(ServiceHealthUtility.GetServiceCurrentHealthByIdAsync(Identity, Connection, AccessToken).GetAwaiter().GetResult(), false); + WriteObject(ServiceHealthUtility.GetServiceCurrentHealthById(this, Identity, Connection, AccessToken), false); } else { - WriteObject(ServiceHealthUtility.GetServiceCurrentHealthAsync(Connection, AccessToken).GetAwaiter().GetResult(), true); + WriteObject(ServiceHealthUtility.GetServiceCurrentHealth(this, Connection, AccessToken), true); } } } diff --git a/src/Commands/ServiceHealth/GetServiceHealthIssue.cs b/src/Commands/ServiceHealth/GetServiceHealthIssue.cs index d1042b6ca..919eb7299 100644 --- a/src/Commands/ServiceHealth/GetServiceHealthIssue.cs +++ b/src/Commands/ServiceHealth/GetServiceHealthIssue.cs @@ -16,11 +16,11 @@ protected override void ExecuteCmdlet() { if (ParameterSpecified(nameof(Identity))) { - WriteObject(ServiceHealthUtility.GetServiceHealthIssueByIdAsync(Identity, Connection, AccessToken).GetAwaiter().GetResult(), false); + WriteObject(ServiceHealthUtility.GetServiceHealthIssueById(this, Identity, Connection, AccessToken), false); } else { - WriteObject(ServiceHealthUtility.GetServiceHealthIssuesAsync(Connection, AccessToken).GetAwaiter().GetResult(), true); + WriteObject(ServiceHealthUtility.GetServiceHealthIssues(this, Connection, AccessToken), true); } } } diff --git a/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsArchived.cs b/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsArchived.cs index 1faa54163..79b0b107c 100644 --- a/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsArchived.cs +++ b/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsArchived.cs @@ -17,18 +17,18 @@ protected override void ExecuteCmdlet() { if (ParameterSpecified(nameof(Identity))) { - WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsArchivedByIdAsync(Identity, Connection, AccessToken).GetAwaiter().GetResult(), true); + WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsArchivedById(this, Identity, Connection, AccessToken), true); } else { // Retrieve all message center announcements - var messageCenterAnnouncements = ServiceHealthUtility.GetServiceUpdateMessagesAsync(Connection, AccessToken).GetAwaiter().GetResult(); + var messageCenterAnnouncements = ServiceHealthUtility.GetServiceUpdateMessages(this, Connection, AccessToken); // Create an array of the Ids of all message center announcements var messageCenterAnnouncementIds = messageCenterAnnouncements.Select(item => item.Id).ToArray(); // Mark all message center announcements as archived - WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsArchivedByIdAsync(messageCenterAnnouncementIds, Connection, AccessToken).GetAwaiter().GetResult(), true); + WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsArchivedById(this, messageCenterAnnouncementIds, Connection, AccessToken), true); } } } diff --git a/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsFavorite.cs b/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsFavorite.cs index 54e71d32e..13e87a89f 100644 --- a/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsFavorite.cs +++ b/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsFavorite.cs @@ -17,18 +17,18 @@ protected override void ExecuteCmdlet() { if (ParameterSpecified(nameof(Identity))) { - WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsFavoriteByIdAsync(Identity, Connection, AccessToken).GetAwaiter().GetResult(), true); + WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsFavoriteById(this, Identity, Connection, AccessToken), true); } else { // Retrieve all message center announcements - var messageCenterAnnouncements = ServiceHealthUtility.GetServiceUpdateMessagesAsync(Connection, AccessToken).GetAwaiter().GetResult(); + var messageCenterAnnouncements = ServiceHealthUtility.GetServiceUpdateMessages(this, Connection, AccessToken); // Create an array of the Ids of all message center announcements var messageCenterAnnouncementIds = messageCenterAnnouncements.Select(item => item.Id).ToArray(); // Mark all message center announcements as favorite - WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsFavoriteByIdAsync(messageCenterAnnouncementIds, Connection, AccessToken).GetAwaiter().GetResult(), true); + WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsFavoriteById(this, messageCenterAnnouncementIds, Connection, AccessToken), true); } } } diff --git a/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsNotArchived.cs b/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsNotArchived.cs index 74c21bd15..c1a96bd9a 100644 --- a/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsNotArchived.cs +++ b/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsNotArchived.cs @@ -17,18 +17,18 @@ protected override void ExecuteCmdlet() { if (ParameterSpecified(nameof(Identity))) { - WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsUnarchivedByIdAsync(Identity, Connection, AccessToken).GetAwaiter().GetResult(), true); + WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsUnarchivedById(this, Identity, Connection, AccessToken), true); } else { // Retrieve all message center announcements - var messageCenterAnnouncements = ServiceHealthUtility.GetServiceUpdateMessagesAsync(Connection, AccessToken).GetAwaiter().GetResult(); + var messageCenterAnnouncements = ServiceHealthUtility.GetServiceUpdateMessages(this, Connection, AccessToken); // Create an array of the Ids of all message center announcements var messageCenterAnnouncementIds = messageCenterAnnouncements.Select(item => item.Id).ToArray(); // Mark all message center announcements as not archived - WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsUnarchivedByIdAsync(messageCenterAnnouncementIds, Connection, AccessToken).GetAwaiter().GetResult(), true); + WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsUnarchivedById(this, messageCenterAnnouncementIds, Connection, AccessToken), true); } } } diff --git a/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsNotFavorite.cs b/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsNotFavorite.cs index 144f6440e..24798f9df 100644 --- a/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsNotFavorite.cs +++ b/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsNotFavorite.cs @@ -16,18 +16,18 @@ protected override void ExecuteCmdlet() { if (ParameterSpecified(nameof(Identity))) { - WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsNotfavoriteByIdAsync(Identity, Connection, AccessToken).GetAwaiter().GetResult(), true); + WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsNotfavoriteById(this, Identity, Connection, AccessToken), true); } else { // Retrieve all message center announcements - var messageCenterAnnouncements = ServiceHealthUtility.GetServiceUpdateMessagesAsync(Connection, AccessToken).GetAwaiter().GetResult(); + var messageCenterAnnouncements = ServiceHealthUtility.GetServiceUpdateMessages(this, Connection, AccessToken); // Create an array of the Ids of all message center announcements var messageCenterAnnouncementIds = messageCenterAnnouncements.Select(item => item.Id).ToArray(); // Mark all message center announcements as not favorites - WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsNotfavoriteByIdAsync(messageCenterAnnouncementIds, Connection, AccessToken).GetAwaiter().GetResult(), true); + WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsNotfavoriteById(this, messageCenterAnnouncementIds, Connection, AccessToken), true); } } } diff --git a/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsRead.cs b/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsRead.cs index 1831ffebf..e2266619c 100644 --- a/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsRead.cs +++ b/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsRead.cs @@ -17,18 +17,18 @@ protected override void ExecuteCmdlet() { if (ParameterSpecified(nameof(Identity))) { - WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsReadByIdAsync(Identity, Connection, AccessToken).GetAwaiter().GetResult(), true); + WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsReadById(this, Identity, Connection, AccessToken), true); } else { // Retrieve all message center announcements - var messageCenterAnnouncements = ServiceHealthUtility.GetServiceUpdateMessagesAsync(Connection, AccessToken).GetAwaiter().GetResult(); + var messageCenterAnnouncements = ServiceHealthUtility.GetServiceUpdateMessages(this, Connection, AccessToken); // Create an array of the Ids of all message center announcements var messageCenterAnnouncementIds = messageCenterAnnouncements.Select(item => item.Id).ToArray(); // Mark all message center announcements as read - WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsReadByIdAsync(messageCenterAnnouncementIds, Connection, AccessToken).GetAwaiter().GetResult(), true); + WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsReadById(this, messageCenterAnnouncementIds, Connection, AccessToken), true); } } } diff --git a/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsUnread.cs b/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsUnread.cs index b412b0d19..6f2efd109 100644 --- a/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsUnread.cs +++ b/src/Commands/ServiceHealth/SetMessageCenterAnnouncementAsUnread.cs @@ -17,18 +17,18 @@ protected override void ExecuteCmdlet() { if (ParameterSpecified(nameof(Identity))) { - WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsUnreadByIdAsync(Identity, Connection, AccessToken).GetAwaiter().GetResult(), true); + WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsUnreadById(this, Identity, Connection, AccessToken), true); } else { // Retrieve all message center announcements - var messageCenterAnnouncements = ServiceHealthUtility.GetServiceUpdateMessagesAsync(Connection, AccessToken).GetAwaiter().GetResult(); + var messageCenterAnnouncements = ServiceHealthUtility.GetServiceUpdateMessages(this, Connection, AccessToken); // Create an array of the Ids of all message center announcements var messageCenterAnnouncementIds = messageCenterAnnouncements.Select(item => item.Id).ToArray(); // Mark all message center announcements as unread - WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsUnreadByIdAsync(messageCenterAnnouncementIds, Connection, AccessToken).GetAwaiter().GetResult(), true); + WriteObject(ServiceHealthUtility.SetServiceUpdateMessageAsUnreadById(this, messageCenterAnnouncementIds, Connection, AccessToken), true); } } } diff --git a/src/Commands/Site/AddTeamsTeam.cs b/src/Commands/Site/AddTeamsTeam.cs index b48ec7b0a..a4eee8dea 100644 --- a/src/Commands/Site/AddTeamsTeam.cs +++ b/src/Commands/Site/AddTeamsTeam.cs @@ -28,14 +28,13 @@ protected override void ExecuteCmdlet() try { var groupId = ClientContext.Site.EnsureProperty(s => s.GroupId); - Microsoft365GroupsUtility.CreateTeamAsync(Connection, AccessToken, groupId).GetAwaiter().GetResult(); + ClearOwners.CreateTeam(this, Connection, AccessToken, groupId); } catch { throw; } } - } } } \ No newline at end of file diff --git a/src/Commands/Site/GetAvailableSiteClassification.cs b/src/Commands/Site/GetAvailableSiteClassification.cs index faecd9e68..e39c10e41 100644 --- a/src/Commands/Site/GetAvailableSiteClassification.cs +++ b/src/Commands/Site/GetAvailableSiteClassification.cs @@ -9,6 +9,7 @@ namespace PnP.PowerShell.Commands.Site { [Cmdlet(VerbsCommon.Get, "PnPAvailableSiteClassification")] [RequiredMinimalApiPermissions("Directory.Read.All")] + [RequiredMinimalApiPermissions("Directory.ReadWrite.All")] [OutputType(typeof(SiteClassificationsSettings))] [Alias("Get-PnPSiteClassification")] [WriteAliasWarning("Please use 'Get-PnPAvailableSiteClassification'. The alias 'Get-PnPSiteClassification' will be removed in a future release.")] diff --git a/src/Commands/SiteDesigns/InvokeSiteScript.cs b/src/Commands/SiteDesigns/InvokeSiteScript.cs index 35cb0eef1..b0d64fcdb 100644 --- a/src/Commands/SiteDesigns/InvokeSiteScript.cs +++ b/src/Commands/SiteDesigns/InvokeSiteScript.cs @@ -55,7 +55,7 @@ protected override void ExecuteCmdlet() else { WriteVerbose($"Executing provided script"); - result = PnP.PowerShell.Commands.Utilities.SiteTemplates.InvokeSiteScript(Connection, AccessToken, Script, hostUrl).GetAwaiter().GetResult().Items; + result = PnP.PowerShell.Commands.Utilities.SiteTemplates.InvokeSiteScript(this, Connection, AccessToken, Script, hostUrl).Items; } break; @@ -81,7 +81,7 @@ protected override void ExecuteCmdlet() else { WriteVerbose($"Executing site script '{script.Title}' ({script.Id})"); - result = PnP.PowerShell.Commands.Utilities.SiteTemplates.InvokeSiteScript(Connection, AccessToken, script, hostUrl).GetAwaiter().GetResult().Items; + result = PnP.PowerShell.Commands.Utilities.SiteTemplates.InvokeSiteScript(this, Connection, AccessToken, script, hostUrl).Items; } } break; diff --git a/src/Commands/Teams/AddTeamsChannel.cs b/src/Commands/Teams/AddTeamsChannel.cs index 707e30586..4a8876ba0 100644 --- a/src/Commands/Teams/AddTeamsChannel.cs +++ b/src/Commands/Teams/AddTeamsChannel.cs @@ -47,7 +47,7 @@ public class AddTeamsChannel : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken); + var groupId = Team.GetGroupId(this, Connection, AccessToken); if (groupId == null) { throw new PSArgumentException("Group not found"); @@ -61,7 +61,7 @@ protected override void ExecuteCmdlet() try { #pragma warning disable CS0618 // Type or member is obsolete - var channel = TeamsUtility.AddChannelAsync(AccessToken, Connection, groupId, DisplayName, Description, ChannelType, OwnerUPN, IsFavoriteByDefault).GetAwaiter().GetResult(); + var channel = TeamsUtility.AddChannel(this, AccessToken, Connection, groupId, DisplayName, Description, ChannelType, OwnerUPN, IsFavoriteByDefault); #pragma warning restore CS0618 // Type or member is obsolete WriteObject(channel); } diff --git a/src/Commands/Teams/AddTeamsChannelUser.cs b/src/Commands/Teams/AddTeamsChannelUser.cs index 50ccfb96b..ab56fbbd2 100644 --- a/src/Commands/Teams/AddTeamsChannelUser.cs +++ b/src/Commands/Teams/AddTeamsChannelUser.cs @@ -26,13 +26,13 @@ public class AddTeamsChannelUser : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken); + var groupId = Team.GetGroupId(this, Connection, AccessToken); if (groupId == null) { throw new PSArgumentException("Group not found"); } - var channelId = Channel.GetId(Connection, AccessToken, groupId); + var channelId = Channel.GetId(this, Connection, AccessToken, groupId); if (channelId == null) { throw new PSArgumentException("Channel not found"); @@ -40,7 +40,7 @@ protected override void ExecuteCmdlet() try { - TeamsUtility.AddChannelMemberAsync(Connection, AccessToken, groupId, channelId, User, Role).GetAwaiter().GetResult(); + TeamsUtility.AddChannelMember(this, Connection, AccessToken, groupId, channelId, User, Role); } catch (GraphException ex) { diff --git a/src/Commands/Teams/AddTeamsTab.cs b/src/Commands/Teams/AddTeamsTab.cs index 73d9a9b25..482fd3021 100644 --- a/src/Commands/Teams/AddTeamsTab.cs +++ b/src/Commands/Teams/AddTeamsTab.cs @@ -66,10 +66,10 @@ public object GetDynamicParameters() protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken); + var groupId = Team.GetGroupId(this, Connection, AccessToken); if (groupId != null) { - var channelId = Channel.GetId(Connection, AccessToken, groupId); + var channelId = Channel.GetId(this, Connection, AccessToken, groupId); if (channelId != null) { try @@ -119,7 +119,7 @@ protected override void ExecuteCmdlet() break; } } - WriteObject(TeamsUtility.AddTabAsync(Connection, AccessToken, groupId, channelId, DisplayName, Type, teamsAppId, entityId, contentUrl, removeUrl, webSiteUrl).GetAwaiter().GetResult()); + WriteObject(TeamsUtility.AddTab(this, Connection, AccessToken, groupId, channelId, DisplayName, Type, teamsAppId, entityId, contentUrl, removeUrl, webSiteUrl)); } catch (GraphException ex) { diff --git a/src/Commands/Teams/AddTeamsUser.cs b/src/Commands/Teams/AddTeamsUser.cs index 7eb0340ea..d0c711d94 100644 --- a/src/Commands/Teams/AddTeamsUser.cs +++ b/src/Commands/Teams/AddTeamsUser.cs @@ -33,29 +33,29 @@ public class AddTeamsUser : PnPGraphCmdlet public string Role; protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken); + var groupId = Team.GetGroupId(this, Connection, AccessToken); if (groupId != null) { try { if (ParameterSpecified(nameof(Channel))) { - var channelId = Channel.GetId(Connection, AccessToken, groupId); + var channelId = Channel.GetId(this, Connection, AccessToken, groupId); if (channelId == null) { throw new PSArgumentException("Channel not found"); } - TeamsUtility.AddChannelMemberAsync(Connection, AccessToken, groupId, channelId, User, Role).GetAwaiter().GetResult(); + TeamsUtility.AddChannelMember(this, Connection, AccessToken, groupId, channelId, User, Role); } else { if (ParameterSetName == ParamSet_ByUser) { - TeamsUtility.AddUserAsync(Connection, AccessToken, groupId, User, Role).GetAwaiter().GetResult(); + TeamsUtility.AddUser(this, Connection, AccessToken, groupId, User, Role); } else { - TeamsUtility.AddUsersAsync(Connection, AccessToken, groupId, Users, Role).GetAwaiter().GetResult(); + TeamsUtility.AddUsers(this, Connection, AccessToken, groupId, Users, Role); } } } diff --git a/src/Commands/Teams/CopyTeamsTeam.cs b/src/Commands/Teams/CopyTeamsTeam.cs index a45639101..810be1ca5 100644 --- a/src/Commands/Teams/CopyTeamsTeam.cs +++ b/src/Commands/Teams/CopyTeamsTeam.cs @@ -48,7 +48,7 @@ public class CopyTeamsTeam : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Identity.GetGroupId(Connection, AccessToken); + var groupId = Identity.GetGroupId(this, Connection, AccessToken); if (groupId == null) { @@ -58,7 +58,7 @@ protected override void ExecuteCmdlet() if (!ParameterSpecified(nameof(PartsToClone))) { // If no specific parts have been provided, all available parts will be copied - PartsToClone = Enum.GetValues(typeof(Microsoft.Graph.ClonableTeamParts)).Cast().ToArray(); + PartsToClone = Enum.GetValues(typeof(ClonableTeamParts)).Cast().ToArray(); } TeamCloneInformation teamClone = new TeamCloneInformation(); @@ -70,7 +70,7 @@ protected override void ExecuteCmdlet() * but currently ignored and can't be set by user */ teamClone.MailNickName = DisplayName; teamClone.Visibility = (GroupVisibility)Enum.Parse(typeof(GroupVisibility), Visibility.ToString()); - TeamsUtility.CloneTeamAsync(AccessToken, Connection, groupId, teamClone).GetAwaiter().GetResult(); + TeamsUtility.CloneTeam(this, AccessToken, Connection, groupId, teamClone); } } } diff --git a/src/Commands/Teams/GetDeletedTeamsTeam.cs b/src/Commands/Teams/GetDeletedTeamsTeam.cs index 16f510e42..10f203db5 100644 --- a/src/Commands/Teams/GetDeletedTeamsTeam.cs +++ b/src/Commands/Teams/GetDeletedTeamsTeam.cs @@ -12,7 +12,7 @@ public class GetDeletedTeamsTeam : PnPGraphCmdlet { protected override void ExecuteCmdlet() { - WriteObject(TeamsUtility.GetDeletedTeamAsync(AccessToken, Connection).GetAwaiter().GetResult()); + WriteObject(TeamsUtility.GetDeletedTeam(this, AccessToken, Connection)); } } } diff --git a/src/Commands/Teams/GetTeamsApp.cs b/src/Commands/Teams/GetTeamsApp.cs index 7f3293ca2..5bfc89e88 100644 --- a/src/Commands/Teams/GetTeamsApp.cs +++ b/src/Commands/Teams/GetTeamsApp.cs @@ -9,7 +9,7 @@ namespace PnP.PowerShell.Commands.Teams { [Cmdlet(VerbsCommon.Get, "PnPTeamsApp")] [RequiredMinimalApiPermissions("Directory.Read.All")] - + [RequiredMinimalApiPermissions("Directory.ReadWrite.All")] [TokenType(TokenType = TokenType.Delegate)] public class GetTeamsApp : PnPGraphCmdlet { @@ -20,7 +20,7 @@ protected override void ExecuteCmdlet() { if (ParameterSpecified(nameof(Identity))) { - var app = Identity.GetApp(Connection, AccessToken); + var app = Identity.GetApp(this, Connection, AccessToken); if (app != null) { WriteObject(app); @@ -28,7 +28,7 @@ protected override void ExecuteCmdlet() } else { - WriteObject(TeamsUtility.GetAppsAsync(AccessToken, Connection).GetAwaiter().GetResult(), true); + WriteObject(TeamsUtility.GetApps(this, AccessToken, Connection), true); } } } diff --git a/src/Commands/Teams/GetTeamsChannel.cs b/src/Commands/Teams/GetTeamsChannel.cs index c9f6de2b6..18b1dbca4 100644 --- a/src/Commands/Teams/GetTeamsChannel.cs +++ b/src/Commands/Teams/GetTeamsChannel.cs @@ -8,6 +8,7 @@ namespace PnP.PowerShell.Commands.Teams { [Cmdlet(VerbsCommon.Get, "PnPTeamsChannel")] [RequiredMinimalApiPermissions("Group.Read.All")] + [RequiredMinimalApiPermissions("Group.ReadWrite.All")] public class GetTeamsChannel : PnPGraphCmdlet { @@ -22,15 +23,15 @@ public class GetTeamsChannel : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken) ?? throw new PSArgumentException("Team not found", nameof(Team)); + var groupId = Team.GetGroupId(this, Connection, AccessToken) ?? throw new PSArgumentException("Team not found", nameof(Team)); if (ParameterSpecified(nameof(Identity))) { - WriteObject(Identity.GetChannel(Connection, AccessToken, groupId, useBeta: IncludeModerationSettings.ToBool())); + WriteObject(Identity.GetChannel(this, Connection, AccessToken, groupId, useBeta: IncludeModerationSettings.ToBool())); } else { - WriteObject(TeamsUtility.GetChannelsAsync(AccessToken, Connection, groupId, useBeta: IncludeModerationSettings.ToBool()).GetAwaiter().GetResult(), true); + WriteObject(TeamsUtility.GetChannels(this, AccessToken, Connection, groupId, useBeta: IncludeModerationSettings.ToBool()), true); } } } diff --git a/src/Commands/Teams/GetTeamsChannelFilesFolder.cs b/src/Commands/Teams/GetTeamsChannelFilesFolder.cs index 034e8dab6..d8f6e27a3 100644 --- a/src/Commands/Teams/GetTeamsChannelFilesFolder.cs +++ b/src/Commands/Teams/GetTeamsChannelFilesFolder.cs @@ -7,6 +7,8 @@ namespace PnP.PowerShell.Commands.Teams { [Cmdlet(VerbsCommon.Get, "PnPTeamsChannelFilesFolder")] [RequiredMinimalApiPermissions("Group.Read.All")] + [RequiredMinimalApiPermissions("Group.ReadWrite.All")] + public class GetTeamsChannelFilesFolder : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true)] @@ -17,18 +19,17 @@ public class GetTeamsChannelFilesFolder : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken); + var groupId = Team.GetGroupId(this, Connection, AccessToken); if (groupId != null) { - var channelId = Channel.GetId(Connection, AccessToken, groupId); + var channelId = Channel.GetId(this, Connection, AccessToken, groupId); if (channelId == null) { throw new PSArgumentException("Channel not found"); } - - WriteObject(Utilities.TeamsUtility.GetChannelsFilesFolderAsync(Connection, AccessToken, groupId, channelId).GetAwaiter().GetResult()); - + + WriteObject(Utilities.TeamsUtility.GetChannelsFilesFolder(this, Connection, AccessToken, groupId, channelId)); } else { diff --git a/src/Commands/Teams/GetTeamsChannelMessage.cs b/src/Commands/Teams/GetTeamsChannelMessage.cs index d234e945c..c198b7640 100644 --- a/src/Commands/Teams/GetTeamsChannelMessage.cs +++ b/src/Commands/Teams/GetTeamsChannelMessage.cs @@ -8,6 +8,8 @@ namespace PnP.PowerShell.Commands.Teams { [Cmdlet(VerbsCommon.Get, "PnPTeamsChannelMessage")] [RequiredMinimalApiPermissions("Group.Read.All")] + [RequiredMinimalApiPermissions("Group.ReadWrite.All")] + public class GetTeamsChannelMessage : PnPGraphCmdlet { [Parameter(Mandatory = true)] @@ -24,13 +26,13 @@ public class GetTeamsChannelMessage : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken); + var groupId = Team.GetGroupId(this, Connection, AccessToken); if (groupId == null) { throw new PSArgumentException("Team not found"); } - var channelId = Channel.GetId(Connection, AccessToken, groupId); + var channelId = Channel.GetId(this, Connection, AccessToken, groupId); if (channelId == null) { throw new PSArgumentException("Channel not found"); @@ -43,12 +45,12 @@ protected override void ExecuteCmdlet() throw new PSArgumentException($"Don't specify {nameof(IncludeDeleted)} when using the {nameof(Identity)} parameter."); } - var message = TeamsUtility.GetMessageAsync(Connection, AccessToken, groupId, channelId, Identity.GetId()).GetAwaiter().GetResult(); + var message = TeamsUtility.GetMessage(this, Connection, AccessToken, groupId, channelId, Identity.GetId()); WriteObject(message); } else { - var messages = TeamsUtility.GetMessagesAsync(Connection, AccessToken, groupId, channelId, IncludeDeleted).GetAwaiter().GetResult(); + var messages = TeamsUtility.GetMessages(this, Connection, AccessToken, groupId, channelId, IncludeDeleted); WriteObject(messages, true); } } diff --git a/src/Commands/Teams/GetTeamsChannelMessageReply.cs b/src/Commands/Teams/GetTeamsChannelMessageReply.cs index fd268439c..a18af7ed8 100644 --- a/src/Commands/Teams/GetTeamsChannelMessageReply.cs +++ b/src/Commands/Teams/GetTeamsChannelMessageReply.cs @@ -8,6 +8,7 @@ namespace PnP.PowerShell.Commands.Teams { [Cmdlet(VerbsCommon.Get, "PnPTeamsChannelMessageReply")] [RequiredMinimalApiPermissions("ChannelMessage.Read.All")] + [RequiredMinimalApiPermissions("ChannelMessage.ReadWrite.All")] public class GetTeamsChannelMessageReply : PnPGraphCmdlet { [Parameter(Mandatory = true)] @@ -27,13 +28,13 @@ public class GetTeamsChannelMessageReply : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken); + var groupId = Team.GetGroupId(this, Connection, AccessToken); if (groupId == null) { throw new PSArgumentException("Group not found"); } - var channelId = Channel.GetId(Connection, AccessToken, groupId); + var channelId = Channel.GetId(this, Connection, AccessToken, groupId); if (channelId == null) { throw new PSArgumentException("Channel not found"); @@ -54,12 +55,12 @@ protected override void ExecuteCmdlet() throw new PSArgumentException($"Don't specify {nameof(IncludeDeleted)} when using the {nameof(Identity)} parameter."); } - var reply = TeamsUtility.GetMessageReplyAsync(Connection, AccessToken, groupId, channelId, messageId, Identity.GetId()).GetAwaiter().GetResult(); + var reply = TeamsUtility.GetMessageReply(this, Connection, AccessToken, groupId, channelId, messageId, Identity.GetId()); WriteObject(reply); } else { - var replies = TeamsUtility.GetMessageRepliesAsync(Connection, AccessToken, groupId, channelId, messageId, IncludeDeleted).GetAwaiter().GetResult(); + var replies = TeamsUtility.GetMessageReplies(this, Connection, AccessToken, groupId, channelId, messageId, IncludeDeleted); WriteObject(replies, true); } } diff --git a/src/Commands/Teams/GetTeamsChannelUser.cs b/src/Commands/Teams/GetTeamsChannelUser.cs index 168f9411b..8a15a549d 100644 --- a/src/Commands/Teams/GetTeamsChannelUser.cs +++ b/src/Commands/Teams/GetTeamsChannelUser.cs @@ -8,6 +8,7 @@ namespace PnP.PowerShell.Commands.Teams { [Cmdlet(VerbsCommon.Get, "PnPTeamsChannelUser")] [RequiredMinimalApiPermissions("ChannelMember.Read.All")] + [RequiredMinimalApiPermissions("ChannelMember.ReadWrite.All")] public class GetTeamsChannelUser : PnPGraphCmdlet { [Parameter(Mandatory = true)] @@ -25,13 +26,13 @@ public class GetTeamsChannelUser : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken); + var groupId = Team.GetGroupId(this, Connection, AccessToken); if (groupId == null) { throw new PSArgumentException("Group not found"); } - var channelId = Channel.GetId(Connection, AccessToken, groupId); + var channelId = Channel.GetId(this, Connection, AccessToken, groupId); if (channelId == null) { throw new PSArgumentException("Channel not found"); @@ -39,11 +40,11 @@ protected override void ExecuteCmdlet() if (ParameterSpecified(nameof(Identity))) { - WriteObject(Identity.GetMembershipAsync(Connection, AccessToken, groupId, channelId).GetAwaiter().GetResult()); + WriteObject(Identity.GetMembership(this, Connection, AccessToken, groupId, channelId)); } else { - WriteObject(TeamsUtility.GetChannelMembersAsync(Connection, AccessToken, groupId, channelId, Role).GetAwaiter().GetResult(), true); + WriteObject(TeamsUtility.GetChannelMembers(this, Connection, AccessToken, groupId, channelId, Role), true); } } } diff --git a/src/Commands/Teams/GetTeamsPrimaryChannel.cs b/src/Commands/Teams/GetTeamsPrimaryChannel.cs index d0a7f2fe6..a593b0201 100644 --- a/src/Commands/Teams/GetTeamsPrimaryChannel.cs +++ b/src/Commands/Teams/GetTeamsPrimaryChannel.cs @@ -16,10 +16,10 @@ public class GetTeamsPrimaryChannel : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken); + var groupId = Team.GetGroupId(this, Connection, AccessToken); if (groupId != null) { - WriteObject(TeamsUtility.GetPrimaryChannelAsync(AccessToken, Connection, groupId).GetAwaiter().GetResult()); + WriteObject(TeamsUtility.GetPrimaryChannel(this, AccessToken, Connection, groupId)); } else { throw new PSArgumentException("Team not found", nameof(Team)); diff --git a/src/Commands/Teams/GetTeamsTab.cs b/src/Commands/Teams/GetTeamsTab.cs index 8c9097f27..46e43c3d0 100644 --- a/src/Commands/Teams/GetTeamsTab.cs +++ b/src/Commands/Teams/GetTeamsTab.cs @@ -9,6 +9,7 @@ namespace PnP.PowerShell.Commands.Teams { [Cmdlet(VerbsCommon.Get, "PnPTeamsTab")] [RequiredMinimalApiPermissions("Group.Read.All")] + [RequiredMinimalApiPermissions("Group.ReadWrite.All")] public class GetTeamsTab : PnPGraphCmdlet { @@ -23,10 +24,10 @@ public class GetTeamsTab : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken); + var groupId = Team.GetGroupId(this, Connection, AccessToken); if (groupId != null) { - var channelId = Channel.GetId(Connection, AccessToken, groupId); + var channelId = Channel.GetId(this, Connection, AccessToken, groupId); if (!string.IsNullOrEmpty(channelId)) { if (ParameterSpecified(nameof(Identity))) @@ -35,7 +36,7 @@ protected override void ExecuteCmdlet() } else { - WriteObject(TeamsUtility.GetTabsAsync(AccessToken, Connection, groupId, channelId).GetAwaiter().GetResult(), true); + WriteObject(TeamsUtility.GetTabs(this, AccessToken, Connection, groupId, channelId), true); } } else diff --git a/src/Commands/Teams/GetTeamsTag.cs b/src/Commands/Teams/GetTeamsTag.cs index cf8baf3b1..85e5d3a28 100644 --- a/src/Commands/Teams/GetTeamsTag.cs +++ b/src/Commands/Teams/GetTeamsTag.cs @@ -10,6 +10,7 @@ namespace PnP.PowerShell.Commands.Teams { [Cmdlet(VerbsCommon.Get, "PnPTeamsTag")] [RequiredMinimalApiPermissions("TeamworkTag.Read")] + [RequiredMinimalApiPermissions("TeamworkTag.ReadWrite")] public class GetTeamsTag : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true)] @@ -20,7 +21,7 @@ public class GetTeamsTag : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken); + var groupId = Team.GetGroupId(this, Connection, AccessToken); if (string.IsNullOrEmpty(groupId)) { throw new PSArgumentException("Team not found"); @@ -28,12 +29,12 @@ protected override void ExecuteCmdlet() if (ParameterSpecified(nameof(Identity))) { - var tags = Identity.GetTag(Connection, AccessToken, groupId); + var tags = Identity.GetTag(this, Connection, AccessToken, groupId); WriteObject(tags, false); } else { - var tags = TeamsUtility.GetTagsAsync(AccessToken, Connection, groupId).GetAwaiter().GetResult(); + var tags = TeamsUtility.GetTags(this, AccessToken, Connection, groupId); WriteObject(tags, true); } } diff --git a/src/Commands/Teams/GetTeamsTeam.cs b/src/Commands/Teams/GetTeamsTeam.cs index e5a22a089..11f618f08 100644 --- a/src/Commands/Teams/GetTeamsTeam.cs +++ b/src/Commands/Teams/GetTeamsTeam.cs @@ -8,6 +8,7 @@ namespace PnP.PowerShell.Commands.Teams { [Cmdlet(VerbsCommon.Get, "PnPTeamsTeam", DefaultParameterSetName = ParameterSet_Identity)] [RequiredMinimalApiPermissions("Group.Read.All")] + [RequiredMinimalApiPermissions("Group.ReadWrite.All")] public class GetTeamsTeam : PnPGraphCmdlet { private const string ParameterSet_Identity = "Identity"; @@ -28,19 +29,19 @@ protected override void ExecuteCmdlet() { if (ParameterSpecified(nameof(Identity))) { - var groupId = Identity.GetGroupId(Connection, AccessToken); + var groupId = Identity.GetGroupId(this, Connection, AccessToken); if(groupId == null) { throw new PSArgumentException("Team not found", nameof(Identity)); } else - { - WriteObject(TeamsUtility.GetTeamAsync(AccessToken, Connection, groupId).GetAwaiter().GetResult()); + { + WriteObject(TeamsUtility.GetTeam(this, AccessToken, Connection, groupId)); } } else { - WriteObject(TeamsUtility.GetTeamsAsync(AccessToken, Connection, Filter).GetAwaiter().GetResult(), true); + WriteObject(TeamsUtility.GetTeamUsingFilter(this, AccessToken, Connection, Filter)); } } } diff --git a/src/Commands/Teams/GetTeamsUser.cs b/src/Commands/Teams/GetTeamsUser.cs index c34e92cf3..ef896a587 100644 --- a/src/Commands/Teams/GetTeamsUser.cs +++ b/src/Commands/Teams/GetTeamsUser.cs @@ -12,6 +12,7 @@ namespace PnP.PowerShell.Commands.Teams { [Cmdlet(VerbsCommon.Get, "PnPTeamsUser")] [RequiredMinimalApiPermissions("Group.Read.All")] + [RequiredMinimalApiPermissions("Group.ReadWrite.All")] public class GetTeamsUser : PnPGraphCmdlet { [Parameter(Mandatory = true)] @@ -25,22 +26,22 @@ public class GetTeamsUser : PnPGraphCmdlet public string Role; protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken); + var groupId = Team.GetGroupId(this, Connection, AccessToken); if (groupId != null) { try { if (ParameterSpecified(nameof(Channel))) { - var teamChannels = TeamsUtility.GetChannelsAsync(AccessToken, Connection, groupId).GetAwaiter().GetResult(); + var teamChannels = TeamsUtility.GetChannels(this, AccessToken, Connection, groupId); - var channelId = Channel.GetId(Connection, AccessToken, groupId); + var channelId = Channel.GetId(this, Connection, AccessToken, groupId); var requestedChannel = teamChannels.FirstOrDefault(c => c.Id == channelId); if (!string.IsNullOrEmpty(channelId) && requestedChannel != null && requestedChannel.MembershipType.ToLower() == TeamChannelType.Private.ToString().ToLower()) { - WriteObject(TeamsUtility.GetUsersAsync(Connection, AccessToken, groupId, channelId, Role).GetAwaiter().GetResult(), true); + WriteObject(TeamsUtility.GetUsers(this, Connection, AccessToken, groupId, channelId, Role), true); } else { @@ -49,7 +50,7 @@ protected override void ExecuteCmdlet() } else { - WriteObject(TeamsUtility.GetUsersAsync(Connection, AccessToken, groupId, Role).GetAwaiter().GetResult(), true); + WriteObject(TeamsUtility.GetUsers(this, Connection, AccessToken, groupId, Role), true); } } catch (GraphException ex) diff --git a/src/Commands/Teams/NewTeamsApp.cs b/src/Commands/Teams/NewTeamsApp.cs index 15197431d..9abe97ab9 100644 --- a/src/Commands/Teams/NewTeamsApp.cs +++ b/src/Commands/Teams/NewTeamsApp.cs @@ -27,7 +27,7 @@ protected override void ExecuteCmdlet() try { var bytes = System.IO.File.ReadAllBytes(Path); - TeamsUtility.AddAppAsync(Connection, AccessToken, bytes).GetAwaiter().GetResult(); + TeamsUtility.AddApp(this, Connection, AccessToken, bytes); } catch (GraphException ex) { diff --git a/src/Commands/Teams/NewTeamsTeam.cs b/src/Commands/Teams/NewTeamsTeam.cs index 6429b9735..176c596a4 100644 --- a/src/Commands/Teams/NewTeamsTeam.cs +++ b/src/Commands/Teams/NewTeamsTeam.cs @@ -147,7 +147,7 @@ protected override void ExecuteCmdlet() } } - WriteObject(TeamsUtility.NewTeamAsync(AccessToken, Connection, GroupId, DisplayName, Description, Classification, MailNickName, (GroupVisibility)Enum.Parse(typeof(GroupVisibility), Visibility.ToString()), teamCI, Owners, Members, SensitivityLabels, Template, ResourceBehaviorOptions).GetAwaiter().GetResult()); + WriteObject(TeamsUtility.NewTeam(this, AccessToken, Connection, GroupId, DisplayName, Description, Classification, MailNickName, (GroupVisibility)Enum.Parse(typeof(GroupVisibility), Visibility.ToString()), teamCI, Owners, Members, SensitivityLabels, Template, ResourceBehaviorOptions)); } } } diff --git a/src/Commands/Teams/RemoveTeamsApp.cs b/src/Commands/Teams/RemoveTeamsApp.cs index 7b5f9a50b..0c1f6d76e 100644 --- a/src/Commands/Teams/RemoveTeamsApp.cs +++ b/src/Commands/Teams/RemoveTeamsApp.cs @@ -20,14 +20,14 @@ public class RemoveTeamsApp : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var app = Identity.GetApp(Connection, AccessToken); + var app = Identity.GetApp(this, Connection, AccessToken); if (app == null) { throw new PSArgumentException("App not found"); } if (Force || ShouldContinue($"Do you want to remove {app.DisplayName}?", Properties.Resources.Confirm)) { - var response = TeamsUtility.DeleteAppAsync(Connection, AccessToken, app.Id).GetAwaiter().GetResult(); + var response = TeamsUtility.DeleteApp(this, Connection, AccessToken, app.Id); if (!response.IsSuccessStatusCode) { if (GraphHelper.TryGetGraphException(response, out GraphException ex)) diff --git a/src/Commands/Teams/RemoveTeamsChannel.cs b/src/Commands/Teams/RemoveTeamsChannel.cs index b12d78e22..4d7dc778c 100644 --- a/src/Commands/Teams/RemoveTeamsChannel.cs +++ b/src/Commands/Teams/RemoveTeamsChannel.cs @@ -27,13 +27,13 @@ protected override void ExecuteCmdlet() { if (Force || ShouldContinue("Removing the channel will also remove all the messages in the channel.", Properties.Resources.Confirm)) { - var groupId = Team.GetGroupId(Connection, AccessToken); + var groupId = Team.GetGroupId(this, Connection, AccessToken); if (groupId != null) { - var channel = Identity.GetChannel(Connection, AccessToken, groupId); + var channel = Identity.GetChannel(this, Connection, AccessToken, groupId); if (channel != null) { - var response = TeamsUtility.DeleteChannelAsync(AccessToken, Connection, groupId, channel.Id).GetAwaiter().GetResult(); + var response = TeamsUtility.DeleteChannel(this, AccessToken, Connection, groupId, channel.Id); if (!response.IsSuccessStatusCode) { if (GraphHelper.TryGetGraphException(response, out GraphException ex)) @@ -48,16 +48,16 @@ protected override void ExecuteCmdlet() WriteError(new ErrorRecord(new Exception($"Channel remove failed"), "REMOVEFAILED", ErrorCategory.InvalidResult, this)); } } - else - { - throw new PSArgumentException("Channel not found"); - } } else { - throw new PSArgumentException("Team not found"); + throw new PSArgumentException("Channel not found"); } } + else + { + throw new PSArgumentException("Team not found"); + } } } } diff --git a/src/Commands/Teams/RemoveTeamsChannelUser.cs b/src/Commands/Teams/RemoveTeamsChannelUser.cs index 1a46995ac..b85cdd710 100644 --- a/src/Commands/Teams/RemoveTeamsChannelUser.cs +++ b/src/Commands/Teams/RemoveTeamsChannelUser.cs @@ -26,19 +26,19 @@ public class RemoveTeamsChannelUser : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken); + var groupId = Team.GetGroupId(this, Connection, AccessToken); if (string.IsNullOrEmpty(groupId)) { throw new PSArgumentException("Group not found"); } - var channelId = Channel.GetId(Connection, AccessToken, groupId); + var channelId = Channel.GetId(this, Connection, AccessToken, groupId); if (string.IsNullOrEmpty(channelId)) { throw new PSArgumentException("Channel not found in the specified team"); } - var memberId = Identity.GetIdAsync(Connection, AccessToken, groupId, channelId).GetAwaiter().GetResult(); + var memberId = Identity.GetId(this, Connection, AccessToken, groupId, channelId); if (string.IsNullOrEmpty(memberId)) { throw new PSArgumentException("User was not found in the specified Teams channel"); @@ -46,8 +46,7 @@ protected override void ExecuteCmdlet() if (Force || ShouldContinue("Remove specified member from the Microsoft Teams channel?", Resources.Confirm)) { - var response = TeamsUtility.DeleteChannelMemberAsync(Connection, AccessToken, groupId, channelId, memberId).GetAwaiter().GetResult(); - + var response = TeamsUtility.DeleteChannelMember(this, Connection, AccessToken, groupId, channelId, memberId); if (!response.IsSuccessStatusCode) { if (GraphHelper.TryGetGraphException(response, out var ex) && !string.IsNullOrEmpty(ex.Error.Message)) diff --git a/src/Commands/Teams/RemoveTeamsTab.cs b/src/Commands/Teams/RemoveTeamsTab.cs index 8e033ddd0..e3a9f4489 100644 --- a/src/Commands/Teams/RemoveTeamsTab.cs +++ b/src/Commands/Teams/RemoveTeamsTab.cs @@ -27,10 +27,10 @@ public class RemoveTeamsTab : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken); + var groupId = Team.GetGroupId(this, Connection, AccessToken); if (groupId != null) { - var channelId = Channel.GetId(Connection, AccessToken, groupId); + var channelId = Channel.GetId(this, Connection, AccessToken, groupId); if (channelId != null) { var tab = Identity.GetTab(this, Connection, AccessToken, groupId, channelId); @@ -38,7 +38,7 @@ protected override void ExecuteCmdlet() { if (Force || ShouldContinue("Removing the tab will remove the settings of this tab too.", Properties.Resources.Confirm)) { - var response = TeamsUtility.DeleteTabAsync(AccessToken, Connection, groupId, channelId, tab.Id).GetAwaiter().GetResult(); + var response = TeamsUtility.DeleteTab(this, AccessToken, Connection, groupId, channelId, tab.Id); if (!response.IsSuccessStatusCode) { if (GraphHelper.TryGetGraphException(response, out GraphException ex)) diff --git a/src/Commands/Teams/RemoveTeamsTag.cs b/src/Commands/Teams/RemoveTeamsTag.cs index e020f39e3..3393dcffa 100644 --- a/src/Commands/Teams/RemoveTeamsTag.cs +++ b/src/Commands/Teams/RemoveTeamsTag.cs @@ -23,15 +23,15 @@ public class RemoveTeamsTag : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken); + var groupId = Team.GetGroupId(this, Connection, AccessToken); if (groupId != null) { - var tag = Identity.GetTag(Connection, AccessToken, groupId); + var tag = Identity.GetTag(this, Connection, AccessToken, groupId); if (tag != null) { if (Force || ShouldContinue("Do you want to remove this tag ?", Properties.Resources.Confirm)) { - var response = TeamsUtility.DeleteTagAsync(Connection, AccessToken, groupId, tag.Id).GetAwaiter().GetResult(); + var response = TeamsUtility.DeleteTag(this, Connection, AccessToken, groupId, tag.Id); if (!response.IsSuccessStatusCode) { if (GraphHelper.TryGetGraphException(response, out GraphException ex)) diff --git a/src/Commands/Teams/RemoveTeamsTeam.cs b/src/Commands/Teams/RemoveTeamsTeam.cs index 2d451ad1a..3b90c4543 100644 --- a/src/Commands/Teams/RemoveTeamsTeam.cs +++ b/src/Commands/Teams/RemoveTeamsTeam.cs @@ -21,12 +21,12 @@ public class RemoveTeamsTeam : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Identity.GetGroupId(Connection, AccessToken); + var groupId = Identity.GetGroupId(this, Connection, AccessToken); if (groupId != null) { if (Force || ShouldContinue("Removing the team will remove all messages in all channels in the team.", Properties.Resources.Confirm)) { - var response = TeamsUtility.DeleteTeamAsync(AccessToken, Connection, groupId).GetAwaiter().GetResult(); + var response = TeamsUtility.DeleteTeam(this, AccessToken, Connection, groupId); if (!response.IsSuccessStatusCode) { if (GraphHelper.TryGetGraphException(response, out GraphException ex)) diff --git a/src/Commands/Teams/RemoveTeamsUser.cs b/src/Commands/Teams/RemoveTeamsUser.cs index 3409403ab..c515b90cf 100644 --- a/src/Commands/Teams/RemoveTeamsUser.cs +++ b/src/Commands/Teams/RemoveTeamsUser.cs @@ -25,14 +25,14 @@ public class RemoveTeamsUser : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken); + var groupId = Team.GetGroupId(this, Connection, AccessToken); if (groupId != null) { try { if (Force || ShouldContinue($"Remove user with UPN {User}?", Properties.Resources.Confirm)) { - TeamsUtility.DeleteUserAsync(Connection, AccessToken, groupId, User, Role).GetAwaiter().GetResult(); + TeamsUtility.DeleteUser(this, Connection, AccessToken, groupId, User, Role); } } catch (GraphException ex) diff --git a/src/Commands/Teams/SetTeamsChannel.cs b/src/Commands/Teams/SetTeamsChannel.cs index 6a834e6cf..7c9c920df 100644 --- a/src/Commands/Teams/SetTeamsChannel.cs +++ b/src/Commands/Teams/SetTeamsChannel.cs @@ -42,8 +42,8 @@ public class SetTeamsChannel : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken) ?? throw new PSArgumentException("Group not found"); - var teamChannel = Identity.GetChannel(Connection, AccessToken, groupId) ?? throw new PSArgumentException("Channel not found"); + var groupId = Team.GetGroupId(this, Connection, AccessToken) ?? throw new PSArgumentException("Group not found"); + var teamChannel = Identity.GetChannel(this, Connection, AccessToken, groupId) ?? throw new PSArgumentException("Channel not found"); // Flag to indicate if we have to use the beta endpoint to perform the update var betaRequired = false; @@ -102,7 +102,7 @@ protected override void ExecuteCmdlet() teamChannel.MembershipType = null; try { - var updated = TeamsUtility.UpdateChannelAsync(Connection, AccessToken, groupId, teamChannel.Id, teamChannel, useBeta: betaRequired).GetAwaiter().GetResult(); + var updated = TeamsUtility.UpdateChannel(this, Connection, AccessToken, groupId, teamChannel.Id, teamChannel, useBeta: betaRequired); WriteObject(updated); } catch (GraphException ex) diff --git a/src/Commands/Teams/SetTeamsChannelUser.cs b/src/Commands/Teams/SetTeamsChannelUser.cs index 30d29a906..ee7c2aba1 100644 --- a/src/Commands/Teams/SetTeamsChannelUser.cs +++ b/src/Commands/Teams/SetTeamsChannelUser.cs @@ -26,19 +26,19 @@ public class SetTeamsChannelUser : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken); + var groupId = Team.GetGroupId(this, Connection, AccessToken); if (groupId == null) { throw new PSArgumentException("Group not found"); } - var channelId = Channel.GetId(Connection, AccessToken, groupId); + var channelId = Channel.GetId(this, Connection, AccessToken, groupId); if (channelId == null) { throw new PSArgumentException("Channel not found"); } - var membershipId = Identity.GetIdAsync(Connection, AccessToken, groupId, channelId).GetAwaiter().GetResult(); + var membershipId = Identity.GetId(this, Connection, AccessToken, groupId, channelId); if (string.IsNullOrEmpty(membershipId)) { throw new PSArgumentException("User was not found in the specified Teams channel"); @@ -46,7 +46,7 @@ protected override void ExecuteCmdlet() try { - var updatedMember = TeamsUtility.UpdateChannelMemberAsync(Connection, AccessToken, groupId, channelId, membershipId, Role).GetAwaiter().GetResult(); + var updatedMember = TeamsUtility.UpdateChannelMember(this, Connection, AccessToken, groupId, channelId, membershipId, Role); WriteObject(updatedMember); } catch (GraphException ex) diff --git a/src/Commands/Teams/SetTeamsTab.cs b/src/Commands/Teams/SetTeamsTab.cs index 6accc454d..cb473ef22 100644 --- a/src/Commands/Teams/SetTeamsTab.cs +++ b/src/Commands/Teams/SetTeamsTab.cs @@ -24,10 +24,10 @@ public class SetTeamsTab : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken); + var groupId = Team.GetGroupId(this, Connection, AccessToken); if (groupId != null) { - var channelId = Channel.GetId(Connection, AccessToken, groupId); + var channelId = Channel.GetId(this, Connection, AccessToken, groupId); if (channelId != null) { var tab = Identity.GetTab(this,Connection, AccessToken, groupId, channelId); @@ -37,7 +37,7 @@ protected override void ExecuteCmdlet() { tab.DisplayName = DisplayName; } - TeamsUtility.UpdateTabAsync(Connection, AccessToken, groupId, channelId, tab).GetAwaiter().GetResult(); + TeamsUtility.UpdateTab(this, Connection, AccessToken, groupId, channelId, tab); } else { diff --git a/src/Commands/Teams/SetTeamsTag.cs b/src/Commands/Teams/SetTeamsTag.cs index 609192692..b524e6d5b 100644 --- a/src/Commands/Teams/SetTeamsTag.cs +++ b/src/Commands/Teams/SetTeamsTag.cs @@ -21,15 +21,15 @@ public class SetTeamsTag : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken); + var groupId = Team.GetGroupId(this, Connection, AccessToken); if (groupId != null) { - var tag = Identity.GetTag(Connection, AccessToken, groupId); + var tag = Identity.GetTag(this, Connection, AccessToken, groupId); if (tag != null) { if (ParameterSpecified(nameof(DisplayName)) && tag.DisplayName != DisplayName) { - TeamsUtility.UpdateTagAsync(Connection, AccessToken, groupId, tag.Id, DisplayName).GetAwaiter().GetResult(); + TeamsUtility.UpdateTag(this, Connection, AccessToken, groupId, tag.Id, DisplayName); } } else diff --git a/src/Commands/Teams/SetTeamsTeam.cs b/src/Commands/Teams/SetTeamsTeam.cs index de1761cde..0e4813f50 100644 --- a/src/Commands/Teams/SetTeamsTeam.cs +++ b/src/Commands/Teams/SetTeamsTeam.cs @@ -84,12 +84,12 @@ public class SetTeamsTeam : PnPGraphCmdlet public bool? AllowCreatePrivateChannels; protected override void ExecuteCmdlet() { - var groupId = Identity.GetGroupId(Connection, AccessToken); + var groupId = Identity.GetGroupId(this, Connection, AccessToken); if (groupId != null) { try { - var team = TeamsUtility.GetTeamAsync(AccessToken, Connection, groupId).GetAwaiter().GetResult(); + var team = TeamsUtility.GetTeam(this, AccessToken, Connection, groupId); var updateGroup = false; var group = new Group(); if (team != null) @@ -125,7 +125,7 @@ protected override void ExecuteCmdlet() if(updateGroup) { - TeamsUtility.UpdateGroupAsync(Connection, AccessToken, groupId, group).GetAwaiter().GetResult(); + TeamsUtility.UpdateGroup(this, Connection, AccessToken, groupId, group); } var teamCI = new TeamCreationInformation(); @@ -147,7 +147,7 @@ protected override void ExecuteCmdlet() teamCI.Classification = ParameterSpecified(nameof(Classification)) ? Classification : null; teamCI.AllowCreatePrivateChannels = ParameterSpecified(nameof(AllowCreatePrivateChannels)) ? AllowCreatePrivateChannels : null; - var updated = TeamsUtility.UpdateTeamAsync(Connection, AccessToken, groupId, teamCI.ToTeam(group.Visibility.Value)).GetAwaiter().GetResult(); + var updated = TeamsUtility.UpdateTeam(this, Connection, AccessToken, groupId, teamCI.ToTeam(group.Visibility.Value)); WriteObject(updated); } } diff --git a/src/Commands/Teams/SetTeamsTeamArchivedState.cs b/src/Commands/Teams/SetTeamsTeamArchivedState.cs index daa43d617..82cf38177 100644 --- a/src/Commands/Teams/SetTeamsTeamArchivedState.cs +++ b/src/Commands/Teams/SetTeamsTeamArchivedState.cs @@ -30,15 +30,15 @@ protected override void ExecuteCmdlet() { throw new PSArgumentException("You can only modify the read only state of a site when archiving a team"); } - var groupId = Identity.GetGroupId(Connection, AccessToken); + var groupId = Identity.GetGroupId(this, Connection, AccessToken); if (groupId != null) { - var team = Identity.GetTeam(Connection, AccessToken); + var team = Identity.GetTeam(this, Connection, AccessToken); if (Archived == team.IsArchived) { throw new PSInvalidOperationException($"Team {team.DisplayName} {(Archived ? "has already been" : "is not")} archived"); } - var response = TeamsUtility.SetTeamArchivedStateAsync(Connection, AccessToken, groupId, Archived, SetSiteReadOnlyForMembers).GetAwaiter().GetResult(); + var response = TeamsUtility.SetTeamArchivedState(this, Connection, AccessToken, groupId, Archived, SetSiteReadOnlyForMembers); if (!response.IsSuccessStatusCode) { if (GraphHelper.TryGetGraphException(response, out GraphException ex)) diff --git a/src/Commands/Teams/SetTeamsTeamPicture.cs b/src/Commands/Teams/SetTeamsTeamPicture.cs index 8a88f2826..cb5babac1 100644 --- a/src/Commands/Teams/SetTeamsTeamPicture.cs +++ b/src/Commands/Teams/SetTeamsTeamPicture.cs @@ -20,7 +20,7 @@ public class SetTeamsTeamPicture : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken); + var groupId = Team.GetGroupId(this, Connection, AccessToken); if (groupId != null) { if (!System.IO.Path.IsPathRooted(Path)) @@ -51,7 +51,7 @@ protected override void ExecuteCmdlet() throw new PSArgumentException("File is not of a supported content type (jpg/png)"); } var byteArray = File.ReadAllBytes(Path); - TeamsUtility.SetTeamPictureAsync(Connection, AccessToken, groupId, byteArray, contentType).GetAwaiter().GetResult(); + TeamsUtility.SetTeamPictureAsync(this, Connection, AccessToken, groupId, byteArray, contentType); } else { diff --git a/src/Commands/Teams/SubmitTeamsChannelMessage.cs b/src/Commands/Teams/SubmitTeamsChannelMessage.cs index 78bec5823..09614fb10 100644 --- a/src/Commands/Teams/SubmitTeamsChannelMessage.cs +++ b/src/Commands/Teams/SubmitTeamsChannelMessage.cs @@ -29,10 +29,10 @@ public class SubmitTeamsChannelMessage : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken); + var groupId = Team.GetGroupId(this, Connection, AccessToken); if (groupId != null) { - var channel = Channel.GetChannel(Connection, AccessToken, groupId); + var channel = Channel.GetChannel(this, Connection, AccessToken, groupId); if (channel != null) { var channelMessage = new TeamChannelMessage(); @@ -40,7 +40,7 @@ protected override void ExecuteCmdlet() channelMessage.Body.Content = Message; channelMessage.Body.ContentType = ContentType == TeamChannelMessageContentType.Html ? "html" : "text"; - TeamsUtility.PostMessageAsync(Connection, AccessToken, groupId, channel.Id, channelMessage).GetAwaiter().GetResult(); + TeamsUtility.PostMessage(this, Connection, AccessToken, groupId, channel.Id, channelMessage); } else { diff --git a/src/Commands/Teams/UpdateTeamsApp.cs b/src/Commands/Teams/UpdateTeamsApp.cs index 28c30a0c5..4cfe0ad83 100644 --- a/src/Commands/Teams/UpdateTeamsApp.cs +++ b/src/Commands/Teams/UpdateTeamsApp.cs @@ -29,12 +29,12 @@ protected override void ExecuteCmdlet() if (System.IO.File.Exists(Path)) { - var app = Identity.GetApp(Connection, AccessToken); + var app = Identity.GetApp(this, Connection, AccessToken); if (app != null) { var bytes = System.IO.File.ReadAllBytes(Path); - var response = TeamsUtility.UpdateAppAsync(Connection, AccessToken, bytes, app.Id).GetAwaiter().GetResult(); + var response = TeamsUtility.UpdateApp(this, Connection, AccessToken, bytes, app.Id); if (!response.IsSuccessStatusCode) { if (GraphHelper.TryGetGraphException(response, out GraphException ex)) diff --git a/src/Commands/Teams/UpdateTeamsUser.cs b/src/Commands/Teams/UpdateTeamsUser.cs index 65e324da1..b610698e9 100644 --- a/src/Commands/Teams/UpdateTeamsUser.cs +++ b/src/Commands/Teams/UpdateTeamsUser.cs @@ -26,24 +26,24 @@ public class UpdateTeamsUser : PnPGraphCmdlet protected override void ExecuteCmdlet() { - var groupId = Team.GetGroupId(Connection, AccessToken); + var groupId = Team.GetGroupId(this, Connection, AccessToken); if (groupId != null) { try { if (Force || ShouldContinue($"Update role for user with UPN {User} ?", Properties.Resources.Confirm)) { - var teamsUser = TeamsUtility.GetUsersAsync(Connection, AccessToken, groupId, string.Empty).GetAwaiter().GetResult(); + var teamsUser = TeamsUtility.GetUsers(this, Connection, AccessToken, groupId, string.Empty); var specifiedUser = teamsUser.Find(u => u.UserPrincipalName.ToLower() == User.ToLower()); if (specifiedUser != null) { // No easy way to get member Id for teams endpoint, need to rely on display name filter to fetch memberId of the specified user and then update - var teamUserWithDisplayName = TeamsUtility.GetTeamUsersWithDisplayNameAsync(Connection, AccessToken, groupId, specifiedUser.DisplayName).GetAwaiter().GetResult(); - var userToUpdate = teamUserWithDisplayName.Find(u => u.UserId == specifiedUser.Id); + var teamUserWithDisplayName = TeamsUtility.GetTeamUsersWithDisplayName(this, Connection, AccessToken, groupId, specifiedUser.DisplayName); + var userToUpdate = teamUserWithDisplayName.Find(u => u.UserId == specifiedUser.Id) ?? throw new PSArgumentException($"User found in the M365 group but not in the team "); // Pass the member id of the user whose role we are changing - WriteObject(TeamsUtility.UpdateTeamUserRole(Connection, AccessToken, groupId, userToUpdate.Id, Role).GetAwaiter().GetResult()); + WriteObject(TeamsUtility.UpdateTeamUserRole(this, Connection, AccessToken, groupId, userToUpdate.Id, Role)); } else { diff --git a/src/Commands/UserProfiles/ExportUserProfile.cs b/src/Commands/UserProfiles/ExportUserProfile.cs index 8d6f190d1..bd63bb554 100644 --- a/src/Commands/UserProfiles/ExportUserProfile.cs +++ b/src/Commands/UserProfiles/ExportUserProfile.cs @@ -21,7 +21,7 @@ protected override void ExecuteCmdlet() hostUrl = hostUrl.Substring(0, hostUrl.Length - 1); } var normalizedUserName = UrlUtilities.UrlEncode($"i:0#.f|membership|{LoginName}"); - var results = RestHelper.GetAsync>(this.HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/GetUserProfileProperties(accountName=@a)?@a='{normalizedUserName}'", AdminContext, false).GetAwaiter().GetResult(); + var results = RestHelper.Get>(this.HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/GetUserProfileProperties(accountName=@a)?@a='{normalizedUserName}'", AdminContext, false); var record = new PSObject(); foreach (var item in results.Items) { diff --git a/src/Commands/UserProfiles/RemoveUserProfile.cs b/src/Commands/UserProfiles/RemoveUserProfile.cs index a4faa900c..4e66b6e0b 100644 --- a/src/Commands/UserProfiles/RemoveUserProfile.cs +++ b/src/Commands/UserProfiles/RemoveUserProfile.cs @@ -27,11 +27,11 @@ protected override void ExecuteCmdlet() if (!ParameterSpecified(nameof(UserId))) { - RestHelper.PostAsync(this.HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/HardDeleteUserProfile(accountName=@a)?@a='{normalizedUserName}'", AdminContext).GetAwaiter().GetResult(); + RestHelper.Post(this.HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/HardDeleteUserProfile(accountName=@a)?@a='{normalizedUserName}'", AdminContext); } else { - RestHelper.PostAsync(this.HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/HardDeleteUserProfile(accountName=@a,userId='{UserId}')?@a='{normalizedUserName}'", AdminContext).GetAwaiter().GetResult(); + RestHelper.Post(this.HttpClient, $"{hostUrl}/_api/sp.userprofiles.peoplemanager/HardDeleteUserProfile(accountName=@a,userId='{UserId}')?@a='{normalizedUserName}'", AdminContext); } WriteVerbose($"Completed deletion of user profile {LoginName}"); diff --git a/src/Commands/Utilities/Auth/ARMEndpoint.cs b/src/Commands/Utilities/Auth/ARMEndpoint.cs new file mode 100644 index 000000000..acc3ed7aa --- /dev/null +++ b/src/Commands/Utilities/Auth/ARMEndpoint.cs @@ -0,0 +1,39 @@ +using PnP.PowerShell.Commands.Base; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PnP.PowerShell.Commands.Utilities.Auth +{ + internal static class ARMEndpoint + { + public static string GetARMEndpoint(PnPConnection connection) + { + string endpoint; + switch (connection.AzureEnvironment) + { + case Framework.AzureEnvironment.Production: + endpoint = "https://management.azure.com/.default"; + break; + case Framework.AzureEnvironment.China: + endpoint = "https://management.chinacloudapi.cn/.default"; + break; + case Framework.AzureEnvironment.USGovernment: + endpoint = "https://management.usgovcloudapi.net/.default"; + break; + case Framework.AzureEnvironment.USGovernmentHigh: + endpoint = "https://management.usgovcloudapi.net/.default"; + break; + case Framework.AzureEnvironment.USGovernmentDoD: + endpoint = "https://management.usgovcloudapi.net/.default"; + break; + default: + endpoint = "https://management.azure.com/.default"; + break; + } + return endpoint; + } + } +} diff --git a/src/Commands/Utilities/AzureADGroupsUtility.cs b/src/Commands/Utilities/AzureADGroupsUtility.cs index 6bfcace78..f9690d647 100644 --- a/src/Commands/Utilities/AzureADGroupsUtility.cs +++ b/src/Commands/Utilities/AzureADGroupsUtility.cs @@ -3,17 +3,16 @@ using PnP.PowerShell.Commands.Utilities.REST; using System; using System.Linq; -using System.Threading.Tasks; using System.Collections.Generic; -using PnP.PowerShell.Commands.Model; +using System.Management.Automation; namespace PnP.PowerShell.Commands.Utilities { internal static class AzureADGroupsUtility { - internal static async Task GetGroupAsync(PnPConnection connection, Guid groupId, string accessToken) + internal static Group GetGroup(Cmdlet cmdlet, PnPConnection connection, Guid groupId, string accessToken) { - var results = await GraphHelper.GetAsync>(connection, $"v1.0/groups?$filter=id eq '{groupId}'", accessToken); + var results = GraphHelper.Get>(cmdlet, connection, $"v1.0/groups?$filter=id eq '{groupId}'", accessToken); if (results != null && results.Items.Any()) { @@ -23,9 +22,9 @@ internal static async Task GetGroupAsync(PnPConnection connection, Guid g return null; } - internal static async Task GetGroupAsync(PnPConnection connection, string displayName, string accessToken) + internal static Group GetGroup(Cmdlet cmdlet, PnPConnection connection, string displayName, string accessToken) { - var results = await GraphHelper.GetAsync>(connection, $"v1.0/groups?$filter=(displayName eq '{displayName}' or mailNickName eq '{displayName}')", accessToken); + var results = GraphHelper.Get>(cmdlet, connection, $"v1.0/groups?$filter=(displayName eq '{displayName}' or mailNickName eq '{displayName}')", accessToken); if (results != null && results.Items.Any()) { @@ -35,15 +34,15 @@ internal static async Task GetGroupAsync(PnPConnection connection, string return null; } - internal static async Task> GetGroupsAsync(PnPConnection connection, string accessToken) + internal static IEnumerable GetGroups(Cmdlet cmdlet, PnPConnection connection, string accessToken) { - var results = await GraphHelper.GetResultCollectionAsync(connection, $"v1.0/groups", accessToken, propertyNameCaseInsensitive: true); + var results = GraphHelper.GetResultCollection(cmdlet, connection, $"v1.0/groups", accessToken, propertyNameCaseInsensitive: true); return results; } - internal static async Task UpdateAsync(PnPConnection connection, string accessToken, Group group) + internal static Group Update(Cmdlet cmdlet, PnPConnection connection, string accessToken, Group group) { - return await GraphHelper.PatchAsync(connection, accessToken, $"v1.0/groups/{group.Id}", group); + return GraphHelper.Patch(cmdlet, connection, accessToken, $"v1.0/groups/{group.Id}", group); } } diff --git a/src/Commands/Utilities/AzureAuthHelper.cs b/src/Commands/Utilities/AzureAuthHelper.cs index 14ddc9218..87a39ddc5 100644 --- a/src/Commands/Utilities/AzureAuthHelper.cs +++ b/src/Commands/Utilities/AzureAuthHelper.cs @@ -10,7 +10,7 @@ namespace PnP.PowerShell.Commands.Utilities public static class AzureAuthHelper { private static string CLIENTID = "1950a258-227b-4e31-a9cf-717495945fc2"; // Well-known Azure Management App Id - internal static async Task AuthenticateAsync(string tenantId, string username, SecureString password, AzureEnvironment azureEnvironment) + internal static async Task AuthenticateAsync(string tenantId, string username, SecureString password, AzureEnvironment azureEnvironment, string customGraphEndpoint = "") { if (string.IsNullOrEmpty(tenantId)) { @@ -22,13 +22,13 @@ internal static async Task AuthenticateAsync(string tenantId, string use var graphEndpoint = $"https://{AuthenticationManager.GetGraphEndPoint(azureEnvironment)}"; if (azureEnvironment == AzureEnvironment.Custom) { - graphEndpoint = Environment.GetEnvironmentVariable("MicrosoftGraphEndPoint", EnvironmentVariableTarget.Process); + graphEndpoint = Environment.GetEnvironmentVariable("MicrosoftGraphEndPoint", EnvironmentVariableTarget.Process) ?? customGraphEndpoint; } return await authManager.GetAccessTokenAsync(new[] { $"{graphEndpoint}/.default" }); } } - internal static string AuthenticateDeviceLogin(CancellationTokenSource cancellationTokenSource, CmdletMessageWriter messageWriter, bool noPopup, AzureEnvironment azureEnvironment, string clientId = "1950a258-227b-4e31-a9cf-717495945fc2") + internal static string AuthenticateDeviceLogin(CancellationTokenSource cancellationTokenSource, CmdletMessageWriter messageWriter, bool noPopup, AzureEnvironment azureEnvironment, string clientId = "1950a258-227b-4e31-a9cf-717495945fc2", string customGraphEndpoint = "") { try { @@ -54,7 +54,7 @@ internal static string AuthenticateDeviceLogin(CancellationTokenSource cancellat var graphEndpoint = $"https://{AuthenticationManager.GetGraphEndPoint(azureEnvironment)}"; if (azureEnvironment == AzureEnvironment.Custom) { - graphEndpoint = Environment.GetEnvironmentVariable("MicrosoftGraphEndPoint", EnvironmentVariableTarget.Process); + graphEndpoint = Environment.GetEnvironmentVariable("MicrosoftGraphEndPoint", EnvironmentVariableTarget.Process) ?? customGraphEndpoint; } return authManager.GetAccessTokenAsync(new string[] { $"{graphEndpoint}/.default" }, cancellationTokenSource.Token).GetAwaiter().GetResult(); } @@ -71,7 +71,7 @@ internal static string AuthenticateDeviceLogin(CancellationTokenSource cancellat return null; } - internal static string AuthenticateInteractive(CancellationTokenSource cancellationTokenSource, CmdletMessageWriter messageWriter, bool noPopup, AzureEnvironment azureEnvironment, string tenantId) + internal static string AuthenticateInteractive(CancellationTokenSource cancellationTokenSource, CmdletMessageWriter messageWriter, bool noPopup, AzureEnvironment azureEnvironment, string tenantId, string customGraphEndpoint = "") { try { @@ -91,7 +91,7 @@ internal static string AuthenticateInteractive(CancellationTokenSource cancellat var graphEndpoint = $"https://{AuthenticationManager.GetGraphEndPoint(azureEnvironment)}"; if (azureEnvironment == AzureEnvironment.Custom) { - graphEndpoint = Environment.GetEnvironmentVariable("MicrosoftGraphEndPoint", EnvironmentVariableTarget.Process); + graphEndpoint = Environment.GetEnvironmentVariable("MicrosoftGraphEndPoint", EnvironmentVariableTarget.Process) ?? customGraphEndpoint; } return authManager.GetAccessTokenAsync(new string[] { $"{graphEndpoint}/.default" }, cancellationTokenSource.Token).GetAwaiter().GetResult(); } diff --git a/src/Commands/Utilities/CopyMover.cs b/src/Commands/Utilities/CopyMover.cs index 9234dadeb..c78f0385a 100644 --- a/src/Commands/Utilities/CopyMover.cs +++ b/src/Commands/Utilities/CopyMover.cs @@ -42,7 +42,7 @@ internal static class CopyMover } }; - var results = await REST.RestHelper.PostAsync>(httpClient, $"{currentContextUri}/_api/site/CreateCopyJobs", clientContext, body, false); + var results = REST.RestHelper.Post>(httpClient, $"{currentContextUri}/_api/site/CreateCopyJobs", clientContext, body, false); if (results != null && results.Items.Any()) { @@ -52,7 +52,7 @@ internal static class CopyMover { copyJobInfo = result }; - var copyJob = await Utilities.REST.RestHelper.PostAsync(httpClient, $"{currentContextUri}/_api/site/GetCopyJobProgress", clientContext, copyJobInfo, false); + var copyJob = Utilities.REST.RestHelper.Post(httpClient, $"{currentContextUri}/_api/site/GetCopyJobProgress", clientContext, copyJobInfo, false); if (copyJob != null) { if (noWait) @@ -63,7 +63,7 @@ internal static class CopyMover { // sleep 1 second await Task.Delay(1000); - copyJob = await Utilities.REST.RestHelper.PostAsync(httpClient, $"{currentContextUri}/_api/site/GetCopyJobProgress", clientContext, copyJobInfo, false); + copyJob = Utilities.REST.RestHelper.Post(httpClient, $"{currentContextUri}/_api/site/GetCopyJobProgress", clientContext, copyJobInfo, false); } foreach (var log in copyJob.Logs) { @@ -83,7 +83,7 @@ public static async Task GetCopyMigrationJobStatusAsync(HttpCl { copyJobInfo = jobInfo }; - var copyJob = await Utilities.REST.RestHelper.PostAsync(httpClient, $"{currentContextUri}/_api/site/GetCopyJobProgress", clientContext, copyJobInfo, false); + var copyJob = Utilities.REST.RestHelper.Post(httpClient, $"{currentContextUri}/_api/site/GetCopyJobProgress", clientContext, copyJobInfo, false); if (copyJob != null) { if (!noWait) @@ -92,7 +92,7 @@ public static async Task GetCopyMigrationJobStatusAsync(HttpCl { // sleep 1 second await Task.Delay(1000); - copyJob = await Utilities.REST.RestHelper.PostAsync(httpClient, $"{currentContextUri}/_api/site/GetCopyJobProgress", clientContext, copyJobInfo, false); + copyJob = Utilities.REST.RestHelper.Post(httpClient, $"{currentContextUri}/_api/site/GetCopyJobProgress", clientContext, copyJobInfo, false); } } } diff --git a/src/Commands/Utilities/MailUtility.cs b/src/Commands/Utilities/MailUtility.cs index 2c5909f36..a9ded5ecc 100644 --- a/src/Commands/Utilities/MailUtility.cs +++ b/src/Commands/Utilities/MailUtility.cs @@ -13,6 +13,7 @@ using PnP.PowerShell.Commands.Enums; using System.IO; using System; +using System.Management.Automation; namespace PnP.PowerShell.Commands.Utilities { @@ -29,7 +30,7 @@ internal static class MailUtility /// The message to send /// Boolean indicating if the sent message should be added to the sent items of the sender. Optional. Defaults to true. /// Thrown if sending the e-mail failed - public static async Task SendGraphMail(PnPConnection connection, string accessToken, Message message, bool saveToSentItems = true) + public static void SendGraphMail(Cmdlet cmdlet, PnPConnection connection, string accessToken, Message message, bool saveToSentItems = true) { var jsonSerializer = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, }; jsonSerializer.Converters.Add(new JsonStringEnumConverter()); @@ -37,11 +38,11 @@ public static async Task SendGraphMail(PnPConnection connection, string accessTo var stringContent = new StringContent(JsonSerializer.Serialize(new SendMailMessage { Message = message, SaveToSentItems = saveToSentItems }, jsonSerializer)); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - var response = await GraphHelper.PostAsync(connection, $"v1.0/users/{message.Sender.EmailAddress.Address}/sendMail", accessToken, stringContent); + var response = GraphHelper.Post(cmdlet, connection, $"v1.0/users/{message.Sender.EmailAddress.Address}/sendMail", accessToken, stringContent); if (response.StatusCode != System.Net.HttpStatusCode.Accepted) { - throw new System.Exception($"Error sending e-mail message: {response.ReasonPhrase}. {(await response.Content.ReadAsStringAsync())}"); + throw new System.Exception($"Error sending e-mail message: {response.ReasonPhrase}. {(response.Content.ReadAsStringAsync().GetAwaiter().GetResult())}"); } } @@ -54,7 +55,7 @@ public static async Task SendGraphMail(PnPConnection connection, string accessTo /// List of TO addresses. /// List of CC addresses. Optional. /// List of BCC addresses. Optional. - public static async Task SendSharePointEmail(ClientContext context, string subject, string body, IEnumerable to, IEnumerable cc = null, IEnumerable bcc = null) + public static void SendSharePointEmail(ClientContext context, string subject, string body, IEnumerable to, IEnumerable cc = null, IEnumerable bcc = null) { EmailProperties properties = new EmailProperties { @@ -74,8 +75,8 @@ public static async Task SendSharePointEmail(ClientContext context, string subje properties.Subject = subject; properties.Body = body; - Microsoft.SharePoint.Client.Utilities.Utility.SendEmail(context, properties); - await context.ExecuteQueryRetryAsync(); + Utility.SendEmail(context, properties); + context.ExecuteQueryRetry(); } /// @@ -93,7 +94,7 @@ public static async Task SendSharePointEmail(ClientContext context, string subje /// Username to authenticate to the SMTP server with. Leave NULL to not authenticate. /// Password to authenticate to the SMTP server with. Leave NULL to not authenticate. /// Content type of the body. By default this is HTML. - public static async Task SendSmtpEmail(string subject, string body, string fromAddress, IEnumerable to, IEnumerable cc = null, IEnumerable bcc = null, MessageImportanceType? importance = null, string servername = "smtp.office365.com", short? serverPort = null, bool? enableSsl = null, string username = null, string password = null, MessageBodyContentType contentType = MessageBodyContentType.Html) + public static void SendSmtpEmail(string subject, string body, string fromAddress, IEnumerable to, IEnumerable cc = null, IEnumerable bcc = null, MessageImportanceType? importance = null, string servername = "smtp.office365.com", short? serverPort = null, bool? enableSsl = null, string username = null, string password = null, MessageBodyContentType contentType = MessageBodyContentType.Html) { using SmtpClient client = new SmtpClient(servername) { @@ -152,7 +153,7 @@ public static async Task SendSmtpEmail(string subject, string body, string fromA } } - await client.SendMailAsync(mail); + client.SendMailAsync(mail).GetAwaiter().GetResult(); } /// diff --git a/src/Commands/Utilities/Microsoft365GroupsUtility.cs b/src/Commands/Utilities/Microsoft365GroupsUtility.cs index 29a709bb1..7ab1facd3 100644 --- a/src/Commands/Utilities/Microsoft365GroupsUtility.cs +++ b/src/Commands/Utilities/Microsoft365GroupsUtility.cs @@ -7,12 +7,14 @@ using System.Text.Json; using PnP.PowerShell.Commands.Model; using PnP.PowerShell.Commands.Base; +using System.Management.Automation; +using System.Threading; namespace PnP.PowerShell.Commands.Utilities { - internal static class Microsoft365GroupsUtility + internal static class ClearOwners { - internal static async Task> GetGroupsAsync(PnPConnection connection, string accessToken, bool includeSiteUrl, bool includeOwners, string filter = null, bool includeSensitivityLabels = false) + internal static IEnumerable GetGroups(Cmdlet cmdlet, PnPConnection connection, string accessToken, bool includeSiteUrl, bool includeOwners, string filter = null, bool includeSensitivityLabels = false) { var items = new List(); string requestUrl = "v1.0/groups"; @@ -31,7 +33,7 @@ internal static async Task> GetGroupsAsync(PnPCon { "ConsistencyLevel", "eventual" } }; } - var result = await GraphHelper.GetResultCollectionAsync(connection, requestUrl, accessToken, additionalHeaders: additionalHeaders); + var result = GraphHelper.GetResultCollection(cmdlet, connection, requestUrl, accessToken, additionalHeaders: additionalHeaders); if (result != null && result.Any()) { items.AddRange(result); @@ -43,7 +45,7 @@ internal static async Task> GetGroupsAsync(PnPCon { foreach (var chunk in chunks) { - var ownerResults = await BatchUtility.GetObjectCollectionBatchedAsync(connection, accessToken, chunk.ToArray(), "/groups/{0}/owners"); + var ownerResults = BatchUtility.GetObjectCollectionBatched(cmdlet, connection, accessToken, chunk.ToArray(), "/groups/{0}/owners"); foreach (var ownerResult in ownerResults) { items.First(i => i.Id.ToString() == ownerResult.Key).Owners = ownerResult.Value; @@ -55,7 +57,7 @@ internal static async Task> GetGroupsAsync(PnPCon { foreach (var chunk in chunks) { - var results = await BatchUtility.GetPropertyBatchedAsync(connection, accessToken, chunk.ToArray(), "/groups/{0}/sites/root", "webUrl"); + var results = BatchUtility.GetPropertyBatched(cmdlet, connection, accessToken, chunk.ToArray(), "/groups/{0}/sites/root", "webUrl"); foreach (var batchResult in results) { items.First(i => i.Id.ToString() == batchResult.Key).SiteUrl = batchResult.Value; @@ -66,7 +68,7 @@ internal static async Task> GetGroupsAsync(PnPCon { foreach (var chunk in chunks) { - var sensitivityLabelResults = await BatchUtility.GetObjectCollectionBatchedAsync(connection, accessToken, chunk.ToArray(), "/groups/{0}/assignedLabels"); + var sensitivityLabelResults = BatchUtility.GetObjectCollectionBatched(cmdlet, connection, accessToken, chunk.ToArray(), "/groups/{0}/assignedLabels"); foreach (var sensitivityLabel in sensitivityLabelResults) { items.First(i => i.Id.ToString() == sensitivityLabel.Key).AssignedLabels = sensitivityLabel.Value?.ToList(); @@ -77,9 +79,9 @@ internal static async Task> GetGroupsAsync(PnPCon return items; } - internal static async Task GetGroupAsync(PnPConnection connection, Guid groupId, string accessToken, bool includeSiteUrl, bool includeOwners, bool detailed, bool includeSensitivityLabels) + internal static Microsoft365Group GetGroup(Cmdlet cmdlet, PnPConnection connection, Guid groupId, string accessToken, bool includeSiteUrl, bool includeOwners, bool detailed, bool includeSensitivityLabels) { - var results = await GraphHelper.GetAsync>(connection, $"v1.0/groups?$filter=groupTypes/any(c:c+eq+'Unified') and id eq '{groupId}'", accessToken); + var results = GraphHelper.Get>(cmdlet, connection, $"v1.0/groups?$filter=groupTypes/any(c:c+eq+'Unified') and id eq '{groupId}'", accessToken); if (results != null && results.Items.Any()) { @@ -94,7 +96,7 @@ internal static async Task GetGroupAsync(PnPConnection connec iterations++; try { - var siteUrlResult = await GraphHelper.GetAsync(connection, $"v1.0/groups/{group.Id}/sites/root?$select=webUrl", accessToken); + var siteUrlResult = GraphHelper.Get(cmdlet, connection, $"v1.0/groups/{group.Id}/sites/root?$select=webUrl", accessToken); if (!string.IsNullOrEmpty(siteUrlResult)) { wait = false; @@ -114,25 +116,25 @@ internal static async Task GetGroupAsync(PnPConnection connec } else { - await Task.Delay(TimeSpan.FromSeconds(30)); + Thread.Sleep(TimeSpan.FromSeconds(30)); } } } } if (includeOwners) { - group.Owners = await GetGroupMembersAsync("owners", connection, group.Id.Value, accessToken); + group.Owners = GetGroupMembers(cmdlet, "owners", connection, group.Id.Value, accessToken); } if (detailed) { - var exchangeOnlineProperties = await GetGroupExchangeOnlineSettingsAsync(connection, group.Id.Value, accessToken); + var exchangeOnlineProperties = GetGroupExchangeOnlineSettings(cmdlet, connection, group.Id.Value, accessToken); group.AllowExternalSenders = exchangeOnlineProperties.AllowExternalSenders; group.AutoSubscribeNewMembers = exchangeOnlineProperties.AutoSubscribeNewMembers; group.IsSubscribedByMail = exchangeOnlineProperties.IsSubscribedByMail; } if (includeSensitivityLabels) { - var sensitivityLabels = await GetGroupSensitivityLabelsAsync(connection, group.Id.Value, accessToken); + var sensitivityLabels = GetGroupSensitivityLabels(cmdlet, connection, group.Id.Value, accessToken); group.AssignedLabels = sensitivityLabels.AssignedLabels; } return group; @@ -140,15 +142,15 @@ internal static async Task GetGroupAsync(PnPConnection connec return null; } - internal static async Task GetGroupAsync(PnPConnection connection, string displayName, string accessToken, bool includeSiteUrl, bool includeOwners, bool detailed, bool includeSensitivityLabels) + internal static Microsoft365Group GetGroup(Cmdlet cmdlet, PnPConnection connection, string displayName, string accessToken, bool includeSiteUrl, bool includeOwners, bool detailed, bool includeSensitivityLabels) { - var results = await GraphHelper.GetAsync>(connection, $"v1.0/groups?$filter=groupTypes/any(c:c+eq+'Unified') and (displayName eq '{displayName}' or mailNickName eq '{displayName}')", accessToken); + var results = GraphHelper.Get>(cmdlet, connection, $"v1.0/groups?$filter=groupTypes/any(c:c+eq+'Unified') and (displayName eq '{displayName}' or mailNickName eq '{displayName}')", accessToken); if (results != null && results.Items.Any()) { var group = results.Items.First(); if (includeSiteUrl) { - var siteUrlResult = await GraphHelper.GetAsync(connection, $"v1.0/groups/{group.Id}/sites/root?$select=webUrl", accessToken); + var siteUrlResult = GraphHelper.Get(cmdlet, connection, $"v1.0/groups/{group.Id}/sites/root?$select=webUrl", accessToken); var resultElement = JsonSerializer.Deserialize(siteUrlResult); if (resultElement.TryGetProperty("webUrl", out JsonElement webUrlElement)) { @@ -157,18 +159,18 @@ internal static async Task GetGroupAsync(PnPConnection connec } if (includeOwners) { - group.Owners = await GetGroupMembersAsync("owners", connection, group.Id.Value, accessToken); + group.Owners = GetGroupMembers(cmdlet, "owners", connection, group.Id.Value, accessToken); } if (detailed) { - var exchangeOnlineProperties = await GetGroupExchangeOnlineSettingsAsync(connection, group.Id.Value, accessToken); + var exchangeOnlineProperties = GetGroupExchangeOnlineSettings(cmdlet, connection, group.Id.Value, accessToken); group.AllowExternalSenders = exchangeOnlineProperties.AllowExternalSenders; group.AutoSubscribeNewMembers = exchangeOnlineProperties.AutoSubscribeNewMembers; group.IsSubscribedByMail = exchangeOnlineProperties.IsSubscribedByMail; } if (includeSensitivityLabels) { - var sensitivityLabels = await GetGroupSensitivityLabelsAsync(connection, group.Id.Value, accessToken); + var sensitivityLabels = GetGroupSensitivityLabels(cmdlet, connection, group.Id.Value, accessToken); group.AssignedLabels = sensitivityLabels.AssignedLabels; } return group; @@ -176,7 +178,7 @@ internal static async Task GetGroupAsync(PnPConnection connec return null; } - internal static async Task> GetExpiringGroupAsync(PnPConnection connection, string accessToken, int limit, bool includeSiteUrl, bool includeOwners) + internal static IEnumerable GetExpiringGroup(Cmdlet cmdlet, PnPConnection connection, string accessToken, int limit, bool includeSiteUrl, bool includeOwners) { var items = new List(); @@ -189,7 +191,7 @@ internal static async Task> GetExpiringGroupAsync // $count=true needs to be here for reasons // see this for some additional details: https://learn.microsoft.com/en-us/graph/aad-advanced-queries?tabs=http#group-properties - var result = await GraphHelper.GetResultCollectionAsync(connection, $"v1.0/groups?$filter=groupTypes/any(c:c+eq+'Unified') and expirationDateTime le {dateStr}&$count=true", accessToken, additionalHeaders: additionalHeaders); + var result = GraphHelper.GetResultCollection(cmdlet, connection, $"v1.0/groups?$filter=groupTypes/any(c:c+eq+'Unified') and expirationDateTime le {dateStr}&$count=true", accessToken, additionalHeaders: additionalHeaders); if (result != null && result.Any()) { items.AddRange(result); @@ -201,7 +203,7 @@ internal static async Task> GetExpiringGroupAsync { foreach (var chunk in chunks) { - var ownerResults = await BatchUtility.GetObjectCollectionBatchedAsync(connection, accessToken, chunk.ToArray(), "/groups/{0}/owners"); + var ownerResults = BatchUtility.GetObjectCollectionBatched(cmdlet, connection, accessToken, chunk.ToArray(), "/groups/{0}/owners"); foreach (var ownerResult in ownerResults) { items.First(i => i.Id.ToString() == ownerResult.Key).Owners = ownerResult.Value; @@ -213,7 +215,7 @@ internal static async Task> GetExpiringGroupAsync { foreach (var chunk in chunks) { - var results = await BatchUtility.GetPropertyBatchedAsync(connection, accessToken, chunk.ToArray(), "/groups/{0}/sites/root", "webUrl"); + var results = BatchUtility.GetPropertyBatched(cmdlet, connection, accessToken, chunk.ToArray(), "/groups/{0}/sites/root", "webUrl"); //var results = await GetSiteUrlBatchedAsync(connection, accessToken, chunk.ToArray()); foreach (var batchResult in results) { @@ -225,14 +227,14 @@ internal static async Task> GetExpiringGroupAsync return items; } - internal static async Task GetDeletedGroupAsync(PnPConnection connection, Guid groupId, string accessToken) + internal static Microsoft365Group GetDeletedGroup(Cmdlet cmdlet, PnPConnection connection, Guid groupId, string accessToken) { - return await GraphHelper.GetAsync(connection, $"v1.0/directory/deleteditems/microsoft.graph.group/{groupId}", accessToken); + return GraphHelper.Get(cmdlet, connection, $"v1.0/directory/deleteditems/microsoft.graph.group/{groupId}", accessToken); } - internal static async Task GetDeletedGroupAsync(PnPConnection connection, string groupName, string accessToken) + internal static Microsoft365Group GetDeletedGroup(Cmdlet cmdlet, PnPConnection connection, string groupName, string accessToken) { - var results = await GraphHelper.GetAsync>(connection, $"v1.0/directory/deleteditems/microsoft.graph.group?$filter=displayName eq '{groupName}' or mailNickname eq '{groupName}'", accessToken); + var results = GraphHelper.Get>(cmdlet, connection, $"v1.0/directory/deleteditems/microsoft.graph.group?$filter=displayName eq '{groupName}' or mailNickname eq '{groupName}'", accessToken); if (results != null && results.Items.Any()) { return results.Items.First(); @@ -240,40 +242,40 @@ internal static async Task GetDeletedGroupAsync(PnPConnection return null; } - internal static async Task> GetDeletedGroupsAsync(PnPConnection connection, string accessToken) + internal static IEnumerable GetDeletedGroups(Cmdlet cmdlet, PnPConnection connection, string accessToken) { - var result = await GraphHelper.GetResultCollectionAsync(connection, "v1.0/directory/deleteditems/microsoft.graph.group", accessToken); + var result = GraphHelper.GetResultCollection(cmdlet, connection, "v1.0/directory/deleteditems/microsoft.graph.group", accessToken); return result; } - internal static async Task RestoreDeletedGroupAsync(PnPConnection connection, Guid groupId, string accessToken) + internal static Microsoft365Group RestoreDeletedGroup(Cmdlet cmdlet, PnPConnection connection, Guid groupId, string accessToken) { - return await GraphHelper.PostAsync(connection, $"v1.0/directory/deleteditems/microsoft.graph.group/{groupId}/restore", accessToken); + return GraphHelper.Post(cmdlet, connection, $"v1.0/directory/deleteditems/microsoft.graph.group/{groupId}/restore", accessToken); } - internal static async Task PermanentlyDeleteDeletedGroupAsync(PnPConnection connection, Guid groupId, string accessToken) + internal static void PermanentlyDeleteDeletedGroup(Cmdlet cmdlet, PnPConnection connection, Guid groupId, string accessToken) { - await GraphHelper.DeleteAsync(connection, $"v1.0/directory/deleteditems/microsoft.graph.group/{groupId}", accessToken); + GraphHelper.Delete(cmdlet, connection, $"v1.0/directory/deleteditems/microsoft.graph.group/{groupId}", accessToken); } - internal static async Task AddOwnersAsync(PnPConnection connection, Guid groupId, string[] users, string accessToken, bool removeExisting) + internal static void AddOwners(Cmdlet cmdlet, PnPConnection connection, Guid groupId, string[] users, string accessToken, bool removeExisting) { - await AddUsersToGroupAsync("owners", connection, groupId, users, accessToken, removeExisting); + AddUsersToGroup(cmdlet, "owners", connection, groupId, users, accessToken, removeExisting); } - internal static async Task AddDirectoryOwnersAsync(PnPConnection connection, Guid groupId, Guid[] users, string accessToken, bool removeExisting) + internal static void AddDirectoryOwners(Cmdlet cmdlet, PnPConnection connection, Guid groupId, Guid[] users, string accessToken, bool removeExisting) { - await AddDirectoryObjectsToGroupAsync("owners", connection, groupId, users, accessToken, removeExisting); + AddDirectoryObjectsToGroup(cmdlet, "owners", connection, groupId, users, accessToken, removeExisting); } - internal static async Task AddMembersAsync(PnPConnection connection, Guid groupId, string[] users, string accessToken, bool removeExisting) + internal static void AddMembers(Cmdlet cmdlet, PnPConnection connection, Guid groupId, string[] users, string accessToken, bool removeExisting) { - await AddUsersToGroupAsync("members", connection, groupId, users, accessToken, removeExisting); + AddUsersToGroup(cmdlet, "members", connection, groupId, users, accessToken, removeExisting); } - internal static async Task AddDirectoryMembersAsync(PnPConnection connection, Guid groupId, Guid[] users, string accessToken, bool removeExisting) + internal static void AddDirectoryMembers(Cmdlet cmdlet, PnPConnection connection, Guid groupId, Guid[] users, string accessToken, bool removeExisting) { - await AddDirectoryObjectsToGroupAsync("members", connection, groupId, users, accessToken, removeExisting); + AddDirectoryObjectsToGroup(cmdlet, "members", connection, groupId, users, accessToken, removeExisting); } internal static string GetUserGraphUrlForUPN(string upn) @@ -285,11 +287,11 @@ internal static string GetUserGraphUrlForUPN(string upn) return $"users/{escapedUpn}"; } - private static async Task AddUsersToGroupAsync(string groupName, PnPConnection connection, Guid groupId, string[] users, string accessToken, bool removeExisting) + private static void AddUsersToGroup(Cmdlet cmdlet, string groupName, PnPConnection connection, Guid groupId, string[] users, string accessToken, bool removeExisting) { foreach (var user in users) { - var userIdResult = await GraphHelper.GetAsync(connection, $"v1.0/{GetUserGraphUrlForUPN(user)}?$select=Id", accessToken); + var userIdResult = GraphHelper.Get(cmdlet, connection, $"v1.0/{GetUserGraphUrlForUPN(user)}?$select=Id", accessToken); var resultElement = JsonSerializer.Deserialize(userIdResult); if (resultElement.TryGetProperty("id", out JsonElement idProperty)) { @@ -302,12 +304,12 @@ private static async Task AddUsersToGroupAsync(string groupName, PnPConnection c var stringContent = new StringContent(JsonSerializer.Serialize(postData)); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - await GraphHelper.PostAsync(connection, $"v1.0/groups/{groupId}/{groupName}/$ref", accessToken, stringContent); + GraphHelper.Post(cmdlet, connection, $"v1.0/groups/{groupId}/{groupName}/$ref", accessToken, stringContent); } } } - private static async Task AddDirectoryObjectsToGroupAsync(string groupName, PnPConnection connection, Guid groupId, Guid[] directoryObjects, string accessToken, bool removeExisting) + private static void AddDirectoryObjectsToGroup(Cmdlet cmdlet, string groupName, PnPConnection connection, Guid groupId, Guid[] directoryObjects, string accessToken, bool removeExisting) { foreach (var dirObject in directoryObjects) { @@ -320,125 +322,125 @@ private static async Task AddDirectoryObjectsToGroupAsync(string groupName, PnPC var stringContent = new StringContent(JsonSerializer.Serialize(postData)); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - await GraphHelper.PostAsync(connection, $"v1.0/groups/{groupId}/{groupName}/$ref", accessToken, stringContent); + GraphHelper.Post(cmdlet, connection, $"v1.0/groups/{groupId}/{groupName}/$ref", accessToken, stringContent); } } - internal static async Task RemoveOwnersAsync(PnPConnection connection, Guid groupId, string[] users, string accessToken) + internal static void RemoveOwners(Cmdlet cmdlet, PnPConnection connection, Guid groupId, string[] users, string accessToken) { - await RemoveUserFromGroupAsync("owners", connection, groupId, users, accessToken); + RemoveUserFromGroup(cmdlet, "owners", connection, groupId, users, accessToken); } - internal static async Task RemoveMembersAsync(PnPConnection connection, Guid groupId, string[] users, string accessToken) + internal static void RemoveMembers(Cmdlet cmdlet, PnPConnection connection, Guid groupId, string[] users, string accessToken) { - await RemoveUserFromGroupAsync("members", connection, groupId, users, accessToken); + RemoveUserFromGroup(cmdlet, "members", connection, groupId, users, accessToken); } - private static async Task RemoveUserFromGroupAsync(string groupName, PnPConnection connection, Guid groupId, string[] users, string accessToken) + private static void RemoveUserFromGroup(Cmdlet cmdlet, string groupName, PnPConnection connection, Guid groupId, string[] users, string accessToken) { foreach (var user in users) { - var resultString = await GraphHelper.GetAsync(connection, $"v1.0/{GetUserGraphUrlForUPN(user)}?$select=Id", accessToken); + var resultString = GraphHelper.Get(cmdlet, connection, $"v1.0/{GetUserGraphUrlForUPN(user)}?$select=Id", accessToken); var resultElement = JsonSerializer.Deserialize(resultString); if (resultElement.TryGetProperty("id", out JsonElement idElement)) { - await GraphHelper.DeleteAsync(connection, $"v1.0/groups/{groupId}/{groupName}/{idElement.GetString()}/$ref", accessToken); + GraphHelper.Delete(cmdlet, connection, $"v1.0/groups/{groupId}/{groupName}/{idElement.GetString()}/$ref", accessToken); } } } - internal static async Task RemoveGroupAsync(PnPConnection connection, Guid groupId, string accessToken) + internal static void RemoveGroup(Cmdlet cmdlet, PnPConnection connection, Guid groupId, string accessToken) { - await GraphHelper.DeleteAsync(connection, $"v1.0/groups/{groupId}", accessToken); + GraphHelper.Delete(cmdlet, connection, $"v1.0/groups/{groupId}", accessToken); } - internal static async Task> GetOwnersAsync(PnPConnection connection, Guid groupId, string accessToken) + internal static IEnumerable GetOwners(Cmdlet cmdlet, PnPConnection connection, Guid groupId, string accessToken) { - return await GetGroupMembersAsync("owners", connection, groupId, accessToken); + return GetGroupMembers(cmdlet, "owners", connection, groupId, accessToken); } - internal static async Task> GetMembersAsync(PnPConnection connection, Guid groupId, string accessToken) + internal static IEnumerable GetMembers(Cmdlet cmdlet, PnPConnection connection, Guid groupId, string accessToken) { - return await GetGroupMembersAsync("members", connection, groupId, accessToken); + return GetGroupMembers(cmdlet, "members", connection, groupId, accessToken); } - private static async Task> GetGroupMembersAsync(string userType, PnPConnection connection, Guid groupId, string accessToken) + private static IEnumerable GetGroupMembers(Cmdlet cmdlet, string userType, PnPConnection connection, Guid groupId, string accessToken) { - var results = await GraphHelper.GetResultCollectionAsync(connection, $"v1.0/groups/{groupId}/{userType}?$select=*", accessToken); + var results = GraphHelper.GetResultCollection(cmdlet, connection, $"v1.0/groups/{groupId}/{userType}?$select=*", accessToken); return results; } - private static async Task GetGroupExchangeOnlineSettingsAsync(PnPConnection connection, Guid groupId, string accessToken) + private static Microsoft365Group GetGroupExchangeOnlineSettings(Cmdlet cmdlet, PnPConnection connection, Guid groupId, string accessToken) { - var results = await GraphHelper.GetAsync(connection, $"v1.0/groups/{groupId}?$select=allowExternalSenders,isSubscribedByMail,autoSubscribeNewMembers", accessToken); + var results = GraphHelper.Get(cmdlet, connection, $"v1.0/groups/{groupId}?$select=allowExternalSenders,isSubscribedByMail,autoSubscribeNewMembers", accessToken); return results; } - private static async Task GetGroupSensitivityLabelsAsync(PnPConnection connection, Guid groupId, string accessToken) + private static Microsoft365Group GetGroupSensitivityLabels(Cmdlet cmdlet, PnPConnection connection, Guid groupId, string accessToken) { - var results = await GraphHelper.GetAsync(connection, $"v1.0/groups/{groupId}?$select=assignedLabels", accessToken); + var results = GraphHelper.Get(cmdlet, connection, $"v1.0/groups/{groupId}?$select=assignedLabels", accessToken); return results; } - internal static async Task ClearMembersAsync(PnPConnection connection, Guid groupId, string accessToken) + internal static void ClearMembers(Cmdlet cmdlet, PnPConnection connection, Guid groupId, string accessToken) { - var members = await GetMembersAsync(connection, groupId, accessToken); + var members = GetMembers(cmdlet, connection, groupId, accessToken); foreach (var member in members) { - await GraphHelper.DeleteAsync(connection, $"v1.0/groups/{groupId}/members/{member.Id}/$ref", accessToken); + GraphHelper.Delete(cmdlet, connection, $"v1.0/groups/{groupId}/members/{member.Id}/$ref", accessToken); } } - internal static async Task ClearOwnersAsync(PnPConnection connection, Guid groupId, string accessToken) + internal static void ClearOwnersAsync(Cmdlet cmdlet, PnPConnection connection, Guid groupId, string accessToken) { - var members = await GetOwnersAsync(connection, groupId, accessToken); + var members = GetOwners(cmdlet, connection, groupId, accessToken); foreach (var member in members) { - await GraphHelper.DeleteAsync(connection, $"v1.0/groups/{groupId}/owners/{member.Id}/$ref", accessToken); + GraphHelper.Delete(cmdlet, connection, $"v1.0/groups/{groupId}/owners/{member.Id}/$ref", accessToken); } } - internal static async Task UpdateOwnersAsync(PnPConnection connection, Guid groupId, string accessToken, string[] owners) + internal static void UpdateOwners(Cmdlet cmdlet, PnPConnection connection, Guid groupId, string accessToken, string[] owners) { - var existingOwners = await GetOwnersAsync(connection, groupId, accessToken); + var existingOwners = GetOwners(cmdlet, connection, groupId, accessToken); foreach (var owner in owners) { if (existingOwners.FirstOrDefault(o => o.UserPrincipalName == owner) == null) { - await AddOwnersAsync(connection, groupId, new string[] { owner }, accessToken, false); + AddOwners(cmdlet, connection, groupId, new string[] { owner }, accessToken, false); } } foreach (var existingOwner in existingOwners) { if (!owners.Contains(existingOwner.UserPrincipalName)) { - await GraphHelper.DeleteAsync(connection, $"v1.0/groups/{groupId}/owners/{existingOwner.Id}/$ref", accessToken); + GraphHelper.Delete(cmdlet, connection, $"v1.0/groups/{groupId}/owners/{existingOwner.Id}/$ref", accessToken); } } } - internal static async Task UpdateMembersAsync(PnPConnection connection, Guid groupId, string accessToken, string[] members) + internal static void UpdateMembersAsync(Cmdlet cmdlet, PnPConnection connection, Guid groupId, string accessToken, string[] members) { - var existingMembers = await GetMembersAsync(connection, groupId, accessToken); + var existingMembers = GetMembers(cmdlet, connection, groupId, accessToken); foreach (var member in members) { if (existingMembers.FirstOrDefault(o => o.UserPrincipalName == member) == null) { - await AddMembersAsync(connection, groupId, new string[] { member }, accessToken, false); + AddMembers(cmdlet, connection, groupId, new string[] { member }, accessToken, false); } } foreach (var existingMember in existingMembers) { if (!members.Contains(existingMember.UserPrincipalName)) { - await GraphHelper.DeleteAsync(connection, $"v1.0/groups/{groupId}/members/{existingMember.Id}/$ref", accessToken); + GraphHelper.Delete(cmdlet, connection, $"v1.0/groups/{groupId}/members/{existingMember.Id}/$ref", accessToken); } } } - internal static async Task UpdateExchangeOnlineSettingAsync(PnPConnection connection, Guid groupId, string accessToken, Microsoft365Group group) + internal static Microsoft365Group UpdateExchangeOnlineSetting(Cmdlet cmdlet, PnPConnection connection, Guid groupId, string accessToken, Microsoft365Group group) { var patchData = new { @@ -446,7 +448,7 @@ internal static async Task UpdateExchangeOnlineSettingAsync(P group.AutoSubscribeNewMembers }; - var result = await GraphHelper.PatchAsync(connection, accessToken, $"v1.0/groups/{groupId}", patchData); + var result = GraphHelper.Patch(cmdlet, connection, accessToken, $"v1.0/groups/{groupId}", patchData); group.AllowExternalSenders = result.AllowExternalSenders; group.AutoSubscribeNewMembers = result.AutoSubscribeNewMembers; @@ -454,7 +456,7 @@ internal static async Task UpdateExchangeOnlineSettingAsync(P return group; } - internal static async Task> GetSiteUrlBatchedAsync(PnPConnection connection, string accessToken, string[] groupIds) + internal static Dictionary GetSiteUrlBatched(Cmdlet cmdlet, PnPConnection connection, string accessToken, string[] groupIds) { Dictionary returnValue = new Dictionary(); @@ -469,7 +471,7 @@ internal static async Task> GetSiteUrlBatchedAsync(Pn } var stringContent = new StringContent(JsonSerializer.Serialize(batch)); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - var result = await GraphHelper.PostAsync(connection, "v1.0/$batch", stringContent, accessToken); + var result = GraphHelper.Post(cmdlet, connection, "v1.0/$batch", stringContent, accessToken); if (result.Responses != null && result.Responses.Any()) { foreach (var response in result.Responses) @@ -485,7 +487,7 @@ internal static async Task> GetSiteUrlBatchedAsync(Pn return returnValue; } - internal static async Task> GetUserIdsBatched(PnPConnection connection, string accessToken, string[] userPrincipalNames) + internal static Dictionary GetUserIdsBatched(Cmdlet cmdlet, PnPConnection connection, string accessToken, string[] userPrincipalNames) { Dictionary returnValue = new Dictionary(); @@ -500,7 +502,7 @@ internal static async Task> GetUserIdsBatched(PnPConn } var stringContent = new StringContent(JsonSerializer.Serialize(batch)); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - var result = await GraphHelper.PostAsync(connection, "v1.0/$batch", stringContent, accessToken); + var result = GraphHelper.Post(cmdlet, connection, "v1.0/$batch", stringContent, accessToken); if (result.Responses != null && result.Responses.Any()) { foreach (var response in result.Responses) @@ -516,9 +518,9 @@ internal static async Task> GetUserIdsBatched(PnPConn return returnValue; } - internal static async Task GetUsersDataBindValueAsync(PnPConnection connection, string accessToken, string[] users) + internal static string[] GetUsersDataBindValue(Cmdlet cmdlet, PnPConnection connection, string accessToken, string[] users) { - var userids = await GetUserIdsBatched(connection, accessToken, users); + var userids = GetUserIdsBatched(cmdlet, connection, accessToken, users); if (userids.Any()) { return userids.Select(u => $"https://{connection.GraphEndPoint}/v1.0/users/{u.Value}").ToArray(); @@ -526,16 +528,16 @@ internal static async Task GetUsersDataBindValueAsync(PnPConnection co return null; } - internal static async Task CreateAsync(PnPConnection connection, string accessToken, Microsoft365Group group, bool createTeam, string logoPath, string[] owners, string[] members, bool? hideFromAddressLists, bool? hideFromOutlookClients, List sensitivityLabels) + internal static Microsoft365Group Create(Cmdlet cmdlet, PnPConnection connection, string accessToken, Microsoft365Group group, bool createTeam, string logoPath, string[] owners, string[] members, bool? hideFromAddressLists, bool? hideFromOutlookClients, List sensitivityLabels) { if (owners != null && owners.Length > 0) { - group.OwnersODataBind = await GetUsersDataBindValueAsync(connection, accessToken, owners); + group.OwnersODataBind = GetUsersDataBindValue(cmdlet, connection, accessToken, owners); } if (members != null && members.Length > 0) { - group.MembersODataBind = await GetUsersDataBindValueAsync(connection, accessToken, members); + group.MembersODataBind = GetUsersDataBindValue(cmdlet, connection, accessToken, members); } if (sensitivityLabels.Count > 0) @@ -555,27 +557,27 @@ internal static async Task CreateAsync(PnPConnection connecti group.AssignedLabels = assignedLabels; } - var newGroup = await GraphHelper.PostAsync(connection, "v1.0/groups", group, accessToken); + var newGroup = GraphHelper.Post(cmdlet, connection, "v1.0/groups", group, accessToken); if (hideFromAddressLists.HasValue || hideFromOutlookClients.HasValue) { - await SetVisibilityAsync(connection, accessToken, newGroup.Id.Value, hideFromAddressLists, hideFromOutlookClients); + SetVisibility(cmdlet, connection, accessToken, newGroup.Id.Value, hideFromAddressLists, hideFromOutlookClients); } if (!string.IsNullOrEmpty(logoPath)) { - await UploadLogoAsync(connection, accessToken, newGroup.Id.Value, logoPath); + UploadLogoAsync(cmdlet, connection, accessToken, newGroup.Id.Value, logoPath); } if (createTeam) { - await CreateTeamAsync(connection, accessToken, newGroup.Id.Value); + CreateTeam(cmdlet, connection, accessToken, newGroup.Id.Value); } return newGroup; } - internal static async Task UploadLogoAsync(PnPConnection connection, string accessToken, Guid groupId, string logoPath) + internal static void UploadLogoAsync(Cmdlet cmdlet, PnPConnection connection, string accessToken, Guid groupId, string logoPath) { var fileBytes = System.IO.File.ReadAllBytes(logoPath); @@ -608,14 +610,14 @@ internal static async Task UploadLogoAsync(PnPConnection connection, string acce var retryCount = 10; while (retryCount > 0) { - var responseMessage = await GraphHelper.PutAsync(connection, $"/v1.0/groups/{groupId}/photo/$value", accessToken, content); + var responseMessage = GraphHelper.Put(cmdlet, connection, $"/v1.0/groups/{groupId}/photo/$value", accessToken, content); if (responseMessage.IsSuccessStatusCode) { updated = true; } if (!updated) { - await Task.Delay(500 * (10 - retryCount)); + Thread.Sleep(500 * (10 - retryCount)); retryCount--; } else @@ -630,7 +632,7 @@ internal static async Task UploadLogoAsync(PnPConnection connection, string acce } } - internal static async Task CreateTeamAsync(PnPConnection connection, string accessToken, Guid groupId) + internal static void CreateTeam(Cmdlet cmdlet, PnPConnection connection, string accessToken, Guid groupId) { var createTeamEndPoint = $"v1.0/groups/{groupId}/team"; bool wait = true; @@ -641,7 +643,7 @@ internal static async Task CreateTeamAsync(PnPConnection connection, string acce iterations++; try { - var teamId = await GraphHelper.PutAsync(connection, createTeamEndPoint, new { }, accessToken); + var teamId = GraphHelper.Put(cmdlet, connection, createTeamEndPoint, new { }, accessToken); if (teamId != null) { wait = false; @@ -656,23 +658,23 @@ internal static async Task CreateTeamAsync(PnPConnection connection, string acce } else { - await Task.Delay(TimeSpan.FromSeconds(30)); + Thread.Sleep(TimeSpan.FromSeconds(30)); } } } } - internal static async Task RenewAsync(PnPConnection connection, string accessToken, Guid groupId) + internal static void Renew(Cmdlet cmdlet, PnPConnection connection, string accessToken, Guid groupId) { - await GraphHelper.PostAsync(connection, $"v1.0/groups/{groupId}/renew", new { }, accessToken); + GraphHelper.Post(cmdlet, connection, $"v1.0/groups/{groupId}/renew", new { }, accessToken); } - internal static async Task UpdateAsync(PnPConnection connection, string accessToken, Microsoft365Group group) + internal static Microsoft365Group Update(Cmdlet cmdlet, PnPConnection connection, string accessToken, Microsoft365Group group) { - return await GraphHelper.PatchAsync(connection, accessToken, $"v1.0/groups/{group.Id}", group); + return GraphHelper.Patch(cmdlet, connection, accessToken, $"v1.0/groups/{group.Id}", group); } - internal static async Task SetVisibilityAsync(PnPConnection connection, string accessToken, Guid groupId, bool? hideFromAddressLists, bool? hideFromOutlookClients) + internal static void SetVisibility(Cmdlet cmdlet, PnPConnection connection, string accessToken, Guid groupId, bool? hideFromAddressLists, bool? hideFromOutlookClients) { var patchData = new { @@ -686,13 +688,13 @@ internal static async Task SetVisibilityAsync(PnPConnection connection, string a { try { - await GraphHelper.PatchAsync(connection, accessToken, $"v1.0/groups/{groupId}", patchData); + GraphHelper.Patch(cmdlet, connection, accessToken, $"v1.0/groups/{groupId}", patchData); retry = false; } catch (Exception) { - await Task.Delay(5000); + Thread.Sleep(5000); iteration++; } @@ -703,71 +705,71 @@ internal static async Task SetVisibilityAsync(PnPConnection connection, string a } } - internal static async Task GetGroupSettingsAsync(PnPConnection connection, string accessToken) + internal static Microsoft365GroupSettingValueCollection GetGroupSettings(Cmdlet cmdlet, PnPConnection connection, string accessToken) { - var result = await GraphHelper.GetAsync(connection, "v1.0/groupSettings", accessToken, propertyNameCaseInsensitive: true); + var result = GraphHelper.Get(cmdlet, connection, "v1.0/groupSettings", accessToken, propertyNameCaseInsensitive: true); return result; } - internal static async Task GetGroupSettingsAsync(PnPConnection connection, string accessToken, string groupId) + internal static Microsoft365GroupSettingValueCollection GetGroupSettings(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId) { - var result = await GraphHelper.GetAsync(connection, $"v1.0/groups/{groupId}/settings", accessToken, propertyNameCaseInsensitive: true); + var result = GraphHelper.Get(cmdlet, connection, $"v1.0/groups/{groupId}/settings", accessToken, propertyNameCaseInsensitive: true); return result; } - internal static async Task CreateGroupSetting(PnPConnection connection, string accessToken, dynamic groupSettingObject) + internal static Microsoft365GroupSetting CreateGroupSetting(Cmdlet cmdlet, PnPConnection connection, string accessToken, dynamic groupSettingObject) { var stringContent = new StringContent(JsonSerializer.Serialize(groupSettingObject)); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - var result = await GraphHelper.PostAsync(connection, "v1.0/groupSettings", stringContent, accessToken, propertyNameCaseInsensitive: true); + var result = GraphHelper.Post(cmdlet, connection, "v1.0/groupSettings", stringContent, accessToken, propertyNameCaseInsensitive: true); return result; } - internal static async Task CreateGroupSetting(PnPConnection connection, string accessToken, string groupId, dynamic groupSettingObject) + internal static Microsoft365GroupSetting CreateGroupSetting(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, dynamic groupSettingObject) { var stringContent = new StringContent(JsonSerializer.Serialize(groupSettingObject)); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - var result = await GraphHelper.PostAsync(connection, $"v1.0/groups/{groupId}/settings", stringContent, accessToken, propertyNameCaseInsensitive: true); + var result = GraphHelper.Post(cmdlet, connection, $"v1.0/groups/{groupId}/settings", stringContent, accessToken, propertyNameCaseInsensitive: true); return result; } - internal static async Task UpdateGroupSetting(PnPConnection connection, string accessToken, string id, dynamic groupSettingObject) + internal static void UpdateGroupSetting(Cmdlet cmdlet, PnPConnection connection, string accessToken, string id, dynamic groupSettingObject) { var stringContent = new StringContent(JsonSerializer.Serialize(groupSettingObject)); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - await GraphHelper.PatchAsync(connection, accessToken, stringContent, $"v1.0/groupSettings/{id}"); + GraphHelper.Patch(cmdlet, connection, accessToken, stringContent, $"v1.0/groupSettings/{id}"); } - internal static async Task UpdateGroupSetting(PnPConnection connection, string accessToken, string id, string groupId, dynamic groupSettingObject) + internal static void UpdateGroupSetting(Cmdlet cmdlet, PnPConnection connection, string accessToken, string id, string groupId, dynamic groupSettingObject) { var stringContent = new StringContent(JsonSerializer.Serialize(groupSettingObject)); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - await GraphHelper.PatchAsync(connection, accessToken, stringContent, $"v1.0/groups/{groupId}/settings/{id}"); + GraphHelper.Patch(cmdlet, connection, accessToken, stringContent, $"v1.0/groups/{groupId}/settings/{id}"); } - internal static async Task RemoveGroupSetting(PnPConnection connection, string accessToken, string id) + internal static void RemoveGroupSetting(Cmdlet cmdlet, PnPConnection connection, string accessToken, string id) { - await GraphHelper.DeleteAsync(connection, $"v1.0/groupSettings/{id}", accessToken); + GraphHelper.Delete(cmdlet, connection, $"v1.0/groupSettings/{id}", accessToken); } - internal static async Task RemoveGroupSetting(PnPConnection connection, string accessToken, string id, string groupId) + internal static void RemoveGroupSetting(Cmdlet cmdlet, PnPConnection connection, string accessToken, string id, string groupId) { - await GraphHelper.DeleteAsync(connection, $"v1.0/groups/{groupId}/settings/{id}", accessToken); + GraphHelper.Delete(cmdlet, connection, $"v1.0/groups/{groupId}/settings/{id}", accessToken); } - internal static async Task GetGroupTemplateSettingsAsync(PnPConnection connection, string accessToken) + internal static Microsoft365GroupTemplateSettingValueCollection GetGroupTemplateSettings(Cmdlet cmdlet, PnPConnection connection, string accessToken) { - var result = await GraphHelper.GetAsync(connection, "v1.0/groupSettingTemplates", accessToken, propertyNameCaseInsensitive: true); + var result = GraphHelper.Get(cmdlet, connection, "v1.0/groupSettingTemplates", accessToken, propertyNameCaseInsensitive: true); return result; } - internal static async Task GetGroupTemplateSettingsAsync(PnPConnection connection, string accessToken, string id) + internal static Microsoft365GroupSettingTemplate GetGroupTemplateSettings(Cmdlet cmdlet, PnPConnection connection, string accessToken, string id) { - var result = await GraphHelper.GetAsync(connection, $"v1.0/groupSettingTemplates/{id}", accessToken, propertyNameCaseInsensitive: true); + var result = GraphHelper.Get(cmdlet, connection, $"v1.0/groupSettingTemplates/{id}", accessToken, propertyNameCaseInsensitive: true); return result; } - internal static async Task SetSensitivityLabelsAsync(PnPConnection connection, string accessToken, Guid groupId, List assignedLabels) + internal static void SetSensitivityLabels(Cmdlet cmdlet, PnPConnection connection, string accessToken, Guid groupId, List assignedLabels) { var patchData = new { @@ -780,13 +782,13 @@ internal static async Task SetSensitivityLabelsAsync(PnPConnection connection, s { try { - await GraphHelper.PatchAsync(connection, accessToken, $"v1.0/groups/{groupId}", patchData); + GraphHelper.Patch(cmdlet, connection, accessToken, $"v1.0/groups/{groupId}", patchData); retry = false; } catch (Exception) { - await Task.Delay(5000); + Thread.Sleep(5000); iteration++; } @@ -797,9 +799,9 @@ internal static async Task SetSensitivityLabelsAsync(PnPConnection connection, s } } - internal static async Task DeletePhotoAsync(PnPConnection connection, string accessToken, Guid groupId) + internal static HttpResponseMessage DeletePhoto(Cmdlet cmdlet, PnPConnection connection, string accessToken, Guid groupId) { - return await GraphHelper.DeleteAsync(connection, $"v1.0/groups/{groupId}/photo/$value", accessToken); + return GraphHelper.Delete(cmdlet, connection, $"v1.0/groups/{groupId}/photo/$value", accessToken); } } } \ No newline at end of file diff --git a/src/Commands/Utilities/PlannerUtility.cs b/src/Commands/Utilities/PlannerUtility.cs index 1f3e91a14..941598a9a 100644 --- a/src/Commands/Utilities/PlannerUtility.cs +++ b/src/Commands/Utilities/PlannerUtility.cs @@ -4,6 +4,7 @@ using PnP.PowerShell.Commands.Utilities.REST; using System.Collections.Generic; using System.Linq; +using System.Management.Automation; using System.Net.Http; using System.Text.Json; using System.Threading.Tasks; @@ -13,19 +14,19 @@ namespace PnP.PowerShell.Commands.Utilities internal static class PlannerUtility { #region Plans - public static async Task> GetPlansAsync(PnPConnection connection, string accessToken, string groupId, bool resolveDisplayNames) + public static IEnumerable GetPlans(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, bool resolveDisplayNames) { var returnCollection = new List(); - var collection = await GraphHelper.GetResultCollectionAsync(connection, $"v1.0/groups/{groupId}/planner/plans", accessToken); + var collection = GraphHelper.GetResultCollection(cmdlet, connection, $"v1.0/groups/{groupId}/planner/plans", accessToken); if (collection != null && collection.Any()) { if (resolveDisplayNames) { foreach (var plan in collection) { - var fullIdentity = await ResolveIdentityAsync(connection, accessToken, plan.CreatedBy.User); + var fullIdentity = ResolveIdentity(cmdlet, connection, accessToken, plan.CreatedBy.User); plan.CreatedBy.User = fullIdentity; - var owner = await ResolveGroupName(connection, accessToken, plan.Owner); + var owner = ResolveGroupName(cmdlet, connection, accessToken, plan.Owner); plan.Owner = owner; returnCollection.Add(plan); } @@ -38,48 +39,48 @@ public static async Task> GetPlansAsync(PnPConnection c return returnCollection; } - public static async Task GetPlanAsync(PnPConnection connection, string accessToken, string planId, bool resolveDisplayNames) + public static PlannerPlan GetPlan(Cmdlet cmdlet, PnPConnection connection, string accessToken, string planId, bool resolveDisplayNames) { - var plan = await GraphHelper.GetAsync(connection, $"v1.0/planner/plans/{planId}", accessToken); + var plan = GraphHelper.Get(cmdlet, connection, $"v1.0/planner/plans/{planId}", accessToken); if (resolveDisplayNames) { - plan.CreatedBy.User = await ResolveIdentityAsync(connection, accessToken, plan.CreatedBy.User); + plan.CreatedBy.User = ResolveIdentity(cmdlet, connection, accessToken, plan.CreatedBy.User); } return plan; } - public static async Task CreatePlanAsync(PnPConnection connection, string accessToken, string groupId, string title) + public static PlannerPlan CreatePlan(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string title) { var stringContent = new StringContent(JsonSerializer.Serialize(new { owner = groupId, title = title })); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - return await GraphHelper.PostAsync(connection, "v1.0/planner/plans", stringContent, accessToken); + return GraphHelper.Post(cmdlet, connection, "v1.0/planner/plans", stringContent, accessToken); } - public static async Task UpdatePlanAsync(PnPConnection connection, string accessToken, PlannerPlan plan, string title) + public static PlannerPlan UpdatePlan(Cmdlet cmdlet, PnPConnection connection, string accessToken, PlannerPlan plan, string title) { var stringContent = new StringContent(JsonSerializer.Serialize(new { title })); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - var responseMessage = await GraphHelper.PatchAsync(connection, accessToken, stringContent, $"v1.0/planner/plans/{plan.Id}", new Dictionary() { { "IF-MATCH", plan.ETag } }); + var responseMessage = GraphHelper.Patch(cmdlet, connection, accessToken, stringContent, $"v1.0/planner/plans/{plan.Id}", new Dictionary() { { "IF-MATCH", plan.ETag } }); while (responseMessage.StatusCode == System.Net.HttpStatusCode.PreconditionFailed) { // retrieve the plan again - plan = await GraphHelper.GetAsync(connection, $"v1.0/planner/plans/{plan.Id}", accessToken); - responseMessage = await GraphHelper.PatchAsync(connection, accessToken, stringContent, $"v1.0/planner/plans/{plan.Id}", new Dictionary() { { "IF-MATCH", plan.ETag } }); + plan = GraphHelper.Get(cmdlet, connection, $"v1.0/planner/plans/{plan.Id}", accessToken); + responseMessage = GraphHelper.Patch(cmdlet, connection, accessToken, stringContent, $"v1.0/planner/plans/{plan.Id}", new Dictionary() { { "IF-MATCH", plan.ETag } }); } if (responseMessage.IsSuccessStatusCode) { - var responseContent = await responseMessage.Content.ReadAsStringAsync(); + var responseContent = responseMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult(); return JsonSerializer.Deserialize(responseContent); } return null; } - public static async Task DeletePlanAsync(PnPConnection connection, string accessToken, string planId) + public static void DeletePlan(Cmdlet cmdlet, PnPConnection connection, string accessToken, string planId) { - var plan = await GetPlanAsync(connection, accessToken, planId, false); + var plan = GetPlan(cmdlet, connection, accessToken, planId, false); if (plan != null) { - await GraphHelper.DeleteAsync(connection, $"v1.0/planner/plans/{planId}", accessToken, new Dictionary() { { "IF-MATCH", plan.ETag } }); + GraphHelper.Delete(cmdlet, connection, $"v1.0/planner/plans/{planId}", accessToken, new Dictionary() { { "IF-MATCH", plan.ETag } }); } } @@ -87,23 +88,23 @@ public static async Task DeletePlanAsync(PnPConnection connection, string access #region Tasks - public static async Task> GetTasksAsync(PnPConnection connection, string accessToken, string planId, bool resolveDisplayNames) + public static IEnumerable GetTasks(Cmdlet cmdlet, PnPConnection connection, string accessToken, string planId, bool resolveDisplayNames) { var returnCollection = new List(); - var collection = await GraphHelper.GetResultCollectionAsync(connection, $"v1.0/planner/plans/{planId}/tasks", accessToken); + var collection = GraphHelper.GetResultCollection(cmdlet, connection, $"v1.0/planner/plans/{planId}/tasks", accessToken); if (collection != null && collection.Any()) { if (resolveDisplayNames) { foreach (var task in collection) { - var fullIdentity = await ResolveIdentityAsync(connection, accessToken, task.CreatedBy.User); + var fullIdentity = ResolveIdentity(cmdlet, connection, accessToken, task.CreatedBy.User); task.CreatedBy.User = fullIdentity; if (task.Assignments != null) { foreach (var assignment in task.Assignments) { - assignment.Value.AssignedBy.User = await ResolveIdentityAsync(connection, accessToken, assignment.Value.AssignedBy.User); + assignment.Value.AssignedBy.User = ResolveIdentity(cmdlet, connection, accessToken, assignment.Value.AssignedBy.User); } } returnCollection.Add(task); @@ -117,24 +118,24 @@ public static async Task> GetTasksAsync(PnPConnection c return returnCollection; } - public static async Task GetTaskAsync(PnPConnection connection, string accessToken, string taskId, bool resolveDisplayNames, bool includeDetails) + public static PlannerTask GetTask(Cmdlet cmdlet, PnPConnection connection, string accessToken, string taskId, bool resolveDisplayNames, bool includeDetails) { - var task = await GraphHelper.GetAsync(connection, $"v1.0/planner/tasks/{taskId}", accessToken); + var task = GraphHelper.Get(cmdlet, connection, $"v1.0/planner/tasks/{taskId}", accessToken); if (resolveDisplayNames) { - task.CreatedBy.User = await ResolveIdentityAsync(connection, accessToken, task.CreatedBy.User); + task.CreatedBy.User = ResolveIdentity(cmdlet, connection, accessToken, task.CreatedBy.User); } if (includeDetails) { - var taskDetails = await GetTaskDetailsAsync(connection, accessToken, taskId, resolveDisplayNames); + var taskDetails = GetTaskDetails(cmdlet,connection, accessToken, taskId, resolveDisplayNames); task.Details = taskDetails; } return task; } - public static async Task GetTaskDetailsAsync(PnPConnection connection, string accessToken, string taskId, bool resolveDisplayNames) + public static PlannerTaskDetails GetTaskDetails(Cmdlet cmdlet, PnPConnection connection, string accessToken, string taskId, bool resolveDisplayNames) { - var taskDetails = await GraphHelper.GetAsync(connection, $"v1.0/planner/tasks/{taskId}/details", accessToken); + var taskDetails = GraphHelper.Get(cmdlet, connection, $"v1.0/planner/tasks/{taskId}/details", accessToken); if (!resolveDisplayNames) return taskDetails; @@ -152,7 +153,7 @@ public static async Task GetTaskDetailsAsync(PnPConnection c { newCheckListItem.LastModifiedBy = new IdentitySet { - User = await ResolveIdentityAsync(connection, accessToken, checklistItem.Value.LastModifiedBy.User) + User = ResolveIdentity(cmdlet, connection, accessToken, checklistItem.Value.LastModifiedBy.User) }; } newItems.Add(checklistItem.Key, newCheckListItem); @@ -162,32 +163,32 @@ public static async Task GetTaskDetailsAsync(PnPConnection c return taskDetails; } - public static async Task AddTaskAsync(PnPConnection connection, string accessToken, PlannerTask task) + public static PlannerTask AddTask(Cmdlet cmdlet, PnPConnection connection, string accessToken, PlannerTask task) { - return await GraphHelper.PostAsync(connection, "v1.0/planner/tasks", task, accessToken); + return GraphHelper.Post(cmdlet, connection, "v1.0/planner/tasks", task, accessToken); } - public static async Task DeleteTaskAsync(PnPConnection connection, string accessToken, string taskId) + public static void DeleteTask(Cmdlet cmdlet, PnPConnection connection, string accessToken, string taskId) { - var task = await GraphHelper.GetAsync(connection, $"v1.0/planner/tasks/{taskId}", accessToken); + var task = GraphHelper.Get(cmdlet, connection, $"v1.0/planner/tasks/{taskId}", accessToken); if (task != null) { - await GraphHelper.DeleteAsync(connection, $"v1.0/planner/tasks/{taskId}", accessToken, new Dictionary() { { "IF-MATCH", task.ETag } }); + GraphHelper.Delete(cmdlet, connection, $"v1.0/planner/tasks/{taskId}", accessToken, new Dictionary() { { "IF-MATCH", task.ETag } }); } } - public static async Task UpdateTaskAsync(PnPConnection connection, string accessToken, PlannerTask taskToUpdate, PlannerTask task) + public static PlannerTask UpdateTask(Cmdlet cmdlet, PnPConnection connection, string accessToken, PlannerTask taskToUpdate, PlannerTask task) { - return await GraphHelper.PatchAsync(connection, accessToken, $"v1.0/planner/tasks/{taskToUpdate.Id}", task, new Dictionary { { "IF-MATCH", taskToUpdate.ETag } }); + return GraphHelper.Patch(cmdlet, connection, accessToken, $"v1.0/planner/tasks/{taskToUpdate.Id}", task, new Dictionary { { "IF-MATCH", taskToUpdate.ETag } }); } - public static async Task UpdateTaskDetailsAsync(PnPConnection connection, string accessToken, PlannerTaskDetails taskToUpdate, string description) + public static void UpdateTaskDetails(Cmdlet cmdlet, PnPConnection connection, string accessToken, PlannerTaskDetails taskToUpdate, string description) { var body = new PlannerTaskDetails { Description = description, }; - await GraphHelper.PatchAsync(connection, accessToken, $"v1.0/planner/tasks/{taskToUpdate.Id}/details", body, new Dictionary { { "IF-MATCH", taskToUpdate.ETag } }); + GraphHelper.Patch(cmdlet, connection, accessToken, $"v1.0/planner/tasks/{taskToUpdate.Id}/details", body, new Dictionary { { "IF-MATCH", taskToUpdate.ETag } }); } #endregion @@ -200,11 +201,11 @@ public static async Task UpdateTaskDetailsAsync(PnPConnection connection, string /// HttpClient instance to use to send out requests /// AccessToken to use to authenticate the request /// PlannerRoster - public static async Task CreateRosterAsync(PnPConnection connection, string accessToken) + public static PlannerRoster CreateRoster(Cmdlet cmdlet, PnPConnection connection, string accessToken) { var stringContent = new StringContent("{ \"@odata.type\": \"#microsoft.graph.plannerRoster\" }"); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - return await GraphHelper.PostAsync(connection, "beta/planner/rosters", stringContent, accessToken); + return GraphHelper.Post(cmdlet, connection, "beta/planner/rosters", stringContent, accessToken); } /// @@ -214,9 +215,9 @@ public static async Task CreateRosterAsync(PnPConnection connecti /// HttpClient instance to use to send out requests /// AccessToken to use to authenticate the request /// PlannerRoster - public static async Task GetRosterAsync(PnPConnection connection, string accessToken, string rosterId) + public static PlannerRoster GetRoster(Cmdlet cmdlet, PnPConnection connection, string accessToken, string rosterId) { - return await GraphHelper.GetAsync(connection, $"beta/planner/rosters/{rosterId}", accessToken); + return GraphHelper.Get(cmdlet, connection, $"beta/planner/rosters/{rosterId}", accessToken); } /// @@ -226,9 +227,9 @@ public static async Task GetRosterAsync(PnPConnection connection, /// HttpClient instance to use to send out requests /// AccessToken to use to authenticate the request /// HttpResponseMessage - public static async Task DeleteRosterAsync(PnPConnection connection, string accessToken, string rosterId) + public static HttpResponseMessage DeleteRoster(Cmdlet cmdlet, PnPConnection connection, string accessToken, string rosterId) { - return await GraphHelper.DeleteAsync(connection, $"beta/planner/rosters/{rosterId}", accessToken); + return GraphHelper.Delete(cmdlet, connection, $"beta/planner/rosters/{rosterId}", accessToken); } /// @@ -239,11 +240,11 @@ public static async Task DeleteRosterAsync(PnPConnection co /// HttpClient instance to use to send out requests /// AccessToken to use to authenticate the request /// PlannerRoster - public static async Task AddRosterMemberAsync(PnPConnection connection, string accessToken, string rosterId, string userId) + public static PlannerRoster AddRosterMember(Cmdlet cmdlet, PnPConnection connection, string accessToken, string rosterId, string userId) { var stringContent = new StringContent("{ \"@odata.type\": \"#microsoft.graph.plannerRosterMember\", \"userId\": \"" + userId + "\" }"); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - return await GraphHelper.PostAsync(connection, $"beta/planner/rosters/{rosterId}/members", stringContent, accessToken); + return GraphHelper.Post(cmdlet, connection, $"beta/planner/rosters/{rosterId}/members", stringContent, accessToken); } /// @@ -254,9 +255,9 @@ public static async Task AddRosterMemberAsync(PnPConnection conne /// HttpClient instance to use to send out requests /// AccessToken to use to authenticate the request /// HttpResponseMessage - public static async Task RemoveRosterMemberAsync(PnPConnection connection, string accessToken, string rosterId, string userId) + public static HttpResponseMessage RemoveRosterMember(Cmdlet cmdlet, PnPConnection connection, string accessToken, string rosterId, string userId) { - return await GraphHelper.DeleteAsync(connection, $"beta/planner/rosters/{rosterId}/members/{userId}", accessToken); + return GraphHelper.Delete(cmdlet, connection, $"beta/planner/rosters/{rosterId}/members/{userId}", accessToken); } /// @@ -266,10 +267,10 @@ public static async Task RemoveRosterMemberAsync(PnPConnect /// HttpClient instance to use to send out requests /// AccessToken to use to authenticate the request /// IEnumerable - public static async Task> GetRosterMembersAsync(PnPConnection connection, string accessToken, string rosterId) + public static IEnumerable GetRosterMembers(Cmdlet cmdlet, PnPConnection connection, string accessToken, string rosterId) { var returnCollection = new List(); - var collection = await GraphHelper.GetResultCollectionAsync(connection, $"beta/planner/rosters/{rosterId}/members", accessToken); + var collection = GraphHelper.GetResultCollection(cmdlet, connection, $"beta/planner/rosters/{rosterId}/members", accessToken); if (collection != null && collection.Any()) { returnCollection = collection.ToList(); @@ -284,9 +285,9 @@ public static async Task> GetRosterMembersAsync /// HttpClient instance to use to send out requests /// AccessToken to use to authenticate the request /// PlannerRoster - public static async Task GetRosterPlansByUserAsync(PnPConnection connection, string accessToken, string userId) + public static PlannerRoster GetRosterPlansByUser(Cmdlet cmdlet, PnPConnection connection, string accessToken, string userId) { - return await GraphHelper.GetAsync(connection, $"beta/users/{userId}/planner/rosterPlans", accessToken); + return GraphHelper.Get(cmdlet, connection, $"beta/users/{userId}/planner/rosterPlans", accessToken); } /// @@ -296,9 +297,9 @@ public static async Task GetRosterPlansByUserAsync(PnPConnection /// HttpClient instance to use to send out requests /// AccessToken to use to authenticate the request /// PlannerRoster - public static async Task GetRosterPlansByRosterAsync(PnPConnection connection, string accessToken, string rosterId) + public static PlannerRoster GetRosterPlansByRoster(Cmdlet cmdlet, PnPConnection connection, string accessToken, string rosterId) { - return await GraphHelper.GetAsync(connection, $"beta/planner/rosters/{rosterId}/plans", accessToken); + return GraphHelper.Get(cmdlet, connection, $"beta/planner/rosters/{rosterId}/plans", accessToken); } #endregion @@ -311,9 +312,9 @@ public static async Task GetRosterPlansByRosterAsync(PnPConnectio /// HttpClient instance to use to send out requests /// AccessToken to use to authenticate the request /// PlannerTenantConfig - public static async Task GetPlannerConfigAsync(PnPConnection connection, string accessToken) + public static PlannerTenantConfig GetPlannerConfig(Cmdlet cmdlet, PnPConnection connection, string accessToken) { - var result = await GraphHelper.GetAsync(connection, "https://tasks.office.com/taskAPI/tenantAdminSettings/Settings", accessToken); + var result = GraphHelper.Get(cmdlet, connection, "https://tasks.office.com/taskAPI/tenantAdminSettings/Settings", accessToken); return result; } @@ -323,7 +324,7 @@ public static async Task GetPlannerConfigAsync(PnPConnectio /// HttpClient instance to use to send out requests /// AccessToken to use to authenticate the request /// PlannerTenantConfig - public static async Task SetPlannerConfigAsync(PnPConnection connection, string accessToken, bool? isPlannerAllowed, bool? allowCalendarSharing, bool? allowTenantMoveWithDataLoss, bool? allowTenantMoveWithDataMigration, bool? allowRosterCreation, bool? allowPlannerMobilePushNotifications) + public static PlannerTenantConfig SetPlannerConfig(Cmdlet cmdlet, PnPConnection connection, string accessToken, bool? isPlannerAllowed, bool? allowCalendarSharing, bool? allowTenantMoveWithDataLoss, bool? allowTenantMoveWithDataMigration, bool? allowRosterCreation, bool? allowPlannerMobilePushNotifications) { var content = new PlannerTenantConfig { @@ -334,7 +335,7 @@ public static async Task SetPlannerConfigAsync(PnPConnectio AllowRosterCreation = allowRosterCreation, AllowPlannerMobilePushNotifications = allowPlannerMobilePushNotifications }; - var result = await GraphHelper.PatchAsync(connection, accessToken, "https://tasks.office.com/taskAPI/tenantAdminSettings/Settings", content); + var result = GraphHelper.Patch(cmdlet, connection, accessToken, "https://tasks.office.com/taskAPI/tenantAdminSettings/Settings", content); return result; } @@ -345,9 +346,9 @@ public static async Task SetPlannerConfigAsync(PnPConnectio /// HttpClient instance to use to send out requests /// AccessToken to use to authenticate the request /// PlannerUserPolicy - public static async Task GetPlannerUserPolicyAsync(PnPConnection connection, string accessToken, string userId) + public static PlannerUserPolicy GetPlannerUserPolicy(Cmdlet cmdlet, PnPConnection connection, string accessToken, string userId) { - var result = await GraphHelper.GetAsync(connection, $"https://tasks.office.com/taskAPI/tenantAdminSettings/UserPolicy('{userId}')", accessToken); + var result = GraphHelper.Get(cmdlet, connection, $"https://tasks.office.com/taskAPI/tenantAdminSettings/UserPolicy('{userId}')", accessToken); return result; } @@ -358,19 +359,19 @@ public static async Task GetPlannerUserPolicyAsync(PnPConnect /// HttpClient instance to use to send out requests /// AccessToken to use to authenticate the request /// PlannerUserPolicy - public static async Task SetPlannerUserPolicyAsync(PnPConnection connection, string accessToken, string userId, bool? blockDeleteTasksNotCreatedBySelf) + public static PlannerUserPolicy SetPlannerUserPolicy(Cmdlet cmdlet, PnPConnection connection, string accessToken, string userId, bool? blockDeleteTasksNotCreatedBySelf) { var content = new PlannerUserPolicy { BlockDeleteTasksNotCreatedBySelf = blockDeleteTasksNotCreatedBySelf }; - var result = await GraphHelper.PutAsync(connection, $"https://tasks.office.com/taskAPI/tenantAdminSettings/UserPolicy('{userId}')", content, accessToken); + var result = GraphHelper.Put(cmdlet, connection, $"https://tasks.office.com/taskAPI/tenantAdminSettings/UserPolicy('{userId}')", content, accessToken); return result; } #endregion - private static async Task ResolveIdentityAsync(PnPConnection connection, string accessToken, Identity identity) + private static Identity ResolveIdentity(Cmdlet cmdlet, PnPConnection connection, string accessToken, Identity identity) { if (identity == null) { @@ -378,7 +379,7 @@ private static async Task ResolveIdentityAsync(PnPConnection connectio } if (identity.DisplayName == null) { - return await GraphHelper.GetAsync(connection, $"v1.0/users/{identity.Id}", accessToken); + return GraphHelper.Get(cmdlet, connection, $"v1.0/users/{identity.Id}", accessToken); } else { @@ -386,9 +387,9 @@ private static async Task ResolveIdentityAsync(PnPConnection connectio } } - private static async Task ResolveGroupName(PnPConnection connection, string accessToken, string id) + private static string ResolveGroupName(Cmdlet cmdlet, PnPConnection connection, string accessToken, string id) { - var group = await GraphHelper.GetAsync(connection, $"v1.0/groups/{id}?$select=displayName", accessToken); + var group = GraphHelper.Get(cmdlet, connection, $"v1.0/groups/{id}?$select=displayName", accessToken); if (group != null) { return group.DisplayName; @@ -401,45 +402,45 @@ private static async Task ResolveGroupName(PnPConnection connection, str #region Buckets - public static async Task> GetBucketsAsync(PnPConnection connection, string accessToken, string planId) + public static IEnumerable GetBuckets(Cmdlet cmdlet, PnPConnection connection, string accessToken, string planId) { - return await GraphHelper.GetResultCollectionAsync(connection, $"v1.0/planner/plans/{planId}/buckets", accessToken); + return GraphHelper.GetResultCollection(cmdlet, connection, $"v1.0/planner/plans/{planId}/buckets", accessToken); } - public static async Task CreateBucketAsync(PnPConnection connection, string accessToken, string name, string planId) + public static PlannerBucket CreateBucket(Cmdlet cmdlet, PnPConnection connection, string accessToken, string name, string planId) { var stringContent = new StringContent(JsonSerializer.Serialize(new { name = name, planId = planId, orderHint = " !" })); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - return await GraphHelper.PostAsync(connection, $"v1.0/planner/buckets", stringContent, accessToken); + return GraphHelper.Post(cmdlet, connection, $"v1.0/planner/buckets", stringContent, accessToken); } - public static async System.Threading.Tasks.Task RemoveBucketAsync(PnPConnection connection, string accessToken, string bucketId) + public static void RemoveBucket(Cmdlet cmdlet, PnPConnection connection, string accessToken, string bucketId) { - var bucket = GraphHelper.GetAsync(connection, $"v1.0/planner/buckets/{bucketId}", accessToken).GetAwaiter().GetResult(); + var bucket = GraphHelper.Get(cmdlet, connection, $"v1.0/planner/buckets/{bucketId}", accessToken); if (bucket != null) { - await GraphHelper.DeleteAsync(connection, $"v1.0/planner/buckets/{bucketId}", accessToken, new Dictionary() { { "IF-MATCH", bucket.ETag } }); + GraphHelper.Delete(cmdlet, connection, $"v1.0/planner/buckets/{bucketId}", accessToken, new Dictionary() { { "IF-MATCH", bucket.ETag } }); } } - public static async Task> GetBucketTasksAsync(PnPConnection connection, string accessToken, string bucketId, bool resolveDisplayNames) + public static IEnumerable GetBucketTasks(Cmdlet cmdlet, PnPConnection connection, string accessToken, string bucketId, bool resolveDisplayNames) { var returnCollection = new List(); - var collection = await GraphHelper.GetAsync>(connection, $"v1.0/planner/buckets/{bucketId}/tasks", accessToken); + var collection = GraphHelper.Get>(cmdlet, connection, $"v1.0/planner/buckets/{bucketId}/tasks", accessToken); if (collection != null && collection.Items.Any()) { if (resolveDisplayNames) { foreach (var task in collection.Items) { - var fullIdentity = await ResolveIdentityAsync(connection, accessToken, task.CreatedBy.User); + var fullIdentity = ResolveIdentity(cmdlet, connection, accessToken, task.CreatedBy.User); task.CreatedBy.User = fullIdentity; if (task.Assignments != null) { foreach (var assignment in task.Assignments) { - assignment.Value.AssignedBy.User = await ResolveIdentityAsync(connection, accessToken, assignment.Value.AssignedBy.User); + assignment.Value.AssignedBy.User = ResolveIdentity(cmdlet, connection, accessToken, assignment.Value.AssignedBy.User); } } returnCollection.Add(task); @@ -456,13 +457,13 @@ public static async Task> GetBucketTasksAsync(PnPConnec { foreach (var task in collection.Items) { - var fullIdentity = await ResolveIdentityAsync(connection, accessToken, task.CreatedBy.User); + var fullIdentity = ResolveIdentity(cmdlet, connection, accessToken, task.CreatedBy.User); task.CreatedBy.User = fullIdentity; if (task.Assignments != null) { foreach (var assignment in task.Assignments) { - assignment.Value.AssignedBy.User = await ResolveIdentityAsync(connection, accessToken, assignment.Value.AssignedBy.User); + assignment.Value.AssignedBy.User = ResolveIdentity(cmdlet, connection, accessToken, assignment.Value.AssignedBy.User); } } returnCollection.Add(task); @@ -478,14 +479,14 @@ public static async Task> GetBucketTasksAsync(PnPConnec return returnCollection; } - public static async Task UpdateBucketAsync(PnPConnection connection, string accessToken, string name, string bucketId) + public static PlannerBucket UpdateBucket(Cmdlet cmdlet, PnPConnection connection, string accessToken, string name, string bucketId) { - var bucket = await GraphHelper.GetAsync(connection, $"v1.0/planner/buckets/{bucketId}", accessToken); + var bucket = GraphHelper.Get(cmdlet, connection, $"v1.0/planner/buckets/{bucketId}", accessToken); if (bucket != null) { var stringContent = new StringContent(JsonSerializer.Serialize(new { name = name })); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - return await GraphHelper.PatchAsync(connection, accessToken, $"v1.0/planner/buckets/{bucketId}", stringContent, new Dictionary() { { "IF-MATCH", bucket.ETag } }); + return GraphHelper.Patch(cmdlet, connection, accessToken, $"v1.0/planner/buckets/{bucketId}", stringContent, new Dictionary() { { "IF-MATCH", bucket.ETag } }); } return null; } diff --git a/src/Commands/Utilities/PowerAppsUtility.cs b/src/Commands/Utilities/PowerAppsUtility.cs index 18779bee4..214bfe6c5 100644 --- a/src/Commands/Utilities/PowerAppsUtility.cs +++ b/src/Commands/Utilities/PowerAppsUtility.cs @@ -1,21 +1,16 @@ using System; -using System.Collections.Generic; -using System.Linq; using System.Net.Http; using System.Net.Http.Headers; -using System.Text; using System.Text.Json; using System.Threading; -using System.Threading.Tasks; using PnP.Framework; -using PnP.PowerShell.Commands.Base; using PnP.PowerShell.Commands.Utilities.REST; namespace PnP.PowerShell.Commands.Utilities { internal static class PowerAppsUtility { - internal static async Task GetWrapper(HttpClient connection, string environmentName, string accessToken, string appName, AzureEnvironment azureEnvironment = AzureEnvironment.Production) + internal static Model.PowerPlatform.PowerApp.PowerAppPackageWrapper GetWrapper(HttpClient connection, string environmentName, string accessToken, string appName, AzureEnvironment azureEnvironment = AzureEnvironment.Production) { var postData = new { @@ -24,7 +19,7 @@ internal static class PowerAppsUtility } }; string baseUrl = PowerPlatformUtility.GetBapEndpoint(azureEnvironment); - var wrapper = await RestHelper.PostAsync(connection, $"{baseUrl}/providers/Microsoft.BusinessAppPlatform/environments/{environmentName}/listPackageResources?api-version=2016-11-01", accessToken, payload: postData); + var wrapper = RestHelper.Post(connection, $"{baseUrl}/providers/Microsoft.BusinessAppPlatform/environments/{environmentName}/listPackageResources?api-version=2016-11-01", accessToken, payload: postData); return wrapper; @@ -43,7 +38,7 @@ internal static HttpResponseHeaders GetResponseHeader(HttpClient connection, str }; string baseUrl = PowerPlatformUtility.GetBapEndpoint(azureEnvironment); - var responseHeader = RestHelper.PostAsyncGetResponseHeader(connection, $"{baseUrl}/providers/Microsoft.BusinessAppPlatform/environments/{environmentName}/exportPackage?api-version=2016-11-01", accessToken, payload: exportPostData).GetAwaiter().GetResult(); + var responseHeader = RestHelper.PostGetResponseHeader(connection, $"{baseUrl}/providers/Microsoft.BusinessAppPlatform/environments/{environmentName}/exportPackage?api-version=2016-11-01", accessToken, payload: exportPostData); return responseHeader; @@ -57,7 +52,7 @@ internal static string GetPackageLink(HttpClient connection, string location, st { do { - var runningresponse = RestHelper.GetAsync(connection, location, accessToken).GetAwaiter().GetResult(); + var runningresponse = RestHelper.Get(connection, location, accessToken); if (runningresponse.TryGetProperty("properties", out JsonElement properties)) { diff --git a/src/Commands/Utilities/REST/GraphBatch.cs b/src/Commands/Utilities/REST/GraphBatch.cs index 712fc2b4b..88fa85ab5 100644 --- a/src/Commands/Utilities/REST/GraphBatch.cs +++ b/src/Commands/Utilities/REST/GraphBatch.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Management.Automation; using System.Net.Http; using System.Text.Json; using System.Text.Json.Serialization; @@ -21,7 +22,7 @@ internal static IEnumerable> Chunk(this IEnumerable source, } } - internal static async Task> GetPropertyBatchedAsync(PnPConnection connection, string accessToken, string[] lookupData, string urlTemplate, string property) + internal static Dictionary GetPropertyBatched(Cmdlet cmdlet, PnPConnection connection, string accessToken, string[] lookupData, string urlTemplate, string property) { Dictionary returnValue = new Dictionary(); @@ -37,7 +38,7 @@ internal static async Task> GetPropertyBatchedAsync(P } var stringContent = new StringContent(JsonSerializer.Serialize(batch)); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - var result = await GraphHelper.PostAsync(connection, "v1.0/$batch", stringContent, accessToken); + var result = GraphHelper.Post(cmdlet, connection, "v1.0/$batch", stringContent, accessToken); if (result.Responses != null && result.Responses.Any()) { foreach (var response in result.Responses) @@ -53,7 +54,7 @@ internal static async Task> GetPropertyBatchedAsync(P return returnValue; } - internal static async Task>> GetObjectCollectionBatchedAsync(PnPConnection connection, string accessToken, string[] lookupData, string urlTemplate) + internal static Dictionary> GetObjectCollectionBatched(Cmdlet cmdlet, PnPConnection connection, string accessToken, string[] lookupData, string urlTemplate) { Dictionary> returnValue = new Dictionary>(); @@ -69,7 +70,7 @@ internal static async Task>> GetObjectCollecti } var stringContent = new StringContent(JsonSerializer.Serialize(batch)); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - var result = await GraphHelper.PostAsync(connection, "v1.0/$batch", stringContent, accessToken); + var result = GraphHelper.Post(cmdlet, connection, "v1.0/$batch", stringContent, accessToken); if (result.Responses != null && result.Responses.Any()) { var options = new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase}; diff --git a/src/Commands/Utilities/REST/GraphHelper.cs b/src/Commands/Utilities/REST/GraphHelper.cs index e222bab5b..dc1e5db30 100644 --- a/src/Commands/Utilities/REST/GraphHelper.cs +++ b/src/Commands/Utilities/REST/GraphHelper.cs @@ -1,4 +1,5 @@ -using PnP.PowerShell.Commands.Base; +using Newtonsoft.Json.Serialization; +using PnP.PowerShell.Commands.Base; using PnP.PowerShell.Commands.Model.Graph; using System; using System.Collections.Generic; @@ -8,7 +9,7 @@ using System.Net.Http; using System.Text.Json; using System.Text.Json.Serialization; -using System.Threading.Tasks; +using System.Threading; namespace PnP.PowerShell.Commands.Utilities.REST { @@ -49,9 +50,11 @@ private static HttpRequestMessage GetMessage(string url, HttpMethod method, PnPC url = url.Substring(1); } - var message = new HttpRequestMessage(); - message.Version = new Version(2, 0); - message.Method = method; + var message = new HttpRequestMessage + { + Version = new Version(2, 0), + Method = method + }; message.Headers.TryAddWithoutValidation("Accept", "application/json"); message.RequestUri = !url.StartsWith("https://", StringComparison.OrdinalIgnoreCase) ? new Uri($"https://{connection.GraphEndPoint}/{url}") : new Uri(url); message.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); @@ -71,16 +74,16 @@ private static HttpRequestMessage GetMessage(string url, HttpMethod method, PnPC return message; } - public static async Task GetAsync(PnPConnection connection, string url, string accessToken, IDictionary additionalHeaders = null) + public static string Get(Cmdlet cmdlet, PnPConnection connection, string url, string accessToken, IDictionary additionalHeaders = null) { var message = GetMessage(url, HttpMethod.Get, connection, accessToken, null, additionalHeaders); - return await SendMessageAsync(connection, message, accessToken); + return SendMessage(cmdlet, connection, message, accessToken); } - public static async Task GetResponseAsync(PnPConnection connection, string url, string accessToken) + public static HttpResponseMessage GetResponse(Cmdlet cmdlet, PnPConnection connection, string url, string accessToken) { var message = GetMessage(url, HttpMethod.Get, connection, accessToken); - return await GetResponseMessageAsync(connection, message); + return GetResponseMessage(cmdlet, connection, message); } /// @@ -93,17 +96,19 @@ public static async Task GetResponseAsync(PnPConnection con /// Policy indicating the CamlCase that should be applied when mapping results to typed objects /// Indicates if the response be mapped to the typed object ignoring different casing /// List with objects of type T returned by the request - public static async Task> GetResultCollectionAsync(PnPConnection connection, string url, string accessToken, bool camlCasePolicy = true, bool propertyNameCaseInsensitive = false, IDictionary additionalHeaders = null) + public static IEnumerable GetResultCollection(Cmdlet cmdlet, PnPConnection connection, string url, string accessToken, bool camlCasePolicy = true, bool propertyNameCaseInsensitive = false, IDictionary additionalHeaders = null) { var results = new List(); - var request = await GetAsync>(connection, url, accessToken, camlCasePolicy, propertyNameCaseInsensitive, additionalHeaders); + var request = Get>(cmdlet, connection, url, accessToken, camlCasePolicy, propertyNameCaseInsensitive, additionalHeaders); if (request.Items.Any()) { results.AddRange(request.Items); while (!string.IsNullOrEmpty(request.NextLink)) { - request = await GetAsync>(connection, request.NextLink, accessToken, camlCasePolicy, propertyNameCaseInsensitive, additionalHeaders); + cmdlet.WriteVerbose($"Paged request. Thus far {results.Count} {typeof(T)} item{(results.Count != 1 ? "s" : "")} retrieved."); + + request = Get>(cmdlet, connection, request.NextLink, accessToken, camlCasePolicy, propertyNameCaseInsensitive, additionalHeaders); if (request.Items.Any()) { results.AddRange(request.Items); @@ -111,6 +116,8 @@ public static async Task> GetResultCollectionAsync(PnPConnecti } } + cmdlet.WriteVerbose($"Returning {results.Count} {typeof(T)} item{(results.Count != 1 ? "s" : "")}"); + return results; } @@ -124,12 +131,12 @@ public static async Task> GetResultCollectionAsync(PnPConnecti /// Policy indicating the CamlCase that should be applied when mapping results to typed objects /// Indicates if the response be mapped to the typed object ignoring different casing /// List with objects of type T returned by the request - public static async Task GetAsync(PnPConnection connection, string url, string accessToken, bool camlCasePolicy = true, bool propertyNameCaseInsensitive = false, IDictionary additionalHeaders = null) + public static T Get(Cmdlet cmdlet, PnPConnection connection, string url, string accessToken, bool camlCasePolicy = true, bool propertyNameCaseInsensitive = false, IDictionary additionalHeaders = null) { - var stringContent = await GetAsync(connection, url, accessToken, additionalHeaders); + var stringContent = Get(cmdlet, connection, url, accessToken, additionalHeaders); if (stringContent != null) { - var options = new JsonSerializerOptions { DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull }; + var options = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }; options.Converters.Add(new JsonStringEnumConverter()); if (camlCasePolicy) { @@ -144,39 +151,40 @@ public static async Task GetAsync(PnPConnection connection, string url, st var entity = JsonSerializer.Deserialize(stringContent, options); return entity; } - catch (Exception) + catch (Exception e) { + cmdlet.WriteWarning($"Failed to parse response from server. Error message: '{e.Message}'. Received content: '{stringContent}'. Model type to parse it to: '{typeof(T)}'."); return default(T); } } return default(T); } - public static async Task PostAsync(PnPConnection connection, string url, string accessToken, HttpContent content, IDictionary additionalHeaders = null) + public static HttpResponseMessage Post(Cmdlet cmdlet, PnPConnection connection, string url, string accessToken, HttpContent content, IDictionary additionalHeaders = null) { var message = GetMessage(url, HttpMethod.Post, connection, accessToken, content, additionalHeaders); - return await GetResponseMessageAsync(connection, message); + return GetResponseMessage(cmdlet, connection, message); } - public static async Task PutAsync(PnPConnection connection, string url, string accessToken, HttpContent content, IDictionary additionalHeaders = null) + public static HttpResponseMessage Put(Cmdlet cmdlet, PnPConnection connection, string url, string accessToken, HttpContent content, IDictionary additionalHeaders = null) { var message = GetMessage(url, HttpMethod.Put, connection, accessToken, content, additionalHeaders); - return await GetResponseMessageAsync(connection, message); + return GetResponseMessage(cmdlet, connection, message); } #region DELETE - public static async Task DeleteAsync(PnPConnection connection, string url, string accessToken, IDictionary additionalHeaders = null) + public static HttpResponseMessage Delete(Cmdlet cmdlet, PnPConnection connection, string url, string accessToken, IDictionary additionalHeaders = null) { var message = GetMessage(url, HttpMethod.Delete, connection, accessToken, null, additionalHeaders); - return await GetResponseMessageAsync(connection, message); + return GetResponseMessage(cmdlet, connection, message); } - public static async Task DeleteAsync(PnPConnection connection, string url, string accessToken, bool camlCasePolicy = true, IDictionary additionalHeaders = null) + public static T Delete(Cmdlet cmdlet, PnPConnection connection, string url, string accessToken, bool camlCasePolicy = true, IDictionary additionalHeaders = null) { - var response = await DeleteAsync(connection, url, accessToken, additionalHeaders); + var response = Delete(cmdlet, connection, url, accessToken, additionalHeaders); if (response.IsSuccessStatusCode) { - var stringContent = await response.Content.ReadAsStringAsync(); + var stringContent = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); if (stringContent != null) { @@ -200,9 +208,9 @@ public static async Task DeleteAsync(PnPConnection connection, string url, #endregion #region PATCH - public static async Task PatchAsync(PnPConnection connection, string accessToken, string url, T content, IDictionary additionalHeaders = null, bool camlCasePolicy = true) + public static T Patch(Cmdlet cmdlet, PnPConnection connection, string accessToken, string url, T content, IDictionary additionalHeaders = null, bool camlCasePolicy = true) { - var serializerSettings = new JsonSerializerOptions() { DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull }; + var serializerSettings = new JsonSerializerOptions() { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }; if (camlCasePolicy) { serializerSettings.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; @@ -210,7 +218,7 @@ public static async Task PatchAsync(PnPConnection connection, string acces var requestContent = new StringContent(JsonSerializer.Serialize(content, serializerSettings)); requestContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); var message = GetMessage(url, HttpMethod.Patch, connection, accessToken, requestContent, additionalHeaders); - var returnValue = await SendMessageAsync(connection, message, accessToken); + var returnValue = SendMessage(cmdlet, connection, message, accessToken); if (!string.IsNullOrEmpty(returnValue)) { return JsonSerializer.Deserialize(returnValue); @@ -221,10 +229,10 @@ public static async Task PatchAsync(PnPConnection connection, string acces } } - public static async Task PatchAsync(PnPConnection connection, string accessToken, string url, HttpContent content, IDictionary additionalHeaders = null) + public static T Patch(Cmdlet cmdlet, PnPConnection connection, string accessToken, string url, HttpContent content, IDictionary additionalHeaders = null) { var message = GetMessage(url, HttpMethod.Patch, connection, accessToken, content, additionalHeaders); - var returnValue = await SendMessageAsync(connection, message, accessToken); + var returnValue = SendMessage(cmdlet, connection, message, accessToken); if (!string.IsNullOrEmpty(returnValue)) { return JsonSerializer.Deserialize(returnValue); @@ -235,23 +243,23 @@ public static async Task PatchAsync(PnPConnection connection, string acces } } - public static async Task PatchAsync(PnPConnection connection, string accessToken, HttpContent content, string url, IDictionary additionalHeaders = null) + public static HttpResponseMessage Patch(Cmdlet cmdlet, PnPConnection connection, string accessToken, HttpContent content, string url, IDictionary additionalHeaders = null) { var message = GetMessage(url, HttpMethod.Patch, connection, accessToken, content, additionalHeaders); - return await GetResponseMessageAsync(connection, message); + return GetResponseMessage(cmdlet, connection, message); } #endregion - public static async Task PostAsync(PnPConnection connection, string url, HttpContent content, string accessToken, IDictionary additionalHeaders = null, bool propertyNameCaseInsensitive = false) + public static T Post(Cmdlet cmdlet, PnPConnection connection, string url, HttpContent content, string accessToken, IDictionary additionalHeaders = null, bool propertyNameCaseInsensitive = false) { - return await PostInternalAsync(connection, url, accessToken, content, additionalHeaders, propertyNameCaseInsensitive); + return PostInternal(cmdlet, connection, url, accessToken, content, additionalHeaders, propertyNameCaseInsensitive); } - public static async Task PutAsync(PnPConnection connection, string url, string accessToken, HttpContent content, IDictionary additionalHeaders = null) + public static T Put(Cmdlet cmdlet, PnPConnection connection, string url, string accessToken, HttpContent content, IDictionary additionalHeaders = null) { var message = GetMessage(url, HttpMethod.Put, connection, accessToken, content, additionalHeaders); - var stringContent = await SendMessageAsync(connection, message, accessToken); + var stringContent = SendMessage(cmdlet, connection, message, accessToken); if (stringContent != null) { try @@ -266,23 +274,23 @@ public static async Task PutAsync(PnPConnection connection, string url, st return default; } - public static async Task PostAsync(PnPConnection connection, string url, T content, string accessToken) + public static T Post(Cmdlet cmdlet, PnPConnection connection, string url, T content, string accessToken) { var requestContent = new StringContent(JsonSerializer.Serialize(content, new JsonSerializerOptions() { DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull, PropertyNamingPolicy = JsonNamingPolicy.CamelCase })); requestContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - return await PostInternalAsync(connection, url, accessToken, requestContent); + return PostInternal(cmdlet, connection, url, accessToken, requestContent); } - public static async Task PostAsync(PnPConnection connection, string url, string accessToken) + public static T Post(Cmdlet cmdlet, PnPConnection connection, string url, string accessToken) { - return await PostInternalAsync(connection, url, accessToken, null); + return PostInternal(cmdlet, connection, url, accessToken, null); } - private static async Task PostInternalAsync(PnPConnection connection, string url, string accessToken, HttpContent content, IDictionary additionalHeaders = null, bool propertyNameCaseInsensitive = false) + private static T PostInternal(Cmdlet cmdlet, PnPConnection connection, string url, string accessToken, HttpContent content, IDictionary additionalHeaders = null, bool propertyNameCaseInsensitive = false) { var message = GetMessage(url, HttpMethod.Post, connection, accessToken, content, additionalHeaders); - var stringContent = await SendMessageAsync(connection, message, accessToken); + var stringContent = SendMessage(cmdlet, connection, message, accessToken); if (stringContent != null) { try @@ -297,12 +305,12 @@ private static async Task PostInternalAsync(PnPConnection connection, stri return default; } - public static async Task PutAsync(PnPConnection connection, string url, T content, string accessToken) + public static T Put(Cmdlet cmdlet, PnPConnection connection, string url, T content, string accessToken) { var requestContent = new StringContent(JsonSerializer.Serialize(content, new JsonSerializerOptions() { DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull, PropertyNamingPolicy = JsonNamingPolicy.CamelCase })); requestContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); var message = GetMessage(url, HttpMethod.Put, connection, accessToken, requestContent); - var returnValue = await SendMessageAsync(connection, message, accessToken); + var returnValue = SendMessage(cmdlet, connection, message, accessToken); if (!string.IsNullOrEmpty(returnValue)) { return JsonSerializer.Deserialize(returnValue, new JsonSerializerOptions() { DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull, PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); @@ -313,31 +321,45 @@ public static async Task PutAsync(PnPConnection connection, string url, T } } - public static async Task DeleteAsync(PnPConnection connection, string url, string accessToken) + public static HttpResponseMessage Delete(Cmdlet cmdlet, PnPConnection connection, string url, string accessToken) { var message = GetMessage(url, HttpMethod.Delete, connection, accessToken); - var response = await GetResponseMessageAsync(connection, message); + var response = GetResponseMessage(cmdlet, connection, message); return response; } - private static async Task SendMessageAsync(PnPConnection connection, HttpRequestMessage message, string accessToken) + private static string SendMessage(Cmdlet cmdlet, PnPConnection connection, HttpRequestMessage message, string accessToken) { - var response = await connection.HttpClient.SendAsync(message); + cmdlet.WriteVerbose($"Making {message.Method} call to {message.RequestUri}{(message.Content != null ? $" with body '{message.Content.ReadAsStringAsync().GetAwaiter().GetResult()}'" : "")}"); + + var response = connection.HttpClient.SendAsync(message).GetAwaiter().GetResult(); while (response.StatusCode == (HttpStatusCode)429) { // throttled var retryAfter = response.Headers.RetryAfter; - await Task.Delay(retryAfter.Delta.Value.Seconds * 1000); - response = await connection.HttpClient.SendAsync(CloneMessage(message)); + + cmdlet.WriteVerbose($"Call got throttled. Retrying in {retryAfter.Delta.Value.Seconds} second{(retryAfter.Delta.Value.Seconds != 1 ? "s" : "")}."); + + Thread.Sleep(retryAfter.Delta.Value.Seconds * 1000); + + cmdlet.WriteVerbose($"Making {message.Method} call to {message.RequestUri}"); + response = connection.HttpClient.SendAsync(CloneMessage(message)).GetAwaiter().GetResult(); } if (response.IsSuccessStatusCode) { - return await response.Content.ReadAsStringAsync(); + var responseBody = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + + cmdlet.WriteVerbose($"Response successful with HTTP {(int)response.StatusCode} {response.StatusCode} containing {responseBody.Length} character{(responseBody.Length != 1 ? "s" : "")}"); + + return responseBody; } else { - var errorContent = await response.Content.ReadAsStringAsync(); - var exception = JsonSerializer.Deserialize(errorContent, new JsonSerializerOptions() { DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull, PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); + var errorContent = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + + cmdlet.WriteVerbose($"Response failed with HTTP {(int)response.StatusCode} {response.StatusCode} containing {errorContent.Length} character{(errorContent.Length != 1 ? "s" : "")}: {errorContent}"); + + var exception = JsonSerializer.Deserialize(errorContent, new JsonSerializerOptions() { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); exception.AccessToken = accessToken; exception.HttpResponse = response; @@ -345,21 +367,30 @@ private static async Task SendMessageAsync(PnPConnection connection, Htt } } - public static async Task GetResponseMessageAsync(PnPConnection connection, HttpRequestMessage message) + public static HttpResponseMessage GetResponseMessage(Cmdlet cmdlet, PnPConnection connection, HttpRequestMessage message) { - var response = await connection.HttpClient.SendAsync(message); + cmdlet.WriteVerbose($"Making {message.Method} call to {message.RequestUri}"); + + var response = connection.HttpClient.SendAsync(message).GetAwaiter().GetResult(); while (response.StatusCode == (HttpStatusCode)429) { // throttled var retryAfter = response.Headers.RetryAfter; - await Task.Delay(retryAfter.Delta.Value.Seconds * 1000); - response = await connection.HttpClient.SendAsync(CloneMessage(message)); + + cmdlet.WriteVerbose($"Call got throttled. Retrying in {retryAfter.Delta.Value.Seconds} second{(retryAfter.Delta.Value.Seconds != 1 ? "s" : "")}."); + + Thread.Sleep(retryAfter.Delta.Value.Seconds * 1000); + + cmdlet.WriteVerbose($"Making {message.Method} call to {message.RequestUri}"); + response = connection.HttpClient.SendAsync(CloneMessage(message)).GetAwaiter().GetResult(); } // Validate if the response was successful, if not throw an exception if (!response.IsSuccessStatusCode) { - if (GraphHelper.TryGetGraphException(response, out GraphException ex)) + cmdlet.WriteVerbose($"Response failed with HTTP {(int)response.StatusCode} {response.StatusCode}"); + + if (TryGetGraphException(response, out GraphException ex)) { if (ex.Error != null) { @@ -371,16 +402,21 @@ public static async Task GetResponseMessageAsync(PnPConnect throw new PSInvalidOperationException($"Call to Microsoft Graph URL {message.RequestUri} failed with status code {response.StatusCode}"); } } + else + { + cmdlet.WriteVerbose($"Response successful with HTTP {(int)response.StatusCode} {response.StatusCode}"); + } return response; } private static HttpRequestMessage CloneMessage(HttpRequestMessage req) { - HttpRequestMessage clone = new HttpRequestMessage(req.Method, req.RequestUri); - - clone.Content = req.Content; - clone.Version = req.Version; + HttpRequestMessage clone = new(req.Method, req.RequestUri) + { + Content = req.Content, + Version = req.Version + }; foreach (KeyValuePair prop in req.Options) { diff --git a/src/Commands/Utilities/REST/RestHelper.cs b/src/Commands/Utilities/REST/RestHelper.cs index c340be8ee..0b23dcc44 100644 --- a/src/Commands/Utilities/REST/RestHelper.cs +++ b/src/Commands/Utilities/REST/RestHelper.cs @@ -7,6 +7,7 @@ using System.Text; using System.Text.Json; using System.Text.Json.Serialization; +using System.Threading; using System.Threading.Tasks; using Microsoft.SharePoint.Client; @@ -147,27 +148,27 @@ private static HttpResponseMessage ExecutePostRequestInternal(ClientContext cont return returnValue; } - public static async Task GetAsync(HttpClient httpClient, string url, string accessToken, string accept = "application/json") + public static string Get(HttpClient httpClient, string url, string accessToken, string accept = "application/json") { var message = GetMessage(url, HttpMethod.Get, accessToken, accept); - return await SendMessageAsync(httpClient, message); + return SendMessage(httpClient, message); } - public static async Task GetByteArrayAsync(HttpClient httpClient, string url, string accessToken, string accept = "application/json") + public static byte[] GetByteArray(HttpClient httpClient, string url, string accessToken, string accept = "application/json") { var message = GetMessage(url, HttpMethod.Get, accessToken, accept); - return await SendMessageByteArrayAsync(httpClient, message); + return SendMessageByteArray(httpClient, message); } - public static async Task GetAsync(HttpClient httpClient, string url, ClientContext clientContext, string accept = "application/json") + public static string Get(HttpClient httpClient, string url, ClientContext clientContext, string accept = "application/json") { var message = GetMessage(url, HttpMethod.Get, clientContext, accept); - return await SendMessageAsync(httpClient, message); + return SendMessage(httpClient, message); } - public static async Task GetAsync(HttpClient httpClient, string url, string accessToken, bool camlCasePolicy = true) + public static T Get(HttpClient httpClient, string url, string accessToken, bool camlCasePolicy = true) { - var stringContent = await GetAsync(httpClient, url, accessToken); + var stringContent = Get(httpClient, url, accessToken); if (stringContent != null) { var options = new JsonSerializerOptions() { DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull }; @@ -187,9 +188,9 @@ public static async Task GetAsync(HttpClient httpClient, string url, strin return default(T); } - public static async Task GetAsync(HttpClient httpClient, string url, ClientContext clientContext, bool camlCasePolicy = true) + public static T Get(HttpClient httpClient, string url, ClientContext clientContext, bool camlCasePolicy = true) { - var stringContent = await GetAsync(httpClient, url, clientContext); + var stringContent = Get(httpClient, url, clientContext); if (stringContent != null) { var options = new JsonSerializerOptions() { DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull }; @@ -213,19 +214,19 @@ public static async Task GetAsync(HttpClient httpClient, string url, Clien #region POST - public static async Task PostAsync(HttpClient httpClient, string url, string accessToken, string accept = "application/json") + public static string Post(HttpClient httpClient, string url, string accessToken, string accept = "application/json") { var message = GetMessage(url, HttpMethod.Post, accessToken, accept); - return await SendMessageAsync(httpClient, message); + return SendMessage(httpClient, message); } - public static async Task PostAsync(HttpClient httpClient, string url, ClientContext clientContext, string accept = "application/json") + public static string Post(HttpClient httpClient, string url, ClientContext clientContext, string accept = "application/json") { var message = GetMessage(url, HttpMethod.Post, clientContext, accept); - return await SendMessageAsync(httpClient, message); + return SendMessage(httpClient, message); } - public static async Task PostAsync(HttpClient httpClient, string url, string accessToken, object payload, string accept = "application/json") + public static string Post(HttpClient httpClient, string url, string accessToken, object payload, string accept = "application/json") { HttpRequestMessage message = null; if (payload != null) @@ -238,10 +239,10 @@ public static async Task PostAsync(HttpClient httpClient, string url, st { message = GetMessage(url, HttpMethod.Post, accessToken, accept); } - return await SendMessageAsync(httpClient, message); + return SendMessage(httpClient, message); } - public static async Task PostAsync(HttpClient httpClient, string url, ClientContext clientContext, object payload, string accept = "application/json") + public static string Post(HttpClient httpClient, string url, ClientContext clientContext, object payload, string accept = "application/json") { HttpRequestMessage message = null; if (payload != null) @@ -254,10 +255,10 @@ public static async Task PostAsync(HttpClient httpClient, string url, Cl { message = GetMessage(url, HttpMethod.Post, clientContext, accept); } - return await SendMessageAsync(httpClient, message); + return SendMessage(httpClient, message); } - public static async Task PostAsync(HttpClient httpClient, string url, ClientContext clientContext, string payload, string contentType = "application/json", string accept = "application/json") + public static string Post(HttpClient httpClient, string url, ClientContext clientContext, string payload, string contentType = "application/json", string accept = "application/json") { HttpRequestMessage message = null; if (payload != null) @@ -270,12 +271,12 @@ public static async Task PostAsync(HttpClient httpClient, string url, Cl { message = GetMessage(url, HttpMethod.Post, clientContext, accept); } - return await SendMessageAsync(httpClient, message); + return SendMessage(httpClient, message); } - public static async Task PostAsync(HttpClient httpClient, string url, string accessToken, object payload, bool camlCasePolicy = true) + public static T Post(HttpClient httpClient, string url, string accessToken, object payload, bool camlCasePolicy = true) { - var stringContent = await PostAsync(httpClient, url, accessToken, payload); + var stringContent = Post(httpClient, url, accessToken, payload); if (stringContent != null) { var options = new JsonSerializerOptions() { DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull }; @@ -295,7 +296,7 @@ public static async Task PostAsync(HttpClient httpClient, string url, stri return default(T); } - public static async Task PostAsyncGetResponseHeader(HttpClient httpClient, string url, string accessToken, object payload, bool camlCasePolicy = true, string accept = "application/json") + public static HttpResponseHeaders PostGetResponseHeader(HttpClient httpClient, string url, string accessToken, object payload, bool camlCasePolicy = true, string accept = "application/json") { HttpRequestMessage message = null; if (payload != null) @@ -308,14 +309,14 @@ public static async Task PostAsyncGetResponseHeader(Http { message = GetMessage(url, HttpMethod.Post, accessToken, accept); } - return await SendMessageAsyncGetResponseHeader(httpClient, message); + return SendMessageGetResponseHeader(httpClient, message); } - public static async Task PostAsync(HttpClient httpClient, string url, ClientContext clientContext, object payload, bool camlCasePolicy = true) + public static T Post(HttpClient httpClient, string url, ClientContext clientContext, object payload, bool camlCasePolicy = true) { - var stringContent = await PostAsync(httpClient, url, clientContext, payload); + var stringContent = Post(httpClient, url, clientContext, payload); if (stringContent != null) { var options = new JsonSerializerOptions() { DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull }; @@ -339,9 +340,9 @@ public static async Task PostAsync(HttpClient httpClient, string url, Clie #endregion #region PATCH - public static async Task PatchAsync(HttpClient httpClient, string url, string accessToken, object payload, bool camlCasePolicy = true) + public static T Patch(HttpClient httpClient, string url, string accessToken, object payload, bool camlCasePolicy = true) { - var stringContent = await PatchAsync(httpClient, url, accessToken, payload); + var stringContent = Patch(httpClient, url, accessToken, payload); if (stringContent != null) { var options = new JsonSerializerOptions() { DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull }; @@ -361,7 +362,7 @@ public static async Task PatchAsync(HttpClient httpClient, string url, str return default(T); } - public static async Task PatchAsync(HttpClient httpClient, string url, string accessToken, object payload, string accept = "application/json") + public static string Patch(HttpClient httpClient, string url, string accessToken, object payload, string accept = "application/json") { HttpRequestMessage message = null; if (payload != null) @@ -374,7 +375,7 @@ public static async Task PatchAsync(HttpClient httpClient, string url, s { message = GetMessage(url, HttpMethod.Patch, accessToken, accept); } - return await SendMessageAsync(httpClient, message); + return SendMessage(httpClient, message); } #endregion @@ -513,18 +514,18 @@ private static HttpResponseMessage ExecuteMergeRequestInternal(ClientContext con #region DELETE - public static async Task DeleteAsync(HttpClient httpClient, string url, string accessToken, string accept = "application/json") + public static string Delete(HttpClient httpClient, string url, string accessToken, string accept = "application/json") { var message = GetMessage(url, HttpMethod.Delete, accessToken, accept); - return await SendMessageAsync(httpClient, message); + return SendMessage(httpClient, message); } - public static async Task DeleteAsync(HttpClient httpClient, string url, string accessToken, bool camlCasePolicy = true) + public static T Delete(HttpClient httpClient, string url, string accessToken, bool camlCasePolicy = true) { - var stringContent = await DeleteAsync(httpClient, url, accessToken); + var stringContent = Delete(httpClient, url, accessToken); if (stringContent != null) { - var options = new JsonSerializerOptions() { DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull }; + var options = new JsonSerializerOptions() { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }; if (camlCasePolicy) { options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; @@ -634,57 +635,57 @@ private static HttpRequestMessage GetMessage(string url, HttpMethod method, Clie return message; } - private static async Task SendMessageAsync(HttpClient httpClient, HttpRequestMessage message) + private static string SendMessage(HttpClient httpClient, HttpRequestMessage message) { - var response = await httpClient.SendAsync(message); + var response = httpClient.SendAsync(message).GetAwaiter().GetResult(); while (response.StatusCode == (HttpStatusCode)429) { // throttled var retryAfter = response.Headers.RetryAfter; - await Task.Delay(retryAfter.Delta.Value.Seconds * 1000); - response = await httpClient.SendAsync(CloneMessage(message)); + Thread.Sleep(retryAfter.Delta.Value.Seconds * 1000); + response = httpClient.Send(CloneMessage(message)); } if (response.IsSuccessStatusCode) { - return await response.Content.ReadAsStringAsync(); + return response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); } else { - var errorContent = await response.Content.ReadAsStringAsync(); + var errorContent = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); throw new HttpRequestException(errorContent); } } - private static async Task SendMessageByteArrayAsync(HttpClient httpClient, HttpRequestMessage message) + private static byte[] SendMessageByteArray(HttpClient httpClient, HttpRequestMessage message) { - var response = await httpClient.SendAsync(message); + var response = httpClient.Send(message); while (response.StatusCode == (HttpStatusCode)429) { // throttled var retryAfter = response.Headers.RetryAfter; - await Task.Delay(retryAfter.Delta.Value.Seconds * 1000); - response = await httpClient.SendAsync(CloneMessage(message)); + Thread.Sleep(retryAfter.Delta.Value.Seconds * 1000); + response = httpClient.Send(CloneMessage(message)); } if (response.IsSuccessStatusCode) { - return await response.Content.ReadAsByteArrayAsync(); + return response.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult(); } else { - var errorContent = await response.Content.ReadAsStringAsync(); + var errorContent = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); throw new HttpRequestException($"HTTP Error {response.StatusCode}: {errorContent}"); } } - private static async Task SendMessageAsyncGetResponseHeader(HttpClient httpClient, HttpRequestMessage message) + private static HttpResponseHeaders SendMessageGetResponseHeader(HttpClient httpClient, HttpRequestMessage message) { - var response = await httpClient.SendAsync(message); + var response = httpClient.SendAsync(message).GetAwaiter().GetResult(); while (response.StatusCode == (HttpStatusCode)429) { // throttled var retryAfter = response.Headers.RetryAfter; - await Task.Delay(retryAfter.Delta.Value.Seconds * 1000); - response = await httpClient.SendAsync(CloneMessage(message)); + Thread.Sleep(retryAfter.Delta.Value.Seconds * 1000); + response = httpClient.SendAsync(CloneMessage(message)).GetAwaiter().GetResult(); } if (response.IsSuccessStatusCode) { @@ -692,12 +693,11 @@ private static async Task SendMessageAsyncGetResponseHeader } else { - var errorContent = await response.Content.ReadAsStringAsync(); + var errorContent = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); ; throw new HttpRequestException(errorContent); } } - private static HttpRequestMessage CloneMessage(HttpRequestMessage req) { HttpRequestMessage clone = new HttpRequestMessage(req.Method, req.RequestUri); @@ -718,5 +718,4 @@ private static HttpRequestMessage CloneMessage(HttpRequestMessage req) return clone; } } - } \ No newline at end of file diff --git a/src/Commands/Utilities/SendMail.cs b/src/Commands/Utilities/SendMail.cs index dc739b2d8..a21f46167 100644 --- a/src/Commands/Utilities/SendMail.cs +++ b/src/Commands/Utilities/SendMail.cs @@ -78,20 +78,20 @@ protected override void ExecuteCmdlet() if (string.IsNullOrWhiteSpace(Password) && string.IsNullOrWhiteSpace(From)) { WriteVerbose("Sending e-mail through SharePoint Online"); - MailUtility.SendSharePointEmail(ClientContext, Subject, Body, To, Cc, Bcc).GetAwaiter().GetResult(); + MailUtility.SendSharePointEmail(ClientContext, Subject, Body, To, Cc, Bcc); } else { if (ParameterSpecified(nameof(Server)) && !string.IsNullOrWhiteSpace(Server)) { WriteVerbose($"Sending e-mail directly through SMTP server {Server}"); - MailUtility.SendSmtpEmail(Subject, Body, From, To, Cc, Bcc, Importance, Server, ServerPort, EnableSsl, Username, Password, BodyContentType ?? MessageBodyContentType.Html).GetAwaiter().GetResult(); + MailUtility.SendSmtpEmail(Subject, Body, From, To, Cc, Bcc, Importance, Server, ServerPort, EnableSsl, Username, Password, BodyContentType ?? MessageBodyContentType.Html); } else { WriteVerbose($"Sending e-mail using Microsoft Graph"); - MailUtility.SendGraphMail(Connection, GraphAccessToken, new Message + MailUtility.SendGraphMail(this, Connection, GraphAccessToken, new Message { Subject = Subject, MessageBody = new Body @@ -106,7 +106,7 @@ protected override void ExecuteCmdlet() ReplyTo = ReplyTo?.Select(t => new Recipient { EmailAddress = new EmailAddress { Address = t } }).ToList(), Importance = Importance, Attachments = MailUtility.GetListOfAttachments(Attachments, SessionState.Path.CurrentFileSystemLocation.Path) - }, SaveToSentItems ?? true).GetAwaiter().GetResult(); + }, SaveToSentItems ?? true); } } diff --git a/src/Commands/Utilities/ServiceHealthUtility.cs b/src/Commands/Utilities/ServiceHealthUtility.cs index 51537fc10..4e9441498 100644 --- a/src/Commands/Utilities/ServiceHealthUtility.cs +++ b/src/Commands/Utilities/ServiceHealthUtility.cs @@ -2,6 +2,7 @@ using PnP.PowerShell.Commands.Model.ServiceHealth; using PnP.PowerShell.Commands.Utilities.REST; using System.Collections.Generic; +using System.Management.Automation; using System.Threading.Tasks; namespace PnP.PowerShell.Commands.Utilities @@ -16,9 +17,9 @@ internal static class ServiceHealthUtility /// Connection to use for retrieval of the data /// AccessToken to use for authentication of the request /// List with objects - public static async Task> GetServiceUpdateMessagesAsync(PnPConnection connection, string accessToken) + public static IEnumerable GetServiceUpdateMessages(Cmdlet cmdlet, PnPConnection connection, string accessToken) { - var collection = await GraphHelper.GetResultCollectionAsync(connection, $"v1.0/admin/serviceAnnouncement/messages", accessToken); + var collection = GraphHelper.GetResultCollection(cmdlet, connection, $"v1.0/admin/serviceAnnouncement/messages", accessToken); return collection; } @@ -29,9 +30,9 @@ public static async Task> GetServiceUpdateMess /// Connection to use for retrieval of the data /// AccessToken to use for authentication of the request /// containing the requested information - public static async Task GetServiceUpdateMessageByIdAsync(string id, PnPConnection connection, string accessToken) + public static ServiceUpdateMessage GetServiceUpdateMessageById(Cmdlet cmdlet, string id, PnPConnection connection, string accessToken) { - var item = await GraphHelper.GetAsync(connection, $"v1.0/admin/serviceAnnouncement/messages/{id}", accessToken); + var item = GraphHelper.Get(cmdlet, connection, $"v1.0/admin/serviceAnnouncement/messages/{id}", accessToken); return item; } @@ -42,9 +43,9 @@ public static async Task GetServiceUpdateMessageByIdAsync( /// HttpClient to use for updating the data /// AccessToken to use for authentication of the request /// Boolean indicating whether the request succeeded - public static async Task SetServiceUpdateMessageAsReadByIdAsync(string id, PnPConnection connection, string accessToken) + public static bool SetServiceUpdateMessageAsReadById(Cmdlet cmdlet, string id, PnPConnection connection, string accessToken) { - return await SetServiceUpdateMessageAsReadByIdAsync(new [] { id }, connection, accessToken); + return SetServiceUpdateMessageAsReadById(cmdlet, new [] { id }, connection, accessToken); } /// @@ -54,10 +55,10 @@ public static async Task SetServiceUpdateMessageAsReadByIdAsync(string id, /// HttpClient to use for updating the data /// AccessToken to use for authentication of the request /// Boolean indicating whether the request succeeded - public static async Task SetServiceUpdateMessageAsReadByIdAsync(string[] id, PnPConnection connection, string accessToken) + public static bool SetServiceUpdateMessageAsReadById(Cmdlet cmdlet, string[] id, PnPConnection connection, string accessToken) { var postBody = new PnP.PowerShell.Commands.Model.ServiceHealth.ServiceUpdateMessageReadStatusBody { MessageIds = id }; - var item = await GraphHelper.PostAsync(connection, "v1.0/admin/serviceAnnouncement/messages/markRead", postBody, accessToken); + var item = GraphHelper.Post(cmdlet, connection, "v1.0/admin/serviceAnnouncement/messages/markRead", postBody, accessToken); return true; } @@ -68,9 +69,9 @@ public static async Task SetServiceUpdateMessageAsReadByIdAsync(string[] i /// HttpClient to use for updating the data /// AccessToken to use for authentication of the request /// Boolean indicating whether the request succeeded - public static async Task SetServiceUpdateMessageAsUnreadByIdAsync(string id, PnPConnection connection, string accessToken) + public static bool SetServiceUpdateMessageAsUnreadById(Cmdlet cmdlet, string id, PnPConnection connection, string accessToken) { - return await SetServiceUpdateMessageAsUnreadByIdAsync(new [] { id }, connection, accessToken); + return SetServiceUpdateMessageAsUnreadById(cmdlet, new [] { id }, connection, accessToken); } /// @@ -80,10 +81,10 @@ public static async Task SetServiceUpdateMessageAsUnreadByIdAsync(string i /// HttpClient to use for updating the data /// AccessToken to use for authentication of the request /// Boolean indicating whether the request succeeded - public static async Task SetServiceUpdateMessageAsUnreadByIdAsync(string[] id, PnPConnection connection, string accessToken) + public static bool SetServiceUpdateMessageAsUnreadById(Cmdlet cmdlet, string[] id, PnPConnection connection, string accessToken) { var postBody = new PnP.PowerShell.Commands.Model.ServiceHealth.ServiceUpdateMessageReadStatusBody { MessageIds = id }; - var item = await GraphHelper.PostAsync(connection, "v1.0/admin/serviceAnnouncement/messages/markUnread", postBody, accessToken); + var item = GraphHelper.Post(cmdlet, connection, "v1.0/admin/serviceAnnouncement/messages/markUnread", postBody, accessToken); return true; } @@ -94,9 +95,9 @@ public static async Task SetServiceUpdateMessageAsUnreadByIdAsync(string[] /// HttpClient to use for updating the data /// AccessToken to use for authentication of the request /// Boolean indicating whether the request succeeded - public static async Task SetServiceUpdateMessageAsArchivedByIdAsync(string id, PnPConnection connection, string accessToken) + public static bool SetServiceUpdateMessageAsArchivedById(Cmdlet cmdlet, string id, PnPConnection connection, string accessToken) { - return await SetServiceUpdateMessageAsArchivedByIdAsync(new [] { id }, connection, accessToken); + return SetServiceUpdateMessageAsArchivedById(cmdlet, new [] { id }, connection, accessToken); } /// @@ -106,10 +107,10 @@ public static async Task SetServiceUpdateMessageAsArchivedByIdAsync(string /// HttpClient to use for updating the data /// AccessToken to use for authentication of the request /// Boolean indicating whether the request succeeded - public static async Task SetServiceUpdateMessageAsArchivedByIdAsync(string[] id, PnPConnection connection, string accessToken) + public static bool SetServiceUpdateMessageAsArchivedById(Cmdlet cmdlet, string[] id, PnPConnection connection, string accessToken) { - var postBody = new PnP.PowerShell.Commands.Model.ServiceHealth.ServiceUpdateMessageReadStatusBody { MessageIds = id }; - var item = await GraphHelper.PostAsync(connection, "v1.0/admin/serviceAnnouncement/messages/archive", postBody, accessToken); + var postBody = new ServiceUpdateMessageReadStatusBody { MessageIds = id }; + var item = GraphHelper.Post(cmdlet, connection, "v1.0/admin/serviceAnnouncement/messages/archive", postBody, accessToken); return true; } @@ -120,9 +121,9 @@ public static async Task SetServiceUpdateMessageAsArchivedByIdAsync(string /// HttpClient to use for updating the data /// AccessToken to use for authentication of the request /// Boolean indicating whether the request succeeded - public static async Task SetServiceUpdateMessageAsUnarchivedByIdAsync(string id, PnPConnection connection, string accessToken) + public static bool SetServiceUpdateMessageAsUnarchivedById(Cmdlet cmdlet, string id, PnPConnection connection, string accessToken) { - return await SetServiceUpdateMessageAsUnarchivedByIdAsync(new [] { id }, connection, accessToken); + return SetServiceUpdateMessageAsUnarchivedById(cmdlet, new [] { id }, connection, accessToken); } /// @@ -132,10 +133,10 @@ public static async Task SetServiceUpdateMessageAsUnarchivedByIdAsync(stri /// HttpClient to use for updating the data /// AccessToken to use for authentication of the request /// Boolean indicating whether the request succeeded - public static async Task SetServiceUpdateMessageAsUnarchivedByIdAsync(string[] id, PnPConnection connection, string accessToken) + public static bool SetServiceUpdateMessageAsUnarchivedById(Cmdlet cmdlet, string[] id, PnPConnection connection, string accessToken) { - var postBody = new PnP.PowerShell.Commands.Model.ServiceHealth.ServiceUpdateMessageReadStatusBody { MessageIds = id }; - var item = await GraphHelper.PostAsync(connection, "v1.0/admin/serviceAnnouncement/messages/unarchive", postBody, accessToken); + var postBody = new ServiceUpdateMessageReadStatusBody { MessageIds = id }; + var item = GraphHelper.Post(cmdlet, connection, "v1.0/admin/serviceAnnouncement/messages/unarchive", postBody, accessToken); return true; } @@ -146,9 +147,9 @@ public static async Task SetServiceUpdateMessageAsUnarchivedByIdAsync(stri /// HttpClient to use for updating the data /// AccessToken to use for authentication of the request /// Boolean indicating whether the request succeeded - public static async Task SetServiceUpdateMessageAsFavoriteByIdAsync(string id, PnPConnection connection, string accessToken) + public static bool SetServiceUpdateMessageAsFavoriteById(Cmdlet cmdlet, string id, PnPConnection connection, string accessToken) { - return await SetServiceUpdateMessageAsFavoriteByIdAsync(new [] { id }, connection, accessToken); + return SetServiceUpdateMessageAsFavoriteById(cmdlet, new [] { id }, connection, accessToken); } /// @@ -158,10 +159,10 @@ public static async Task SetServiceUpdateMessageAsFavoriteByIdAsync(string /// HttpClient to use for updating the data /// AccessToken to use for authentication of the request /// Boolean indicating whether the request succeeded - public static async Task SetServiceUpdateMessageAsFavoriteByIdAsync(string[] id, PnPConnection connection, string accessToken) + public static bool SetServiceUpdateMessageAsFavoriteById(Cmdlet cmdlet, string[] id, PnPConnection connection, string accessToken) { var postBody = new PnP.PowerShell.Commands.Model.ServiceHealth.ServiceUpdateMessageReadStatusBody { MessageIds = id }; - var item = await GraphHelper.PostAsync(connection, "v1.0/admin/serviceAnnouncement/messages/favorite", postBody, accessToken); + var item = GraphHelper.Post(cmdlet, connection, "v1.0/admin/serviceAnnouncement/messages/favorite", postBody, accessToken); return true; } @@ -172,9 +173,9 @@ public static async Task SetServiceUpdateMessageAsFavoriteByIdAsync(string /// HttpClient to use for updating the data /// AccessToken to use for authentication of the request /// Boolean indicating whether the request succeeded - public static async Task SetServiceUpdateMessageAsNotfavoriteByIdAsync(string id, PnPConnection connection, string accessToken) + public static bool SetServiceUpdateMessageAsNotfavoriteById(Cmdlet cmdlet, string id, PnPConnection connection, string accessToken) { - return await SetServiceUpdateMessageAsNotfavoriteByIdAsync(new [] { id }, connection, accessToken); + return SetServiceUpdateMessageAsNotfavoriteById(cmdlet, new [] { id }, connection, accessToken); } /// @@ -184,10 +185,10 @@ public static async Task SetServiceUpdateMessageAsNotfavoriteByIdAsync(str /// HttpClient to use for updating the data /// AccessToken to use for authentication of the request /// Boolean indicating whether the request succeeded - public static async Task SetServiceUpdateMessageAsNotfavoriteByIdAsync(string[] id, PnPConnection connection, string accessToken) + public static bool SetServiceUpdateMessageAsNotfavoriteById(Cmdlet cmdlet, string[] id, PnPConnection connection, string accessToken) { var postBody = new PnP.PowerShell.Commands.Model.ServiceHealth.ServiceUpdateMessageReadStatusBody { MessageIds = id }; - var item = await GraphHelper.PostAsync(connection, "v1.0/admin/serviceAnnouncement/messages/unfavorite", postBody, accessToken); + var item = GraphHelper.Post(cmdlet, connection, "v1.0/admin/serviceAnnouncement/messages/unfavorite", postBody, accessToken); return true; } @@ -201,9 +202,9 @@ public static async Task SetServiceUpdateMessageAsNotfavoriteByIdAsync(str /// Connection to use for retrieval of the data /// AccessToken to use for authentication of the request /// List with objects - public static async Task> GetServiceHealthIssuesAsync(PnPConnection connection, string accessToken) + public static IEnumerable GetServiceHealthIssues(Cmdlet cmdlet, PnPConnection connection, string accessToken) { - var collection = await GraphHelper.GetResultCollectionAsync(connection, $"v1.0/admin/serviceAnnouncement/issues", accessToken); + var collection = GraphHelper.GetResultCollection(cmdlet, connection, $"v1.0/admin/serviceAnnouncement/issues", accessToken); return collection; } @@ -214,9 +215,9 @@ public static async Task> GetServiceHealthIssues /// Connection to use for retrieval of the data /// AccessToken to use for authentication of the request /// containing the requested information - public static async Task GetServiceHealthIssueByIdAsync(string id, PnPConnection connection, string accessToken) + public static ServiceHealthIssue GetServiceHealthIssueById(Cmdlet cmdlet, string id, PnPConnection connection, string accessToken) { - var item = await GraphHelper.GetAsync(connection, $"v1.0/admin/serviceAnnouncement/issues/{id}", accessToken); + var item = GraphHelper.Get(cmdlet, connection, $"v1.0/admin/serviceAnnouncement/issues/{id}", accessToken); return item; } @@ -230,9 +231,9 @@ public static async Task GetServiceHealthIssueByIdAsync(stri /// Connection to use for retrieval of the data /// AccessToken to use for authentication of the request /// List with objects - public static async Task> GetServiceCurrentHealthAsync(PnPConnection connection, string accessToken) + public static IEnumerable GetServiceCurrentHealth(Cmdlet cmdlet, PnPConnection connection, string accessToken) { - var collection = await GraphHelper.GetResultCollectionAsync(connection, $"v1.0/admin/serviceAnnouncement/healthOverviews", accessToken); + var collection = GraphHelper.GetResultCollection(cmdlet, connection, $"v1.0/admin/serviceAnnouncement/healthOverviews", accessToken); return collection; } @@ -243,9 +244,9 @@ public static async Task> GetServiceCurrentHea /// Connection to use for retrieval of the data /// AccessToken to use for authentication of the request /// containing the requested information - public static async Task GetServiceCurrentHealthByIdAsync(string id, PnPConnection connection, string accessToken) + public static ServiceHealthCurrent GetServiceCurrentHealthById(Cmdlet cmdlet, string id, PnPConnection connection, string accessToken) { - var item = await GraphHelper.GetAsync(connection, $"v1.0/admin/serviceAnnouncement/healthOverviews/{id}", accessToken); + var item = GraphHelper.Get(cmdlet, connection, $"v1.0/admin/serviceAnnouncement/healthOverviews/{id}", accessToken); return item; } diff --git a/src/Commands/Utilities/ServicePrincipalUtility.cs b/src/Commands/Utilities/ServicePrincipalUtility.cs index 192337b05..901c26f39 100644 --- a/src/Commands/Utilities/ServicePrincipalUtility.cs +++ b/src/Commands/Utilities/ServicePrincipalUtility.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Management.Automation; using System.Net.Http; namespace PnP.PowerShell.Commands.Utilities @@ -16,7 +17,7 @@ internal static class ServicePrincipalUtility /// /// Returns all service principals /// - public static List GetServicePrincipals(PnPConnection connection, string accesstoken, string filter = null) + public static List GetServicePrincipals(Cmdlet cmdlet, PnPConnection connection, string accesstoken, string filter = null) { string requestUrl = $"https://{connection.GraphEndPoint}/v1.0/servicePrincipals"; Dictionary additionalHeaders = null; @@ -28,24 +29,24 @@ public static List GetServicePrincipals(PnPConnection c { "ConsistencyLevel", "eventual" } }; } - var result = REST.GraphHelper.GetResultCollectionAsync(connection, requestUrl, accesstoken, additionalHeaders: additionalHeaders).GetAwaiter().GetResult(); + var result = REST.GraphHelper.GetResultCollection(cmdlet, connection, requestUrl, accesstoken, additionalHeaders: additionalHeaders); return result.ToList(); } /// /// Returns the service principal of the provided built in type /// - public static AzureADServicePrincipal GetServicePrincipalByBuiltInType(PnPConnection connection, string accesstoken, ServicePrincipalBuiltInType builtInType) + public static AzureADServicePrincipal GetServicePrincipalByBuiltInType(Cmdlet cmdlet, PnPConnection connection, string accesstoken, ServicePrincipalBuiltInType builtInType) { AzureADServicePrincipal result = null; switch (builtInType) { case ServicePrincipalBuiltInType.MicrosoftGraph: - result = ServicePrincipalUtility.GetServicePrincipalByAppId(connection, accesstoken, new Guid("00000003-0000-0000-c000-000000000000")); + result = ServicePrincipalUtility.GetServicePrincipalByAppId(cmdlet, connection, accesstoken, new Guid("00000003-0000-0000-c000-000000000000")); break; case ServicePrincipalBuiltInType.SharePointOnline: - result = ServicePrincipalUtility.GetServicePrincipalByAppId(connection, accesstoken, new Guid("00000003-0000-0ff1-ce00-000000000000")); + result = ServicePrincipalUtility.GetServicePrincipalByAppId(cmdlet, connection, accesstoken, new Guid("00000003-0000-0ff1-ce00-000000000000")); break; default: @@ -57,12 +58,12 @@ public static AzureADServicePrincipal GetServicePrincipalByBuiltInType(PnPConnec /// /// Returns the service principal of the provided object id /// - public static AzureADServicePrincipal GetServicePrincipalByObjectId(PnPConnection connection, string accesstoken, Guid objectId) + public static AzureADServicePrincipal GetServicePrincipalByObjectId(Cmdlet cmdlet, PnPConnection connection, string accesstoken, Guid objectId) { IEnumerable result; try { - result = Utilities.REST.GraphHelper.GetResultCollectionAsync(connection, $"https://{connection.GraphEndPoint}/v1.0/servicePrincipals?$filter=id eq '{objectId}'", accesstoken).GetAwaiter().GetResult(); + result = Utilities.REST.GraphHelper.GetResultCollection(cmdlet, connection, $"https://{connection.GraphEndPoint}/v1.0/servicePrincipals?$filter=id eq '{objectId}'", accesstoken); var servicePrincipal = result.FirstOrDefault(); servicePrincipal.AppRoles.ForEach(ar => ar.ServicePrincipal = servicePrincipal); @@ -75,12 +76,12 @@ public static AzureADServicePrincipal GetServicePrincipalByObjectId(PnPConnectio /// /// Returns the service principal of the provided app id /// - public static AzureADServicePrincipal GetServicePrincipalByAppId(PnPConnection connection, string accesstoken, Guid appId) + public static AzureADServicePrincipal GetServicePrincipalByAppId(Cmdlet cmdlet, PnPConnection connection, string accesstoken, Guid appId) { IEnumerable result; try { - result = Utilities.REST.GraphHelper.GetResultCollectionAsync(connection, $"https://{connection.GraphEndPoint}/v1.0/servicePrincipals?$filter=appid eq '{appId}'", accesstoken).GetAwaiter().GetResult(); + result = Utilities.REST.GraphHelper.GetResultCollection(cmdlet, connection, $"https://{connection.GraphEndPoint}/v1.0/servicePrincipals?$filter=appid eq '{appId}'", accesstoken); var servicePrincipal = result.FirstOrDefault(); servicePrincipal.AppRoles.ForEach(ar => ar.ServicePrincipal = servicePrincipal); @@ -93,12 +94,12 @@ public static AzureADServicePrincipal GetServicePrincipalByAppId(PnPConnection c /// /// Returns the service principal with the provided name /// - public static AzureADServicePrincipal GetServicePrincipalByAppName(PnPConnection connection, string accesstoken, string appName) + public static AzureADServicePrincipal GetServicePrincipalByAppName(Cmdlet cmdlet, PnPConnection connection, string accesstoken, string appName) { IEnumerable result; try { - result = Utilities.REST.GraphHelper.GetResultCollectionAsync(connection, $"https://{connection.GraphEndPoint}/v1.0/servicePrincipals?$filter=displayName eq '{appName}'", accesstoken).GetAwaiter().GetResult(); + result = Utilities.REST.GraphHelper.GetResultCollection(cmdlet, connection, $"https://{connection.GraphEndPoint}/v1.0/servicePrincipals?$filter=displayName eq '{appName}'", accesstoken); var servicePrincipal = result.FirstOrDefault(); servicePrincipal.AppRoles.ForEach(ar => ar.ServicePrincipal = servicePrincipal); @@ -111,13 +112,13 @@ public static AzureADServicePrincipal GetServicePrincipalByAppName(PnPConnection /// /// Returns the service principal app role assignments of the service principal with the provided object id /// - public static List GetServicePrincipalAppRoleAssignmentsByServicePrincipalObjectId(PnPConnection connection, string accesstoken, string servicePrincipalObjectId, string appRoleAssignmentId) + public static List GetServicePrincipalAppRoleAssignmentsByServicePrincipalObjectId(Cmdlet cmdlet, PnPConnection connection, string accesstoken, string servicePrincipalObjectId, string appRoleAssignmentId) { try { // Retrieve the specific app role assigned to the service principal - var results = Utilities.REST.GraphHelper.GetAsync(connection, $"https://{connection.GraphEndPoint}/v1.0/servicePrincipals/{servicePrincipalObjectId}/appRoleAssignments/{appRoleAssignmentId}", accesstoken).GetAwaiter().GetResult(); - var enrichedResults = ServicePrincipalUtility.EnrichAzureADServicePrincipalAppRoleAssignments(connection, accesstoken, new List { results }); + var results = Utilities.REST.GraphHelper.Get(cmdlet, connection, $"https://{connection.GraphEndPoint}/v1.0/servicePrincipals/{servicePrincipalObjectId}/appRoleAssignments/{appRoleAssignmentId}", accesstoken); + var enrichedResults = ServicePrincipalUtility.EnrichAzureADServicePrincipalAppRoleAssignments(cmdlet, connection, accesstoken, new List { results }); return enrichedResults.ToList(); } catch (Exception) { } @@ -127,13 +128,13 @@ public static List GetServicePrincipal /// /// Returns the service principal app role assignments of the service principal with the provided object id /// - public static List GetServicePrincipalAppRoleAssignmentsByServicePrincipalObjectId(PnPConnection connection, string accesstoken, string servicePrincipalObjectId) + public static List GetServicePrincipalAppRoleAssignmentsByServicePrincipalObjectId(Cmdlet cmdlet, PnPConnection connection, string accesstoken, string servicePrincipalObjectId) { try { // Retrieve all the app role assigned to the service principal - var results = Utilities.REST.GraphHelper.GetResultCollectionAsync(connection, $"https://{connection.GraphEndPoint}/v1.0/servicePrincipals/{servicePrincipalObjectId}/appRoleAssignments", accesstoken).GetAwaiter().GetResult(); - var enrichedResults = ServicePrincipalUtility.EnrichAzureADServicePrincipalAppRoleAssignments(connection, accesstoken, results); + var results = Utilities.REST.GraphHelper.GetResultCollection(cmdlet, connection, $"https://{connection.GraphEndPoint}/v1.0/servicePrincipals/{servicePrincipalObjectId}/appRoleAssignments", accesstoken); + var enrichedResults = ServicePrincipalUtility.EnrichAzureADServicePrincipalAppRoleAssignments(cmdlet, connection, accesstoken, results); return enrichedResults.ToList(); } catch (Exception) { } @@ -147,7 +148,7 @@ public static List GetServicePrincipal /// Access Token to use to authenticate to Microsoft Graph /// Enumerable with app role assignments to enrich /// Enriched app role assignements - private static IEnumerable EnrichAzureADServicePrincipalAppRoleAssignments(PnPConnection connection, string accesstoken, IEnumerable azureADServicePrincipalAppRoleAssignments) + private static IEnumerable EnrichAzureADServicePrincipalAppRoleAssignments(Cmdlet cmdlet, PnPConnection connection, string accesstoken, IEnumerable azureADServicePrincipalAppRoleAssignments) { // Since the result does not contain the friendly claim value (i.e. Group.ReadWrite.All) but just identifiers for it, we will enrich the result with the friendly name oursevles var servicePrincipalCache = new Dictionary(); @@ -168,7 +169,7 @@ private static IEnumerable EnrichAzure else { // Service principal is not in cache yet, retrieve it from the Graph API - servicePrincipal = GetServicePrincipalByObjectId(connection, accesstoken, azureADServicePrincipalAppRoleAssignment.ResourceId.Value); + servicePrincipal = GetServicePrincipalByObjectId(cmdlet, connection, accesstoken, azureADServicePrincipalAppRoleAssignment.ResourceId.Value); if (servicePrincipal != null) { @@ -194,11 +195,11 @@ private static IEnumerable EnrichAzure /// The service principal to add the role to /// The app role to add to the service principal /// The service principal app role assignment - public static AzureADServicePrincipalAppRoleAssignment AddServicePrincipalRoleAssignment(PnPConnection connection, string accesstoken, AzureADServicePrincipal principalToAddRoleTo, AzureADServicePrincipalAppRole appRoleToAdd) + public static AzureADServicePrincipalAppRoleAssignment AddServicePrincipalRoleAssignment(Cmdlet cmdlet, PnPConnection connection, string accesstoken, AzureADServicePrincipal principalToAddRoleTo, AzureADServicePrincipalAppRole appRoleToAdd) { var content = new StringContent($"{{'principalId':'{principalToAddRoleTo.Id}','resourceId':'{appRoleToAdd.ServicePrincipal.Id}','appRoleId':'{appRoleToAdd.Id}'}}"); content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - var result = Utilities.REST.GraphHelper.PostAsync(connection, $"https://{connection.GraphEndPoint}/v1.0/servicePrincipals/{principalToAddRoleTo.Id}/appRoleAssignments", content, accesstoken).GetAwaiter().GetResult(); + var result = Utilities.REST.GraphHelper.Post(cmdlet, connection, $"https://{connection.GraphEndPoint}/v1.0/servicePrincipals/{principalToAddRoleTo.Id}/appRoleAssignments", content, accesstoken); return result; } @@ -208,12 +209,12 @@ public static AzureADServicePrincipalAppRoleAssignment AddServicePrincipalRoleAs /// Connection to use to communicate with Microsoft Graph /// Access Token to use to authenticate to Microsoft Graph /// The service principal to remove the role assignments from - public static void RemoveServicePrincipalRoleAssignment(PnPConnection connection, string accesstoken, AzureADServicePrincipal principalToRemoveRoleFrom) + public static void RemoveServicePrincipalRoleAssignment(Cmdlet cmdlet, PnPConnection connection, string accesstoken, AzureADServicePrincipal principalToRemoveRoleFrom) { - var assignments = GetServicePrincipalAppRoleAssignmentsByServicePrincipalObjectId(connection, accesstoken, principalToRemoveRoleFrom.Id); + var assignments = GetServicePrincipalAppRoleAssignmentsByServicePrincipalObjectId(cmdlet, connection, accesstoken, principalToRemoveRoleFrom.Id); foreach (var assignment in assignments) { - Utilities.REST.GraphHelper.DeleteAsync(connection, $"https://{connection.GraphEndPoint}/v1.0/servicePrincipals/{principalToRemoveRoleFrom.Id}/appRoleAssignments/{assignment.Id}", accesstoken).GetAwaiter().GetResult(); + Utilities.REST.GraphHelper.Delete(cmdlet, connection, $"https://{connection.GraphEndPoint}/v1.0/servicePrincipals/{principalToRemoveRoleFrom.Id}/appRoleAssignments/{assignment.Id}", accesstoken); } } @@ -224,14 +225,14 @@ public static void RemoveServicePrincipalRoleAssignment(PnPConnection connection /// Access Token to use to authenticate to Microsoft Graph /// The service principal to remove the role assignment from /// The app role to remove from the role assignments - public static void RemoveServicePrincipalRoleAssignment(PnPConnection connection, string accesstoken, AzureADServicePrincipal principalToRemoveRoleFrom, AzureADServicePrincipalAppRole appRoleToRemove) + public static void RemoveServicePrincipalRoleAssignment(Cmdlet cmdlet, PnPConnection connection, string accesstoken, AzureADServicePrincipal principalToRemoveRoleFrom, AzureADServicePrincipalAppRole appRoleToRemove) { - var assignments = GetServicePrincipalAppRoleAssignmentsByServicePrincipalObjectId(connection, accesstoken, principalToRemoveRoleFrom.Id); + var assignments = GetServicePrincipalAppRoleAssignmentsByServicePrincipalObjectId(cmdlet, connection, accesstoken, principalToRemoveRoleFrom.Id); foreach (var assignment in assignments) { if (assignment.AppRoleId == appRoleToRemove.Id) { - Utilities.REST.GraphHelper.DeleteAsync(connection, $"https://{connection.GraphEndPoint}/v1.0/servicePrincipals/{principalToRemoveRoleFrom.Id}/appRoleAssignments/{assignment.Id}", accesstoken).GetAwaiter().GetResult(); + Utilities.REST.GraphHelper.Delete(cmdlet, connection, $"https://{connection.GraphEndPoint}/v1.0/servicePrincipals/{principalToRemoveRoleFrom.Id}/appRoleAssignments/{assignment.Id}", accesstoken); } } } @@ -243,14 +244,14 @@ public static void RemoveServicePrincipalRoleAssignment(PnPConnection connection /// Access Token to use to authenticate to Microsoft Graph /// The service principal to remove the role assignment from /// The name of the app role to remove from the role assignments - public static void RemoveServicePrincipalRoleAssignment(PnPConnection connection, string accesstoken, AzureADServicePrincipal principalToRemoveRoleFrom, string roleName) + public static void RemoveServicePrincipalRoleAssignment(Cmdlet cmdlet, PnPConnection connection, string accesstoken, AzureADServicePrincipal principalToRemoveRoleFrom, string roleName) { - var assignments = GetServicePrincipalAppRoleAssignmentsByServicePrincipalObjectId(connection, accesstoken, principalToRemoveRoleFrom.Id); + var assignments = GetServicePrincipalAppRoleAssignmentsByServicePrincipalObjectId(cmdlet, connection, accesstoken, principalToRemoveRoleFrom.Id); foreach (var assignment in assignments) { if (assignment.AppRoleName == roleName) { - Utilities.REST.GraphHelper.DeleteAsync(connection, $"https://{connection.GraphEndPoint}/v1.0/servicePrincipals/{principalToRemoveRoleFrom.Id}/appRoleAssignments/{assignment.Id}", accesstoken).GetAwaiter().GetResult(); + Utilities.REST.GraphHelper.Delete(cmdlet, connection, $"https://{connection.GraphEndPoint}/v1.0/servicePrincipals/{principalToRemoveRoleFrom.Id}/appRoleAssignments/{assignment.Id}", accesstoken); } } } @@ -262,9 +263,9 @@ public static void RemoveServicePrincipalRoleAssignment(PnPConnection connection /// Access Token to use to authenticate to Microsoft Graph /// The service principal to remove the role assignment from /// The app role assignment to remove from the service principal - public static void RemoveServicePrincipalRoleAssignment(PnPConnection connection, string accesstoken, AzureADServicePrincipalAppRoleAssignment appRoleAssignmenToRemove) + public static void RemoveServicePrincipalRoleAssignment(Cmdlet cmdlet, PnPConnection connection, string accesstoken, AzureADServicePrincipalAppRoleAssignment appRoleAssignmenToRemove) { - Utilities.REST.GraphHelper.DeleteAsync(connection, $"https://{connection.GraphEndPoint}/v1.0/servicePrincipals/{appRoleAssignmenToRemove.PrincipalId}/appRoleAssignments/{appRoleAssignmenToRemove.Id}", accesstoken).GetAwaiter().GetResult(); + Utilities.REST.GraphHelper.Delete(cmdlet, connection, $"https://{connection.GraphEndPoint}/v1.0/servicePrincipals/{appRoleAssignmenToRemove.PrincipalId}/appRoleAssignments/{appRoleAssignmenToRemove.Id}", accesstoken); } } } \ No newline at end of file diff --git a/src/Commands/Utilities/SiteTemplates.cs b/src/Commands/Utilities/SiteTemplates.cs index 091a7dab9..3c5107257 100644 --- a/src/Commands/Utilities/SiteTemplates.cs +++ b/src/Commands/Utilities/SiteTemplates.cs @@ -6,6 +6,7 @@ using PnP.PowerShell.Commands.Model.SharePoint; using System.Collections.Generic; using PnP.PowerShell.Commands.Base; +using System.Management.Automation; namespace PnP.PowerShell.Commands.Utilities { @@ -24,9 +25,9 @@ internal static class SiteTemplates /// The Site Script to invoke /// The URL of the SharePoint site to invoke the Site Script on /// HttpResponseMessage with the - public static async Task> InvokeSiteScript(PnPConnection connection, string accessToken, TenantSiteScript script, string siteUrl) + public static RestResultCollection InvokeSiteScript(Cmdlet cmdlet, PnPConnection connection, string accessToken, TenantSiteScript script, string siteUrl) { - return await InvokeSiteScript(connection, accessToken, script.Content, siteUrl); + return InvokeSiteScript(cmdlet, connection, accessToken, script.Content, siteUrl); } /// @@ -37,7 +38,7 @@ public static async Task> I /// The Site Script content to invoke /// The URL of the SharePoint site to invoke the Site Script on /// - public static async Task> InvokeSiteScript(PnPConnection connection, string accessToken, string scriptContent, string siteUrl) + public static RestResultCollection InvokeSiteScript(Cmdlet cmdlet, PnPConnection connection, string accessToken, string scriptContent, string siteUrl) { // Properly encode the contents of the provided site script var escapedScript = Regex.Replace(scriptContent.Replace("\\\"", "\\\\\\\""), "(?> I postBody.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); // Execute the request to apply the site script - var results = await GraphHelper.PostAsync>(connection, $"{siteUrl.TrimEnd('/')}/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.ExecuteTemplateScript()", postBody, accessToken, new Dictionary{{ "Accept", "application/json" }}); + var results = GraphHelper.Post>(cmdlet, connection, $"{siteUrl.TrimEnd('/')}/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.ExecuteTemplateScript()", postBody, accessToken, new Dictionary{{ "Accept", "application/json" }}); return results; } diff --git a/src/Commands/Utilities/TeamsUtility.cs b/src/Commands/Utilities/TeamsUtility.cs index 2085f758f..3b72b2088 100644 --- a/src/Commands/Utilities/TeamsUtility.cs +++ b/src/Commands/Utilities/TeamsUtility.cs @@ -11,7 +11,7 @@ using System.Management.Automation; using System.Net.Http; using System.Text.Json; -using System.Text.Json.Serialization; +using System.Threading; using System.Threading.Tasks; using Group = PnP.PowerShell.Commands.Model.Graph.Group; using Team = PnP.PowerShell.Commands.Model.Teams.Team; @@ -25,7 +25,7 @@ internal static class TeamsUtility private const int PageSize = 100; #region Team - public static async Task> GetGroupsWithTeamAsync(PnPConnection connection, string accessToken, string filter = null) + public static List GetGroupsWithTeam(Cmdlet cmdlet, PnPConnection connection, string accessToken, string filter = null) { Dictionary additionalHeaders = null; string requestUrl; @@ -50,23 +50,23 @@ public static async Task> GetGroupsWithTeamAsync(PnPConnection conne requestUrl = $"v1.0/groups?$filter={filter}&$select=Id,DisplayName,MailNickName,Description,Visibility&$top={PageSize}&$count=true"; } - var collection = await GraphHelper.GetResultCollectionAsync(connection, requestUrl, accessToken, additionalHeaders: additionalHeaders); + var collection = GraphHelper.GetResultCollection(cmdlet, connection, requestUrl, accessToken, additionalHeaders: additionalHeaders); return collection.ToList(); } - public static async Task GetGroupWithTeamAsync(PnPConnection connection, string accessToken, string mailNickname) + public static Group GetGroupWithTeam(Cmdlet cmdlet, PnPConnection connection, string accessToken, string mailNickname) { - return await GraphHelper.GetAsync(connection, $"v1.0/groups?$filter=(resourceProvisioningOptions/Any(x:x eq 'Team') and mailNickname eq '{mailNickname}')&$select=Id,DisplayName,MailNickName,Description,Visibility", accessToken); + return GraphHelper.Get(cmdlet, connection, $"v1.0/groups?$filter=(resourceProvisioningOptions/Any(x:x eq 'Team') and mailNickname eq '{mailNickname}')&$select=Id,DisplayName,MailNickName,Description,Visibility", accessToken); } - public static async Task> GetTeamsAsync(string accessToken, PnPConnection connection, String filter) + public static List GetTeamUsingFilter(Cmdlet cmdlet, string accessToken, PnPConnection connection, String filter) { List teams = new List(); - var groups = await GetGroupsWithTeamAsync(connection, accessToken, filter); + var groups = GetGroupsWithTeam(cmdlet, connection, accessToken, filter); foreach (var group in groups) { - Team team = await ParseTeamJsonAsync(accessToken, connection, group.Id); + Team team = ParseTeamJson(cmdlet, accessToken, connection, group.Id); if (team != null) { @@ -79,12 +79,12 @@ public static async Task> GetTeamsAsync(string accessToken, PnPConnec return teams; } - public static async Task GetTeamAsync(string accessToken, PnPConnection connection, string groupId) + public static Team GetTeam(Cmdlet cmdlet, string accessToken, PnPConnection connection, string groupId) { // get the group - var group = await GraphHelper.GetAsync(connection, $"v1.0/groups/{groupId}?$select=Id,DisplayName,MailNickName,Description,Visibility", accessToken); + var group = GraphHelper.Get(cmdlet, connection, $"v1.0/groups/{groupId}?$select=Id,DisplayName,MailNickName,Description,Visibility", accessToken); - Team team = await ParseTeamJsonAsync(accessToken, connection, group.Id); + Team team = ParseTeamJson(cmdlet, accessToken, connection, group.Id); if (team != null) { team.DisplayName = group.DisplayName; @@ -98,11 +98,11 @@ public static async Task GetTeamAsync(string accessToken, PnPConnection co } } - public static async Task DeleteTeamAsync(string accessToken, PnPConnection connection, string groupId) + public static HttpResponseMessage DeleteTeam(Cmdlet cmdlet, string accessToken, PnPConnection connection, string groupId) { - return await GraphHelper.DeleteAsync(connection, $"v1.0/groups/{groupId}", accessToken); + return GraphHelper.Delete(cmdlet, connection, $"v1.0/groups/{groupId}", accessToken); } - public static async Task CloneTeamAsync(string accessToken, PnPConnection connection, string groupId, TeamCloneInformation teamClone) + public static HttpResponseMessage CloneTeam(Cmdlet cmdlet, string accessToken, PnPConnection connection, string groupId, TeamCloneInformation teamClone) { StringContent content = new StringContent(JsonSerializer.Serialize(new { @@ -114,14 +114,14 @@ public static async Task CloneTeamAsync(string accessToken, partsToClone = String.Join(",", teamClone.PartsToClone) })); content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - return await GraphHelper.PostAsync(connection, $"v1.0/teams/{groupId}/clone", accessToken, content); + return GraphHelper.Post(cmdlet, connection, $"v1.0/teams/{groupId}/clone", accessToken, content); } - private static async Task ParseTeamJsonAsync(string accessToken, PnPConnection connection, string groupId) + private static Team ParseTeamJson(Cmdlet cmdlet, string accessToken, PnPConnection connection, string groupId) { // Get Settings try { - var team = await GraphHelper.GetAsync(connection, $"v1.0/teams/{groupId}", accessToken, false, true); + var team = GraphHelper.Get(cmdlet, connection, $"v1.0/teams/{groupId}", accessToken, false, true); if (team != null) { team.GroupId = groupId; @@ -147,7 +147,7 @@ private static async Task ParseTeamJsonAsync(string accessToken, PnPConnec } } - public static async Task NewTeamAsync(string accessToken, PnPConnection connection, string groupId, string displayName, string description, string classification, string mailNickname, GroupVisibility visibility, TeamCreationInformation teamCI, string[] owners, string[] members, Guid[] sensitivityLabels, TeamsTemplateType templateType = TeamsTemplateType.None, TeamResourceBehaviorOptions?[] resourceBehaviorOptions = null) + public static Team NewTeam(Cmdlet cmdlet, string accessToken, PnPConnection connection, string groupId, string displayName, string description, string classification, string mailNickname, GroupVisibility visibility, TeamCreationInformation teamCI, string[] owners, string[] members, Guid[] sensitivityLabels, TeamsTemplateType templateType = TeamsTemplateType.None, TeamResourceBehaviorOptions?[] resourceBehaviorOptions = null) { Group group = null; Team returnTeam = null; @@ -155,7 +155,7 @@ public static async Task NewTeamAsync(string accessToken, PnPConnection co // Create the Group if (string.IsNullOrEmpty(groupId)) { - group = await CreateGroupAsync(accessToken, connection, displayName, description, classification, mailNickname, visibility, owners, sensitivityLabels, templateType, resourceBehaviorOptions); + group = CreateGroup(cmdlet, accessToken, connection, displayName, description, classification, mailNickname, visibility, owners, sensitivityLabels, templateType, resourceBehaviorOptions); bool wait = true; int iterations = 0; while (wait) @@ -164,7 +164,7 @@ public static async Task NewTeamAsync(string accessToken, PnPConnection co try { - var createdGroup = await GraphHelper.GetAsync(connection, $"v1.0/groups/{group.Id}", accessToken); + var createdGroup = GraphHelper.Get(cmdlet, connection, $"v1.0/groups/{group.Id}", accessToken); if (!string.IsNullOrEmpty(createdGroup.DisplayName)) { wait = false; @@ -173,7 +173,7 @@ public static async Task NewTeamAsync(string accessToken, PnPConnection co catch (Exception) { // In case of exception wait for 5 secs - await Task.Delay(TimeSpan.FromSeconds(5)); + Thread.Sleep(TimeSpan.FromSeconds(5)); } // Don't wait more than 1 minute @@ -185,7 +185,7 @@ public static async Task NewTeamAsync(string accessToken, PnPConnection co } else { - group = await GraphHelper.GetAsync(connection, $"v1.0/groups/{groupId}", accessToken); + group = GraphHelper.Get(cmdlet, connection, $"v1.0/groups/{groupId}", accessToken); if (group == null) { throw new PSArgumentException($"Cannot find group with id {groupId}"); @@ -202,22 +202,22 @@ public static async Task NewTeamAsync(string accessToken, PnPConnection co { try { - var teamSettings = await GraphHelper.PutAsync(connection, $"v1.0/groups/{group.Id}/team", team, accessToken); + var teamSettings = GraphHelper.Put(cmdlet, connection, $"v1.0/groups/{group.Id}/team", team, accessToken); if (teamSettings != null) { - returnTeam = await GetTeamAsync(accessToken, connection, group.Id); + returnTeam = GetTeam(cmdlet, accessToken, connection, group.Id); } retry = false; } catch (GraphException ge) when (ge.HttpResponse.StatusCode == System.Net.HttpStatusCode.Conflict) { // Handle conflict exceptions as if it succeeded, as it means a previous request succeeded enabling teams - returnTeam = await GetTeamAsync(accessToken, connection, group.Id); + returnTeam = GetTeam(cmdlet, accessToken, connection, group.Id); retry = false; } catch (Exception) { - await Task.Delay(5000); + Thread.Sleep(5000); iteration++; if (iteration > 10) { @@ -254,7 +254,7 @@ public static async Task NewTeamAsync(string accessToken, PnPConnection co var ownersAndMembers = BatchUtility.Chunk(teamOwnersAndMembers, 200); foreach (var chunk in ownersAndMembers) { - await GraphHelper.PostAsync(connection, $"v1.0/teams/{group.Id}/members/add", new { values = chunk.ToList() }, accessToken); + GraphHelper.Post(cmdlet, connection, $"v1.0/teams/{group.Id}/members/add", new { values = chunk.ToList() }, accessToken); } } } @@ -271,14 +271,14 @@ internal static string GetUserGraphUrlForUPN(string upn) return $"users/{escapedUpn}"; } - private static async Task CreateGroupAsync(string accessToken, PnPConnection connection, string displayName, string description, string classification, string mailNickname, GroupVisibility visibility, string[] owners, Guid[] sensitivityLabels, TeamsTemplateType templateType = TeamsTemplateType.None, TeamResourceBehaviorOptions?[] resourceBehaviorOptions = null) + private static Group CreateGroup(Cmdlet cmdlet, string accessToken, PnPConnection connection, string displayName, string description, string classification, string mailNickname, GroupVisibility visibility, string[] owners, Guid[] sensitivityLabels, TeamsTemplateType templateType = TeamsTemplateType.None, TeamResourceBehaviorOptions?[] resourceBehaviorOptions = null) { // When creating a group, we always need an owner, thus we'll try to define it from the passed in owners array string ownerId = null; if (owners != null && owners.Length > 0) { // Owner(s) have been provided, use the first owner as the initial owner. The other owners will be added later. - var user = await GraphHelper.GetAsync(connection, $"v1.0/{GetUserGraphUrlForUPN(owners[0])}?$select=Id", accessToken); + var user = GraphHelper.Get(cmdlet, connection, $"v1.0/{GetUserGraphUrlForUPN(owners[0])}?$select=Id", accessToken); if (user != null) { @@ -288,7 +288,7 @@ private static async Task CreateGroupAsync(string accessToken, PnPConnect else { // Unable to find the owner by its user principal name, try looking for it on its email address - var collection = await GraphHelper.GetResultCollectionAsync(connection, $"v1.0/users?$filter=mail eq '{owners[0]}'&$select=Id", accessToken); + var collection = GraphHelper.GetResultCollection(cmdlet, connection, $"v1.0/users?$filter=mail eq '{owners[0]}'&$select=Id", accessToken); if (collection != null && collection.Any()) { // User found on its email address @@ -306,7 +306,7 @@ private static async Task CreateGroupAsync(string accessToken, PnPConnect if (contextSettings.Type != Framework.Utilities.Context.ClientContextType.AzureADCertificate) { // A delegate context is available, make the user part of the delegate token the owner - var user = await GraphHelper.GetAsync(connection, "v1.0/me?$select=Id", accessToken); + var user = GraphHelper.Get(cmdlet, connection, "v1.0/me?$select=Id", accessToken); if (user != null) { @@ -323,7 +323,7 @@ private static async Task CreateGroupAsync(string accessToken, PnPConnect Description = description, Classification = classification, MailEnabled = true, - MailNickname = mailNickname ?? await CreateAliasAsync(connection, accessToken), + MailNickname = mailNickname ?? CreateAlias(cmdlet, connection, accessToken), GroupTypes = new List() { "Unified" }, SecurityEnabled = false, Visibility = visibility == GroupVisibility.NotSpecified ? GroupVisibility.Private : visibility @@ -381,7 +381,7 @@ private static async Task CreateGroupAsync(string accessToken, PnPConnect } try { - return await GraphHelper.PostAsync(connection, "v1.0/groups", group, accessToken); + return GraphHelper.Post(cmdlet, connection, "v1.0/groups", group, accessToken); } catch (GraphException ex) { @@ -396,7 +396,7 @@ private static async Task CreateGroupAsync(string accessToken, PnPConnect } } - private static async Task CreateAliasAsync(PnPConnection connection, string accessToken) + private static string CreateAlias(Cmdlet cmdlet, PnPConnection connection, string accessToken) { var guid = Guid.NewGuid().ToString(); var teamName = string.Empty; @@ -404,7 +404,7 @@ private static async Task CreateAliasAsync(PnPConnection connection, str do { var teamNameTemp = $"msteams_{guid.Substring(0, 8)}{guid.Substring(9, 4)}"; - var collection = await GraphHelper.GetAsync>(connection, $"v1.0/groups?$filter=groupTypes/any(c:c+eq+'Unified') and (mailNickname eq '{teamNameTemp}')", accessToken); + var collection = GraphHelper.Get>(cmdlet, connection, $"v1.0/groups?$filter=groupTypes/any(c:c+eq+'Unified') and (mailNickname eq '{teamNameTemp}')", accessToken); if (collection != null) { if (!collection.Items.Any()) teamName = teamNameTemp; @@ -414,43 +414,43 @@ private static async Task CreateAliasAsync(PnPConnection connection, str return teamName; } - public static async Task UpdateTeamAsync(PnPConnection connection, string accessToken, string groupId, Team team) + public static Team UpdateTeam(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, Team team) { - return await GraphHelper.PatchAsync(connection, accessToken, $"v1.0/teams/{groupId}", team); + return GraphHelper.Patch(cmdlet, connection, accessToken, $"v1.0/teams/{groupId}", team); } - public static async Task UpdateGroupAsync(PnPConnection connection, string accessToken, string groupId, Group group) + public static Group UpdateGroup(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, Group group) { - return await GraphHelper.PatchAsync(connection, accessToken, $"v1.0/groups/{groupId}", group); + return GraphHelper.Patch(cmdlet, connection, accessToken, $"v1.0/groups/{groupId}", group); } - public static async Task SetTeamPictureAsync(PnPConnection connection, string accessToken, string teamId, byte[] bytes, string contentType) + public static void SetTeamPictureAsync(Cmdlet cmdlet, PnPConnection connection, string accessToken, string teamId, byte[] bytes, string contentType) { var byteArrayContent = new ByteArrayContent(bytes); byteArrayContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType); - await GraphHelper.PutAsync(connection, $"v1.0/teams/{teamId}/photo/$value", accessToken, byteArrayContent); + GraphHelper.Put(cmdlet, connection, $"v1.0/teams/{teamId}/photo/$value", accessToken, byteArrayContent); } - public static async Task SetTeamArchivedStateAsync(PnPConnection connection, string accessToken, string groupId, bool archived, bool? setSiteReadOnly) + public static HttpResponseMessage SetTeamArchivedState(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, bool archived, bool? setSiteReadOnly) { if (archived) { StringContent content = new StringContent(JsonSerializer.Serialize(setSiteReadOnly.HasValue ? new { shouldSetSpoSiteReadOnlyForMembers = setSiteReadOnly } : null)); content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - return await GraphHelper.PostAsync(connection, $"v1.0/teams/{groupId}/archive", accessToken, content); + return GraphHelper.Post(cmdlet, connection, $"v1.0/teams/{groupId}/archive", accessToken, content); } else { StringContent content = new StringContent(""); content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - return await GraphHelper.PostAsync(connection, $"v1.0/teams/{groupId}/unarchive", accessToken, content); + return GraphHelper.Post(cmdlet, connection, $"v1.0/teams/{groupId}/unarchive", accessToken, content); } } - public static async Task> GetDeletedTeamAsync(string accessToken, PnPConnection connection) + public static IEnumerable GetDeletedTeam(Cmdlet cmdlet, string accessToken, PnPConnection connection) { // get the deleted team - var deletedTeams = await GraphHelper.GetResultCollectionAsync(connection, $"beta/teamwork/deletedTeams", accessToken); + var deletedTeams = GraphHelper.GetResultCollection(cmdlet, connection, $"beta/teamwork/deletedTeams", accessToken); if (deletedTeams != null && deletedTeams.Any()) { return deletedTeams; @@ -460,9 +460,9 @@ public static async Task> GetDeletedTeamAsync(string ac #endregion #region Users - public static async Task AddUserAsync(PnPConnection connection, string accessToken, string groupId, string upn, string role) + public static void AddUser(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string upn, string role) { - var userIdResult = await GraphHelper.GetAsync(connection, $"v1.0/{GetUserGraphUrlForUPN(upn)}?$select=Id", accessToken); + var userIdResult = GraphHelper.Get(cmdlet, connection, $"v1.0/{GetUserGraphUrlForUPN(upn)}?$select=Id", accessToken); var resultElement = JsonSerializer.Deserialize(userIdResult); if (resultElement.TryGetProperty("id", out JsonElement idProperty)) { @@ -474,11 +474,11 @@ public static async Task AddUserAsync(PnPConnection connection, string accessTok var stringContent = new StringContent(JsonSerializer.Serialize(postData)); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); - await GraphHelper.PostAsync(connection, $"v1.0/groups/{groupId}/{role.ToLower()}s/$ref", accessToken, stringContent); + GraphHelper.Post(cmdlet, connection, $"v1.0/groups/{groupId}/{role.ToLower()}s/$ref", accessToken, stringContent); } } - public static async Task AddUsersAsync(PnPConnection connection, string accessToken, string groupId, string[] upn, string role) + public static void AddUsers(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string[] upn, string role) { var teamChannelMember = new List(); if (upn != null && upn.Length > 0) @@ -492,13 +492,13 @@ public static async Task AddUsersAsync(PnPConnection connection, string accessTo var chunks = BatchUtility.Chunk(teamChannelMember, 200); foreach (var chunk in chunks.ToList()) { - await GraphHelper.PostAsync(connection, $"v1.0/teams/{groupId}/members/add", new { values = chunk.ToList() }, accessToken); + GraphHelper.Post(cmdlet, connection, $"v1.0/teams/{groupId}/members/add", new { values = chunk.ToList() }, accessToken); } } } } - public static async Task> GetUsersAsync(PnPConnection connection, string accessToken, string groupId, string role) + public static List GetUsers(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string role) { var selectedRole = role != null ? role.ToLower() : null; var owners = new List(); @@ -506,7 +506,7 @@ public static async Task> GetUsersAsync(PnPConnection connection, str var members = new List(); if (selectedRole != "guest") { - owners = (await GraphHelper.GetResultCollectionAsync(connection, $"v1.0/groups/{groupId}/owners?$select=Id,displayName,userPrincipalName,userType", accessToken)).Select(t => new User() + owners = (GraphHelper.GetResultCollection(cmdlet, connection, $"v1.0/groups/{groupId}/owners?$select=Id,displayName,userPrincipalName,userType", accessToken)).Select(t => new User() { Id = t.Id, DisplayName = t.DisplayName, @@ -516,7 +516,7 @@ public static async Task> GetUsersAsync(PnPConnection connection, str } if (selectedRole != "owner") { - var users = (await GraphHelper.GetResultCollectionAsync(connection, $"v1.0/groups/{groupId}/members?$select=Id,displayName,userPrincipalName,userType", accessToken)); + var users = (GraphHelper.GetResultCollection(cmdlet, connection, $"v1.0/groups/{groupId}/members?$select=Id,displayName,userPrincipalName,userType", accessToken)); HashSet hashSet = new HashSet(owners.Select(u => u.Id)); foreach (var user in users) { @@ -555,12 +555,12 @@ public static async Task> GetUsersAsync(PnPConnection connection, str return finalList; } - public static async Task> GetUsersAsync(PnPConnection connection, string accessToken, string groupId, string channelId, string role) + public static IEnumerable GetUsers(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string channelId, string role) { List users = new List(); var selectedRole = role != null ? role.ToLower() : null; - var collection = await GraphHelper.GetResultCollectionAsync(connection, $"v1.0/teams/{groupId}/channels/{channelId}/members", accessToken); + var collection = GraphHelper.GetResultCollection(cmdlet, connection, $"v1.0/teams/{groupId}/channels/{channelId}/members", accessToken); if (collection != null && collection.Any()) { users.AddRange(collection.Select(m => new User() { DisplayName = m.DisplayName, Id = m.UserId, UserPrincipalName = m.Email, UserType = m.Roles.Count > 0 ? m.Roles[0].ToLower() : "" })); @@ -576,34 +576,34 @@ public static async Task> GetUsersAsync(PnPConnection connecti } } - public static async Task DeleteUserAsync(PnPConnection connection, string accessToken, string groupId, string upn, string role) + public static void DeleteUser(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string upn, string role) { - var user = await GraphHelper.GetAsync(connection, $"v1.0/{GetUserGraphUrlForUPN(upn)}?$select=Id", accessToken); + var user = GraphHelper.Get(cmdlet, connection, $"v1.0/{GetUserGraphUrlForUPN(upn)}?$select=Id", accessToken); if (user != null) { // check if the user is an owner - var owners = await GraphHelper.GetResultCollectionAsync(connection, $"v1.0/groups/{groupId}/owners?$select=Id", accessToken); + var owners = GraphHelper.GetResultCollection(cmdlet, connection, $"v1.0/groups/{groupId}/owners?$select=Id", accessToken); if (owners.Any() && owners.FirstOrDefault(u => u.Id.Equals(user.Id, StringComparison.OrdinalIgnoreCase)) != null) { if (owners.Count() == 1) { throw new PSInvalidOperationException("Last owner cannot be removed"); } - await GraphHelper.DeleteAsync(connection, $"v1.0/groups/{groupId}/owners/{user.Id}/$ref", accessToken); + GraphHelper.Delete(cmdlet, connection, $"v1.0/groups/{groupId}/owners/{user.Id}/$ref", accessToken); } if (!role.Equals("owner", StringComparison.OrdinalIgnoreCase)) { - await GraphHelper.DeleteAsync(connection, $"v1.0/groups/{groupId}/members/{user.Id}/$ref", accessToken); + GraphHelper.Delete(cmdlet, connection, $"v1.0/groups/{groupId}/members/{user.Id}/$ref", accessToken); } } } - public static async Task> GetTeamUsersWithDisplayNameAsync(PnPConnection connection, string accessToken, string groupId, string userDisplayName) + public static List GetTeamUsersWithDisplayName(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string userDisplayName) { // multiple users can have same display name, so using list var teamUserWithDisplayName = new List(); - teamUserWithDisplayName = (await GraphHelper.GetResultCollectionAsync(connection, $"v1.0/teams/{groupId}/members?$filter=displayname eq '{userDisplayName}'", accessToken)).Select(t => new TeamUser() + teamUserWithDisplayName = (GraphHelper.GetResultCollection(cmdlet, connection, $"v1.0/teams/{groupId}/members?$filter=displayname eq '{userDisplayName}'", accessToken)).Select(t => new TeamUser() { Id = t.Id, DisplayName = t.DisplayName, @@ -614,7 +614,7 @@ public static async Task> GetTeamUsersWithDisplayNameAsync(PnPCon return teamUserWithDisplayName; } - public static async Task UpdateTeamUserRole(PnPConnection connection, string accessToken, string groupId, string teamMemberId, string role) + public static TeamUser UpdateTeamUserRole(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string teamMemberId, string role) { var teamUser = new TeamUser { @@ -624,7 +624,7 @@ public static async Task UpdateTeamUserRole(PnPConnection connection, var updateUserEndpoint = $"v1.0/teams/{groupId}/members/{teamMemberId}"; - var result = await GraphHelper.PatchAsync(connection, accessToken, updateUserEndpoint, teamUser); + var result = GraphHelper.Patch(cmdlet, connection, accessToken, updateUserEndpoint, teamUser); return result; } @@ -633,30 +633,45 @@ public static async Task UpdateTeamUserRole(PnPConnection connection, #region Channel - public static async Task GetChannelAsync(string accessToken, PnPConnection connection, string groupId, string channelId, bool useBeta = false) + public static TeamChannel GetChannel(Cmdlet cmdlet, string accessToken, PnPConnection connection, string groupId, string channelId, bool useBeta = false) { - var channel = await GraphHelper.GetAsync(connection, $"{(useBeta ? "beta" : "v1.0")}/teams/{groupId}/channels/{channelId}", accessToken); + var additionalHeaders = new Dictionary() + { + { "Prefer", "include-unknown-enum-members" } + }; + + var channel = GraphHelper.Get(cmdlet, connection, $"{(useBeta ? "beta" : "v1.0")}/teams/{groupId}/channels/{channelId}", accessToken, additionalHeaders: additionalHeaders); return channel; } - public static async Task> GetChannelsAsync(string accessToken, PnPConnection connection, string groupId, bool useBeta = false) + public static IEnumerable GetChannels(Cmdlet cmdlet, string accessToken, PnPConnection connection, string groupId, bool useBeta = false) { - var collection = await GraphHelper.GetResultCollectionAsync(connection, $"{(useBeta ? "beta" : "v1.0")}/teams/{groupId}/channels", accessToken); + var additionalHeaders = new Dictionary() + { + { "Prefer", "include-unknown-enum-members" } + }; + + var collection = GraphHelper.GetResultCollection(cmdlet, connection, $"{(useBeta ? "beta" : "v1.0")}/teams/{groupId}/channels", accessToken, additionalHeaders: additionalHeaders); return collection; } - public static async Task GetPrimaryChannelAsync(string accessToken, PnPConnection connection, string groupId, bool useBeta = false) + public static TeamChannel GetPrimaryChannel(Cmdlet cmdlet, string accessToken, PnPConnection connection, string groupId, bool useBeta = false) { - var collection = await GraphHelper.GetAsync(connection, $"{(useBeta ? "beta" : "v1.0")}/teams/{groupId}/primaryChannel", accessToken); + var additionalHeaders = new Dictionary() + { + { "Prefer", "include-unknown-enum-members" } + }; + + var collection = GraphHelper.Get(cmdlet, connection, $"{(useBeta ? "beta" : "v1.0")}/teams/{groupId}/primaryChannel", accessToken, additionalHeaders: additionalHeaders); return collection; } - public static async Task DeleteChannelAsync(string accessToken, PnPConnection connection, string groupId, string channelId, bool useBeta = false) + public static HttpResponseMessage DeleteChannel(Cmdlet cmdlet, string accessToken, PnPConnection connection, string groupId, string channelId, bool useBeta = false) { - return await GraphHelper.DeleteAsync(connection, $"{(useBeta ? "beta" : "v1.0")}/teams/{groupId}/channels/{channelId}", accessToken); + return GraphHelper.Delete(cmdlet, connection, $"{(useBeta ? "beta" : "v1.0")}/teams/{groupId}/channels/{channelId}", accessToken); } - public static async Task AddChannelAsync(string accessToken, PnPConnection connection, string groupId, string displayName, string description, TeamsChannelType channelType, string ownerUPN, bool isFavoriteByDefault) + public static TeamChannel AddChannel(Cmdlet cmdlet, string accessToken, PnPConnection connection, string groupId, string displayName, string description, TeamsChannelType channelType, string ownerUPN, bool isFavoriteByDefault) { var channel = new TeamChannel() { @@ -674,32 +689,32 @@ public static async Task AddChannelAsync(string accessToken, PnPCon if (channelType == TeamsChannelType.Private || channelType == TeamsChannelType.Shared) { channel.Type = "#Microsoft.Graph.channel"; - var user = await GraphHelper.GetAsync(connection, $"v1.0/{GetUserGraphUrlForUPN(ownerUPN)}", accessToken); + var user = GraphHelper.Get(cmdlet, connection, $"v1.0/{GetUserGraphUrlForUPN(ownerUPN)}", accessToken); channel.Members = new List(); channel.Members.Add(new TeamChannelMember() { Roles = new List { "owner" }, UserIdentifier = $"https://{connection.GraphEndPoint}/v1.0/users('{user.Id}')" }); - return await GraphHelper.PostAsync(connection, $"v1.0/teams/{groupId}/channels", channel, accessToken); + return GraphHelper.Post(cmdlet, connection, $"v1.0/teams/{groupId}/channels", channel, accessToken); } else { channel.IsFavoriteByDefault = null; - return await GraphHelper.PostAsync(connection, $"v1.0/teams/{groupId}/channels", channel, accessToken); + return GraphHelper.Post(cmdlet, connection, $"v1.0/teams/{groupId}/channels", channel, accessToken); } } - public static async Task PostMessageAsync(PnPConnection connection, string accessToken, string groupId, string channelId, TeamChannelMessage message) + public static void PostMessage(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string channelId, TeamChannelMessage message) { - await GraphHelper.PostAsync(connection, $"v1.0/teams/{groupId}/channels/{channelId}/messages", message, accessToken); + GraphHelper.Post(cmdlet, connection, $"v1.0/teams/{groupId}/channels/{channelId}/messages", message, accessToken); } - public static async Task GetMessageAsync(PnPConnection connection, string accessToken, string groupId, string channelId, string messageId) + public static TeamChannelMessage GetMessage(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string channelId, string messageId) { - return await GraphHelper.GetAsync(connection, $"v1.0/teams/{groupId}/channels/{channelId}/messages/{messageId}", accessToken); + return GraphHelper.Get(cmdlet, connection, $"v1.0/teams/{groupId}/channels/{channelId}/messages/{messageId}", accessToken); } - public static async Task> GetMessagesAsync(PnPConnection connection, string accessToken, string groupId, string channelId, bool includeDeleted = false) + public static List GetMessages(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string channelId, bool includeDeleted = false) { List messages = new List(); - var collection = await GraphHelper.GetResultCollectionAsync(connection, $"v1.0/teams/{groupId}/channels/{channelId}/messages", accessToken); + var collection = GraphHelper.GetResultCollection(cmdlet, connection, $"v1.0/teams/{groupId}/channels/{channelId}/messages", accessToken); messages.AddRange(collection); if (includeDeleted) @@ -715,9 +730,9 @@ public static async Task> GetMessagesAsync(PnPConnectio /// /// List all the replies to a message in a channel of a team. /// - public static async Task> GetMessageRepliesAsync(PnPConnection connection, string accessToken, string groupId, string channelId, string messageId, bool includeDeleted = false) + public static List GetMessageReplies(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string channelId, string messageId, bool includeDeleted = false) { - var replies = await GraphHelper.GetResultCollectionAsync(connection, $"v1.0/teams/{groupId}/channels/{channelId}/messages/{messageId}/replies", accessToken); + var replies = GraphHelper.GetResultCollection(cmdlet, connection, $"v1.0/teams/{groupId}/channels/{channelId}/messages/{messageId}/replies", accessToken); return includeDeleted ? replies.ToList() : replies.Where(r => !r.DeletedDateTime.HasValue).ToList(); } @@ -725,17 +740,17 @@ public static async Task> GetMessageRepliesAsync(P /// /// Get a specific reply of a message in a channel of a team. /// - public static async Task GetMessageReplyAsync(PnPConnection connection, string accessToken, string groupId, string channelId, string messageId, string replyId) + public static TeamChannelMessageReply GetMessageReply(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string channelId, string messageId, string replyId) { - return await GraphHelper.GetAsync(connection, $"v1.0/teams/{groupId}/channels/{channelId}/messages/{messageId}/replies/{replyId}", accessToken); + return GraphHelper.Get(cmdlet, connection, $"v1.0/teams/{groupId}/channels/{channelId}/messages/{messageId}/replies/{replyId}", accessToken); } /// /// Updates a Teams Channel /// - public static async Task UpdateChannelAsync(PnPConnection connection, string accessToken, string groupId, string channelId, TeamChannel channel, bool useBeta = false) + public static TeamChannel UpdateChannel(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string channelId, TeamChannel channel, bool useBeta = false) { - return await GraphHelper.PatchAsync(connection, accessToken, $"{(useBeta ? "beta" : "v1.0")}/teams/{groupId}/channels/{channelId}", channel); + return GraphHelper.Patch(cmdlet, connection, accessToken, $"{(useBeta ? "beta" : "v1.0")}/teams/{groupId}/channels/{channelId}", channel); } #endregion @@ -745,12 +760,12 @@ public static async Task UpdateChannelAsync(PnPConnection connectio /// Get specific memberbership of user who has access to a certain Microsoft Teams channel. /// /// User channel membership. - public static async Task GetChannelMemberAsync(PnPConnection connection, string accessToken, string groupId, string channelId, string membershipId) + public static TeamChannelMember GetChannelMember(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string channelId, string membershipId) { // Currently the Graph request to get a membership by id fails (v1.0/teams/{groupId}/channels/{channelId}/members/{membershipId}). // This is why the method below is used. - var memberships = await GetChannelMembersAsync(connection, accessToken, groupId, channelId); + var memberships = GetChannelMembers(cmdlet, connection, accessToken, groupId, channelId); return memberships.FirstOrDefault(m => membershipId.Equals(m.Id)); } @@ -758,9 +773,9 @@ public static async Task GetChannelMemberAsync(PnPConnection /// Get list of all memberships of a certain Microsoft Teams channel. /// /// List of memberships. - public static async Task> GetChannelMembersAsync(PnPConnection connection, string accessToken, string groupId, string channelId, string role = null) + public static IEnumerable GetChannelMembers(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string channelId, string role = null) { - var collection = await GraphHelper.GetResultCollectionAsync(connection, $"v1.0/teams/{groupId}/channels/{channelId}/members", accessToken); + var collection = GraphHelper.GetResultCollection(cmdlet, connection, $"v1.0/teams/{groupId}/channels/{channelId}/members", accessToken); if (!string.IsNullOrEmpty(role)) { @@ -776,7 +791,7 @@ public static async Task> GetChannelMembersAsync( /// /// User role, valid values: Owner, Member /// Added membership. - public static async Task AddChannelMemberAsync(PnPConnection connection, string accessToken, string groupId, string channelId, string upn, string role) + public static TeamChannelMember AddChannelMember(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string channelId, string upn, string role) { var channelMember = new TeamChannelMember { @@ -787,23 +802,23 @@ public static async Task AddChannelMemberAsync(PnPConnection if (role.Equals("owner", StringComparison.OrdinalIgnoreCase)) channelMember.Roles.Add("owner"); - return await GraphHelper.PostAsync(connection, $"v1.0/teams/{groupId}/channels/{channelId}/members", channelMember, accessToken); + return GraphHelper.Post(cmdlet, connection, $"v1.0/teams/{groupId}/channels/{channelId}/members", channelMember, accessToken); } /// /// Remove specified member of a specified Microsoft Teams channel. /// /// True when removal succeeded, else false. - public static async Task DeleteChannelMemberAsync(PnPConnection connection, string accessToken, string groupId, string channelId, string membershipId) + public static HttpResponseMessage DeleteChannelMember(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string channelId, string membershipId) { - return await GraphHelper.DeleteAsync(connection, $"v1.0/teams/{groupId}/channels/{channelId}/members/{membershipId}", accessToken); + return GraphHelper.Delete(cmdlet, connection, $"v1.0/teams/{groupId}/channels/{channelId}/members/{membershipId}", accessToken); } /// /// Update the role of a specific member of a Microsoft Teams channel. /// /// Updated membership object. - public static async Task UpdateChannelMemberAsync(PnPConnection connection, string accessToken, string groupId, string channelId, string membershipId, string role) + public static TeamChannelMember UpdateChannelMember(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string channelId, string membershipId, string role) { var channelMember = new TeamChannelMember(); @@ -811,41 +826,41 @@ public static async Task UpdateChannelMemberAsync(PnPConnecti if (role.Equals("owner", StringComparison.OrdinalIgnoreCase)) channelMember.Roles.Add("owner"); - return await GraphHelper.PatchAsync(connection, accessToken, $"v1.0/teams/{groupId}/channels/{channelId}/members/{membershipId}", channelMember); + return GraphHelper.Patch(cmdlet, connection, accessToken, $"v1.0/teams/{groupId}/channels/{channelId}/members/{membershipId}", channelMember); } - public static async Task GetChannelsFilesFolderAsync(PnPConnection connection, string accessToken, string groupId, string channelId) + public static TeamsChannelFilesFolder GetChannelsFilesFolder(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string channelId) { - var collection = await GraphHelper.GetAsync(connection, $"v1.0/teams/{groupId}/channels/{channelId}/filesFolder", accessToken); + var collection = GraphHelper.Get(cmdlet, connection, $"v1.0/teams/{groupId}/channels/{channelId}/filesFolder", accessToken); return collection; } #endregion #region Tabs - public static async Task> GetTabsAsync(string accessToken, PnPConnection connection, string groupId, string channelId) + public static IEnumerable GetTabs(Cmdlet cmdlet, string accessToken, PnPConnection connection, string groupId, string channelId) { - var collection = await GraphHelper.GetResultCollectionAsync(connection, $"v1.0/teams/{groupId}/channels/{channelId}/tabs", accessToken); + var collection = GraphHelper.GetResultCollection(cmdlet, connection, $"v1.0/teams/{groupId}/channels/{channelId}/tabs", accessToken); return collection; } - public static async Task GetTabAsync(string accessToken, PnPConnection connection, string groupId, string channelId, string tabId) + public static TeamTab GetTab(Cmdlet cmdlet, string accessToken, PnPConnection connection, string groupId, string channelId, string tabId) { - return await GraphHelper.GetAsync(connection, $"v1.0/teams/{groupId}/channels/{channelId}/tabs/{tabId}?$expand=teamsApp", accessToken, propertyNameCaseInsensitive: true); + return GraphHelper.Get(cmdlet, connection, $"v1.0/teams/{groupId}/channels/{channelId}/tabs/{tabId}?$expand=teamsApp", accessToken, propertyNameCaseInsensitive: true); } - public static async Task DeleteTabAsync(string accessToken, PnPConnection connection, string groupId, string channelId, string tabId) + public static HttpResponseMessage DeleteTab(Cmdlet cmdlet, string accessToken, PnPConnection connection, string groupId, string channelId, string tabId) { - return await GraphHelper.DeleteAsync(connection, $"v1.0/teams/{groupId}/channels/{channelId}/tabs/{tabId}", accessToken); + return GraphHelper.Delete(cmdlet, connection, $"v1.0/teams/{groupId}/channels/{channelId}/tabs/{tabId}", accessToken); } - public static async Task UpdateTabAsync(PnPConnection connection, string accessToken, string groupId, string channelId, TeamTab tab) + public static void UpdateTab(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string channelId, TeamTab tab) { tab.Configuration = null; - await GraphHelper.PatchAsync(connection, accessToken, $"v1.0/teams/{groupId}/channels/{channelId}/tabs/{tab.Id}", tab); + GraphHelper.Patch(cmdlet, connection, accessToken, $"v1.0/teams/{groupId}/channels/{channelId}/tabs/{tab.Id}", tab); } - public static async Task AddTabAsync(PnPConnection connection, string accessToken, string groupId, string channelId, string displayName, TeamTabType tabType, string teamsAppId, string entityId, string contentUrl, string removeUrl, string websiteUrl) + public static TeamTab AddTab(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string channelId, string displayName, TeamTabType tabType, string teamsAppId, string entityId, string contentUrl, string removeUrl, string websiteUrl) { TeamTab tab = new TeamTab(); switch (tabType) @@ -963,65 +978,64 @@ public static async Task AddTabAsync(PnPConnection connection, string a } tab.DisplayName = displayName; tab.TeamsAppOdataBind = $"https://{connection.GraphEndPoint}/v1.0/appCatalogs/teamsApps/{tab.TeamsAppId}"; - return await GraphHelper.PostAsync(connection, $"v1.0/teams/{groupId}/channels/{channelId}/tabs", tab, accessToken); + return GraphHelper.Post(cmdlet, connection, $"v1.0/teams/{groupId}/channels/{channelId}/tabs", tab, accessToken); } #endregion #region Apps - public static async Task> GetAppsAsync(string accessToken, PnPConnection connection) + public static IEnumerable GetApps(Cmdlet cmdlet, string accessToken, PnPConnection connection) { - var collection = await GraphHelper.GetResultCollectionAsync(connection, $"v1.0/appCatalogs/teamsApps", accessToken); + var collection = GraphHelper.GetResultCollection(cmdlet, connection, $"v1.0/appCatalogs/teamsApps", accessToken); return collection; } - public static async Task AddAppAsync(PnPConnection connection, string accessToken, byte[] bytes) + public static TeamApp AddApp(Cmdlet cmdlet, PnPConnection connection, string accessToken, byte[] bytes) { var byteArrayContent = new ByteArrayContent(bytes); byteArrayContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/zip"); - var response = await GraphHelper.PostAsync(connection, "v1.0/appCatalogs/teamsApps", accessToken, byteArrayContent); + var response = GraphHelper.Post(cmdlet, connection, "v1.0/appCatalogs/teamsApps", accessToken, byteArrayContent); var content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); return JsonSerializer.Deserialize(content, new JsonSerializerOptions() { DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull, PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); } - public static async Task UpdateAppAsync(PnPConnection connection, string accessToken, byte[] bytes, string appId) + public static HttpResponseMessage UpdateApp(Cmdlet cmdlet, PnPConnection connection, string accessToken, byte[] bytes, string appId) { var byteArrayContent = new ByteArrayContent(bytes); byteArrayContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/zip"); - return await GraphHelper.PutAsync(connection, $"v1.0/appCatalogs/teamsApps/{appId}", accessToken, byteArrayContent); + return GraphHelper.Put(cmdlet, connection, $"v1.0/appCatalogs/teamsApps/{appId}", accessToken, byteArrayContent); } - public static async Task DeleteAppAsync(PnPConnection connection, string accessToken, string appId) + public static HttpResponseMessage DeleteApp(Cmdlet cmdlet, PnPConnection connection, string accessToken, string appId) { - return await GraphHelper.DeleteAsync(connection, $"v1.0/appCatalogs/teamsApps/{appId}", accessToken); + return GraphHelper.Delete(cmdlet, connection, $"v1.0/appCatalogs/teamsApps/{appId}", accessToken); } #endregion #region Tags - public static async Task> GetTagsAsync(string accessToken, PnPConnection connection, string groupId) + public static IEnumerable GetTags(Cmdlet cmdlet, string accessToken, PnPConnection connection, string groupId) { - var collection = await GraphHelper.GetResultCollectionAsync(connection, $"v1.0/teams/{groupId}/tags", accessToken); + var collection = GraphHelper.GetResultCollection(cmdlet, connection, $"v1.0/teams/{groupId}/tags", accessToken); return collection; } - public static async Task GetTagsWithIdAsync(string accessToken, PnPConnection connection, string groupId, string tagId) + public static TeamTag GetTagsWithId(Cmdlet cmdlet, string accessToken, PnPConnection connection, string groupId, string tagId) { - var tagInformation = await GraphHelper.GetAsync(connection, $"v1.0/teams/{groupId}/tags/{tagId}", accessToken); + var tagInformation = GraphHelper.Get(cmdlet, connection, $"v1.0/teams/{groupId}/tags/{tagId}", accessToken); return tagInformation; } - public static async Task UpdateTagAsync(PnPConnection connection, string accessToken, string groupId, string tagId, string displayName) + public static void UpdateTag(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string tagId, string displayName) { var body = new { displayName = displayName }; - await GraphHelper.PatchAsync(connection, accessToken, $"v1.0/teams/{groupId}/tags/{tagId}", body); + GraphHelper.Patch(cmdlet, connection, accessToken, $"v1.0/teams/{groupId}/tags/{tagId}", body); } - public static async Task DeleteTagAsync(PnPConnection connection, string accessToken, string groupId, string tagId) + public static HttpResponseMessage DeleteTag(Cmdlet cmdlet, PnPConnection connection, string accessToken, string groupId, string tagId) { - return await GraphHelper.DeleteAsync(connection, $"v1.0/teams/{groupId}/tags/{tagId}", accessToken); + return GraphHelper.Delete(cmdlet, connection, $"v1.0/teams/{groupId}/tags/{tagId}", accessToken); } - #endregion } } \ No newline at end of file diff --git a/src/Commands/Utilities/VersionChecker.cs b/src/Commands/Utilities/VersionChecker.cs index 185773068..8c6b9ee59 100644 --- a/src/Commands/Utilities/VersionChecker.cs +++ b/src/Commands/Utilities/VersionChecker.cs @@ -1,8 +1,12 @@ using System; using System.Diagnostics; +using System.Linq; using System.Management.Automation; using System.Net.Http; +using System.Net.Http.Headers; using System.Reflection; +using System.Xml; +using System.Xml.Linq; namespace PnP.PowerShell.Commands.Utilities { @@ -62,7 +66,7 @@ public static void CheckVersion(PSCmdlet cmdlet) cmdlet?.WriteVerbose($"Checking for updates, current version is {productVersion}. See https://pnp.github.io/powershell/articles/configuration.html#disable-or-enable-version-checks for more information."); // Check for the latest available version - var onlineVersion = GetAvailableVersion(isNightly); + var onlineVersion = GetAvailableVersion2(isNightly); if (IsNewer(onlineVersion)) { @@ -74,7 +78,7 @@ public static void CheckVersion(PSCmdlet cmdlet) } else { - cmdlet?.WriteVerbose("No newer version of PnP PowerShell is available"); + cmdlet?.WriteVerbose($"No newer version of PnP PowerShell is available, latest available version is {onlineVersion}"); } VersionChecked = true; } @@ -93,9 +97,9 @@ public static bool IsNewer(string availableVersionString) { var assembly = Assembly.GetExecutingAssembly(); var versionInfo = FileVersionInfo.GetVersionInfo(assembly.Location); - var productVersion = versionInfo.ProductVersion; - - if (Version.TryParse(availableVersionString, out Version availableVersion)) + var productVersion = versionInfo.ProductVersion; + + if (SemanticVersion.TryParse(availableVersionString, out SemanticVersion availableVersion)) { if (availableVersion.Major > versionInfo.ProductMajorPart) { @@ -111,7 +115,7 @@ public static bool IsNewer(string availableVersionString) { if (productVersion.Contains("-")) { - if (versionInfo.ProductMajorPart == availableVersion.Major && versionInfo.ProductMinorPart == availableVersion.Minor && availableVersion.Build > versionInfo.ProductBuildPart) + if (versionInfo.ProductMajorPart == availableVersion.Major && versionInfo.ProductMinorPart == availableVersion.Minor && availableVersion.Patch > versionInfo.ProductBuildPart) { return true; } @@ -134,6 +138,7 @@ internal static string GetAvailableVersion(bool isNightly) httpClient.Timeout = TimeSpan.FromSeconds(VersionCheckTimeOut); var request = new HttpRequestMessage(HttpMethod.Get, isNightly ? NightlyVersionCheckUrl : ReleaseVersionCheckUrl); request.Version = new Version(2, 0); + var response = httpClient.SendAsync(request).GetAwaiter().GetResult(); if (response.IsSuccessStatusCode) { @@ -144,6 +149,36 @@ internal static string GetAvailableVersion(bool isNightly) return null; } + internal static string GetAvailableVersion2(bool isNightly) + { + var httpClient = PnP.Framework.Http.PnPHttpClient.Instance.GetHttpClient(); + + // Deliberately lowering timeout as the version check is not critical so in case of a slower or blocked internet connection, this should not block the cmdlet for too long + httpClient.Timeout = TimeSpan.FromSeconds(VersionCheckTimeOut); + var request = new HttpRequestMessage(HttpMethod.Get, "https://www.powershellgallery.com/api/v2/FindPackagesById()?id='PnP.PowerShell'&$top=10&$orderby=Created%20desc"); + request.Version = new Version(2, 0); + var response = httpClient.SendAsync(request).GetAwaiter().GetResult(); + if (response.IsSuccessStatusCode) + { + XNamespace atomNS = "http://www.w3.org/2005/Atom"; + XNamespace metadataNS = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"; + XNamespace dataServicesNS = "http://schemas.microsoft.com/ado/2007/08/dataservices"; + var onlineVersion = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + var xml = XDocument.Parse(onlineVersion); + var entry = xml.Root.Elements(atomNS + "entry").FirstOrDefault(); + if(entry!= null) + { + var properties = entry.Elements(metadataNS + "properties").FirstOrDefault(); + if(properties != null) + { + var version = properties.Element(dataServicesNS + "Version").Value; + return version; + } + } + } + return null; + } + /// /// Retrieves the latest available version of PnP PowerShell. If the current version is a nightly build, it will check for the latest nightly build as well. If the current version is a stable build, it will only check for the latest stable build. /// diff --git a/src/Commands/Web/GetWebHeader.cs b/src/Commands/Web/GetWebHeader.cs index d8b68878d..9cef045a0 100644 --- a/src/Commands/Web/GetWebHeader.cs +++ b/src/Commands/Web/GetWebHeader.cs @@ -21,7 +21,7 @@ protected override void ExecuteCmdlet() HeaderLayout = CurrentWeb.HeaderLayout, HeaderEmphasis = CurrentWeb.HeaderEmphasis, HideTitleInHeader = CurrentWeb.HideTitleInHeader, - HeaderBackgroundImageUrl = UrlUtilities.UrlDecode(CurrentWeb.AllProperties["BackgroundImageUrl"] as string) + HeaderBackgroundImageUrl = CurrentWeb.AllProperties.FieldValues.ContainsKey("BackgroundImageUrl") ? UrlUtilities.UrlDecode(CurrentWeb.AllProperties["BackgroundImageUrl"] as string) : string.Empty }; WriteObject(response); } diff --git a/src/Commands/Web/SetWebHeader.cs b/src/Commands/Web/SetWebHeader.cs index 1875e796c..b07d8aad8 100644 --- a/src/Commands/Web/SetWebHeader.cs +++ b/src/Commands/Web/SetWebHeader.cs @@ -110,7 +110,7 @@ protected override void ExecuteCmdlet() var stringContent = new StringContent("{" + string.Join(",", setSiteBackgroundImageInstructions) + ",\"type\":2,\"aspect\":0}"); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); CurrentWeb.EnsureProperties(p => p.Url); - var result = GraphHelper.PostAsync(Connection, $"{CurrentWeb.Url.TrimEnd('/')}/_api/siteiconmanager/setsitelogo", AccessToken, stringContent).GetAwaiter().GetResult(); + var result = GraphHelper.Post(this, Connection, $"{CurrentWeb.Url.TrimEnd('/')}/_api/siteiconmanager/setsitelogo", AccessToken, stringContent); WriteVerbose($"Response from setsitelogo request: {result.StatusCode}"); } } @@ -129,7 +129,7 @@ private void SetSiteImage(string imageUrl, string imageType, int aspect) var stringContent = new StringContent($"{{\"relativeLogoUrl\":\"{imageUrl}\",\"type\":0,\"aspect\":{aspect}}}"); stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); CurrentWeb.EnsureProperties(p => p.Url); - var result = GraphHelper.PostAsync(Connection, $"{CurrentWeb.Url.TrimEnd('/')}/_api/siteiconmanager/setsitelogo", AccessToken, stringContent).GetAwaiter().GetResult(); + var result = GraphHelper.Post(this, Connection, $"{CurrentWeb.Url.TrimEnd('/')}/_api/siteiconmanager/setsitelogo", AccessToken, stringContent); WriteVerbose($"Response from {imageType} request: {result.StatusCode}"); } } diff --git a/version.txt b/version.txt index 9b5ea9efc..c51908eaf 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -2.4.98 \ No newline at end of file +2.11.2 \ No newline at end of file