Authentication and performance update (#216)

This commit is contained in:
Isaiah Williams 2019-12-05 13:53:53 -06:00 коммит произвёл GitHub
Родитель bc4d77cfa2
Коммит 6af4d665ce
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
162 изменённых файлов: 2650 добавлений и 927 удалений

Просмотреть файл

@ -20,7 +20,40 @@
# Change Log
## 2.0.1911.6
## 3.0.0 - December 2019
* Agreement
* Added the [Get-PartnerAgreementStatus](https://docs.microsoft.com/powershell/module/partnercenter/Get-PartnerAgreementStatus) command to get the status of acceptance of the Microsoft Partner Agreement for the specified partner
* Authentication
* Added the `AzureAccessToken` parameter to the [Connect-PartnerCenter](https://docs.microsoft.com/powershell/module/partnercenter/Connect-PartnerCenter) command, this value will be used to interact with Azure when using commands that leverage the Azure Resource Manager API
* Updated how [Connect-PartnerCenter](https://docs.microsoft.com/powershell/module/partnercenter/Connect-PartnerCenter) writes warnings during an authentication attempt
* Updated how [New-PartnerAccessToken](https://docs.microsoft.com/powershell/module/partnercenter/New-PartnerAccessToken) prompts for interaction
* When using [Connect-PartnerCenter](https://docs.microsoft.com/powershell/module/partnercenter/Connect-PartnerCenter) with an access token the account and tenant information are now extracted from the access token
* Azure
* Added the [Get-PartnerAzureBillingPolicy](https://docs.microsoft.com/powershell/module/partnercenter/Get-PartnerAzureBillingPolicy) to get the billing policy for the specified customer
* Added the [Set-PartnerAzureBillingPolicy](https://docs.microsoft.com/powershell/module/partnercenter/Set-PartnerAzureBillingPolicy) to update the billing policy for the specified customer
* Build
* Updating the test project from .NET Core 2.2 to .NET 3.0
* Dependency
* Updated to the latest version of the Partner Center SDK for .NET
* Invoice
* Added the `Period` parameter to the [Get-PartnerInvoiceLineItem](https://docs.microsoft.com/powershell/module/partnercenter/Get-PartnerInvoiceLineItem) command to provide a way for the user to specify if they want the current or previous unbilled line items
* Addressed issue [#202](https://github.com/microsoft/Partner-Center-PowerShell/issues/202) that was returning request for invoice line items with no errors
* Module
* Addressed issue [#217](https://github.com/microsoft/Partner-Center-PowerShell/issues/217) that was impacting executing commands through Azure Automation
* Updated the transient error strategy for network operations
* When running any command with with the `Debug` parameter the request and response from the API will be written to the console in addition to any operation specific debug information
* Security
* Modified the [Get-PartnerUser](https://docs.microsoft.com/powershell/module/partnercenter/Get-PartnerUser) command to leverage a task scheduler for requesting from Microsoft Graph
* Modified the [Get-PartnerUserSignActivity](https://docs.microsoft.com/powershell/module/partnercenter/Get-PartnerUserSignActivity) command to leverage a task scheduler for requesting from Microsoft Graph
* Updated how [Test-PartnerSecurityRequirement](https://docs.microsoft.com/powershell/module/partnercenter/Test-PartnerSecurityRequirement) prompts for interaction
* Subscription
* Addressed an issue where the request for subscriptions by partner was causing an `InvalidCastException` to be thrown
* Corrected the output for the [Get-PartnerCustomerAzurePlanEntitlement](https://docs.microsoft.com/powershell/module/partnercenter/Get-PartnerCustomerAzurePlanEntitlement) command
* Validation
* Addressed a scenario where a `NullReferenceException` could be thrown when running the [Test-PartnerAddress](https://docs.microsoft.com/powershell/module/partnercenter/Test-PartnerAddress) command
## 2.0.1911.6 - November 2019
* Authentication
* Updated how [Connect-PartnerCenter](https://docs.microsoft.com/powershell/module/partnercenter/Connect-PartnerCenter) writes warnings during an authentication attempt
@ -28,13 +61,13 @@
* Azure
* Added the [Set-PartnerAzureSubscription](https://docs.microsoft.com/powershell/module/partnercenter/Set-PartnerAzureSubscription) command to update the display name of an Azure subscription provided through an Azure Plan
## 2.0.1911.5
## 2.0.1911.5 - November 2019
* Security
* Optimized the [Get-PartnerUser](https://docs.microsoft.com/powershell/module/partnercenter/Get-PartnerProductUpgrade) command
* Optimized the [Get-PartnerUserSignActivity](https://docs.microsoft.com/powershell/module/partnercenter/Get-PartnerUserSignActivity) command
## 2.0.1911.4
## 2.0.1911.4 - November 2019
* Azure
* Added the [Get-PartnerAzureBillingAccount](https://docs.microsoft.com/powershell/module/partnercenter/get-partnerazurebillingaccount) command to get billing accounts where the authenticated user has access
@ -44,19 +77,19 @@
* Updated the [Get-PartnerUser](https://docs.microsoft.com/powershell/module/partnercenter/Get-PartnerProductUpgrade) command to ensure all user accounts are returned
* Updated the [Get-PartnerUserSignActivity](https://docs.microsoft.com/powershell/module/partnercenter/Get-PartnerUserSignActivity) command to ensure all user sign-in activities are returned
## 2.0.1911.3
## 2.0.1911.3 - November 2019
* Authentication
* Addressed issue [#186](https://github.com/microsoft/Partner-Center-PowerShell/issues/186) that was preventing access token from being generated when using the device code flow
* Security
* Addressed issue preventing the [Test-PartnerSecurityRequirement](https://docs.microsoft.com/powershell/module/partnercenter/test-partnersecurityrequirement) command from working as expected
## 2.0.1911.2
## 2.0.1911.2 - November 2019
* Dependencies
* Addressed issues [#183](https://github.com/microsoft/Partner-Center-PowerShell/issues/181) and [#183](https://github.com/microsoft/Partner-Center-PowerShell/issues/183) caused by an assembly binding issue
## 2.0.1911.1
## 2.0.1911.1 - November 2019
* Authentication
* Addressed issue preventing CTRL+C from interrupting the waiting for a response during the interactive authentication scenario
@ -80,17 +113,17 @@
* Added the [Get-PartnerCustomerUsageRecord](https://docs.microsoft.com/powershell/module/partnercenter/Get-PartnerCustomerUsageRecord) command to get month usage records for all customers
* Removed the `Get-PartnerCustomerSubscriptionUsage` command due to changes with the Partner Center SDK for .NET. This command will be replaced with the [Get-PartnerCustomerSubscriptionMeterUsage](https://docs.microsoft.com/powershell/module/partnercenter/Get-PartnerCustomerSubscriptionMeterUsage) and [Get-PartnerCustomerSubscriptionResourceUsage](https://docs.microsoft.com/powershell/module/partnercenter/Get-PartnerCustomerSubscriptionResourceUsage) commands
## 2.0.1909.5
## 2.0.1909.5 - September 2019
* Dependency
* Corrected an issue that was preventing a dependency from being updated after a successful build
## 2.0.1909.4
## 2.0.1909.4 - September 2019
* Authentication
* Log events from the Microsoft Authentication Library (MSAL) will now be written to the console when the debug flag is set
## 2.0.1909.3
## 2.0.1909.3 - September 2019
* Authentication
* Address issue [#156](https://github.com/microsoft/Partner-Center-PowerShell/issues/156) where the refresh token was not being returned if it had not been previously used by the module during an interactive authentication attempt
@ -98,12 +131,12 @@
* Security
* Adding the [Test-PartnerSecurityRequirement](https://docs.microsoft.com/powershell/module/partnercenter/Test-PartnerSecurityRequirement) command to help validate that the authenticating account was challenged for multi-factor authentication
## 2.0.1909.2
## 2.0.1909.2 - September 2019
* Authentication
* Addressed issue [#153](https://github.com/microsoft/Partner-Center-PowerShell/issues/153) that was preventing the [New-PartnerAccessToken](https://docs.microsoft.com/powershell/module/partnercenter/New-PartnerAccessToken) command from working as expected.
## 2.0.1909.1
## 2.0.1909.1 - September 2019
* Agreements
* Added the [Get-PartnerAgreementTemplate](https://docs.microsoft.com/powershell/module/partnercenter/Get-PartnerAgreementTemplate) command to provide access to the links download or view the Microsoft Customer Agreement
@ -119,7 +152,7 @@
* Subscriptions
* Added the [New-PartnerCustomerSubscriptionActivation](https://docs.microsoft.com/powershell/module/partnercenter/Get-PartnerCustomerSubscriptionActivation) command to make it where third-party subscriptions can be activated in the integration sandbox
## 1.5.1908.1
## 1.5.1908.1 - August 2019
* Authentication
* Transitioned from Active Directory Authentication Library (ADAL) to the Microsoft Authentication Library (MSAL)
@ -127,33 +160,33 @@
* Added the [Get-PartnerRole](https://docs.microsoft.com/powershell/module/partnercenter/Get-PartnerRole) command to get partner roles
* Added the [Get-PartnerRoleMember](https://docs.microsoft.com/powershell/module/partnercenter/Get-PartnerRoleMember) command to get the members for the specified partner role
## 1.5.1907.2
## 1.5.1907.2 - July 2019
* Devices
* Modified the output for the [New-PartnerCustomerDeviceBatch](https://docs.microsoft.com/powershell/module/partnercenter/New-PartnerCustomerAgreement) command.
## 1.5.1907.1
## 1.5.1907.1 - July 2019
* Agreements
* Removed the *UserId* parameter from the [New-PartnerCustomerAgreement](https://docs.microsoft.com/powershell/module/partnercenter/New-PartnerCustomerAgreement) command
* Devices
* Addressed an issue preventing the successful creation of a device batch
## 1.5.1905.1
## 1.5.1905.1 - May 2019
* Users
* Added the following properties to the user model
* ImmutableId
* PhoneNumber
## 1.5.1904.3
## 1.5.1904.3 - April 2019
* Invoices
* Addressed issue [#117](https://github.com/Microsoft/Partner-Center-PowerShell/issues/117), where the cannot access stream error was being thrown
* Subscriptions
* Added breaking change warning for the removal the *AutoRenew* flag from the [Set-PartnerCustomerSubscription](https://docs.microsoft.com/powershell/module/partnercenter/set-partnercustomersubscription) command
## 1.5.1904.2
## 1.5.1904.2 - April 2019
* Authentication
* Addressed issue [#113](https://github.com/Microsoft/Partner-Center-PowerShell/issues/113), where the access token would expire for long running operations
@ -162,7 +195,7 @@
* Utilization
* Added the page size parameter to the Get-PartnerCustomerSubscriptionUtilization command
## 1.5.1904.1
## 1.5.1904.1 - April 2019
* Auditing
* Renamed the CreateInvoice operation type to ReadyInvoice
@ -173,12 +206,12 @@
* Utilization
* Modified the default end date value for the Get-PartnerCustomerSubscriptionUtilization command to use UTC time
## 1.5.1903.6
## 1.5.1903.6 - March 2019
* Products
* Addressed an issue with requesting products
## 1.5.1903.5
## 1.5.1903.5 - March 2019
* Auditing
* Added new operation and resource types
@ -238,7 +271,7 @@
* Validations
* Added the ability to request validation codes used to create Government Community Cloud customers
## Version 1.5.1902.5
## Version 1.5.1902.5 - February 2019
* Added the New-PartnerCustomerApplicationConsent command
* This command can be used to create a new application consent for the specified customer

Просмотреть файл

@ -20,9 +20,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{BE2D140E-5
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerShell.UnitTests", "test\PowerShell.UnitTests\PowerShell.UnitTests.csproj", "{08C08BAF-107D-43BB-9560-DA2D40B27816}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Billing", "src\Billing\Billing.csproj", "{C445D44E-EEB2-4B49-A862-0F0E292F9843}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Billing", "src\Billing\Billing.csproj", "{C445D44E-EEB2-4B49-A862-0F0E292F9843}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Subscription", "src\Subscription\Subscription.csproj", "{74A40D93-A16E-4823-A8A9-25EDFDF9886A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Subscription", "src\Subscription\Subscription.csproj", "{74A40D93-A16E-4823-A8A9-25EDFDF9886A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution

Просмотреть файл

@ -1,11 +1,11 @@
strategy:
matrix:
Linux:
imageName: 'ubuntu-16.04'
imageName: 'ubuntu-latest'
macOS:
imageName: 'macos-10.13'
imageName: 'macOS-latest'
Windows:
imageName: 'Windows-2019'
imageName: 'windows-latest'
trigger:
- master
@ -31,7 +31,14 @@ steps:
targetArgument: '$(Build.SourcesDirectory)'
result: 'PoliCheck.xml'
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
- task: UseDotNet@2
displayName: 'Use .NET Core 3.0'
inputs:
packageType: sdk
version: 3.0.x
installationPath: $(Agent.ToolsDirectory)/dotnet
- task: DotNetCoreCLI@2
displayName: Build
inputs:
@ -118,7 +125,7 @@ steps:
- task: DeleteFiles@1
displayName: Delete the code sign summary file
inputs:
SourceFolder: '_layout'
SourceFolder: '$(system.DefaultWorkingDirectory)'
Contents: '**\CodeSignSummary-*.md'
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), eq(variables['Build.SourceBranch'], 'refs/heads/master'))

Просмотреть файл

@ -68,7 +68,7 @@
<Target Name="Test">
<Message Importance="high" Text="Running unit tests..." />
<MakeDir Directories="$(TestOutputDirectory)" ContinueOnError="false" />
<Exec Command="dotnet test Partner-Center-PowerShell.sln --configuration $(Configuration) --framework netcoreapp2.2 --logger trx --results-directory &quot;$(TestOutputDirectory)&quot;" />
<Exec Command="dotnet test Partner-Center-PowerShell.sln --configuration $(Configuration) --framework netcoreapp3.0 --logger trx --results-directory &quot;$(TestOutputDirectory)&quot;" />
</Target>
<Target Name="ValidateModule">

Просмотреть файл

@ -2,7 +2,7 @@
<package>
<metadata>
<id>PartnerCenter</id>
<version>2.0.1911.6</version>
<version>3.0.0</version>
<authors>Microsoft Corporation</authors>
<owners>Microsoft</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>

Просмотреть файл

@ -0,0 +1,79 @@
<!--
Please leave this section at the top of the breaking change documentation.
New breaking changes should go under the section titled "Current Breaking Changes", and should adhere to the following format:
# Current Breaking Changes
## Release X.0.0 - January 2017
The following cmdlets were affected by this release:
**Cmdlet 1**
- Description of what has changed
```powershell
# Old
# Sample of how the cmdlet was previously called
# New
# Sample of how the cmdlet should now be called
```
-->
# Current Breaking Changes
## Release 3.0.0 - December 2019
* Subscription
* [Get-PartnerCustomerAzurePlanEntitlement](https://docs.microsoft.com/powershell/module/partnercenter/Get-PartnerCustomerAzurePlanEntitlement) output has changed
```output
# Old
ContinuationToken :
Items : {9681cddd-4b96-4d67-96e5-399a827d5375}
TotalCount : 1
Links : Microsoft.Store.PartnerCenter.Models.StandardResourceCollectionLinks
Attributes : Microsoft.Store.PartnerCenter.Models.ResourceAttributes
# New
FriendlyName Id Status SubscriptionId
------------ -- ------ --------------
Microsoft Azure 9681cddd-4b96-4d67-96e5-399a827d5375 active 0d066578-66b7-40f6-afad-6e179df3ad80
```
* [New-PartnerAzureSubscription](https://docs.microsoft.com/powershell/module/partnercenter/Neew-PartnerAzureSubscription) the `CustomerName` parameter will be replaced by the `CustomerId` parameter starting wth version 3.0.1
```powershell
# Old
New-PartnerAzureSubscription -BillingAccountName '99a13315-xxxx-xxxx-xxxx-xxxxxxxxxxxx:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_xxxx-xx-xx' -CustomerName 'Contoso' -DisplayName 'Microsoft Azure'
# New
New-PartnerAzureSubscription -BillingAccountName '99a13315-xxxx-xxxx-xxxx-xxxxxxxxxxxx:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_xxxx-xx-xx' -CustomerId '1e5a6ab0-e5ef-4f4e-a208-399e792b5ed4' -DisplayName 'Microsoft Azure'
```
## Release 2.0.1910.1 - October 2019
* Usage
* Removed the `Get-PartnerCustomerSubscriptionUsage` command due to changes with the Partner Center SDK for .NET. This command will be replaced with the [Get-PartnerCustomerSubscriptionMeterUsage](https://docs.microsoft.com/powershell/module/partnercenter/Get-PartnerCustomerSubscriptionMeterUsage) and [Get-PartnerCustomerSubscriptionResourceUsage](https://docs.microsoft.com/powershell/module/partnercenter/Get-PartnerCustomerSubscriptionResourceUsage) commands
## Release 2.0.1909.1 - September 2019
* Authentication
* Environments have been renamed to match the Azure PowerShell module. The new values are: *AzureChinaCloud*, *AzureCloud*, *AzureGermanCloud*, *AzurePPE*, and *AzureUSGovernment*
* Replaced the `Consent` parameter with the `UseAuthorizationCode` parameter for the `New-PartnerAccessToken` cmdlet
* Replaced the `Resource` parameter with the `Scopes` parameter for the `Connect-PartnerCenter` and `New-PartnerAccessToken` cmdlets
* ServicePrincipal parameter is now required when using a confidential client with the `Connect-PartnerCenter` and `New-PartnerAccessToken` cmdlets
* When using the [New-PartnerAccessToken](https://docs.microsoft.com/powershell/module/partnercenter/new-partneraccesstoken) command and the `UseAuthorizationCode` parameter you will be prompted to authentication interactively using the authorization code flow. The redirect URI value will generated dynamically. This generation process will attempt to find a port between 8400 and 8999 that is not in use. Once an available port has been found, the redirect URL value will be constructed (e.g. <http://localhost:8400>). So, it is important that you have configured the redirect URI value for your Azure Active Directory application accordingly.
* Module
* The `PartnerCenter` module now supports PowerShell 5.1 and PowerShell, as a result the `PartnerCenter.NetCore` module will be retired
## Release 1.5.1906.1 - June 2019
* Agreements
* The *UserId* parameter will be removed from the [New-PartnerCustomerAgreement](https://docs.microsoft.com/powershell/module/partnercenter/new-partnercustomeragreement) command. Enhancements to the API have been to derive this value based on the authenticated user
## Release 1.5.1905.1 - May 2019
* Subscriptions
* The *AutoRenew* flag will be removed from the [Set-PartnerCustomerSubscription](https://docs.microsoft.com/powershell/module/partnercenter/set-partnercustomersubscription) command

Просмотреть файл

@ -68,16 +68,14 @@ PS C:\> Connect-PartnerCenter -Credential $credential -Tenant 'xxxx-xxxx-xxxx-xx
The first command gets the service principal credentials (application identifier and service principal secret), and then stores them in the $credential variable. The second command connects to Partner Center using the service principal credentials stored in $credential for the specified Tenant. The ServicePrincipal switch parameter indicates that the account authenticates as a service principal.
### Example 3: Connect to Partner using an access token
### Example 3: Connect to Partner using a refresh token
```powershell
PS C:\> $credential = Get-Credential
PS C:\> $refreshToken = '<refreshToken>'
PS C:\> $token = New-PartnerAccessToken -ApplicationId 'xxxx-xxxx-xxxx-xxxx' -Credential $credential -RefreshToken $refreshToken -Scopes "https://api.partnercenter.microsoft.com/user_impersonation" -Tenant 'xxxx-xxxx-xxxx-xxxx'
PS C:\> Connect-PartnerCenter -AccessToken $token.AccessToken
PS C:\> Connect-PartnerCenter -ApplicationId 'xxxx-xxxx-xxxx-xxxx' -RefreshToken $refreshToken
```
The first command gets the service principal credentials (application identifier and service principal secret), and then stores them in the $credential variable. The third command generates a new access token using the specified refresh token. The final command connects to Partner Center using the access token stored in $token.AccessToken for authentication. The ServicePrincipal switch parameter indicates that the refresh token was generated using a confidential client.
Connects to Partner Center using a refresh token.
## PARAMETERS

Просмотреть файл

@ -0,0 +1,91 @@
---
content_git_url: https://github.com/Microsoft/Partner-Center-PowerShell/blob/master/docs/help/Get-PartnerAgreementStatus.md
external help file: Microsoft.Store.PartnerCenter.PowerShell.dll-Help.xml
Module Name: PartnerCenter
online version: https://docs.microsoft.com/powershell/module/partnercenter/Get-PartnerAgreementStatus
original_content_git_url: https://github.com/Microsoft/Partner-Center-PowerShell/blob/master/docs/help/Get-PartnerAgreementStatus.md
schema: 2.0.0
---
# Get-PartnerAgreementStatus
## SYNOPSIS
Gets the status of acceptance of the Microsoft Partner Agreement for the specified partner.
## SYNTAX
### ByTenantId (Default)
```powershell
Get-PartnerAgreementStatus [-TenantId] <String> [<CommonParameters>]
```
### ByMpnId
```powershell
Get-PartnerAgreementStatus [-MpnId] <String> [<CommonParameters>]
```
## DESCRIPTION
Gets the status of acceptance of the Microsoft Partner Agreement for the specified partner.
## EXAMPLES
### Example 1
```powershell
PS C:\> Get-PartnerAgreementStatus -MpnId '999999'
```
Gets the status of acceptance of the Microsoft Partner Agreement for the specified partner.
### Example 2
```powershell
PS C:\> Get-PartnerAgreementStatus -TenantId 'd96a841d-1672-4175-a878-df65b98a8550'
```
Gets the status of acceptance of the Microsoft Partner Agreement for the specified partner.
## PARAMETERS
### -MpnId
The Microsoft Partner Network (MPN) identifier for the partner.
```yaml
Type: String
Parameter Sets: ByMpnId
Aliases:
Required: True
Position: 0
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -TenantId
The tenant identifier for the partner.
```yaml
Type: String
Parameter Sets: ByTenantId
Aliases:
Required: True
Position: 0
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).
## INPUTS
### None
## OUTPUTS
### Microsoft.Store.PartnerCenter.Models.Compliance.AgreementSignatureStatus
## NOTES
## RELATED LINKS

Просмотреть файл

@ -0,0 +1,78 @@
---
content_git_url: https://github.com/Microsoft/Partner-Center-PowerShell/blob/master/docs/help/Get-PartnerAzureBillingPolicy.md
external help file: Microsoft.Store.PartnerCenter.PowerShell.dll-Help.xml
Module Name: PartnerCenter
online version: https://docs.microsoft.com/powershell/module/partnercenter/Get-PartnerAzureBillingPolicy
original_content_git_url: https://github.com/Microsoft/Partner-Center-PowerShell/blob/master/docs/help/Get-PartnerAzureBillingPolicy.md
schema: 2.0.0
---
# Get-PartnerAzureBillingPolicy
## SYNOPSIS
Gets the billing policy for the specified customer.
## SYNTAX
```powershell
Get-PartnerAzureBillingPolicy -BillingAccountName <String> -CustomerId <String> [<CommonParameters>]
```
## DESCRIPTION
Gets the billing policy for the specified customer.
## EXAMPLES
### Example 1
```powershell
PS C:\> Get-PartnerAzureBillingPolicy -BillingAccountName '99a13315-xxxx-xxxx-xxxx-xxxxxxxxxxxx:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_xxxx-xx-xx' -CustomerId '7b93c1be-57f6-4d8c-9270-e9b97c071557'
```
Gets the billing policy for the specified customer.
## PARAMETERS
### -BillingAccountName
The name for the billing account.
```yaml
Type: String
Parameter Sets: (All)
Aliases:
Required: True
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -CustomerId
The identifier for the customer.
```yaml
Type: String
Parameter Sets: (All)
Aliases:
Required: True
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).
## INPUTS
### None
## OUTPUTS
### Microsoft.Azure.Management.Billing.Models.CustomerPolicy
## NOTES
## RELATED LINKS

Просмотреть файл

@ -71,7 +71,7 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## OUTPUTS
### Microsoft.Store.PartnerCenter.Models.Subscriptions.AzureEntitlement
### Microsoft.Store.PartnerCenter.PowerShell.Models.Subscriptions.PSAzureEntitlement
## NOTES

Просмотреть файл

@ -14,11 +14,18 @@ Gets the line items for the specified invoice.
## SYNTAX
### ByInvoice (Default)
```powershell
Get-PartnerInvoiceLineItem -BillingProvider <BillingProvider> [-CurrencyCode <String>] -InvoiceId <String>
-LineItemType <InvoiceLineItemType> [<CommonParameters>]
```
### ByBillingPeriod
```powershell
Get-PartnerInvoiceLineItem -BillingProvider <BillingProvider> [-CurrencyCode <String>] -InvoiceId <String>
-LineItemType <InvoiceLineItemType> -Period <BillingPeriod> [<CommonParameters>]
```
## DESCRIPTION
Gets the line items for the specified invoice.
@ -40,7 +47,7 @@ The billing provide for the line items.
Type: BillingProvider
Parameter Sets: (All)
Aliases:
Accepted values: Azure, Office, OneTime, Marketplace
Accepted values: All, Azure, Office, OneTime, Marketplace
Required: True
Position: Named
@ -95,6 +102,22 @@ Accept pipeline input: False
Accept wildcard characters: False
```
### -Period
The billing period for the line items.
```yaml
Type: BillingPeriod
Parameter Sets: ByBillingPeriod
Aliases:
Accepted values: Current, Previous
Required: True
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).

Просмотреть файл

@ -14,11 +14,18 @@ Creates a new Azure subscription for Microsoft Partner Agreement billing account
## SYNTAX
### ByCustomerName (Default)
```powershell
New-PartnerAzureSubscription -BillingAccountName <String> -CustomerName <String> -DisplayName <String>
[-ResellerId <String>] [<CommonParameters>]
```
### ByCustomerId
```powershell
New-PartnerAzureSubscription -BillingAccountName <String> -CustomerId <String> -DisplayName <String>
[-ResellerId <String>] [<CommonParameters>]
```
## DESCRIPTION
Creates a new Azure subscription for Microsoft Partner Agreement billing account.
@ -26,7 +33,7 @@ Creates a new Azure subscription for Microsoft Partner Agreement billing account
### Example 1
```powershell
PS C:\> New-PartnerAzureSubscription -BillingAccountName '99a13315-xxxx-xxxx-xxxx-xxxxxxxxxxxx:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_xxxx-xx-xx' -CustomerName 'Contoso' -DisplayName 'Microsoft Azure'
PS C:\> New-PartnerAzureSubscription -BillingAccountName '99a13315-xxxx-xxxx-xxxx-xxxxxxxxxxxx:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_xxxx-xx-xx' -CustomerId 'cb20b9f1-d3e8-4dad-9d4f-5e4c92baed92' -DisplayName 'Microsoft Azure'
```
Creates a new Azure subscription for Microsoft Partner Agreement billing account.
@ -48,12 +55,27 @@ Accept pipeline input: False
Accept wildcard characters: False
```
### -CustomerId
The identifier for the customer.
```yaml
Type: String
Parameter Sets: ByCustomerId
Aliases:
Required: True
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -CustomerName
The name for the customer.
```yaml
Type: String
Parameter Sets: (All)
Parameter Sets: ByCustomerName
Aliases:
Required: True

Просмотреть файл

@ -10,7 +10,7 @@ schema: 2.0.0
# New-PartnerCustomerCart
## SYNOPSIS
Creates an order for a customer.
Creates a cart for a customer.
## SYNTAX
@ -20,12 +20,32 @@ New-PartnerCustomerCart -CustomerId <String> -LineItems <PSCartLineItem[]> [-Wha
```
## DESCRIPTION
Creates an order for a customer.
Creates a cart for a customer.
## EXAMPLES
### Example 1
```powershell
PS C:\> # Get the product information for the Azure Plan
PS C:\> $product = Get-PartnerProduct -ProductId 'DZH318Z0BPS6'
PS C:\> # Get the SKU information for the Azure Plan
PS C:\> $sku = Get-PartnerProductSku -ProductId $product.ProductId
PS C:\> # Get the availability information required for purchasing an Azure Plan
PS C:\> $availability = Get-PartnerProductAvailability -ProductId $product.ProductId -SkuId $sku.SkuId
PS C:\>
PS C:\> $lineItem = New-Object -TypeName Microsoft.Store.PartnerCenter.PowerShell.Models.Carts.PSCartLineItem
PS C:\>
PS C:\> $lineItem.BillingCycle = 'OneTime'
PS C:\> $lineItem.CatalogItemId = $availability.CatalogItemId
PS C:\> $lineItem.Quantity = 1
PS C:\>
PS C:\> New-PartnerCustomerCart -CustomerId '46a62ece-10ad-42e5-b3f1-b2ed53e6fc08' -LineItems $lineItem
```
Creates a cart for the specified with a line item to purchase an Azure Plan
### Example 2
```powershell
PS C:\> $lineItem = New-Object -TypeName Microsoft.Store.PartnerCenter.PowerShell.Models.Carts.PSCartLineItem
PS C:\>
PS C:\> $lineItem.BillingCycle = 'OneTime'
@ -39,7 +59,7 @@ PS C:\>
PS C:\> New-PartnerCustomerCart -CustomerId '46a62ece-10ad-42e5-b3f1-b2ed53e6fc08' -LineItems $lineItem
```
Creates an order for a customer.
Creates an cart for a customer.
## PARAMETERS

Просмотреть файл

@ -29,12 +29,18 @@ Gets the agreement metadata for the Microsoft Cloud Agreement.
### [Get-PartnerAgreementDocument](Get-PartnerAgreementDocument.md)
Gets the links to download or view the Microsoft Customer Agreement template.
### [Get-PartnerAgreementStatus](Get-PartnerAgreementStatus.md)
Gets the status of acceptance of the Microsoft Partner Agreement for the specified partner.
### [Get-PartnerAuditRecord](Get-PartnerAuditRecord.md)
Gets audit records from Partner Center.
### [Get-PartnerAzureBillingAccount](Get-PartnerAzureBillingAccount.md)
Gets the billing accounts where the authenticated user has access.
### [Get-PartnerAzureBillingPolicy](Get-PartnerAzureBillingPolicy.md)
Gets the billing policy for the specified customer.
### [Get-PartnerAzureBillingProfile](Get-PartnerAzureBillingProfile.md)
Gets the billing profiles for specified billing account.
@ -308,6 +314,9 @@ Display detailed information about PowerShell errors, with extended details for
### [Restore-PartnerCustomerUser](Restore-PartnerCustomerUser.md)
Restores a previously removed customer user from the customer's tenant.
### [Set-PartnerAzureBillingPolicy](Set-PartnerAzureBillingPolicy.md)
Updates the billing policy for the specified customer.
### [Set-PartnerAzureSubscription](Set-PartnerAzureSubscription.md)
Updates an Azure subscription that is part of an Azure Plan.
@ -361,4 +370,3 @@ Tests if the specified domain name is available for creating a new tenant.
### [Test-PartnerSecurityRequirement](Test-PartnerSecurityRequirement.md)
Tests the account, used during authentication, if multi-factor authentication was enforced.

Просмотреть файл

@ -0,0 +1,101 @@
---
content_git_url: https://github.com/Microsoft/Partner-Center-PowerShell/blob/master/docs/help/Set-PartnerAzureBillingPolicy.md
external help file: Microsoft.Store.PartnerCenter.PowerShell.dll-Help.xml
Module Name: PartnerCenter
online version: https://docs.microsoft.com/powershell/module/partnercenter/Set-PartnerAzureBillingPolicy
original_content_git_url: https://github.com/Microsoft/Partner-Center-PowerShell/blob/master/docs/help/Set-PartnerAzureBillingPolicy.md
schema: 2.0.0
---
# Set-PartnerAzureBillingPolicy
## SYNOPSIS
Updates the billing policy for the specified customer.
## SYNTAX
```powershell
Set-PartnerAzureBillingPolicy -BillingAccountName <String> -CustomerId <String> [-ViewCharges]
[<CommonParameters>]
```
## DESCRIPTION
Updates the billing policy for the specified customer.
## EXAMPLES
### Example 1
```powershell
PS C:\> Set-PartnerAzureBillingPolicy -BillingAccountName '99a13315-xxxx-xxxx-xxxx-xxxxxxxxxxxx:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_xxxx-xx-xx' -CustomerId '7b93c1be-57f6-4d8c-9270-e9b97c071557' -ViewCharges:$true
```
Enables the view charges feature which allows the customer to see retail pricing for Azure services.
### Example 2
```powershell
PS C:\> Set-PartnerAzureBillingPolicy -BillingAccountName '99a13315-xxxx-xxxx-xxxx-xxxxxxxxxxxx:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_xxxx-xx-xx' -CustomerId '7b93c1be-57f6-4d8c-9270-e9b97c071557' -ViewCharges:$false
```
Disables the view charges feature which allows the customer to see retail pricing for Azure services.
## PARAMETERS
### -BillingAccountName
The name for the billing account.
```yaml
Type: String
Parameter Sets: (All)
Aliases:
Required: True
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -CustomerId
The identifier for the customer.
```yaml
Type: String
Parameter Sets: (All)
Aliases:
Required: True
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -ViewCharges
A flag that indicates whether or not the customer can view charges for Azure services.
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:
Required: True
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).
## INPUTS
### None
## OUTPUTS
### Microsoft.Azure.Management.Billing.Models.CustomerPolicy
## NOTES
## RELATED LINKS

Просмотреть файл

@ -64,7 +64,7 @@ Accept wildcard characters: False
```
### -SubscriptionName
The display name for the subscription..
The display name for the subscription.
```yaml
Type: String

Просмотреть файл

@ -16,7 +16,7 @@ Tests whether or not the specified address is valid.
```powershell
Test-PartnerAddress -AddressLine1 <String> [-AddressLine2 <String>] [-City <String>] [-Country <String>]
-PostalCode <String> [-Region <String>] [-State <String>] [-WhatIf] [-Confirm] [<CommonParameters>]
[-PostalCode <String>] [-Region <String>] [-State <String>] [<CommonParameters>]
```
## DESCRIPTION
@ -101,7 +101,7 @@ Type: String
Parameter Sets: (All)
Aliases:
Required: True
Required: False
Position: Named
Default value: None
Accept pipeline input: False
@ -138,37 +138,6 @@ Accept pipeline input: False
Accept wildcard characters: False
```
### -Confirm
Prompts you for confirmation before running the cmdlet.
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases: cf
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -WhatIf
Shows what would happen if the cmdlet runs.
The cmdlet is not run.
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases: wi
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).

Просмотреть файл

@ -23,6 +23,35 @@
# Upcoming Breaking Changes
## Release 3.0.0 - December 2019
* Subscription
* [Get-PartnerCustomerAzurePlanEntitlement](https://docs.microsoft.com/powershell/module/partnercenter/Get-PartnerCustomerAzurePlanEntitlement) output has changed
```output
# Old
ContinuationToken :
Items : {9681cddd-4b96-4d67-96e5-399a827d5375}
TotalCount : 1
Links : Microsoft.Store.PartnerCenter.Models.StandardResourceCollectionLinks
Attributes : Microsoft.Store.PartnerCenter.Models.ResourceAttributes
# New
FriendlyName Id Status SubscriptionId
------------ -- ------ --------------
Microsoft Azure 9681cddd-4b96-4d67-96e5-399a827d5375 active 0d066578-66b7-40f6-afad-6e179df3ad80
```
* [New-PartnerAzureSubscription](https://docs.microsoft.com/powershell/module/partnercenter/Neew-PartnerAzureSubscription) the `CustomerName` parameter will be replaced by the `CustomerId` parameter starting wth version 3.0.1
```powershell
# Old
New-PartnerAzureSubscription -BillingAccountName '99a13315-xxxx-xxxx-xxxx-xxxxxxxxxxxx:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_xxxx-xx-xx' -CustomerName 'Contoso' -DisplayName 'Microsoft Azure'
# New
New-PartnerAzureSubscription -BillingAccountName '99a13315-xxxx-xxxx-xxxx-xxxxxxxxxxxx:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_xxxx-xx-xx' -CustomerId '1e5a6ab0-e5ef-4f4e-a208-399e792b5ed4' -DisplayName 'Microsoft Azure'
```
## Release 2.0.1910.1 - October 2019
* Usage

Просмотреть файл

@ -28,7 +28,7 @@ namespace Microsoft.Azure.Management.Billing
/// </param>
public static BillingProperty Get(this IBillingPropertyOperations operations)
{
return operations.GetAsync().GetAwaiter().GetResult();
return operations.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
/// <summary>

Просмотреть файл

@ -27,7 +27,7 @@ namespace Microsoft.Azure.Management.Billing
/// </param>
public static LineOfCredit Get(this ILineOfCreditsOperations operations)
{
return operations.GetAsync().GetAwaiter().GetResult();
return operations.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
/// <summary>

Просмотреть файл

@ -28,7 +28,7 @@ namespace Microsoft.Azure.Management.Billing
/// </param>
public static IPage<Operation> List(this IOperations operations)
{
return operations.ListAsync().GetAwaiter().GetResult();
return operations.ListAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
/// <summary>

Просмотреть файл

@ -178,7 +178,7 @@ namespace Microsoft.Azure.Management.Billing
/// </param>
public static IPage<RecipientTransferDetails> List(this IRecipientTransfersOperations operations)
{
return operations.ListAsync().GetAwaiter().GetResult();
return operations.ListAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
/// <summary>

Просмотреть файл

@ -4,11 +4,17 @@
namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
{
using System;
using System.Linq;
using System.Management.Automation;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Extensions;
using Identity.Client;
using IdentityModel.JsonWebTokens;
using Models.Authentication;
using PartnerCenter.Exceptions;
using Rest;
/// <summary>
/// Provides the ability to authenticate using an access token.
@ -19,33 +25,48 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
/// Apply this authenticator to the given authentication parameters.
/// </summary>
/// <param name="parameters">The complex object containing authentication specific information.</param>
/// <param name="promptAction">The action used to prompt for interaction.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <returns>
/// An instance of <see cref="AuthenticationResult" /> that represents the access token generated as result of a successful authenication.
/// </returns>
public override async Task<AuthenticationResult> AuthenticateAsync(AuthenticationParameters parameters, Action<string> promptAction = null, CancellationToken cancellationToken = default)
public override async Task<AuthenticationResult> AuthenticateAsync(AuthenticationParameters parameters, CancellationToken cancellationToken = default)
{
AccessTokenParameters accessTokenParameters = parameters as AccessTokenParameters;
JsonWebToken jwt = new JsonWebToken(accessTokenParameters.AccessToken);
JsonWebToken token;
string value;
if (DateTimeOffset.UtcNow > jwt.ValidTo)
if (parameters.Scopes.Contains($"{parameters.Environment.PartnerCenterEndpoint}/user_impersonation"))
{
value = parameters.Account.GetProperty(PartnerAccountPropertyType.AccessToken);
}
else
{
throw new PSInvalidOperationException("This operation is not supported when you connect using an access token. Please connect interactively or using a refresh token.");
}
token = new JsonWebToken(value);
ServiceClientTracing.Information($"[AccessTokenAuthenticator] The specified access token expires at {token.ValidTo}");
if (DateTimeOffset.UtcNow > token.ValidTo)
{
throw new PartnerException("The access token has expired. Generate a new one and try again.");
}
await Task.CompletedTask;
ServiceClientTracing.Information("[AccessTokenAuthenticator] Constructing the authentication result based on the specified access token");
return new AuthenticationResult(
accessTokenParameters.AccessToken,
value,
false,
null,
jwt.ValidTo,
jwt.ValidTo,
parameters.Account.Tenant,
token.ValidTo,
token.ValidTo,
token.GetClaim("tid").Value,
GetAccount(token),
null,
null,
parameters.Scopes);
parameters.Scopes,
Guid.Empty);
}
/// <summary>
@ -57,5 +78,28 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
{
return parameters is AccessTokenParameters;
}
private IAccount GetAccount(JsonWebToken token)
{
token.AssertNotNull(nameof(token));
token.TryGetClaim("upn", out Claim claim);
if (claim != null)
{
ServiceClientTracing.Information($"[AccessTokenAuthenticator] The UPN claim value is {claim.Value}");
ServiceClientTracing.Information($"[AccessTokenAuthenticator] Constructing the resource account value based on specified access token");
return new ResourceAccount(
"login.microsoftonline.com",
$"{token.GetClaim("oid").Value}.{token.GetClaim("tid")}",
token.GetClaim("oid").Value,
token.GetClaim("tid").Value,
claim.Value);
}
ServiceClientTracing.Information("[AccessTokenAuthenticator] The UPN claim is not present in the access token.");
return null;
}
}
}

Просмотреть файл

@ -4,7 +4,6 @@
namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
{
using System.Collections.Generic;
using Extensions;
using Models.Authentication;
/// <summary>
@ -19,10 +18,5 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
: base(account, environment, scopes)
{
}
/// <summary>
/// Gets the access token.
/// </summary>
public string AccessToken => Account.GetProperty(PartnerAccountPropertyType.AccessToken);
}
}

Просмотреть файл

@ -4,6 +4,7 @@
namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
{
using System.Collections.Generic;
using Extensions;
using Models.Authentication;
/// <summary>
@ -16,6 +17,10 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
/// </summary>
protected AuthenticationParameters(PartnerAccount account, PartnerEnvironment environment, IEnumerable<string> scopes)
{
account.AssertNotNull(nameof(account));
environment.AssertNotNull(nameof(environment));
scopes.AssertNotNull(nameof(scopes));
Account = account;
Environment = environment;
Scopes = scopes;

Просмотреть файл

@ -3,7 +3,6 @@
namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
{
using System;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
@ -26,12 +25,11 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
/// Apply this authenticator to the given authentication parameters.
/// </summary>
/// <param name="parameters">The complex object containing authentication specific information.</param>
/// <param name="promptAction">The action used to prompt for interaction.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <returns>
/// An instance of <see cref="AuthenticationResult" /> that represents the access token generated as result of a successful authenication.
/// </returns>
public abstract Task<AuthenticationResult> AuthenticateAsync(AuthenticationParameters parameters, Action<string> promptAction, CancellationToken cancellationToken = default);
public abstract Task<AuthenticationResult> AuthenticateAsync(AuthenticationParameters parameters, CancellationToken cancellationToken = default);
/// <summary>
/// Determine if this authenticator can apply to the given authentication parameters.
@ -129,25 +127,21 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
/// </summary>
/// <param name="parameters">The complex object containing authentication specific information.</param>
/// <param name="token">The token based authentication information.</param>
/// <param name="promptAction">The action used to prompt for interaction.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <returns><c>true</c> if the request can be authenticated; otherwise <c>false</c>.</returns>
public bool TryAuthenticate(AuthenticationParameters parameters, out Task<AuthenticationResult> token, Action<string> promptAction = null, CancellationToken cancellationToken = default)
public async Task<AuthenticationResult> TryAuthenticateAsync(AuthenticationParameters parameters, CancellationToken cancellationToken = default)
{
token = null;
if (CanAuthenticate(parameters))
{
token = AuthenticateAsync(parameters, promptAction, cancellationToken);
return true;
return await AuthenticateAsync(parameters, cancellationToken).ConfigureAwait(false);
}
if (Next != null)
{
return Next.TryAuthenticate(parameters, out token, promptAction, cancellationToken);
return await Next.TryAuthenticateAsync(parameters, cancellationToken).ConfigureAwait(false);
}
return false;
return null;
}
}
}

Просмотреть файл

@ -8,52 +8,33 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
using System.Threading.Tasks;
using Extensions;
using Identity.Client;
using Models;
using Models.Authentication;
using Rest;
/// <summary>
/// Provides the ability to authenticate using the device code flow.
/// </summary>
internal class DeviceCodeAuthenticator : DelegatingAuthenticator
{
/// <summary>
/// The message that will be written utilizing the prompt action.
/// </summary>
private string message;
/// <summary>
/// Apply this authenticator to the given authentication parameters.
/// </summary>
/// <param name="parameters">The complex object containing authentication specific information.</param>
/// <param name="promptAction">The action used to prompt for interaction.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <returns>
/// An instance of <see cref="AuthenticationToken" /> that represents the access token generated as result of a successful authenication.
/// </returns>
public override async Task<AuthenticationResult> AuthenticateAsync(AuthenticationParameters parameters, Action<string> promptAction = null, CancellationToken cancellationToken = default)
public override async Task<AuthenticationResult> AuthenticateAsync(AuthenticationParameters parameters, CancellationToken cancellationToken = default)
{
IPublicClientApplication app = GetClient(parameters.Account, parameters.Environment).AsPublicClient();
Task<AuthenticationResult> task = Task<AuthenticationResult>.Factory.StartNew(() =>
app.AcquireTokenWithDeviceCode(parameters.Scopes, deviceCodeResult =>
{
message = deviceCodeResult.Message;
return Task.CompletedTask;
}).ExecuteAsync(cancellationToken).GetAwaiter().GetResult());
while (true)
ServiceClientTracing.Information($"[DeviceCodeAuthenticator] Calling AcquireTokenWithDeviceCode - Scopes: '{string.Join(", ", parameters.Scopes)}'");
return await app.AcquireTokenWithDeviceCode(parameters.Scopes, deviceCodeResult =>
{
if (!string.IsNullOrEmpty(message))
{
promptAction(message);
break;
}
cancellationToken.ThrowIfCancellationRequested();
Thread.Sleep(1000);
}
await Task.CompletedTask;
return task.Result;
WriteWarning(deviceCodeResult.Message);
return Task.CompletedTask;
}).ExecuteAsync(cancellationToken).ConfigureAwait(false);
}
/// <summary>
@ -65,5 +46,13 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
{
return parameters is DeviceCodeParameters;
}
private void WriteWarning(string message)
{
if (PartnerSession.Instance.TryGetComponent("WriteWarning", out EventHandler<StreamEventArgs> writeWarningEvent))
{
writeWarningEvent(this, new StreamEventArgs { Resource = message });
}
}
}
}

Просмотреть файл

@ -3,7 +3,6 @@
namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
{
using System;
using System.Threading;
using System.Threading.Tasks;
using Identity.Client;
@ -22,28 +21,29 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
/// Apply this authenticator to the given authentication parameters.
/// </summary>
/// <param name="parameters">The complex object containing authentication specific information.</param>
/// <param name="promptAction">The action used to prompt for interaction.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <returns>
/// An instance of <see cref="AuthenticationToken" /> that represents the access token generated as result of a successful authenication.
/// </returns>
Task<AuthenticationResult> AuthenticateAsync(AuthenticationParameters parameters, Action<string> promptAction, CancellationToken cancellationToken = default);
Task<AuthenticationResult> AuthenticateAsync(AuthenticationParameters parameters, CancellationToken cancellationToken = default);
/// <summary>
/// Determine if this authenticator can apply to the given authentication parameters.
/// </summary>
/// <param name="parameters">The complex object containing authentication specific information.</param>
/// <returns><c>true</c> if this authenticator can apply; otherwise <c>false</c>.</returns>
/// <returns>
/// An instance of <see cref="AuthenticationToken" /> that represents the access token generated as result of a successful authenication.
/// </returns>
bool CanAuthenticate(AuthenticationParameters parameters);
/// <summary>
/// Determine if this request can be authenticated using the given authenticator, and authenticate if it can.
/// </summary>
/// <param name="parameters">The complex object containing authentication specific information.</param>
/// <param name="token">The token based authentication information.</param>
/// <param name="promptAction">The action used to prompt for interaction.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <returns><c>true</c> if the request can be authenticated; otherwise <c>false</c>.</returns>
bool TryAuthenticate(AuthenticationParameters parameters, out Task<AuthenticationResult> token, Action<string> promptAction = null, CancellationToken cancellationToken = default);
/// <returns>
/// An instance of <see cref="AuthenticationToken" /> that represents the access token generated as result of a successful authenication.
/// </returns>
Task<AuthenticationResult> TryAuthenticateAsync(AuthenticationParameters parameters, CancellationToken cancellationToken = default);
}
}

Просмотреть файл

@ -4,7 +4,6 @@
namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
{
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Net;
using System.Net.Sockets;
@ -14,7 +13,10 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
using Extensions;
using Identity.Client;
using Identity.Client.Extensibility;
using Models;
using Models.Authentication;
using Network;
using Rest;
/// <summary>
/// Provides the ability to authenticate using an interactive interface.
@ -25,23 +27,17 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
/// Apply this authenticator to the given authentication parameters.
/// </summary>
/// <param name="parameters">The complex object containing authentication specific information.</param>
/// <param name="promptAction">The action used to prompt for interaction.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <returns>
/// An instance of <see cref="AuthenticationResult" /> that represents the access token generated as result of a successful authenication.
/// </returns>
public override async Task<AuthenticationResult> AuthenticateAsync(AuthenticationParameters parameters, Action<string> promptAction = null, CancellationToken cancellationToken = default)
public override async Task<AuthenticationResult> AuthenticateAsync(AuthenticationParameters parameters, CancellationToken cancellationToken = default)
{
AuthenticationResult authResult;
IClientApplicationBase app;
InteractiveParameters interactiveParameters = parameters as InteractiveParameters;
Task<Task<AuthenticationResult>> task;
TcpListener listener = null;
int count = 0;
string redirectUri = null;
Queue<string> messages;
int port = 8399;
while (++port < 9000)
@ -56,62 +52,42 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
}
catch (Exception ex)
{
promptAction($"Port {port} is taken with exception '{ex.Message}'; trying to connect to the next port.");
WriteWarning($"Port {port} is taken with exception '{ex.Message}'; trying to connect to the next port.");
listener?.Stop();
}
}
app = GetClient(parameters.Account, parameters.Environment, redirectUri);
messages = new Queue<string>();
if (app is IConfidentialClientApplication)
{
ICustomWebUi customWebUi = new DefaultOsBrowserWebUi(messages, interactiveParameters.Message);
ICustomWebUi customWebUi = new DefaultOsBrowserWebUi(interactiveParameters.Message);
task = Task<Task<AuthenticationResult>>.Factory.StartNew(async () =>
{
Uri authCodeUrl = await customWebUi.AcquireAuthorizationCodeAsync(
await app.AsConfidentialClient().GetAuthorizationRequestUrl(parameters.Scopes).ExecuteAsync(cancellationToken).ConfigureAwait(false),
new Uri(redirectUri),
cancellationToken).ConfigureAwait(false);
ServiceClientTracing.Information($"[InteractiveUserAuthenticator] Calling AcquireAuthorizationCodeAsync - Scopes: '{string.Join(",", parameters.Scopes)}'");
NameValueCollection queryStringParameters = HttpUtility.ParseQueryString(authCodeUrl.Query);
Uri authCodeUrl = await customWebUi.AcquireAuthorizationCodeAsync(
await app.AsConfidentialClient().GetAuthorizationRequestUrl(parameters.Scopes).ExecuteAsync(cancellationToken).ConfigureAwait(false),
new Uri(redirectUri),
cancellationToken).ConfigureAwait(false);
return await app.AsConfidentialClient().AcquireTokenByAuthorizationCode(
parameters.Scopes,
queryStringParameters["code"]).ExecuteAsync(cancellationToken).ConfigureAwait(false);
});
NameValueCollection queryStringParameters = HttpUtility.ParseQueryString(authCodeUrl.Query);
ServiceClientTracing.Information($"[InteractiveUserAuthenticator] Calling AcquireTokenByAuthorizationCode - Scopes: '{string.Join(",", parameters.Scopes)}'");
authResult = await app.AsConfidentialClient().AcquireTokenByAuthorizationCode(
parameters.Scopes,
queryStringParameters["code"]).ExecuteAsync(cancellationToken).ConfigureAwait(false);
}
else
{
task = Task<Task<AuthenticationResult>>.Factory.StartNew(async () =>
{
return await app.AsPublicClient().AcquireTokenInteractive(parameters.Scopes)
.WithCustomWebUi(new DefaultOsBrowserWebUi(messages, interactiveParameters.Message))
.WithPrompt(Prompt.ForceLogin)
.ExecuteAsync(cancellationToken).ConfigureAwait(false);
});
ServiceClientTracing.Information(string.Format("[InteractiveUserAuthenticator] Calling AcquireTokenInteractive - Scopes: '{0}'", string.Join(",", parameters.Scopes)));
authResult = await app.AsPublicClient().AcquireTokenInteractive(parameters.Scopes)
.WithCustomWebUi(new DefaultOsBrowserWebUi(interactiveParameters.Message))
.WithPrompt(Prompt.ForceLogin)
.ExecuteAsync(cancellationToken).ConfigureAwait(false);
}
while (true)
{
while (messages.Count > 0)
{
promptAction(messages.Dequeue());
count++;
}
if (count >= 2)
{
break;
}
cancellationToken.ThrowIfCancellationRequested();
Thread.Sleep(1000);
}
authResult = await task.Result.ConfigureAwait(false);
return authResult;
}
@ -124,5 +100,13 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
{
return parameters is InteractiveParameters;
}
private void WriteWarning(string message)
{
if (PartnerSession.Instance.TryGetComponent("WriteWarning", out EventHandler<StreamEventArgs> writeWarningEvent))
{
writeWarningEvent(this, new StreamEventArgs { Resource = message });
}
}
}
}

Просмотреть файл

@ -3,12 +3,12 @@
namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
{
using System;
using System.Threading;
using System.Threading.Tasks;
using Extensions;
using Identity.Client;
using Models.Authentication;
using Rest;
/// <summary>
/// Provides the ability to authenticate using a refresh token.
@ -19,21 +19,24 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
/// Apply this authenticator to the given authentication parameters.
/// </summary>
/// <param name="parameters">The complex object containing authentication specific information.</param>
/// <param name="promptAction">The action used to prompt for interaction.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <returns>
/// An instance of <see cref="AuthenticationResult" /> that represents the access token generated as result of a successful authenication.
/// </returns>
public override async Task<AuthenticationResult> AuthenticateAsync(AuthenticationParameters parameters, Action<string> promptAction = null, CancellationToken cancellationToken = default)
public override async Task<AuthenticationResult> AuthenticateAsync(AuthenticationParameters parameters, CancellationToken cancellationToken = default)
{
IClientApplicationBase app = GetClient(parameters.Account, parameters.Environment);
ServiceClientTracing.Information("[RefreshTokenAuthenticator] Calling GetAccountsAysnc");
IAccount account = await app.GetAccountAsync(parameters.Account.Identifier).ConfigureAwait(false);
if (account != null)
{
ServiceClientTracing.Information($"[RefreshTokenAuthenticator] Calling AcquireTokenSilent - Scopes: '{string.Join(", ", parameters.Scopes)}'");
return await app.AcquireTokenSilent(parameters.Scopes, account).ExecuteAsync(cancellationToken).ConfigureAwait(false);
}
ServiceClientTracing.Information($"[RefreshTokenAuthenticator] Calling AcquireTokenByRefreshToken - Scopes: '{string.Join(", ", parameters.Scopes)}'");
return await app.AsRefreshTokenClient().AcquireTokenByRefreshToken(
parameters.Scopes,
parameters.Account.GetProperty(PartnerAccountPropertyType.RefreshToken)).ExecuteAsync(cancellationToken).ConfigureAwait(false);

Просмотреть файл

@ -3,7 +3,6 @@
namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
{
using System;
using System.Threading;
using System.Threading.Tasks;
using Extensions;
@ -18,12 +17,11 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
/// Apply this authenticator to the given authentication parameters.
/// </summary>
/// <param name="parameters">The complex object containing authentication specific information.</param>
/// <param name="promptAction">The action used to prompt for interaction.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <returns>
/// An instance of <see cref="AuthenticationResult" /> that represents the access token generated as result of a successful authenication.
/// </returns>
public override async Task<AuthenticationResult> AuthenticateAsync(AuthenticationParameters parameters, Action<string> promptAction, CancellationToken cancellationToken = default)
public override async Task<AuthenticationResult> AuthenticateAsync(AuthenticationParameters parameters, CancellationToken cancellationToken = default)
{
IConfidentialClientApplication app = GetClient(parameters.Account, parameters.Environment).AsConfidentialClient();

Просмотреть файл

@ -3,13 +3,13 @@
namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Extensions;
using Identity.Client;
using Rest;
/// <summary>
/// Provides the ability to authenticate non-interactively.
@ -20,17 +20,18 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
/// Apply this authenticator to the given authentication parameters.
/// </summary>
/// <param name="parameters">The complex object containing authentication specific information.</param>
/// <param name="promptAction">The action used to prompt for interaction.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <returns>
/// An instance of <see cref="AuthenticationResult" /> that represents the access token generated as result of a successful authenication.
/// </returns>
public override async Task<AuthenticationResult> AuthenticateAsync(AuthenticationParameters parameters, Action<string> promptAction = null, CancellationToken cancellationToken = default)
public override async Task<AuthenticationResult> AuthenticateAsync(AuthenticationParameters parameters, CancellationToken cancellationToken = default)
{
IPublicClientApplication app = GetClient(parameters.Account, parameters.Environment).AsPublicClient();
ServiceClientTracing.Information(string.Format("[SilentAuthenticator] Calling GetAccountsAsync"));
IEnumerable<IAccount> accounts = await app.GetAccountsAsync().ConfigureAwait(false);
ServiceClientTracing.Information($"[SilentAuthenticator] Calling AcquireTokenSilent - Scopes: '{string.Join(",", parameters.Scopes)}', UserId: '{((SilentParameters)parameters).UserId}', Number of accounts: '{accounts.Count()}'");
AuthenticationResult authResult = await app.AcquireTokenSilent(
parameters.Scopes,
accounts.FirstOrDefault(a => a.HomeAccountId.ObjectId.Equals(((SilentParameters)parameters).UserId)))

Просмотреть файл

@ -51,7 +51,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
if (ShouldProcess(string.Format(CultureInfo.CurrentCulture, Resources.AddPartnerCustomerCartLineItemWhatIf, CartId)))
{
cart = Partner.Customers[CustomerId].Carts[CartId].GetAsync().GetAwaiter().GetResult();
cart = Partner.Customers[CustomerId].Carts[CartId].GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
lineItems = cart.LineItems.ToList();
cartLineItem = new CartLineItem();

Просмотреть файл

@ -71,7 +71,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
customerId.AssertNotEmpty(nameof(customerId));
userId.AssertNotEmpty(nameof(userId));
return Partner.Customers[customerId].Users[userId].GetAsync().GetAwaiter().GetResult(); ;
return Partner.Customers[customerId].Users[userId].GetAsync().ConfigureAwait(false).GetAwaiter().GetResult(); ;
}
}

Просмотреть файл

@ -18,7 +18,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
[Cmdlet(VerbsCommunications.Connect, "PartnerCenter", DefaultParameterSetName = UserParameterSet, SupportsShouldProcess = true)]
[OutputType(typeof(PartnerContext))]
public class ConnectPartnerCenter : PartnerPSCmdlet, IModuleAssemblyInitializer
public class ConnectPartnerCenter : PartnerAsyncCmdlet, IModuleAssemblyInitializer
{
/// <summary>
/// The name of the access token parameter set.
@ -166,9 +166,9 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
}
/// <summary>
/// Performs the operations associated with the command.
/// Executes the operations associated with the cmdlet.
/// </summary>
protected override void ProcessRecord()
public override void ExecuteCmdlet()
{
IPartner partnerOperations;
OrganizationProfile profile;
@ -231,37 +231,38 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
$"{environment.AzureAdGraphEndpoint}/.default" :
$"{environment.PartnerCenterEndpoint}/user_impersonation");
account.Tenant = string.IsNullOrEmpty(Tenant) ? "common" : Tenant;
account.Tenant = string.IsNullOrEmpty(Tenant) ? "organizations" : Tenant;
PartnerSession.Instance.AuthenticationFactory.Authenticate(
account,
environment,
new[] { account.GetProperty(PartnerAccountPropertyType.Scope) },
Message,
WriteWarning,
WriteDebug,
CancellationToken);
PartnerSession.Instance.Context = new PartnerContext
Scheduler.RunTask(async () =>
{
Account = account,
Environment = environment
};
await PartnerSession.Instance.AuthenticationFactory.AuthenticateAsync(
account,
environment,
new[] { account.GetProperty(PartnerAccountPropertyType.Scope) },
Message,
CancellationToken).ConfigureAwait(false);
try
{
partnerOperations = PartnerSession.Instance.ClientFactory.CreatePartnerOperations();
profile = partnerOperations.Profiles.OrganizationProfile.GetAsync().GetAwaiter().GetResult();
PartnerSession.Instance.Context = new PartnerContext
{
Account = account,
Environment = environment
};
PartnerSession.Instance.Context.CountryCode = profile.DefaultAddress.Country;
PartnerSession.Instance.Context.Locale = profile.Culture;
}
catch (PartnerException)
{
/* This error can safely be ignored */
}
try
{
partnerOperations = PartnerSession.Instance.ClientFactory.CreatePartnerOperations();
profile = await partnerOperations.Profiles.OrganizationProfile.GetAsync().ConfigureAwait(false);
WriteObject(PartnerSession.Instance.Context);
PartnerSession.Instance.Context.CountryCode = profile.DefaultAddress.Country;
PartnerSession.Instance.Context.Locale = profile.Culture;
}
catch (PartnerException)
{
/* This error can safely be ignored */
}
WriteObject(PartnerSession.Instance.Context);
});
}
}
}

Просмотреть файл

@ -32,15 +32,15 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
if (string.IsNullOrEmpty(AgreementType))
{
agreements = Partner.AgreementDetails.GetAsync().GetAwaiter().GetResult();
agreements = Partner.AgreementDetails.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
else if (AgreementType.Equals("All", StringComparison.InvariantCultureIgnoreCase))
{
agreements = Partner.AgreementDetails.ByAgreementType("*").GetAsync().GetAwaiter().GetResult();
agreements = Partner.AgreementDetails.ByAgreementType("*").GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
else
{
agreements = Partner.AgreementDetails.ByAgreementType(AgreementType).GetAsync().GetAwaiter().GetResult();
agreements = Partner.AgreementDetails.ByAgreementType(AgreementType).GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
WriteObject(agreements.Items.Select(a => new PSAgreementMetaData(a)), true);

Просмотреть файл

@ -0,0 +1,35 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
{
using System.Management.Automation;
using System.Text.RegularExpressions;
using PartnerCenter.Models.Compliance;
[Cmdlet(VerbsCommon.Get, "PartnerAgreementStatus", DefaultParameterSetName = "ByTenantId")]
[OutputType(typeof(AgreementSignatureStatus))]
public class GetPartnerAgreementStatus : PartnerCmdlet
{
/// <summary>
/// Gets or sets the Microsoft Partner Network (MPN) identifier.
/// </summary>
[Parameter(HelpMessage = "The Microsoft Partner Network (MPN) identifier for the partner.", Mandatory = true, ParameterSetName = "ByMpnId", Position = 0)]
public string MpnId { get; set; }
/// <summary>
/// Gets or sets the tenant identifier.
/// </summary>
[Parameter(HelpMessage = "The tenant identifier for the partner.", Mandatory = true, ParameterSetName = "ByTenantId", Position = 0)]
[ValidatePattern(@"^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$", Options = RegexOptions.Compiled | RegexOptions.IgnoreCase)]
public string TenantId { get; set; }
/// <summary>
/// Executes the operations associated with the cmdlet.
/// </summary>
public override void ExecuteCmdlet()
{
WriteObject(Partner.Compliance.AgreementSignatureStatus.GetAsync(MpnId, TenantId, CancellationToken).ConfigureAwait(false).GetAwaiter().GetResult());
}
}
}

Просмотреть файл

@ -59,7 +59,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
while (enumerator.HasValue)
{
records.AddRange(enumerator.Current.Items.Select(r => new PSAuditRecord(r)));
enumerator.NextAsync().GetAwaiter().GetResult();
enumerator.NextAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
}

Просмотреть файл

@ -9,16 +9,20 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
using Models.Authentication;
[Cmdlet(VerbsCommon.Get, "PartnerAzureBillingAccount"), OutputType(typeof(BillingAccount))]
public class GetPartnerAzureBillingAccount : PartnerPSCmdlet
public class GetPartnerAzureBillingAccount : PartnerAsyncCmdlet
{
/// <summary>
/// Executes the operations associated with the cmdlet.
/// </summary>
public override void ExecuteCmdlet()
{
IBillingManagementClient client = PartnerSession.Instance.ClientFactory.CreateServiceClient<BillingManagementClient>(new[] { $"{PartnerSession.Instance.Context.Environment.AzureEndpoint}/user_impersonation" });
Scheduler.RunTask(async () =>
{
IBillingManagementClient client = await PartnerSession.Instance.ClientFactory.CreateServiceClientAsync<BillingManagementClient>(new[] { $"{PartnerSession.Instance.Context.Environment.AzureEndpoint}/user_impersonation" });
BillingAccountListResult data = await client.BillingAccounts.ListAsync(null, CancellationToken).ConfigureAwait(false);
WriteObject(client.BillingAccounts.ListAsync(null, CancellationToken).ConfigureAwait(false).GetAwaiter().GetResult().Value, true);
WriteObject(data.Value, true);
}, true);
}
}
}

Просмотреть файл

@ -0,0 +1,42 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
{
using System.Management.Automation;
using System.Text.RegularExpressions;
using Azure.Management.Billing;
using Azure.Management.Billing.Models;
using Models.Authentication;
[Cmdlet(VerbsCommon.Get, "PartnerAzureBillingPolicy")]
[OutputType(typeof(CustomerPolicy))]
public class GetPartnerAzureBillingPolicy : PartnerAsyncCmdlet
{
/// <summary>
/// Gets or sets the name for the billing account.
/// </summary>
[Parameter(HelpMessage = "The name for the billing account.", Mandatory = true)]
public string BillingAccountName { get; set; }
/// <summary>
/// Gets or sets the identifier for the customer.
/// </summary>
[Parameter(HelpMessage = "The identifier for the customer.", Mandatory = true)]
[ValidatePattern(@"^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$", Options = RegexOptions.Compiled | RegexOptions.IgnoreCase)]
public string CustomerId { get; set; }
/// <summary>
/// Executes the operations associated with the cmdlet.
/// </summary>
public override void ExecuteCmdlet()
{
Scheduler.RunTask(async () =>
{
IBillingManagementClient client = await PartnerSession.Instance.ClientFactory.CreateServiceClientAsync<BillingManagementClient>(new[] { $"{PartnerSession.Instance.Context.Environment.AzureEndpoint}/user_impersonation" });
WriteObject(client.Policies.GetByCustomerAsync(BillingAccountName, CustomerId, CancellationToken).ConfigureAwait(false).GetAwaiter().GetResult());
}, true);
}
}
}

Просмотреть файл

@ -10,12 +10,13 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
using Rest.Azure;
[Cmdlet(VerbsCommon.Get, "PartnerAzureBillingProfile"), OutputType(typeof(BillingAccount))]
public class GetPartnerAzureBillingProfile : PartnerPSCmdlet
public class GetPartnerAzureBillingProfile : PartnerAsyncCmdlet
{
/// <summary>
/// Gets or set the name for the billing account.
/// </summary>
[Parameter(HelpMessage = "The name for the billing account", Mandatory = true)]
[ValidateNotNullOrEmpty]
public string BillingAccountName { get; set; }
/// <summary>
@ -23,10 +24,13 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
IBillingManagementClient client = PartnerSession.Instance.ClientFactory.CreateServiceClient<BillingManagementClient>(new[] { $"{PartnerSession.Instance.Context.Environment.AzureEndpoint}//user_impersonation" });
IPage<Customer> data = client.Customers.ListByBillingAccountAsync(BillingAccountName, null, null, CancellationToken).ConfigureAwait(false).GetAwaiter().GetResult();
Scheduler.RunTask(async () =>
{
IBillingManagementClient client = await PartnerSession.Instance.ClientFactory.CreateServiceClientAsync<BillingManagementClient>(new[] { $"{PartnerSession.Instance.Context.Environment.AzureEndpoint}//user_impersonation" });
IPage<Customer> data = client.Customers.ListByBillingAccountAsync(BillingAccountName, null, null, CancellationToken).ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(data, true);
WriteObject(data, true);
}, true);
}
}
}

Просмотреть файл

@ -17,7 +17,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
WriteObject(new PSBillingProfile(Partner.Profiles.BillingProfile.GetAsync().GetAwaiter().GetResult()));
WriteObject(new PSBillingProfile(Partner.Profiles.BillingProfile.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult()));
}
}
}

Просмотреть файл

@ -20,7 +20,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
WriteObject(new PSCountryValidationRules(Partner.CountryValidationRules.ByCountry(CountryCode).GetAsync().GetAwaiter().GetResult()));
WriteObject(new PSCountryValidationRules(Partner.CountryValidationRules.ByCountry(CountryCode).GetAsync().ConfigureAwait(false).GetAwaiter().GetResult()));
}
}
}

Просмотреть файл

@ -21,7 +21,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
[Cmdlet(VerbsCommon.Get, "PartnerCustomer", DefaultParameterSetName = "ById")]
[OutputType(typeof(PSCustomer))]
public class GetPartnerCustomer : PartnerCmdlet
public class GetPartnerCustomer : PartnerAsyncCmdlet
{
/// <summary>
/// Gets or sets the optional customer identifier.
@ -46,49 +46,53 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
IResourceCollectionEnumerator<SeekBasedResourceCollection<Customer>> customersEnumerator;
List<Customer> customers = new List<Customer>();
SeekBasedResourceCollection<Customer> seekCustomers;
if (!string.IsNullOrEmpty(CustomerId))
Scheduler.RunTask(async () =>
{
WriteObject(new PSCustomer(Partner.Customers[CustomerId].GetAsync().GetAwaiter().GetResult()));
return;
}
if (ParameterSetName.Equals("ByDomain", StringComparison.InvariantCultureIgnoreCase))
{
Graph.GraphServiceClient client = PartnerSession.Instance.ClientFactory.CreateGraphServiceClient() as Graph.GraphServiceClient;
client.AuthenticationProvider = new GraphAuthenticationProvider();
IPartner partner = await PartnerSession.Instance.ClientFactory.CreatePartnerOperationsAsync();
IResourceCollectionEnumerator<SeekBasedResourceCollection<Customer>> customersEnumerator;
List<Customer> customers = new List<Customer>();
SeekBasedResourceCollection<Customer> seekCustomers;
Graph.IGraphServiceContractsCollectionPage data = client.Contracts.Request().Filter($"defaultDomainName eq '{Domain}'").GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
if (data.CurrentPage != null && data.CurrentPage.Any())
if (!string.IsNullOrEmpty(CustomerId))
{
Customer customer = Partner.Customers.ById(data.CurrentPage[0].CustomerId.ToString()).GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(new PSCustomer(customer));
WriteObject(new PSCustomer(await partner.Customers[CustomerId].GetAsync().ConfigureAwait(false)));
return;
}
if (ParameterSetName.Equals("ByDomain", StringComparison.InvariantCultureIgnoreCase))
{
Graph.GraphServiceClient client = PartnerSession.Instance.ClientFactory.CreateGraphServiceClient() as Graph.GraphServiceClient;
client.AuthenticationProvider = new GraphAuthenticationProvider();
seekCustomers = Partner.Customers.QueryAsync(
QueryFactory.BuildSimpleQuery(new SimpleFieldFilter(
CustomerSearchField.Domain.ToString(),
FieldFilterOperation.StartsWith,
Domain))).ConfigureAwait(false).GetAwaiter().GetResult();
}
else
{
seekCustomers = Partner.Customers.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
Graph.IGraphServiceContractsCollectionPage data = await client.Contracts.Request().Filter($"defaultDomainName eq '{Domain}'").GetAsync().ConfigureAwait(false);
customersEnumerator = Partner.Enumerators.Customers.Create(seekCustomers);
if (data.CurrentPage != null && data.CurrentPage.Any())
{
Customer customer = await partner.Customers.ById(data.CurrentPage[0].CustomerId.ToString()).GetAsync().ConfigureAwait(false);
WriteObject(new PSCustomer(customer));
return;
}
while (customersEnumerator.HasValue)
{
customers.AddRange(customersEnumerator.Current.Items);
customersEnumerator.NextAsync().GetAwaiter().GetResult();
}
seekCustomers = await partner.Customers.QueryAsync(
QueryFactory.BuildSimpleQuery(new SimpleFieldFilter(
CustomerSearchField.Domain.ToString(),
FieldFilterOperation.StartsWith,
Domain))).ConfigureAwait(false);
}
else
{
seekCustomers = await partner.Customers.GetAsync().ConfigureAwait(false);
}
WriteObject(customers.Select(c => new PSCustomer(c)), true);
customersEnumerator = partner.Enumerators.Customers.Create(seekCustomers);
while (customersEnumerator.HasValue)
{
customers.AddRange(customersEnumerator.Current.Items);
await customersEnumerator.NextAsync().ConfigureAwait(false);
}
WriteObject(customers.Select(c => new PSCustomer(c)), true);
}, true);
}
}
}

Просмотреть файл

@ -35,11 +35,11 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
{
if (string.IsNullOrEmpty(AgreementType))
{
WriteObject(Partner.Customers[CustomerId].Agreements.GetAsync().GetAwaiter().GetResult().Items.Select(a => new PSAgreement(a)), true);
WriteObject(Partner.Customers[CustomerId].Agreements.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult().Items.Select(a => new PSAgreement(a)), true);
}
else
{
WriteObject(Partner.Customers[CustomerId].Agreements.ByAgreementType(AgreementType).GetAsync().GetAwaiter().GetResult().Items.Select(a => new PSAgreement(a)), true);
WriteObject(Partner.Customers[CustomerId].Agreements.ByAgreementType(AgreementType).GetAsync().ConfigureAwait(false).GetAwaiter().GetResult().Items.Select(a => new PSAgreement(a)), true);
}
}
}

Просмотреть файл

@ -3,15 +3,17 @@
namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
{
using System.Linq;
using System.Management.Automation;
using System.Text.RegularExpressions;
using Models.Subscriptions;
using PartnerCenter.Models;
using PartnerCenter.Models.Subscriptions;
/// <summary>
/// Gets a list of Azure Plan entitlements for a customer from Partner Center.
/// </summary>
[Cmdlet(VerbsCommon.Get, "PartnerCustomerAzurePlanEntitlement"), OutputType(typeof(AzureEntitlement))]
[Cmdlet(VerbsCommon.Get, "PartnerCustomerAzurePlanEntitlement"), OutputType(typeof(PSAzureEntitlement))]
public class GetPartnerCustomerAzurePlanEntitlement : PartnerCmdlet
{
/// <summary>
@ -40,7 +42,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
.GetAwaiter()
.GetResult();
WriteObject(entitlements, true);
WriteObject(entitlements.Items.Select(e => new PSAzureEntitlement(e)), true);
}
}
}

Просмотреть файл

@ -22,7 +22,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
WriteObject(new PSCustomerBillingProfile(Partner.Customers[CustomerId].Profiles.Billing.GetAsync().GetAwaiter().GetResult()));
WriteObject(new PSCustomerBillingProfile(Partner.Customers[CustomerId].Profiles.Billing.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult()));
}
}
}

Просмотреть файл

@ -29,7 +29,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
WriteObject(new PSCart(Partner.Customers[CustomerId].Carts[CartId].GetAsync().GetAwaiter().GetResult()));
WriteObject(new PSCart(Partner.Customers[CustomerId].Carts[CartId].GetAsync().ConfigureAwait(false).GetAwaiter().GetResult()));
}
}
}

Просмотреть файл

@ -25,7 +25,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
WriteObject(new PSCustomerCompanyProfile(Partner.Customers[CustomerId].Profiles.Company.GetAsync().GetAwaiter().GetResult()));
WriteObject(new PSCustomerCompanyProfile(Partner.Customers[CustomerId].Profiles.Company.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult()));
}
}
}

Просмотреть файл

@ -62,7 +62,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
IEnumerable<ConfigurationPolicy> devicePolicy;
customerId.AssertNotEmpty(nameof(customerId));
devicePolicy = Partner.Customers[customerId].ConfigurationPolicies.GetAsync().GetAwaiter().GetResult().Items;
devicePolicy = Partner.Customers[customerId].ConfigurationPolicies.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult().Items;
WriteObject(devicePolicy.Select(d => new PSConfigurationPolicy(d)), true);
}
@ -83,7 +83,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
customerId.AssertNotEmpty(nameof(customerId));
policyId.AssertNotEmpty(nameof(policyId));
devicePolicy = Partner.Customers[customerId].ConfigurationPolicies[policyId].GetAsync().GetAwaiter().GetResult();
devicePolicy = Partner.Customers[customerId].ConfigurationPolicies[policyId].GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(new PSConfigurationPolicy(devicePolicy), true);
}
}

Просмотреть файл

@ -35,7 +35,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
IEnumerable<Device> devices = Partner.Customers[CustomerId].DeviceBatches[BatchId].Devices.GetAsync().GetAwaiter().GetResult().Items;
IEnumerable<Device> devices = Partner.Customers[CustomerId].DeviceBatches[BatchId].Devices.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult().Items;
WriteObject(devices.Select(d => new PSDevice(d)), true);
}
}

Просмотреть файл

@ -28,7 +28,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
IEnumerable<DeviceBatch> deviceBatch = Partner.Customers[CustomerId].DeviceBatches.GetAsync().GetAwaiter().GetResult().Items;
IEnumerable<DeviceBatch> deviceBatch = Partner.Customers[CustomerId].DeviceBatches.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult().Items;
WriteObject(deviceBatch.Select(db => new PSDeviceBatch(db)), true);
}
}

Просмотреть файл

@ -27,7 +27,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
{
ResourceCollection<CustomerLicensesDeploymentInsights> insights;
insights = Partner.Customers[CustomerId].Analytics.Licenses.Deployment.GetAsync().GetAwaiter().GetResult();
insights = Partner.Customers[CustomerId].Analytics.Licenses.Deployment.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(insights.Items.Select(i => new PSCustomerLicensesDeploymentInsights(i)), true);
}

Просмотреть файл

@ -59,7 +59,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
customerId.AssertNotEmpty(nameof(customerId));
managedServices = Partner.Customers.ById(CustomerId).ManagedServices.GetAsync().GetAwaiter().GetResult();
managedServices = Partner.Customers.ById(CustomerId).ManagedServices.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
if (managedServices.TotalCount > 0)
{
@ -84,7 +84,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
customerId.AssertNotEmpty(nameof(customerId));
managedServiceId.AssertNotEmpty(nameof(managedServiceId));
managedServices = Partner.Customers.ById(CustomerId).ManagedServices.GetAsync().GetAwaiter().GetResult();
managedServices = Partner.Customers.ById(CustomerId).ManagedServices.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
if (managedServices.TotalCount > 0)
{

Просмотреть файл

@ -40,7 +40,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
WriteObject(Partner.Customers[CustomerId].Orders[OrderId].OrderLineItems[OrderLineItemNumber].ActivationLink.GetAsync().GetAwaiter().GetResult().Items, true);
WriteObject(Partner.Customers[CustomerId].Orders[OrderId].OrderLineItems[OrderLineItemNumber].ActivationLink.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult().Items, true);
}
}
}

Просмотреть файл

@ -31,7 +31,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
WriteObject(Partner.Customers[CustomerId].Orders[OrderId].ProvisioningStatus.GetAsync().GetAwaiter().GetResult().Items.Select(s => new PSOrderLineItemProvisioningStatus(s)));
WriteObject(Partner.Customers[CustomerId].Orders[OrderId].ProvisioningStatus.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult().Items.Select(s => new PSOrderLineItemProvisioningStatus(s)));
}
}
}

Просмотреть файл

@ -25,7 +25,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
WriteObject(Partner.Customers[CustomerId].Qualification.GetAsync().GetAwaiter().GetResult());
WriteObject(Partner.Customers[CustomerId].Qualification.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult());
}
}
}

Просмотреть файл

@ -34,7 +34,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
{
ResourceCollection<ServiceCostLineItem> lineItems;
lineItems = Partner.Customers[CustomerId].ServiceCosts.ByBillingPeriod(BillingPeriod).LineItems.GetAsync().GetAwaiter().GetResult();
lineItems = Partner.Customers[CustomerId].ServiceCosts.ByBillingPeriod(BillingPeriod).LineItems.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(lineItems.Items.Select(i => new PSServiceCostLineItem(i)), true);
}

Просмотреть файл

@ -30,7 +30,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
ServiceCostsSummary summary = Partner.Customers[CustomerId].ServiceCosts.ByBillingPeriod(BillingPeriod).Summary.GetAsync().GetAwaiter().GetResult();
ServiceCostsSummary summary = Partner.Customers[CustomerId].ServiceCosts.ByBillingPeriod(BillingPeriod).Summary.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(new PSServiceCostsSummary(summary));
}

Просмотреть файл

@ -11,9 +11,12 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
using Models.Subscriptions;
using PartnerCenter.Models;
using PartnerCenter.Models.Subscriptions;
using System.Threading.Tasks;
using Models.Authentication;
[Cmdlet(VerbsCommon.Get, "PartnerCustomerSubscription", DefaultParameterSetName = "ByCustomer"), OutputType(typeof(PSSubscription))]
public class GetPartnerCustomerSubscription : PartnerCmdlet
[Cmdlet(VerbsCommon.Get, "PartnerCustomerSubscription", DefaultParameterSetName = "ByCustomer")]
[OutputType(typeof(PSSubscription))]
public class GetPartnerCustomerSubscription : PartnerAsyncCmdlet
{
/// <summary>
/// Gets or sets the customer object used to scope the request.
@ -62,48 +65,35 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
string customerId = (InputObject == null) ? CustomerId : InputObject.CustomerId;
if (string.IsNullOrEmpty(SubscriptionId))
Scheduler.RunTask(async () =>
{
GetSubscriptions(customerId, MpnId, OrderId);
}
else
{
GetSubscription(customerId, SubscriptionId);
}
}
IPartner partner = await PartnerSession.Instance.ClientFactory.CreatePartnerOperationsAsync();
string customerId = (InputObject == null) ? CustomerId : InputObject.CustomerId;
private void GetSubscription(string customerId, string subscriptionId)
{
Subscription subscription;
if (string.IsNullOrEmpty(SubscriptionId))
{
ResourceCollection<Subscription> subscriptions;
customerId.AssertNotEmpty(nameof(customerId));
subscriptionId.AssertNotEmpty(nameof(subscriptionId));
if (!string.IsNullOrWhiteSpace(MpnId))
{
subscriptions = await partner.Customers[customerId].Subscriptions.ByPartner(MpnId).GetAsync().ConfigureAwait(false);
}
else if (!string.IsNullOrWhiteSpace(OrderId))
{
subscriptions = await partner.Customers[customerId].Subscriptions.ByOrder(OrderId).GetAsync().ConfigureAwait(false);
}
else
{
subscriptions = await partner.Customers[customerId].Subscriptions.GetAsync().ConfigureAwait(false);
}
subscription = Partner.Customers[customerId].Subscriptions[subscriptionId].GetAsync().GetAwaiter().GetResult();
WriteObject(new PSSubscription(subscription));
}
private void GetSubscriptions(string customerId, string mpnId = null, string orderId = null)
{
ResourceCollection<Subscription> subscriptions;
if (!string.IsNullOrWhiteSpace(mpnId))
{
subscriptions = Partner.Customers[customerId].Subscriptions.ByPartner(mpnId).GetAsync().GetAwaiter().GetResult();
}
else if (!string.IsNullOrWhiteSpace(orderId))
{
subscriptions = Partner.Customers[customerId].Subscriptions.ByOrder(orderId).GetAsync().GetAwaiter().GetResult();
}
else
{
subscriptions = Partner.Customers[customerId].Subscriptions.GetAsync().GetAwaiter().GetResult();
}
WriteObject(subscriptions.Items.Select(s => new PSSubscription(s)), true);
WriteObject(subscriptions.Items.Select(s => new PSSubscription(s)), true);
}
else
{
WriteObject(new PSSubscription(await partner.Customers[customerId].Subscriptions[SubscriptionId].GetAsync().ConfigureAwait(false)));
}
}, true);
}
}
}

Просмотреть файл

@ -35,7 +35,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
ResourceCollection<Subscription> subscripions = Partner.Customers[CustomerId].Subscriptions[SubscriptionId].AddOns.GetAsync().GetAwaiter().GetResult();
ResourceCollection<Subscription> subscripions = Partner.Customers[CustomerId].Subscriptions[SubscriptionId].AddOns.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(subscripions.Items.Select(s => new PSSubscription(s)), true);
}
}

Просмотреть файл

@ -34,7 +34,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
{
ResourceCollection<MeterUsageRecord> usageRecords;
usageRecords = Partner.Customers[CustomerId].Subscriptions[SubscriptionId].UsageRecords.ByMeter.GetAsync().GetAwaiter().GetResult();
usageRecords = Partner.Customers[CustomerId].Subscriptions[SubscriptionId].UsageRecords.ByMeter.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(usageRecords.Items.Select(r => new PSMeterUsageRecord(r)), true);
}
}

Просмотреть файл

@ -33,7 +33,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
SubscriptionProvisioningStatus status = Partner.Customers[CustomerId].Subscriptions[SubscriptionId].ProvisioningStatus.GetAsync().GetAwaiter().GetResult();
SubscriptionProvisioningStatus status = Partner.Customers[CustomerId].Subscriptions[SubscriptionId].ProvisioningStatus.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(new PSSubscriptionProvisioningStatus(status));
}

Просмотреть файл

@ -33,7 +33,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
SubscriptionRegistrationStatus status = Partner.Customers[CustomerId].Subscriptions[SubscriptionId].RegistrationStatus.GetAsync().GetAwaiter().GetResult();
SubscriptionRegistrationStatus status = Partner.Customers[CustomerId].Subscriptions[SubscriptionId].RegistrationStatus.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(new PSSubscriptionRegistrationStatus(status));
}

Просмотреть файл

@ -34,7 +34,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
{
ResourceCollection<ResourceUsageRecord> usageRecords;
usageRecords = Partner.Customers[CustomerId].Subscriptions[SubscriptionId].UsageRecords.ByResource.GetAsync().GetAwaiter().GetResult();
usageRecords = Partner.Customers[CustomerId].Subscriptions[SubscriptionId].UsageRecords.ByResource.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(usageRecords.Items.Select(r => new PSResourceUsageRecord(r)), true);
}
}

Просмотреть файл

@ -30,7 +30,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
SupportContact contact = Partner.Customers[CustomerId].Subscriptions[SubscriptionId].SupportContact.GetAsync().GetAwaiter().GetResult();
SupportContact contact = Partner.Customers[CustomerId].Subscriptions[SubscriptionId].SupportContact.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(new PSSupportContact(contact));
}
}

Просмотреть файл

@ -37,7 +37,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
{
ResourceCollection<Upgrade> upgrades;
upgrades = Partner.Customers.ById(CustomerId).Subscriptions.ById(SubscriptionId).Upgrades.GetAsync().GetAwaiter().GetResult();
upgrades = Partner.Customers.ById(CustomerId).Subscriptions.ById(SubscriptionId).Upgrades.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(upgrades.Items.Select(c => new PSCustomerSubscriptionUpgrades(c)), true);
}
}

Просмотреть файл

@ -8,8 +8,8 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
using System.Linq;
using System.Management.Automation;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Enumerators;
using Models.Authentication;
using Models.Utilizations;
using PartnerCenter.Models;
using PartnerCenter.Models.Utilizations;
@ -17,8 +17,9 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// <summary>
/// Cmdlet used to obtain Azure utilization records for the specified subscription.
/// </summary>
[Cmdlet(VerbsCommon.Get, "PartnerCustomerSubscriptionUtilization"), OutputType(typeof(PSAzureUtilizationRecord))]
public class GetPartnerCustomerSubscriptionUtilization : PartnerCmdlet
[Cmdlet(VerbsCommon.Get, "PartnerCustomerSubscriptionUtilization")]
[OutputType(typeof(PSAzureUtilizationRecord))]
public class GetPartnerCustomerSubscriptionUtilization : PartnerAsyncCmdlet
{
/// <summary>
/// Gets or sets the identifier of the customer that owns the subscription.
@ -75,38 +76,38 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
List<PSAzureUtilizationRecord> records = Task.Run(() => RunAsync()).ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(records, true);
}
public async Task<List<PSAzureUtilizationRecord>> RunAsync()
{
IResourceCollectionEnumerator<ResourceCollection<AzureUtilizationRecord>> enumerator;
List<PSAzureUtilizationRecord> records = new List<PSAzureUtilizationRecord>();
ResourceCollection<AzureUtilizationRecord> utilizationRecords;
utilizationRecords = await Partner.Customers[CustomerId]
.Subscriptions[SubscriptionId]
.Utilization.Azure.QueryAsync(
StartDate,
EndDate ?? DateTimeOffset.UtcNow,
Granularity ?? AzureUtilizationGranularity.Daily,
!ShowDetails.IsPresent || ShowDetails.ToBool(),
PageSize == null ? 1000 : PageSize.Value).ConfigureAwait(false);
if (utilizationRecords?.TotalCount > 0)
Scheduler.RunTask(async () =>
{
enumerator = Partner.Enumerators.Utilization.Azure.Create(utilizationRecords);
IPartner partner = await PartnerSession.Instance.ClientFactory.CreatePartnerOperationsAsync();
while (enumerator.HasValue)
IResourceCollectionEnumerator<ResourceCollection<AzureUtilizationRecord>> enumerator;
List<PSAzureUtilizationRecord> records = new List<PSAzureUtilizationRecord>();
ResourceCollection<AzureUtilizationRecord> utilizationRecords;
utilizationRecords = await partner.Customers[CustomerId]
.Subscriptions[SubscriptionId]
.Utilization.Azure.QueryAsync(
StartDate,
EndDate ?? DateTimeOffset.UtcNow,
Granularity ?? AzureUtilizationGranularity.Daily,
!ShowDetails.IsPresent || ShowDetails.ToBool(),
PageSize == null ? 1000 : PageSize.Value).ConfigureAwait(false);
if (utilizationRecords?.TotalCount > 0)
{
records.AddRange(enumerator.Current.Items.Select(r => new PSAzureUtilizationRecord(r)));
await enumerator.NextAsync().ConfigureAwait(false);
}
}
enumerator = partner.Enumerators.Utilization.Azure.Create(utilizationRecords);
return records;
while (enumerator.HasValue)
{
records.AddRange(enumerator.Current.Items.Select(r => new PSAzureUtilizationRecord(r)));
await enumerator.NextAsync().ConfigureAwait(false);
}
}
WriteObject(records, true);
}, true);
}
}
}

Просмотреть файл

@ -32,7 +32,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
ResourceCollection<Conversion> conversions = Partner.Customers.ById(CustomerId).Subscriptions.ById(SubscriptionId).Conversions.GetAsync().GetAwaiter().GetResult();
ResourceCollection<Conversion> conversions = Partner.Customers.ById(CustomerId).Subscriptions.ById(SubscriptionId).Conversions.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(conversions.Items.Select(c => new PSCustomerTrialConversion(c)), true);
}
}

Просмотреть файл

@ -22,7 +22,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
WriteObject(new PSCustomerUsageSummary(Partner.Customers[CustomerId].UsageSummary.GetAsync().GetAwaiter().GetResult()));
WriteObject(new PSCustomerUsageSummary(Partner.Customers[CustomerId].UsageSummary.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult()));
}
}
}

Просмотреть файл

@ -94,7 +94,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
customerId.AssertNotEmpty(nameof(customerId));
userId.AssertNotEmpty(nameof(userId));
WriteObject(new PSCustomerUser(Partner.Customers[customerId].Users[userId].GetAsync().GetAwaiter().GetResult()));
WriteObject(new PSCustomerUser(Partner.Customers[customerId].Users[userId].GetAsync().ConfigureAwait(false).GetAwaiter().GetResult()));
}
/// <summary>
@ -114,13 +114,13 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
users = new List<CustomerUser>();
seekUsers = Partner.Customers[customerId].Users.GetAsync().GetAwaiter().GetResult();
seekUsers = Partner.Customers[customerId].Users.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
usersEnumerator = Partner.Enumerators.CustomerUsers.Create(seekUsers);
while (usersEnumerator.HasValue)
{
users.AddRange(usersEnumerator.Current.Items);
usersEnumerator.NextAsync().GetAwaiter().GetResult();
usersEnumerator.NextAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
return users;
@ -151,7 +151,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
while (usersEnumerator.HasValue)
{
users.AddRange(usersEnumerator.Current.Items);
usersEnumerator.NextAsync().GetAwaiter().GetResult();
usersEnumerator.NextAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
return users;

Просмотреть файл

@ -6,6 +6,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
using System.Linq;
using System.Management.Automation;
using System.Text.RegularExpressions;
using Models.Authentication;
using Models.Licenses;
using PartnerCenter.Models;
using PartnerCenter.Models.Licenses;
@ -13,8 +14,9 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// <summary>
/// Command that gets the licenses assigned to a user from a customer.
/// </summary>
[Cmdlet(VerbsCommon.Get, "PartnerCustomerUserLicense"), OutputType(typeof(PSLicense))]
public class GetPartnerCustomerUserLicense : PartnerCmdlet
[Cmdlet(VerbsCommon.Get, "PartnerCustomerUserLicense")]
[OutputType(typeof(PSLicense))]
public class GetPartnerCustomerUserLicense : PartnerAsyncCmdlet
{
/// <summary>
/// Gets or sets the required customer identifier.
@ -42,10 +44,16 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
ResourceCollection<License> licenses = Partner.Customers[CustomerId]
.Users[UserId].Licenses.GetAsync(LicenseGroup?.Select(item => item).ToList()).GetAwaiter().GetResult();
Scheduler.RunTask(async () =>
{
IPartner partner = await PartnerSession.Instance.ClientFactory.CreatePartnerOperationsAsync();
ResourceCollection<License> licenses = await partner.Customers[CustomerId]
.Users[UserId].Licenses.GetAsync(LicenseGroup?.Select(item => item).ToList());
WriteObject(licenses.Items.Select(l => new PSLicense(l)), true);
}, true);
WriteObject(licenses.Items.Select(l => new PSLicense(l)), true);
}
}
}

Просмотреть файл

@ -63,7 +63,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
customerId.AssertNotEmpty(nameof(customerId));
userId.AssertNotEmpty(nameof(userId));
roles = Partner.Customers[customerId].Users[userId].DirectoryRoles.GetAsync().GetAwaiter().GetResult().Items;
roles = Partner.Customers[customerId].Users[userId].DirectoryRoles.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult().Items;
WriteObject(roles.Select(e => new PSDirectoryRole(e)), true);
}
@ -80,7 +80,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
customerId.AssertNotEmpty(nameof(customerId));
roles = Partner.Customers[customerId].DirectoryRoles.GetAsync().GetAwaiter().GetResult().Items;
roles = Partner.Customers[customerId].DirectoryRoles.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult().Items;
WriteObject(roles.Select(e => new PSDirectoryRole(e)), true);
}
}

Просмотреть файл

@ -36,7 +36,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
}
else
{
resellers = Partner.Customers[CustomerId].Relationships.GetAsync().GetAwaiter().GetResult();
resellers = Partner.Customers[CustomerId].Relationships.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
WriteObject(resellers.Items.Select(r => new PSPartnerRelationship(r)), true);

Просмотреть файл

@ -35,7 +35,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
}
else
{
WriteObject(new PSInvoice(Partner.Invoices[InvoiceId].GetAsync().GetAwaiter().GetResult()));
WriteObject(new PSInvoice(Partner.Invoices[InvoiceId].GetAsync().ConfigureAwait(false).GetAwaiter().GetResult()));
}
}
@ -45,7 +45,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
List<PSInvoice> invoices;
ResourceCollection<Invoice> resources;
resources = Partner.Invoices.GetAsync().GetAwaiter().GetResult();
resources = Partner.Invoices.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
enumerator = Partner.Enumerators.Invoices.Create(resources);
invoices = new List<PSInvoice>();
@ -53,7 +53,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
while (enumerator.HasValue)
{
invoices.AddRange(enumerator.Current.Items.Select(i => new PSInvoice(i)));
enumerator.NextAsync().GetAwaiter().GetResult();
enumerator.NextAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
WriteObject(invoices, true);

Просмотреть файл

@ -3,9 +3,11 @@
namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation;
using Models.Authentication;
using PartnerCenter.Enumerators;
using PartnerCenter.Models;
using PartnerCenter.Models.Invoices;
@ -14,94 +16,120 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// <summary>
/// Gets a list of line items for the specified invoice from Partner Center.
/// </summary>
[Cmdlet(VerbsCommon.Get, "PartnerInvoiceLineItem"), OutputType(typeof(PSInvoiceLineItem))]
public class GetPartnerInvoiceLineItem : PartnerCmdlet
[Cmdlet(VerbsCommon.Get, "PartnerInvoiceLineItem", DefaultParameterSetName = ByInvoiceParameterSet)]
[OutputType(typeof(PSInvoiceLineItem))]
public class GetPartnerInvoiceLineItem : PartnerAsyncCmdlet
{
/// <summary>
/// Name for the by invoice parameter set.
/// </summary>
private const string ByInvoiceParameterSet = "ByInvoice";
/// <summary>
/// Name for the by billing period parameter set.
/// </summary>
private const string ByBillingPeriodParameterSet = "ByBillingPeriod";
/// <summary>
/// Gets or sets the billing provider.
/// </summary>
[Parameter(HelpMessage = "The billing provide for the line items.", Mandatory = true)]
[ValidateSet(nameof(BillingProvider.Azure), nameof(BillingProvider.Office), nameof(BillingProvider.OneTime), nameof(BillingProvider.Marketplace))]
[Parameter(HelpMessage = "The billing provide for the line items.", Mandatory = true, ParameterSetName = ByBillingPeriodParameterSet)]
[Parameter(HelpMessage = "The billing provide for the line items.", Mandatory = true, ParameterSetName = ByInvoiceParameterSet)]
[ValidateSet(nameof(BillingProvider.All), nameof(BillingProvider.Azure), nameof(BillingProvider.Office), nameof(BillingProvider.OneTime), nameof(BillingProvider.Marketplace))]
public BillingProvider BillingProvider { get; set; }
/// <summary>
/// Gets or sets the currenty code.
/// </summary>
[Parameter(HelpMessage = "The currency code for the unbilled line items.", Mandatory = false)]
[Parameter(HelpMessage = "The currency code for the unbilled line items.", Mandatory = false, ParameterSetName = ByBillingPeriodParameterSet)]
[Parameter(HelpMessage = "The currency code for the unbilled line items.", Mandatory = false, ParameterSetName = ByInvoiceParameterSet)]
[ValidateNotNull]
public string CurrencyCode { get; set; }
/// <summary>
/// Gets or set the identifier for the invoice.
/// </summary>
[Parameter(HelpMessage = "The identifier corresponding to the invoice.", Mandatory = true)]
[Parameter(HelpMessage = "The identifier corresponding to the invoice.", Mandatory = true, ParameterSetName = ByBillingPeriodParameterSet)]
[Parameter(HelpMessage = "The identifier corresponding to the invoice.", Mandatory = true, ParameterSetName = ByInvoiceParameterSet)]
[ValidateNotNullOrEmpty]
public string InvoiceId { get; set; }
/// <summary>
/// Gets or sets the invoice line item type.
/// </summary>
[Parameter(HelpMessage = "The type of invoice line items.", Mandatory = true)]
[Parameter(HelpMessage = "The type of invoice line items.", Mandatory = true, ParameterSetName = ByBillingPeriodParameterSet)]
[Parameter(HelpMessage = "The type of invoice line items.", Mandatory = true, ParameterSetName = ByInvoiceParameterSet)]
[ValidateSet(nameof(InvoiceLineItemType.BillingLineItems), nameof(InvoiceLineItemType.UsageLineItems))]
public InvoiceLineItemType LineItemType { get; set; }
/// <summary>
/// Gets or sets the billing period.
/// </summary>
[Parameter(HelpMessage = "The billing period for the line items.", Mandatory = true, ParameterSetName = ByBillingPeriodParameterSet)]
[ValidateSet(nameof(BillingPeriod.Current), nameof(BillingPeriod.Previous))]
public BillingPeriod Period { get; set; }
/// <summary>
/// Executes the operations associated with the cmdlet.
/// </summary>
public override void ExecuteCmdlet()
{
IResourceCollectionEnumerator<ResourceCollection<InvoiceLineItem>> enumerator;
List<InvoiceLineItem> items;
ResourceCollection<InvoiceLineItem> lineItems;
Scheduler.RunTask(async () =>
{
IPartner partner = await PartnerSession.Instance.ClientFactory.CreatePartnerOperationsAsync();
IResourceCollectionEnumerator<ResourceCollection<InvoiceLineItem>> enumerator;
List<InvoiceLineItem> items;
ResourceCollection<InvoiceLineItem> lineItems;
if (BillingProvider == BillingProvider.Marketplace)
{
lineItems = Partner.Invoices[InvoiceId].By(BillingProvider, LineItemType, CurrencyCode, BillingPeriod.Current).GetAsync().GetAwaiter().GetResult();
}
else
{
lineItems = Partner.Invoices[InvoiceId].By(BillingProvider, LineItemType).GetAsync().GetAwaiter().GetResult();
}
if (ParameterSetName.Equals(ByBillingPeriodParameterSet, StringComparison.InvariantCultureIgnoreCase))
{
lineItems = await partner.Invoices[InvoiceId].By(BillingProvider, LineItemType, CurrencyCode, Period).GetAsync().ConfigureAwait(false);
}
else
{
lineItems = await partner.Invoices[InvoiceId].By(BillingProvider, LineItemType).GetAsync().ConfigureAwait(false);
}
enumerator = Partner.Enumerators.InvoiceLineItems.Create(lineItems);
items = new List<InvoiceLineItem>();
enumerator = partner.Enumerators.InvoiceLineItems.Create(lineItems);
items = new List<InvoiceLineItem>();
while (enumerator.HasValue)
{
items.AddRange(enumerator.Current.Items);
enumerator.NextAsync().GetAwaiter().GetResult();
}
while (enumerator.HasValue)
{
items.AddRange(enumerator.Current.Items);
await enumerator.NextAsync().ConfigureAwait(false);
}
if (LineItemType == InvoiceLineItemType.BillingLineItems)
{
if (BillingProvider == BillingProvider.Azure)
if (LineItemType == InvoiceLineItemType.BillingLineItems)
{
WriteObject(items.Select(i => new PSUsageBasedLineItem((UsageBasedLineItem)i)), true);
if (BillingProvider == BillingProvider.Azure)
{
WriteObject(items.Select(i => new PSUsageBasedLineItem((UsageBasedLineItem)i)), true);
}
else if (BillingProvider == BillingProvider.Office)
{
WriteObject(items.Select(i => new PSLicenseBasedLineItem((LicenseBasedLineItem)i)), true);
}
else if (BillingProvider == BillingProvider.OneTime)
{
WriteObject(items.Select(i => new PSOneTimeInvoiceLineItem((OneTimeInvoiceLineItem)i)), true);
}
else if (BillingProvider == BillingProvider.Marketplace)
{
WriteObject(items.Select(i => new PSDailyRatedUsageLineItem((DailyRatedUsageLineItem)i)), true);
}
}
else if (BillingProvider == BillingProvider.Office)
else
{
WriteObject(items.Select(i => new PSLicenseBasedLineItem((LicenseBasedLineItem)i)), true);
if (BillingProvider == BillingProvider.Azure)
{
WriteObject(items.Select(i => new PSDailyUsageLineItem((DailyUsageLineItem)i)), true);
}
else
{
WriteObject(items.Select(i => new PSDailyRatedUsageLineItem((DailyRatedUsageLineItem)i)), true);
}
}
else if (BillingProvider == BillingProvider.OneTime)
{
WriteObject(items.Select(i => new PSOneTimeInvoiceLineItem((OneTimeInvoiceLineItem)i)), true);
}
else if (BillingProvider == BillingProvider.Marketplace)
{
WriteObject(items.Select(i => new PSDailyRatedUsageLineItem((DailyRatedUsageLineItem)i)), true);
}
}
else
{
if (BillingProvider == BillingProvider.Azure)
{
WriteObject(items.Select(i => new PSDailyUsageLineItem((DailyUsageLineItem)i)), true);
}
else if (BillingProvider == BillingProvider.Marketplace)
{
WriteObject(items.Select(i => new PSDailyRatedUsageLineItem((DailyRatedUsageLineItem)i)), true);
}
}
}, true);
}
}
}

Просмотреть файл

@ -61,7 +61,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
throw new PSInvalidOperationException($"The path already exists: {filePath}. Specify the -Overwrite switch to overwrite the file");
}
using (Stream stream = Partner.Invoices.ById(InvoiceId).Documents.Statement.GetAsync().GetAwaiter().GetResult())
using (Stream stream = Partner.Invoices.ById(InvoiceId).Documents.Statement.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult())
{
FileStream file = File.Create(filePath);
stream.Seek(0, SeekOrigin.Begin);

Просмотреть файл

@ -17,7 +17,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
ResourceCollection<InvoiceSummary> summaries = Partner.Invoices.Summaries.GetAsync().GetAwaiter().GetResult();
ResourceCollection<InvoiceSummary> summaries = Partner.Invoices.Summaries.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(summaries.Items.Select(s => new PSInvoiceSummary(s)), true);
}

Просмотреть файл

@ -72,7 +72,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
try
{
using (Stream stream = Partner.Invoices.ById(InvoiceId).Documents.Statement.GetAsync().GetAwaiter().GetResult())
using (Stream stream = Partner.Invoices.ById(InvoiceId).Documents.Statement.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult())
{
fileStream = File.Create(filePath);
stream.Seek(0, SeekOrigin.Begin);

Просмотреть файл

@ -17,7 +17,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
WriteObject(new PSLegalBusinessProfile(Partner.Profiles.LegalBusinessProfile.GetAsync().GetAwaiter().GetResult()));
WriteObject(new PSLegalBusinessProfile(Partner.Profiles.LegalBusinessProfile.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult()));
}
}
}

Просмотреть файл

@ -20,7 +20,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
ResourceCollection<PartnerLicensesDeploymentInsights> insights = Partner.Analytics.Licenses.Deployment.GetAsync().GetAwaiter().GetResult();
ResourceCollection<PartnerLicensesDeploymentInsights> insights = Partner.Analytics.Licenses.Deployment.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(insights.Items.Select(l => new PSPartnerLicensesDeploymentInsight(l)), true);
}
}

Просмотреть файл

@ -20,7 +20,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
ResourceCollection<PartnerLicensesUsageInsights> insights = Partner.Analytics.Licenses.Usage.GetAsync().GetAwaiter().GetResult();
ResourceCollection<PartnerLicensesUsageInsights> insights = Partner.Analytics.Licenses.Usage.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(insights.Items.Select(l => new PSPartnerLicensesUsageInsight(l)), true);
}
}

Просмотреть файл

@ -26,7 +26,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
if (string.IsNullOrEmpty(MpnId))
{
profile = Partner.Profiles.MpnProfile.GetAsync().GetAwaiter().GetResult();
profile = Partner.Profiles.MpnProfile.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
else
{

Просмотреть файл

@ -86,7 +86,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
countryCode.AssertNotEmpty(nameof(countryCode));
offerId.AssertNotEmpty(nameof(offerId));
offer = Partner.Offers.ByCountry(countryCode).ById(offerId).GetAsync().GetAwaiter().GetResult();
offer = Partner.Offers.ByCountry(countryCode).ById(offerId).GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(new PSOffer(offer));
}
@ -103,7 +103,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
countryCode.AssertNotEmpty(nameof(countryCode));
offers = Partner.Offers.ByCountry(countryCode).GetAsync().GetAwaiter().GetResult();
offers = Partner.Offers.ByCountry(countryCode).GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
WriteOutput(offers.Items);
}
@ -119,7 +119,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
countryCode.AssertNotEmpty(nameof(countryCode));
category.AssertNotEmpty(nameof(category));
offers = Partner.Offers.ByCountry(countryCode).ByCategory(category).GetAsync().GetAwaiter().GetResult();
offers = Partner.Offers.ByCountry(countryCode).ByCategory(category).GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
WriteOutput(offers.Items);
}

Просмотреть файл

@ -39,7 +39,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
ResourceCollection<Offer> offers;
string countryCode = (string.IsNullOrEmpty(CountryCode)) ? PartnerSession.Instance.Context.CountryCode : CountryCode;
offers = Partner.Offers.ByCountry(countryCode).ById(OfferId).AddOns.GetAsync().GetAwaiter().GetResult();
offers = Partner.Offers.ByCountry(countryCode).ById(OfferId).AddOns.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(offers.Items.Select(o => new PSOffer(o)), true);
}

Просмотреть файл

@ -27,7 +27,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
ResourceCollection<OfferCategory> offerCategories = Partner.OfferCategories.ByCountry(CountryCode).GetAsync().GetAwaiter().GetResult();
ResourceCollection<OfferCategory> offerCategories = Partner.OfferCategories.ByCountry(CountryCode).GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(offerCategories.Items.Select(c => new PSOfferCategory(c)));
}

Просмотреть файл

@ -17,7 +17,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
WriteObject(new PSOrganizationProfile(Partner.Profiles.OrganizationProfile.GetAsync().GetAwaiter().GetResult()));
WriteObject(new PSOrganizationProfile(Partner.Profiles.OrganizationProfile.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult()));
}
}
}

Просмотреть файл

@ -92,7 +92,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
// If segment is specified, get the information using the segment. Otherwise don't
if (!string.IsNullOrEmpty(segment))
{
productAvailability = Partner.Products.ByCountry(countryCode).ById(productId).Skus.ById(skuId).Availabilities.ByTargetSegment(segment).GetAsync().GetAwaiter().GetResult();
productAvailability = Partner.Products.ByCountry(countryCode).ById(productId).Skus.ById(skuId).Availabilities.ByTargetSegment(segment).GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
if (productAvailability.TotalCount > 0)
{
@ -101,7 +101,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
}
else
{
productAvailability = Partner.Products.ByCountry(countryCode).ById(productId).Skus.ById(skuId).Availabilities.GetAsync().GetAwaiter().GetResult();
productAvailability = Partner.Products.ByCountry(countryCode).ById(productId).Skus.ById(skuId).Availabilities.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
if (productAvailability.TotalCount > 0)
{
@ -119,7 +119,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// <param name="availabilityId">Identifier for the product availability.</param>
private void GetProductAvailabilityById(string countryCode, string productId, string skuId, string availabilityId)
{
Availability productAvailability = Partner.Products.ByCountry(countryCode).ById(productId).Skus.ById(skuId).Availabilities.ById(availabilityId).GetAsync().GetAwaiter().GetResult();
Availability productAvailability = Partner.Products.ByCountry(countryCode).ById(productId).Skus.ById(skuId).Availabilities.ById(availabilityId).GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
if (productAvailability != null)
{

Просмотреть файл

@ -17,7 +17,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
WriteObject(new PSCustomerRelationshipRequest(Partner.Customers.RelationshipRequest.GetAsync().GetAwaiter().GetResult()));
WriteObject(new PSCustomerRelationshipRequest(Partner.Customers.RelationshipRequest.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult()));
}
}
}

Просмотреть файл

@ -20,7 +20,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
SeekBasedResourceCollection<Role> roles = Partner.Roles.GetAsync().GetAwaiter().GetResult();
SeekBasedResourceCollection<Role> roles = Partner.Roles.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(roles.Items.Select(r => new PSRole(r)), true);
}

Просмотреть файл

@ -28,7 +28,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
SeekBasedResourceCollection<UserMember> members = Partner.Roles[RoleId].Members.GetAsync().GetAwaiter().GetResult();
SeekBasedResourceCollection<UserMember> members = Partner.Roles[RoleId].Members.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(members.Items.Select(m => new PSUserMember(m)), true);
}

Просмотреть файл

@ -36,7 +36,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
ResourceCollection<ServiceIncidents> incidents;
IEnumerable<ServiceIncidentDetail> results;
incidents = Partner.ServiceIncidents.GetAsync().GetAwaiter().GetResult();
incidents = Partner.ServiceIncidents.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
if (incidents.TotalCount > 0)
{

Просмотреть файл

@ -99,7 +99,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
requestId.AssertNotEmpty(nameof(requestId));
request = Partner.Customers.ById(customerId).ServiceRequests.ById(requestId).GetAsync().GetAwaiter().GetResult();
request = Partner.Customers.ById(customerId).ServiceRequests.ById(requestId).GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
if (request != null)
{
@ -123,7 +123,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
customerId.AssertNotEmpty(nameof(customerId));
requests = Partner.Customers.ById(customerId).ServiceRequests.GetAsync().GetAwaiter().GetResult();
requests = Partner.Customers.ById(customerId).ServiceRequests.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
if (requests.TotalCount > 0)
{
@ -144,7 +144,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
requestId.AssertNotEmpty(nameof(requestId));
request = Partner.ServiceRequests.ById(requestId).GetAsync().GetAwaiter().GetResult();
request = Partner.ServiceRequests.ById(requestId).GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
if (request != null)
{
@ -162,7 +162,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
{
ResourceCollection<ServiceRequest> requests;
requests = Partner.ServiceRequests.GetAsync().GetAwaiter().GetResult();
requests = Partner.ServiceRequests.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
if (requests.TotalCount > 0)
{
@ -181,7 +181,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
while (enumerator.HasValue)
{
serviceRequests.AddRange(enumerator.Current.Items);
enumerator.NextAsync().GetAwaiter().GetResult();
enumerator.NextAsync().ConfigureAwait(false).GetAwaiter().GetResult();
}
if (severity.HasValue && status.HasValue)

Просмотреть файл

@ -31,7 +31,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
ResourceCollection<SupportTopic> topics;
IEnumerable<SupportTopic> results;
topics = Partner.ServiceRequests.SupportTopics.GetAsync().GetAwaiter().GetResult();
topics = Partner.ServiceRequests.SupportTopics.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult();
if (topics.TotalCount > 0)
{

Просмотреть файл

@ -17,7 +17,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
WriteObject(new PSSupportProfile(Partner.Profiles.SupportProfile.GetAsync().GetAwaiter().GetResult()));
WriteObject(new PSSupportProfile(Partner.Profiles.SupportProfile.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult()));
}
}
}

Просмотреть файл

@ -9,12 +9,13 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
using Graph;
using Models.Authentication;
using Network;
using Properties;
/// <summary>
/// Command that gets partner level user accounts.
/// </summary>
[Cmdlet(VerbsCommon.Get, "PartnerUser"), OutputType(typeof(User))]
public class GetPartnerUser : PartnerCmdlet
public class GetPartnerUser : PartnerAsyncCmdlet
{
/// <summary>
/// Gets or sets the user identifier.
@ -29,22 +30,38 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
[Alias("UPN")]
public string UserPrincipalName { get; set; }
/// <summary>
/// Operations that happen before the cmdlet is executed.
/// </summary>
protected override void BeginProcessing()
{
if (PartnerSession.Instance.Context == null)
{
throw new PSInvalidOperationException(Resources.RunConnectPartnerCenter);
}
base.BeginProcessing();
}
/// <summary>
/// Executes the operations associated with the cmdlet.
/// </summary>
public override void ExecuteCmdlet()
{
GraphServiceClient client = PartnerSession.Instance.ClientFactory.CreateGraphServiceClient() as GraphServiceClient;
client.AuthenticationProvider = new GraphAuthenticationProvider();
Scheduler.RunTask(async () =>
{
GraphServiceClient client = PartnerSession.Instance.ClientFactory.CreateGraphServiceClient() as GraphServiceClient;
client.AuthenticationProvider = new GraphAuthenticationProvider();
if (string.IsNullOrEmpty(UserId) && string.IsNullOrEmpty(UserPrincipalName))
{
WriteObject(GetUsersAsync(client).ConfigureAwait(false).GetAwaiter().GetResult(), true);
}
else
{
WriteObject(client.Users[string.IsNullOrEmpty(UserPrincipalName) ? UserId : UserPrincipalName].Request().GetAsync().ConfigureAwait(false).GetAwaiter().GetResult());
}
if (string.IsNullOrEmpty(UserId) && string.IsNullOrEmpty(UserPrincipalName))
{
WriteObject(await GetUsersAsync(client).ConfigureAwait(false), true);
}
else
{
WriteObject(await client.Users[string.IsNullOrEmpty(UserPrincipalName) ? UserId : UserPrincipalName].Request().GetAsync().ConfigureAwait(false));
}
});
}
private async Task<List<User>> GetUsersAsync(IGraphServiceClient client)

Просмотреть файл

@ -7,13 +7,13 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
using System.Collections.Generic;
using System.Management.Automation;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Graph;
using Models.Authentication;
using Network;
using Properties;
[Cmdlet(VerbsCommon.Get, "PartnerUserSignInActivity"), OutputType(typeof(SignIn))]
public class GetPartnerUserSignInActivity : PartnerCmdlet
public class GetPartnerUserSignInActivity : PartnerAsyncCmdlet
{
/// <summary>
/// Gets or sets the end date porition of the query.
@ -34,12 +34,24 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
[ValidatePattern(@"^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$", Options = RegexOptions.Compiled | RegexOptions.IgnoreCase)]
public string UserId { get; set; }
/// <summary>
/// Operations that happen before the cmdlet is executed.
/// </summary>
protected override void BeginProcessing()
{
if (PartnerSession.Instance.Context == null)
{
throw new PSInvalidOperationException(Resources.RunConnectPartnerCenter);
}
base.BeginProcessing();
}
/// <summary>
/// Executes the operations associated with the cmdlet.
/// </summary>
public override void ExecuteCmdlet()
{
List<SignIn> activities;
string filter = string.Empty;
if (StartDate != null)
@ -57,39 +69,35 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
filter = AppendValue(filter, $"userId eq '{UserId}'");
}
activities = GetSignInActivitiesAsync(filter).ConfigureAwait(false).GetAwaiter().GetResult();
WriteObject(activities, true);
}
private async Task<List<SignIn>> GetSignInActivitiesAsync(string filter)
{
List<SignIn> activities;
List<QueryOption> queryOptions = null;
if (!string.IsNullOrEmpty(filter))
Scheduler.RunTask(async () =>
{
queryOptions = new List<QueryOption>
List<SignIn> activities;
List<QueryOption> queryOptions = null;
if (!string.IsNullOrEmpty(filter))
{
new QueryOption("$filter", $"({filter})")
};
}
queryOptions = new List<QueryOption>
{
new QueryOption("$filter", $"({filter})")
};
}
GraphServiceClient client = PartnerSession.Instance.ClientFactory.CreateGraphServiceClient() as GraphServiceClient;
client.AuthenticationProvider = new GraphAuthenticationProvider();
GraphServiceClient client = PartnerSession.Instance.ClientFactory.CreateGraphServiceClient() as GraphServiceClient;
client.AuthenticationProvider = new GraphAuthenticationProvider();
IAuditLogRootSignInsCollectionPage data = await client
.AuditLogs.SignIns.Request(queryOptions).GetAsync(CancellationToken).ConfigureAwait(false);
IAuditLogRootSignInsCollectionPage data = await client
.AuditLogs.SignIns.Request(queryOptions).GetAsync(CancellationToken).ConfigureAwait(false);
activities = new List<SignIn>(data.CurrentPage);
activities = new List<SignIn>(data.CurrentPage);
while (data.NextPageRequest != null)
{
data = await data.NextPageRequest.GetAsync(CancellationToken).ConfigureAwait(false);
activities.AddRange(data.CurrentPage);
}
while (data.NextPageRequest != null)
{
data = await data.NextPageRequest.GetAsync(CancellationToken).ConfigureAwait(false);
activities.AddRange(data.CurrentPage);
}
return activities;
WriteObject(activities, true);
});
}
private static string AppendValue(string baseValue, string appendValue)

Просмотреть файл

@ -19,7 +19,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
WriteObject(Partner.Validations.GetValidationCodesAsync().GetAwaiter().GetResult().Select(c => new PSValidationCode(c)), true);
WriteObject(Partner.Validations.GetValidationCodesAsync().ConfigureAwait(false).GetAwaiter().GetResult().Select(c => new PSValidationCode(c)), true);
}
}
}

Просмотреть файл

@ -9,20 +9,25 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
using System.Management.Automation;
using System.Text;
using Extensions;
using Factories;
using Identity.Client;
using Microsoft.Store.PartnerCenter.PowerShell.Factories;
using Models.Authentication;
using Newtonsoft.Json.Linq;
[Cmdlet(VerbsCommon.New, "PartnerAccessToken")]
[OutputType(typeof(AuthResult))]
public class NewPartnerAccessToken : PartnerPSCmdlet
public class NewPartnerAccessToken : PartnerAsyncCmdlet
{
/// <summary>
/// The name of the access token parameter set.
/// </summary>
private const string AccessTokenParameterSet = "AccessToken";
/// <summary>
/// The name of the by module parameter set.
/// </summary>
private const string ByModuleParameterSet = "ByModule";
/// <summary>
/// The message written to the console.
/// </summary>
@ -53,7 +58,10 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// <summary>
/// Gets or sets the application identifier.
/// </summary>
[Parameter(HelpMessage = "The application identifier to be used during authentication.", Mandatory = true)]
[Parameter(HelpMessage = "The application identifier to be used during authentication.", Mandatory = true, ParameterSetName = AccessTokenParameterSet)]
[Parameter(HelpMessage = "The application identifier to be used during authentication.", Mandatory = true, ParameterSetName = ServicePrincipalParameterSet)]
[Parameter(HelpMessage = "The application identifier to be used during authentication.", Mandatory = true, ParameterSetName = ServicePrincipalCertificateParameterSet)]
[Parameter(HelpMessage = "The application identifier to be used during authentication.", Mandatory = true, ParameterSetName = UserParameterSet)]
[Alias("ClientId")]
[ValidateNotNullOrEmpty]
public string ApplicationId { get; set; }
@ -61,7 +69,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// <summary>
/// Gets or sets the certificate thumbprint.
/// </summary>
[Parameter(ParameterSetName = ServicePrincipalCertificateParameterSet, Mandatory = true, HelpMessage = "Certificate Hash (Thumbprint)")]
[Parameter(HelpMessage = "Certificate Hash (Thumbprint)", Mandatory = true, ParameterSetName = ServicePrincipalCertificateParameterSet)]
public string CertificateThumbprint { get; set; }
/// <summary>
@ -80,6 +88,14 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
[ValidateNotNullOrEmpty]
public EnvironmentName Environment { get; set; }
/// <summary>
/// Gets or sets the module that an access token is being generated.
/// </summary>
[Parameter(HelpMessage = "The module that an access token is being generated.", Mandatory = true, ParameterSetName = ByModuleParameterSet)]
[Alias("ModuleName")]
[ValidateSet(nameof(ModuleName.ExchangeOnline))]
public ModuleName Module { get; set; }
/// <summary>
/// Gets or sets the refresh token to use during authentication.
/// </summary>
@ -90,7 +106,10 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// <summary>
/// Gets or sets the scopes used for authentication.
/// </summary>
[Parameter(HelpMessage = "Scopes requested to access a protected API.", Mandatory = true)]
[Parameter(HelpMessage = "Scopes requested to access a protected API.", Mandatory = true, ParameterSetName = AccessTokenParameterSet)]
[Parameter(HelpMessage = "Scopes requested to access a protected API.", Mandatory = true, ParameterSetName = ServicePrincipalParameterSet)]
[Parameter(HelpMessage = "Scopes requested to access a protected API.", Mandatory = true, ParameterSetName = ServicePrincipalCertificateParameterSet)]
[Parameter(HelpMessage = "Scopes requested to access a protected API.", Mandatory = false, ParameterSetName = UserParameterSet)]
public string[] Scopes { get; set; }
/// <summary>
@ -105,6 +124,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
[Alias("Domain", "TenantId")]
[Parameter(HelpMessage = "Identifier or name for the tenant.", Mandatory = false, ParameterSetName = AccessTokenParameterSet)]
[Parameter(HelpMessage = "Identifier or name for the tenant.", Mandatory = false, ParameterSetName = ByModuleParameterSet)]
[Parameter(HelpMessage = "Identifier or name for the tenant.", Mandatory = true, ParameterSetName = ServicePrincipalCertificateParameterSet)]
[Parameter(HelpMessage = "Identifier or name for the tenant.", Mandatory = true, ParameterSetName = ServicePrincipalParameterSet)]
[Parameter(HelpMessage = "Identifier or name for the tenant.", Mandatory = false, ParameterSetName = UserParameterSet)]
@ -122,126 +142,139 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// Gets or sets a flag indicating if the device code flow should be used.
/// </summary>
[Alias("DeviceCode", "DeviceAuth", "Device")]
[Parameter(ParameterSetName = UserParameterSet, Mandatory = false, HelpMessage = "Use device code authentication instead of a browser control")]
[Parameter(ParameterSetName = UserParameterSet, Mandatory = false, HelpMessage = "Use device code authentication instead of a browser control.")]
public SwitchParameter UseDeviceAuthentication { get; set; }
/// <summary>
/// Performs the execution of the command.
/// Executes the operations associated with the cmdlet.
/// </summary>
protected override void ProcessRecord()
public override void ExecuteCmdlet()
{
PartnerAccount account = new PartnerAccount();
if (ParameterSetName.Equals(AccessTokenParameterSet, StringComparison.InvariantCultureIgnoreCase))
Scheduler.RunTask(async () =>
{
account.SetProperty(PartnerAccountPropertyType.AccessToken, AccessToken);
account.Type = AccountType.AccessToken;
}
else if (ParameterSetName.Equals(ServicePrincipalParameterSet, StringComparison.InvariantCultureIgnoreCase))
{
account.ObjectId = Credential.UserName;
account.SetProperty(PartnerAccountPropertyType.ServicePrincipalSecret, Credential.Password.ConvertToString());
account.Type = AccountType.ServicePrincipal;
}
else
{
account.Type = AccountType.User;
}
PartnerAccount account = new PartnerAccount();
string applicationId;
if (UseAuthorizationCode.IsPresent)
{
account.SetProperty("UseAuthCode", "true");
}
if (UseDeviceAuthentication.IsPresent)
{
account.SetProperty("UseDeviceAuth", "true");
}
if (!string.IsNullOrEmpty(RefreshToken))
{
account.SetProperty(PartnerAccountPropertyType.RefreshToken, RefreshToken);
}
account.SetProperty(PartnerAccountPropertyType.ApplicationId, ApplicationId);
account.Tenant = string.IsNullOrEmpty(Tenant) ? "common" : Tenant;
AuthenticationResult authResult = PartnerSession.Instance.AuthenticationFactory.Authenticate(
account,
PartnerEnvironment.PublicEnvironments[Environment],
Scopes,
Message,
WriteWarning,
WriteDebug,
CancellationToken);
byte[] cacheData = SharedTokenCacheClientFactory.GetTokenCache(ApplicationId).SerializeMsalV3();
IEnumerable<string> knownPropertyNames = new[] { "AccessToken", "RefreshToken", "IdToken", "Account", "AppMetadata" };
JObject root = JObject.Parse(Encoding.UTF8.GetString(cacheData, 0, cacheData.Length));
IDictionary<string, JToken> known = (root as IDictionary<string, JToken>)
.Where(kvp => knownPropertyNames.Any(p => string.Equals(kvp.Key, p, StringComparison.OrdinalIgnoreCase)))
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
IDictionary<string, TokenCacheItem> tokens = new Dictionary<string, TokenCacheItem>();
if (known.ContainsKey("RefreshToken"))
{
foreach (JToken token in root["RefreshToken"].Values())
if (ParameterSetName.Equals(AccessTokenParameterSet, StringComparison.InvariantCultureIgnoreCase))
{
if (token is JObject j)
{
TokenCacheItem item = new TokenCacheItem
{
ClientId = ExtractExistingOrEmptyString(j, "client_id"),
CredentialType = ExtractExistingOrEmptyString(j, "credential_type"),
Environment = ExtractExistingOrEmptyString(j, "environment"),
HomeAccountId = ExtractExistingOrEmptyString(j, "home_account_id"),
RawClientInfo = ExtractExistingOrEmptyString(j, "client_info"),
Secret = ExtractExistingOrEmptyString(j, "secret")
};
account.SetProperty(PartnerAccountPropertyType.AccessToken, AccessToken);
account.Type = AccountType.AccessToken;
applicationId = ApplicationId;
}
else if (ParameterSetName.Equals(ByModuleParameterSet, StringComparison.InvariantCultureIgnoreCase))
{
account.SetProperty(PartnerAccountPropertyType.UseDeviceAuth, "true");
account.Type = AccountType.User;
applicationId = PowerShellModule.KnownModules[Module].ApplicationId;
tokens.Add($"{item.HomeAccountId}-{item.Environment}-RefreshToken-{item.ClientId}--", item);
Scopes = PowerShellModule.KnownModules[Module].Scopes.ToArray();
}
else if (ParameterSetName.Equals(ServicePrincipalParameterSet, StringComparison.InvariantCultureIgnoreCase))
{
account.ObjectId = Credential.UserName;
account.SetProperty(PartnerAccountPropertyType.ServicePrincipalSecret, Credential.Password.ConvertToString());
account.Type = AccountType.ServicePrincipal;
applicationId = ApplicationId;
}
else
{
account.Type = AccountType.User;
applicationId = ApplicationId;
}
if (!ParameterSetName.Equals(ByModuleParameterSet, StringComparison.InvariantCultureIgnoreCase))
{
if (UseAuthorizationCode.IsPresent)
{
account.SetProperty(PartnerAccountPropertyType.UseAuthCode, "true");
}
if (UseDeviceAuthentication.IsPresent)
{
account.SetProperty(PartnerAccountPropertyType.UseDeviceAuth, "true");
}
}
}
string key = GetTokenCacheKey(authResult);
if (!string.IsNullOrEmpty(RefreshToken))
{
account.SetProperty(PartnerAccountPropertyType.RefreshToken, RefreshToken);
}
AuthResult result = new AuthResult(
authResult.AccessToken,
authResult.IsExtendedLifeTimeToken,
authResult.UniqueId,
authResult.ExpiresOn,
authResult.ExtendedExpiresOn,
authResult.TenantId,
authResult.Account,
authResult.IdToken,
authResult.Scopes);
account.SetProperty(PartnerAccountPropertyType.ApplicationId, applicationId);
account.Tenant = string.IsNullOrEmpty(Tenant) ? "organizations" : Tenant;
if (tokens.ContainsKey(key))
{
result.RefreshToken = tokens[key].Secret;
}
AuthenticationResult authResult = await PartnerSession.Instance.AuthenticationFactory.AuthenticateAsync(
account,
PartnerEnvironment.PublicEnvironments[Environment],
Scopes,
Message,
CancellationToken).ConfigureAwait(false);
WriteObject(result);
}
byte[] cacheData = SharedTokenCacheClientFactory.GetMsalCacheStorage(ApplicationId).ReadData();
private string GetTokenCacheKey(AuthenticationResult authResult)
{
return $"{authResult.Account.HomeAccountId.Identifier}-{authResult.Account.Environment}-RefreshToken-{ApplicationId}--";
IEnumerable<string> knownPropertyNames = new[] { "AccessToken", "RefreshToken", "IdToken", "Account", "AppMetadata" };
JObject root = JObject.Parse(Encoding.UTF8.GetString(cacheData, 0, cacheData.Length));
IDictionary<string, JToken> known = (root as IDictionary<string, JToken>)
.Where(kvp => knownPropertyNames.Any(p => string.Equals(kvp.Key, p, StringComparison.OrdinalIgnoreCase)))
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
IDictionary<string, TokenCacheItem> tokens = new Dictionary<string, TokenCacheItem>();
if (known.ContainsKey("RefreshToken"))
{
foreach (JToken token in root["RefreshToken"].Values())
{
if (token is JObject j)
{
TokenCacheItem item = new TokenCacheItem
{
ClientId = ExtractExistingOrEmptyString(j, "client_id"),
CredentialType = ExtractExistingOrEmptyString(j, "credential_type"),
Environment = ExtractExistingOrEmptyString(j, "environment"),
HomeAccountId = ExtractExistingOrEmptyString(j, "home_account_id"),
RawClientInfo = ExtractExistingOrEmptyString(j, "client_info"),
Secret = ExtractExistingOrEmptyString(j, "secret")
};
tokens.Add($"{item.HomeAccountId}-{item.Environment}-RefreshToken-{item.ClientId}--", item);
}
}
}
AuthResult result = new AuthResult(
authResult.AccessToken,
authResult.IsExtendedLifeTimeToken,
authResult.UniqueId,
authResult.ExpiresOn,
authResult.ExtendedExpiresOn,
authResult.TenantId,
authResult.Account,
authResult.IdToken,
authResult.Scopes,
authResult.CorrelationId);
if (authResult.Account != null)
{
string key = SharedTokenCacheClientFactory.GetTokenCacheKey(authResult, applicationId);
if (tokens.ContainsKey(key))
{
result.RefreshToken = tokens[key].Secret;
}
}
WriteObject(result);
});
}
private static string ExtractExistingOrEmptyString(JObject json, string key)
{
if (json.TryGetValue(key, out JToken val))
{
string strVal = val.ToObject<string>();
json.Remove(key);
return strVal;
return val.ToObject<string>(); ;
}
return string.Empty;

Просмотреть файл

@ -3,14 +3,27 @@
namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
{
using System;
using System.Management.Automation;
using System.Text.RegularExpressions;
using Azure.Management.Profiles.Subscription;
using Azure.Management.Profiles.Subscription.Models;
using Models.Authentication;
[Cmdlet(VerbsCommon.New, "PartnerAzureSubscription"), OutputType(typeof(SubscriptionCreationResult))]
public class NewPartnerAzureSubscription : PartnerPSCmdlet
[Cmdlet(VerbsCommon.New, "PartnerAzureSubscription", DefaultParameterSetName = ByCustomerNameParameterSet)]
[OutputType(typeof(SubscriptionCreationResult))]
public class NewPartnerAzureSubscription : PartnerAsyncCmdlet
{
/// <summary>
/// Name of the by customer identifier parameter set.
/// </summary>
private const string ByCustomerIdParameterSet = "ByCustomerId";
/// <summary>
/// Name of the by customer name parameter set.
/// </summary>
private const string ByCustomerNameParameterSet = "ByCustomerName";
/// <summary>
/// Gets or sets the name for the billing account.
/// </summary>
@ -20,9 +33,17 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// <summary>
/// Gets or sets the name for the customer.
/// </summary>
[Parameter(HelpMessage = "The name for the customer.", Mandatory = true)]
[BreakingChange("Replacing the customer name parameter with the customer identifier parameter.", "3.0.1", NewWay = "New-PartnerAzureSubscription -BillingAccountName '99a13315-xxxx-xxxx-xxxx-xxxxxxxxxxxx:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_xxxx-xx-xx' -CustomerId '1e5a6ab0-e5ef-4f4e-a208-399e792b5ed4' -DisplayName 'Microsoft Azure'", OldWay = "New-PartnerAzureSubscription -BillingAccountName '99a13315-xxxx-xxxx-xxxx-xxxxxxxxxxxx:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_xxxx-xx-xx' -CustomerName 'Contoso' -DisplayName 'Microsoft Azure'")]
[Parameter(HelpMessage = "The name of the customer.", Mandatory = true, ParameterSetName = ByCustomerNameParameterSet)]
public string CustomerName { get; set; }
/// <summary>
/// Gets or sets the identifier for the customer.
/// </summary>
[Parameter(HelpMessage = "The identifier for the customer.", Mandatory = true, ParameterSetName = ByCustomerIdParameterSet)]
[ValidatePattern(@"^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$", Options = RegexOptions.Compiled | RegexOptions.IgnoreCase)]
public string CustomerId { get; set; }
/// <summary>
/// Gets or sets the display name for the subscription.
/// </summary>
@ -40,15 +61,25 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
/// </summary>
public override void ExecuteCmdlet()
{
ISubscriptionClient client = PartnerSession.Instance.ClientFactory.CreateServiceClient<SubscriptionClient>(new[] { $"{PartnerSession.Instance.Context.Environment.AzureEndpoint}/user_impersonation" });
ModernCspSubscriptionCreationParameters parameters = new ModernCspSubscriptionCreationParameters
Scheduler.RunTask(async () =>
{
DisplayName = DisplayName,
ResellerId = ResellerId ?? null,
SkuId = "0001"
};
ISubscriptionClient client = await PartnerSession.Instance.ClientFactory.CreateServiceClientAsync<SubscriptionClient>(new[] { $"{PartnerSession.Instance.Context.Environment.AzureEndpoint}/user_impersonation" });
ModernCspSubscriptionCreationParameters parameters = new ModernCspSubscriptionCreationParameters
{
DisplayName = DisplayName,
ResellerId = ResellerId ?? null,
SkuId = "0001"
};
WriteObject(client.SubscriptionFactory.CreateCspSubscriptionAsync(BillingAccountName, CustomerName, parameters, CancellationToken).ConfigureAwait(false).GetAwaiter().GetResult());
if (ParameterSetName.Equals(ByCustomerIdParameterSet, StringComparison.InvariantCultureIgnoreCase))
{
WriteObject(await client.SubscriptionFactory.CreateCspSubscriptionAsync(BillingAccountName, CustomerId, parameters, CancellationToken).ConfigureAwait(false));
}
else
{
WriteObject(await client.SubscriptionFactory.CreateCspSubscriptionAsync(BillingAccountName, CustomerName, parameters, CancellationToken).ConfigureAwait(false));
}
}, true);
}
}
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше