Azure / azure-powershell

Microsoft Azure PowerShell
Other
4.21k stars 3.81k forks source link

Connect-AzAccount: inconsistent behaviour when using WhatIf flag - breaks tests #12511

Closed rodolfograve closed 4 years ago

rodolfograve commented 4 years ago

Description

The Connect-AzAccount function writes an object to the standard output when not using -WhatIf. However, it doesn't when -WhatIf is present.

Since WhatIf is key when writing tests, this breaks tests for commands that use Connect-AzAccount and return a value of its own. This is because of PowerShell's behaviour to treat any standard output as a value returned by the function.

I believe this is the section causing the issue: https://github.com/Azure/azure-powershell/blob/f1b754320ca279d65949ae18740b20440b773c89/src/Accounts/Accounts/Account/ConnectAzureRmAccount.cs#L329-L338

WriteObject(...) is inside the if (ShouldProcess...) and there is no else to return some fake value.

Writing tests for PowerShell scripts is already hard enough, particularly for those scripts that target some infrastructure (most of them?). Hopefully key frameworks like PowerShell Az can relieve some of the pain by providing first-class support for testing.

To be clear, the issue here is that my tests would pass (they use WhatIf) but my scripts will fail when used for real.

Steps to reproduce

Function Connect-ToMySubscription {
    [CmdletBinding(SupportsShouldProcess, ConfirmImpact="Low")]
    Param()
    Connect-AzAccount
    # Return my own object. Only for illustration purposes. In a real example I could be returning an instance of my own class, with more properties, functions, etc.
    return @{TimeStamp=Get-Date}
}

$Result = Connect-ToMySubscription
$ResultWithWhatIf = Connect-ToMySubscription -WhatIf

If ($Result.GetType() -ne $ResultWithWhatIf.GetType()) {
    Throw "I would like my tests to be able to assume Connect-ToMySubscription will always return the same value, WhatIf or not"
}

Environment data

Name                           Value
----                           -----
PSVersion                      7.0.3
PSEdition                      Core
GitCommitId                    7.0.3
OS                             Microsoft Windows 10.0.18363
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Module versions

    Directory: F:\Users\rodolfog\PowerShell\Modules

ModuleType Version    PreRelease Name                                PSEdition ExportedCommands
---------- -------    ---------- ----                                --------- ----------------
Script     4.4.0                 Az                                  Core,Desk
Script     1.9.1                 Az.Accounts                         Core,Desk {Disable-AzDataCollection, Disable-AzCo…
Script     1.1.1                 Az.Advisor                          Core,Desk {Get-AzAdvisorRecommendation, Enable-Az…
Script     1.1.3                 Az.Aks                              Core,Desk {Get-AzAks, New-AzAks, Remove-AzAks, Im…
Script     1.1.4                 Az.AnalysisServices                 Core,Desk {Resume-AzAnalysisServicesServer, Suspe…
Script     2.0.1                 Az.ApiManagement                    Core,Desk {Add-AzApiManagementApiToProduct, Add-A…
Script     1.1.0                 Az.ApplicationInsights              Core,Desk {Get-AzApplicationInsights, New-AzAppli…
Script     1.3.7                 Az.Automation                       Core,Desk {Get-AzAutomationHybridWorkerGroup, Rem…
Script     3.1.0                 Az.Batch                            Core,Desk {Remove-AzBatchAccount, Get-AzBatchAcco…
Script     1.0.3                 Az.Billing                          Core,Desk {Get-AzBillingInvoice, Get-AzBillingPer…
Script     1.4.3                 Az.Cdn                              Core,Desk {Get-AzCdnProfile, Get-AzCdnProfileSsoU…
Script     1.5.0                 Az.CognitiveServices                Core,Desk {Get-AzCognitiveServicesAccount, Get-Az…
Script     4.2.1                 Az.Compute                          Core,Desk {Remove-AzAvailabilitySet, Get-AzAvaila…
Script     1.0.3                 Az.ContainerInstance                Core,Desk {New-AzContainerGroup, Get-AzContainerG…
Script     1.1.1                 Az.ContainerRegistry                Core,Desk {New-AzContainerRegistry, Get-AzContain…
Script     1.1.0                 Az.DataBoxEdge                      Core,Desk {Get-AzDataBoxEdgeJob, Get-AzDataBoxEdg…
Script     1.9.0                 Az.DataFactory                      Core,Desk {Set-AzDataFactoryV2, Update-AzDataFact…
Script     1.0.2                 Az.DataLakeAnalytics                Core,Desk {Get-AzDataLakeAnalyticsDataSource, New…
Script     1.2.8                 Az.DataLakeStore                    Core,Desk {Get-AzDataLakeStoreTrustedIdProvider, …
Script     1.0.0                 Az.DataShare                        Core,Desk {New-AzDataShareAccount, Get-AzDataShar…
Script     1.1.0                 Az.DeploymentManager                Core,Desk {Get-AzDeploymentManagerArtifactSource,…
Script     1.0.0                 Az.DesktopVirtualization            Core,Desk {Disconnect-AzWvdUserSession, Get-AzWvd…
Script     1.0.2                 Az.DevTestLabs                      Core,Desk {Get-AzDtlAllowedVMSizesPolicy, Get-AzD…
Script     1.1.2                 Az.Dns                              Core,Desk {Get-AzDnsRecordSet, New-AzDnsRecordCon…
Script     1.3.0                 Az.EventGrid                        Core,Desk {New-AzEventGridTopic, Get-AzEventGridT…
Script     1.5.0                 Az.EventHub                         Core,Desk {New-AzEventHubNamespace, Get-AzEventHu…
Script     1.6.0                 Az.FrontDoor                        Core,Desk {New-AzFrontDoor, Get-AzFrontDoor, Set-…
Script     1.0.1                 Az.Functions                        Core,Desk {Get-AzFunctionApp, Get-AzFunctionAppAv…
Script     3.3.1                 Az.HDInsight                        Core,Desk {Get-AzHDInsightJob, New-AzHDInsightSqo…
Script     1.1.0                 Az.HealthcareApis                   Core,Desk {New-AzHealthcareApisService, Remove-Az…
Script     2.5.0                 Az.IotHub                           Core,Desk {Add-AzIotHubKey, Get-AzIotHubEventHubC…
Script     2.0.0                 Az.KeyVault                         Core,Desk {Add-AzKeyVaultCertificate, Update-AzKe…
Script     1.3.2                 Az.LogicApp                         Core,Desk {Get-AzIntegrationAccountAgreement, Get…
Script     1.1.3                 Az.MachineLearning                  Core,Desk {Move-AzMlCommitmentAssociation, Get-Az…
Script     1.0.0                 Az.Maintenance                      Core,Desk {Get-AzApplyUpdate, Get-AzConfiguration…
Script     1.0.2                 Az.ManagedServices                  Core,Desk {Get-AzManagedServicesAssignment, New-A…
Script     1.0.2                 Az.MarketplaceOrdering              Core,Desk {Get-AzMarketplaceTerms, Set-AzMarketpl…
Script     1.1.1                 Az.Media                            Core,Desk {Sync-AzMediaServiceStorageKey, Set-AzM…
Script     2.0.2                 Az.Monitor                          Core,Desk {Get-AzMetricDefinition, Get-AzMetric, …
Script     3.2.0                 Az.Network                          Core,Desk {Add-AzApplicationGatewayAuthentication…
Script     1.1.1                 Az.NotificationHubs                 Core,Desk {Get-AzNotificationHub, Get-AzNotificat…
Script     2.2.0                 Az.OperationalInsights              Core,Desk {New-AzOperationalInsightsAzureActivity…
Script     1.3.1                 Az.PolicyInsights                   Core,Desk {Get-AzPolicyEvent, Get-AzPolicyState, …
Script     1.1.2                 Az.PowerBIEmbedded                  Core,Desk {Remove-AzPowerBIWorkspaceCollection, G…
Script     1.0.3                 Az.PrivateDns                       Core,Desk {Get-AzPrivateDnsZone, Remove-AzPrivate…
Script     2.11.0                Az.RecoveryServices                 Core,Desk {Get-AzRecoveryServicesBackupProperty, …
Script     1.2.1                 Az.RedisCache                       Core,Desk {Remove-AzRedisCachePatchSchedule, New-…
Script     1.0.3                 Az.Relay                            Core,Desk {New-AzRelayNamespace, Get-AzRelayNames…
Script     2.3.0                 Az.Resources                        Core,Desk {Get-AzProviderOperation, Remove-AzRole…
Script     1.4.1                 Az.ServiceBus                       Core,Desk {New-AzServiceBusNamespace, Get-AzServi…
Script     2.1.0                 Az.ServiceFabric                    Core,Desk {Add-AzServiceFabricClientCertificate, …
Script     1.1.1                 Az.SignalR                          Core,Desk {New-AzSignalR, Get-AzSignalR, Get-AzSi…
Script     2.9.0                 Az.Sql                              Core,Desk {Get-AzSqlDatabaseTransparentDataEncryp…
Script     1.1.0                 Az.SqlVirtualMachine                Core,Desk {New-AzSqlVM, Get-AzSqlVM, Update-AzSql…
Script     2.3.0                 Az.Storage                          Core,Desk {Get-AzStorageAccount, Get-AzStorageAcc…
Script     1.3.0                 Az.StorageSync                      Core,Desk {Invoke-AzStorageSyncCompatibilityCheck…
Script     1.0.1                 Az.StreamAnalytics                  Core,Desk {Get-AzStreamAnalyticsFunction, Get-AzS…
Script     1.0.0                 Az.Support                          Core,Desk {Get-AzSupportService, Get-AzSupportPro…
Script     1.0.4                 Az.TrafficManager                   Core,Desk {Add-AzTrafficManagerCustomHeaderToEndp…
Script     1.11.0                Az.Websites                         Core,Desk {Get-AzAppServicePlan, Set-AzAppService…

    Directory: C:\program files\powershell\7\Modules

ModuleType Version    PreRelease Name                                PSEdition ExportedCommands
---------- -------    ---------- ----                                --------- ----------------
Manifest   7.0.0.0               CimCmdlets                          Core      {Get-CimAssociatedInstance, Get-CimClas…
Manifest   1.2.5                 Microsoft.PowerShell.Archive        Desk      {Compress-Archive, Expand-Archive}
Manifest   7.0.0.0               Microsoft.PowerShell.Diagnostics    Core      {Get-WinEvent, New-WinEvent, Get-Counte…
Manifest   7.0.0.0               Microsoft.PowerShell.Host           Core      {Start-Transcript, Stop-Transcript}
Manifest   7.0.0.0               Microsoft.PowerShell.Management     Core      {Add-Content, Clear-Content, Get-Clipbo…
Manifest   7.0.0.0               Microsoft.PowerShell.Security       Core      {Get-Acl, Set-Acl, Get-PfxCertificate, …
Manifest   7.0.0.0               Microsoft.PowerShell.Utility        Core      {Export-Alias, Get-Alias, Import-Alias,…
Manifest   7.0.0.0               Microsoft.WSMan.Management          Core      {Disable-WSManCredSSP, Enable-WSManCred…
Script     1.4.7                 PackageManagement                   Desk      {Find-Package, Get-Package, Get-Package…
Script     2.2.4.1               PowerShellGet                       Desk      {Find-Command, Find-DSCResource, Find-M…
Script     2.0.5                 PSDesiredStateConfiguration         Core      {Configuration, New-DscChecksum, Get-Ds…
Script     7.0.0.0               PSDiagnostics                       Core      {Disable-PSTrace, Disable-PSWSManCombin…
Script     2.0.2                 PSReadLine                          Desk      {Get-PSReadLineKeyHandler, Set-PSReadLi…
Binary     2.0.3                 ThreadJob                           Desk      Start-ThreadJob

    Directory: C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules

ModuleType Version    PreRelease Name                                PSEdition ExportedCommands
---------- -------    ---------- ----                                --------- ----------------
Manifest   1.0.0.0               AppBackgroundTask                   Core,Desk {Disable-AppBackgroundTaskDiagnosticLog…
Manifest   2.0.1.0               Appx                                Core,Desk {Add-AppxPackage, Get-AppxPackage, Get-…
Script     1.0.0.0               AssignedAccess                      Core,Desk {Clear-AssignedAccess, Get-AssignedAcce…
Manifest   1.0.0.0               BitLocker                           Core,Desk {Unlock-BitLocker, Suspend-BitLocker, R…
Manifest   1.0.0.0               BranchCache                         Core,Desk {Add-BCDataCacheExtension, Clear-BCCach…
Manifest   1.0                   Defender                            Core,Desk {Get-MpPreference, Set-MpPreference, Ad…
Manifest   1.0.2.0               DeliveryOptimization                Core,Desk {Delete-DeliveryOptimizationCache, Get-…
Manifest   1.0.0.0               DirectAccessClientComponents        Core,Desk {Disable-DAManualEntryPointSelection, E…
Script     3.0                   Dism                                Core,Desk {Add-AppxProvisionedPackage, Add-Window…
Manifest   1.0.0.0               DnsClient                           Core,Desk {Resolve-DnsName, Clear-DnsClientCache,…
Manifest   1.0.0.0               EventTracingManagement              Core,Desk {Start-EtwTraceSession, New-EtwTraceSes…
Manifest   2.0.0.0               International                       Core,Desk {Get-WinDefaultInputMethodOverride, Set…
Manifest   3.0.0.0               Microsoft.PowerShell.Diagnostics    Core,Desk {Get-WinEvent, Get-Counter, Import-Coun…
Manifest   1.0.0.0               Microsoft.PowerShell.LocalAccounts  Core,Desk {Add-LocalGroupMember, Disable-LocalUse…
Manifest   3.1.0.0               Microsoft.PowerShell.Management     Core,Desk {Add-Content, Clear-Content, Clear-Item…
Manifest   1.0                   MMAgent                             Core,Desk {Disable-MMAgent, Enable-MMAgent, Set-M…
Manifest   2.0.0.0               NetAdapter                          Core,Desk {Disable-NetAdapter, Disable-NetAdapter…
Manifest   1.0.0.0               NetConnection                       Core,Desk {Get-NetConnectionProfile, Set-NetConne…
Manifest   1.0.0.0               NetEventPacketCapture               Core,Desk {New-NetEventSession, Remove-NetEventSe…
Manifest   2.0.0.0               NetLbfo                             Core,Desk {Add-NetLbfoTeamMember, Add-NetLbfoTeam…
Manifest   1.0.0.0               NetNat                              Core,Desk {Get-NetNat, Get-NetNatExternalAddress,…
Manifest   2.0.0.0               NetQos                              Core,Desk {Get-NetQosPolicy, Set-NetQosPolicy, Re…
Manifest   2.0.0.0               NetSecurity                         Core,Desk {Get-DAPolicyChange, New-NetIPsecAuthPr…
Manifest   1.0.0.0               NetSwitchTeam                       Core,Desk {New-NetSwitchTeam, Remove-NetSwitchTea…
Manifest   1.0.0.0               NetTCPIP                            Core,Desk {Get-NetIPAddress, Get-NetIPInterface, …
Manifest   1.0.0.0               NetworkConnectivityStatus           Core,Desk {Get-DAConnectionStatus, Get-NCSIPolicy…
Manifest   1.0.0.0               NetworkSwitchManager                Core,Desk {Disable-NetworkSwitchEthernetPort, Ena…
Manifest   1.0.0.0               NetworkTransition                   Core,Desk {Add-NetIPHttpsCertBinding, Disable-Net…
Manifest   1.0.0.0               PcsvDevice                          Core,Desk {Get-PcsvDevice, Start-PcsvDevice, Stop…
Manifest   1.0.0.0               PnpDevice                           Core,Desk {Get-PnpDevice, Get-PnpDeviceProperty, …
Manifest   1.1                   PrintManagement                     Core,Desk {Add-Printer, Add-PrinterDriver, Add-Pr…
Binary     1.0.11                ProcessMitigations                  Core,Desk {Get-ProcessMitigation, Set-ProcessMiti…
Manifest   1.0.0.0               ScheduledTasks                      Core,Desk {Get-ScheduledTask, Set-ScheduledTask, …
Manifest   2.0.0.0               SecureBoot                          Core,Desk {Confirm-SecureBootUEFI, Set-SecureBoot…
Manifest   2.0.0.0               SmbShare                            Core,Desk {Get-SmbShare, Remove-SmbShare, Set-Smb…
Manifest   2.0.0.0               SmbWitness                          Core,Desk {Get-SmbWitnessClient, Move-SmbWitnessC…
Manifest   1.0.0.0               StartLayout                         Core,Desk {Export-StartLayout, Import-StartLayout…
Manifest   2.0.0.0               Storage                             Core,Desk {Add-InitiatorIdToMaskingSet, Add-Parti…
Manifest   1.0.0.0               TroubleshootingPack                 Core,Desk {Get-TroubleshootingPack, Invoke-Troubl…
Manifest   2.0.0.0               TrustedPlatformModule               Core,Desk {Get-Tpm, Initialize-Tpm, Clear-Tpm, Un…
Binary     2.1.639.0             UEV                                 Core,Desk
Manifest   2.0.0.0               VpnClient                           Core,Desk {Add-VpnConnection, Set-VpnConnection, …
Manifest   1.0.0.0               Wdac                                Core,Desk {Get-OdbcDriver, Set-OdbcDriver, Get-Od…
Manifest   2.0.0.0               Whea                                Core,Desk {Get-WheaMemoryPolicy, Set-WheaMemoryPo…
Manifest   1.0.0.0               WindowsDeveloperLicense             Core,Desk {Get-WindowsDeveloperLicense, Unregiste…
Script     1.0                   WindowsErrorReporting               Core,Desk {Enable-WindowsErrorReporting, Disable-…
Manifest   1.0.0.0               WindowsSearch                       Core,Desk {Get-WindowsSearchSetting, Set-WindowsS…
Manifest   1.0.0.0               WindowsUpdate                       Core,Desk Get-WindowsUpdateLog
Manifest   1.0.0.2               WindowsUpdateProvider               Core,Desk {Get-WUAVersion, Get-WULastInstallation…

Debug output

DEBUG: 10:56:08 - ConnectAzureRmAccountCommand begin processing with ParameterSet 'UserWithSubscriptionId'.
DEBUG: 10:56:08 - using account id 'rodolfograve@gmail.com'...
DEBUG: 10:56:08 - Autosave setting from startup session: 'CurrentUser'
DEBUG: 10:56:08 - No autosave setting detected in environment variable 'AzContextAutoSave'.
DEBUG: 10:56:08 - Using Autosave scope 'CurrentUser'
DEBUG: [Common.Authentication]: Authenticating using configuration values: Domain: 'Common', Endpoint: 'https://login.microsoftonline.com/', ClientId: '1950a258-227b-4e31-a9cf-717495945fc2', ClientRedirect: 'urn:ietf:wg:oauth:2.0:oob', ResourceClientUri: 'https://management.core.windows.net/', ValidateAuthority: 'True'
DEBUG: [Common.Authentication]: Acquiring token using context with Authority 'https://login.microsoftonline.com/Common/', CorrelationId: '00000000-0000-0000-0000-000000000000', ValidateAuthority: 'True'
DEBUG: [Common.Authentication]: Acquiring token using AdalConfiguration with Domain: 'Common', AdEndpoint: 'https://login.microsoftonline.com/', ClientId: '1950a258-227b-4e31-a9cf-717495945fc2', ClientRedirectUri: urn:ietf:wg:oauth:2.0:oob
WARNING: To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code C7T23CXRC to authenticate.
DEBUG: [ADAL]: Information: 2020-07-28T09:56:08.4120584Z: 76b474e3-011f-414a-b0e2-423e3bdcfc18 - LoggerBase.cs: ADAL PCL.CoreCLR with assembly version '3.19.2.6005', file version '3.19.50302.0130' and informational version '2a8bec6c4c76d0c1ef819b55bdc3cda2d2605056' is running...

DEBUG: [ADAL]: Information: 2020-07-28T09:56:08.4121380Z: 76b474e3-011f-414a-b0e2-423e3bdcfc18 - LoggerBase.cs: ADAL PCL.CoreCLR with assembly version '3.19.2.6005', file version '3.19.50302.0130' and informational version '2a8bec6c4c76d0c1ef819b55bdc3cda2d2605056' is running...

DEBUG: [ADAL]: Information: 2020-07-28T09:56:08.4140844Z: 76b474e3-011f-414a-b0e2-423e3bdcfc18 - LoggerBase.cs: === Token Acquisition started:
        CacheType: null
        Authentication Target: User
        , Authority Host: login.microsoftonline.com

DEBUG: [ADAL]: Information: 2020-07-28T09:56:08.4141634Z: 76b474e3-011f-414a-b0e2-423e3bdcfc18 - LoggerBase.cs: === Token Acquisition started:
        Authority: https://login.microsoftonline.com/Common/
        Resource: https://management.core.windows.net/
        ClientId: 1950a258-227b-4e31-a9cf-717495945fc2
        CacheType: null
        Authentication Target: User

DEBUG: [ADAL]: Warning: 2020-07-28T09:56:34.2981775Z: 76b474e3-011f-414a-b0e2-423e3bdcfc18 - LoggerBase.cs: Returned correlation id '80678d72-02e1-4680-a898-7cd4f740d3e2' does not match the sent correlation id '76b474e3-011f-414a-b0e2-423e3bdcfc18'

DEBUG: [ADAL]: Warning: 2020-07-28T09:56:34.2983649Z: 76b474e3-011f-414a-b0e2-423e3bdcfc18 - LoggerBase.cs: Returned correlation id '80678d72-02e1-4680-a898-7cd4f740d3e2' does not match the sent correlation id '76b474e3-011f-414a-b0e2-423e3bdcfc18'

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.3005408Z: 00000000-0000-0000-0000-000000000000 - LoggerBase.cs: Deserialized 5 items to token cache.

DEBUG: [ADAL]: Verbose: 2020-07-28T09:56:34.3007219Z: 76b474e3-011f-414a-b0e2-423e3bdcfc18 - LoggerBase.cs: Storing token in the cache...

DEBUG: [ADAL]: Verbose: 2020-07-28T09:56:34.3008276Z: 76b474e3-011f-414a-b0e2-423e3bdcfc18 - LoggerBase.cs: Storing token in the cache...

DEBUG: [ADAL]: Verbose: 2020-07-28T09:56:34.3009443Z: 76b474e3-011f-414a-b0e2-423e3bdcfc18 - LoggerBase.cs: An item was stored in the cache

DEBUG: [ADAL]: Verbose: 2020-07-28T09:56:34.3010410Z: 76b474e3-011f-414a-b0e2-423e3bdcfc18 - LoggerBase.cs: An item was stored in the cache

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.3012567Z: 76b474e3-011f-414a-b0e2-423e3bdcfc18 - LoggerBase.cs: === Token Acquisition finished successfully. An access token was returned: Expiration Time: 28/07/2020 10:56:33 +00:00

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.3013844Z: 76b474e3-011f-414a-b0e2-423e3bdcfc18 - LoggerBase.cs: === Token Acquisition finished successfully. An access token was returned: Expiration Time: 28/07/2020 10:56:33 +00:00Access Token Hash: oIEr19dlzmTqEWHoM75WVhVlI2Wo+X84DDpn+3pTYiU=
         User id: 3B42ufYhX5Q19K6cdS_AqBpORRDfA7BZU6QN1sveQqQ

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.3015248Z: 00000000-0000-0000-0000-000000000000 - LoggerBase.cs: Serializing token cache with 5 items.

DEBUG: ============================ HTTP REQUEST ============================

HTTP Method:
GET

Absolute Uri:
https://management.azure.com/tenants?api-version=2016-06-01

Headers:
x-ms-client-request-id        : f61ccc41-b4f4-4750-826d-c17f73ac3af9
Accept-Language               : en-US

Body:

DEBUG: ============================ HTTP RESPONSE ============================

Status Code:
OK

Headers:
Cache-Control                 : no-cache
Pragma                        : no-cache
x-ms-ratelimit-remaining-tenant-reads: 11998
x-ms-request-id               : 3ac65d1c-8d59-458b-9358-3ea6721d50bf
x-ms-correlation-request-id   : 3ac65d1c-8d59-458b-9358-3ea6721d50bf
x-ms-routing-request-id       : UKWEST:20200728T095633Z:3ac65d1c-8d59-458b-9358-3ea6721d50bf
Strict-Transport-Security     : max-age=31536000; includeSubDomains
X-Content-Type-Options        : nosniff
Date                          : Tue, 28 Jul 2020 09:56:32 GMT

Body:
{
  "value": [
    {
      "id": "/tenants/a599a1f5-fa4f-4265-9ea5-_redacted_",
      "tenantId": "a599a1f5-fa4f-4265-9ea5-_redacted_"
    },
    {
      "id": "/tenants/32c8e182-eaf3-43ba-abe6-_redacted_",
      "tenantId": "32c8e182-eaf3-43ba-abe6-_redacted_"
    }
  ]
}

DEBUG: [Common.Authentication]: Authenticating using configuration values: Domain: 'a599a1f5-fa4f-4265-9ea5-_redacted_', Endpoint: 'https://login.microsoftonline.com/', ClientId: '1950a258-227b-4e31-a9cf-717495945fc2', ClientRedirect: 'urn:ietf:wg:oauth:2.0:oob', ResourceClientUri: 'https://management.core.windows.net/', ValidateAuthority: 'True'
DEBUG: [Common.Authentication]: Acquiring token using context with Authority 'https://login.microsoftonline.com/a599a1f5-fa4f-4265-9ea5-_redacted_/', CorrelationId: '00000000-0000-0000-0000-000000000000', ValidateAuthority: 'True'
DEBUG: [Common.Authentication]: Acquiring token using AdalConfiguration with Domain: 'a599a1f5-fa4f-4265-9ea5-_redacted_', AdEndpoint: 'https://login.microsoftonline.com/', ClientId: '1950a258-227b-4e31-a9cf-717495945fc2', ClientRedirectUri: urn:ietf:wg:oauth:2.0:oob
DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.4875573Z: 782e3a6a-1809-4272-938b-3d417d5971a0 - LoggerBase.cs: ADAL PCL.CoreCLR with assembly version '3.19.2.6005', file version '3.19.50302.0130' and informational version '2a8bec6c4c76d0c1ef819b55bdc3cda2d2605056' is running...

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.4876982Z: 782e3a6a-1809-4272-938b-3d417d5971a0 - LoggerBase.cs: ADAL PCL.CoreCLR with assembly version '3.19.2.6005', file version '3.19.50302.0130' and informational version '2a8bec6c4c76d0c1ef819b55bdc3cda2d2605056' is running...

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.4878207Z: 782e3a6a-1809-4272-938b-3d417d5971a0 - LoggerBase.cs: === Token Acquisition started:
        CacheType: null
        Authentication Target: User
        , Authority Host: login.microsoftonline.com

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.4879223Z: 782e3a6a-1809-4272-938b-3d417d5971a0 - LoggerBase.cs: === Token Acquisition started:
        Authority: https://login.microsoftonline.com/a599a1f5-fa4f-4265-9ea5-_redacted_/
        Resource: https://management.core.windows.net/
        ClientId: 1950a258-227b-4e31-a9cf-717495945fc2
        CacheType: null
        Authentication Target: User

DEBUG: [ADAL]: Verbose: 2020-07-28T09:56:34.4881035Z: 782e3a6a-1809-4272-938b-3d417d5971a0 - LoggerBase.cs: Loading from cache.

DEBUG: [ADAL]: Verbose: 2020-07-28T09:56:34.4881979Z: 782e3a6a-1809-4272-938b-3d417d5971a0 - LoggerBase.cs: Loading from cache.

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.4896390Z: 00000000-0000-0000-0000-000000000000 - LoggerBase.cs: Deserialized 5 items to token cache.

DEBUG: [ADAL]: Verbose: 2020-07-28T09:56:34.4898023Z: 782e3a6a-1809-4272-938b-3d417d5971a0 - LoggerBase.cs: Looking up cache for a token...

DEBUG: [ADAL]: Verbose: 2020-07-28T09:56:34.4898961Z: 782e3a6a-1809-4272-938b-3d417d5971a0 - LoggerBase.cs: Looking up cache for a token...

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.4900162Z: 782e3a6a-1809-4272-938b-3d417d5971a0 - LoggerBase.cs: An item matching the requested resource was found in the cache

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.4901066Z: 782e3a6a-1809-4272-938b-3d417d5971a0 - LoggerBase.cs: An item matching the requested resource was found in the cache

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.4902433Z: 782e3a6a-1809-4272-938b-3d417d5971a0 - LoggerBase.cs: An expired or near expiry token was found in the cache

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.4903327Z: 782e3a6a-1809-4272-938b-3d417d5971a0 - LoggerBase.cs: An expired or near expiry token was found in the cache

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.4904165Z: 782e3a6a-1809-4272-938b-3d417d5971a0 - LoggerBase.cs: A matching item (access token or refresh token or both) was found in the cache

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.4905122Z: 782e3a6a-1809-4272-938b-3d417d5971a0 - LoggerBase.cs: A matching item (access token or refresh token or both) was found in the cache

DEBUG: [ADAL]: Verbose: 2020-07-28T09:56:34.4906087Z: 782e3a6a-1809-4272-938b-3d417d5971a0 - LoggerBase.cs: Refreshing access token...

DEBUG: [ADAL]: Verbose: 2020-07-28T09:56:34.4906957Z: 782e3a6a-1809-4272-938b-3d417d5971a0 - LoggerBase.cs: Refreshing access token...

DEBUG: [ADAL]: Error: 2020-07-28T09:56:34.7200378Z: 782e3a6a-1809-4272-938b-3d417d5971a0 - LoggerBase.cs: Exception type: Microsoft.IdentityModel.Clients.ActiveDirectory.AdalSilentTokenAcquisitionException, ErrorCode: failed_to_acquire_token_silently ---> Exception type: Microsoft.IdentityModel.Clients.ActiveDirectory.AdalServiceException, ErrorCode: invalid_grant, StatusCode: 400 ---> Exception type: System.Net.Http.HttpRequestException ---> Exception type: Microsoft.IdentityModel.Clients.ActiveDirectory.AdalException, ErrorCode: {"error":"invalid_grant","error_description":"AADSTS700082: The refresh token has expired due to inactivity. The token was issued on 2019-10-12T11:04:52.8016649Z and was inactive for 90.00:00:00.\r\nTrace ID: e5ab2b81-3d4a-4754-8648-78567b761200\r\nCorrelation ID: 782e3a6a-1809-4272-938b-3d417d5971a0\r\nTimestamp: 2020-07-28 09:56:33Z","error_codes":[700082],"timestamp":"2020-07-28 09:56:33Z","trace_id":"e5ab2b81-3d4a-4754-8648-78567b761200","correlation_id":"782e3a6a-1809-4272-938b-3d417d5971a0","error_uri":"https://login.microsoftonline.com/error?code=700082"}
--- End of inner exception stack trace ---
--- End of inner exception stack trace ---
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Http.AdalHttpClient.GetResponseAsync[T](Boolean respondToDeviceAuthChallenge)
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Http.AdalHttpClient.GetResponseAsync[T]()
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.SendHttpMessageAsync(IRequestParameters requestParameters)
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.SendTokenRequestByRefreshTokenAsync(String refreshToken)
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.RefreshAccessTokenAsync(AuthenticationResultEx result)
--- End of inner exception stack trace ---
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenSilentHandler.SendTokenRequestAsync()
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.CheckAndAcquireTokenUsingBrokerAsync()
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.RunAsync()

DEBUG: [ADAL]: Error: 2020-07-28T09:56:34.7214864Z: 782e3a6a-1809-4272-938b-3d417d5971a0 - LoggerBase.cs: Microsoft.IdentityModel.Clients.ActiveDirectory.AdalSilentTokenAcquisitionException: Failed to acquire token silently as no token was found in the cache. Call method AcquireToken
 ---> Microsoft.IdentityModel.Clients.ActiveDirectory.AdalServiceException: AADSTS700082: The refresh token has expired due to inactivity. The token was issued on 2019-10-12T11:04:52.8016649Z and was inactive for 90.00:00:00.
Trace ID: e5ab2b81-3d4a-4754-8648-78567b761200
Correlation ID: 782e3a6a-1809-4272-938b-3d417d5971a0
Timestamp: 2020-07-28 09:56:33Z
 ---> System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (BadRequest).
 ---> Microsoft.IdentityModel.Clients.ActiveDirectory.AdalException: {"error":"invalid_grant","error_description":"AADSTS700082: The refresh token has expired due to inactivity. The token was issued on 2019-10-12T11:04:52.8016649Z and was inactive for 90.00:00:00.\r\nTrace ID: e5ab2b81-3d4a-4754-8648-78567b761200\r\nCorrelation ID: 782e3a6a-1809-4272-938b-3d417d5971a0\r\nTimestamp: 2020-07-28 09:56:33Z","error_codes":[700082],"timestamp":"2020-07-28 09:56:33Z","trace_id":"e5ab2b81-3d4a-4754-8648-78567b761200","correlation_id":"782e3a6a-1809-4272-938b-3d417d5971a0","error_uri":"https://login.microsoftonline.com/error?code=700082"}: Unknown error
        ErrorCode: {"error":"invalid_grant","error_description":"AADSTS700082: The refresh token has expired due to inactivity. The token was issued on 2019-10-12T11:04:52.8016649Z and was inactive for 90.00:00:00.\r\nTrace ID: e5ab2b81-3d4a-4754-8648-78567b761200\r\nCorrelation ID: 782e3a6a-1809-4272-938b-3d417d5971a0\r\nTimestamp: 2020-07-28 09:56:33Z","error_codes":[700082],"timestamp":"2020-07-28 09:56:33Z","trace_id":"e5ab2b81-3d4a-4754-8648-78567b761200","correlation_id":"782e3a6a-1809-4272-938b-3d417d5971a0","error_uri":"https://login.microsoftonline.com/error?code=700082"}
   --- End of inner exception stack trace ---
   --- End of inner exception stack trace ---
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Http.AdalHttpClient.GetResponseAsync[T](Boolean respondToDeviceAuthChallenge)
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Http.AdalHttpClient.GetResponseAsync[T]()
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.SendHttpMessageAsync(IRequestParameters requestParameters)
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.SendTokenRequestByRefreshTokenAsync(String refreshToken)
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.RefreshAccessTokenAsync(AuthenticationResultEx result)
        ErrorCode: invalid_grant
        StatusCode: 400
   --- End of inner exception stack trace ---
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenSilentHandler.SendTokenRequestAsync()
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.CheckAndAcquireTokenUsingBrokerAsync()
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.RunAsync()
        ErrorCode: failed_to_acquire_token_silently

DEBUG: [Common.Authentication]: Authenticating using configuration values: Domain: '32c8e182-eaf3-43ba-abe6-_redacted_', Endpoint: 'https://login.microsoftonline.com/', ClientId: '1950a258-227b-4e31-a9cf-_redacted_', ClientRedirect: 'urn:ietf:wg:oauth:2.0:oob', ResourceClientUri: 'https://management.core.windows.net/', ValidateAuthority: 'True'
DEBUG: [Common.Authentication]: Acquiring token using context with Authority 'https://login.microsoftonline.com/32c8e182-eaf3-43ba-abe6-2a96471cb119/', CorrelationId: '00000000-0000-0000-0000-000000000000', ValidateAuthority: 'True'
DEBUG: [Common.Authentication]: Acquiring token using AdalConfiguration with Domain: '32c8e182-eaf3-43ba-abe6-2a96471cb119', AdEndpoint: 'https://login.microsoftonline.com/', ClientId: '1950a258-227b-4e31-a9cf-_redacted_', ClientRedirectUri: urn:ietf:wg:oauth:2.0:oob
DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.7227000Z: 6ef3a031-0c2d-4504-9038-db56486668e5 - LoggerBase.cs: ADAL PCL.CoreCLR with assembly version '3.19.2.6005', file version '3.19.50302.0130' and informational version '2a8bec6c4c76d0c1ef819b55bdc3cda2d2605056' is running...

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.7228104Z: 6ef3a031-0c2d-4504-9038-db56486668e5 - LoggerBase.cs: ADAL PCL.CoreCLR with assembly version '3.19.2.6005', file version '3.19.50302.0130' and informational version '2a8bec6c4c76d0c1ef819b55bdc3cda2d2605056' is running...

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.7229065Z: 6ef3a031-0c2d-4504-9038-db56486668e5 - LoggerBase.cs: === Token Acquisition started:
        CacheType: null
        Authentication Target: User
        , Authority Host: login.microsoftonline.com

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.7229811Z: 6ef3a031-0c2d-4504-9038-db56486668e5 - LoggerBase.cs: === Token Acquisition started:
        Authority: https://login.microsoftonline.com/32c8e182-eaf3-43ba-abe6-_redacted_/
        Resource: https://management.core.windows.net/
        ClientId: 1950a258-227b-4e31-a9cf-717495945fc2
        CacheType: null
        Authentication Target: User

DEBUG: [ADAL]: Verbose: 2020-07-28T09:56:34.7231461Z: 6ef3a031-0c2d-4504-9038-db56486668e5 - LoggerBase.cs: Loading from cache.

DEBUG: [ADAL]: Verbose: 2020-07-28T09:56:34.7232296Z: 6ef3a031-0c2d-4504-9038-db56486668e5 - LoggerBase.cs: Loading from cache.

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.7246666Z: 00000000-0000-0000-0000-000000000000 - LoggerBase.cs: Deserialized 5 items to token cache.

DEBUG: [ADAL]: Verbose: 2020-07-28T09:56:34.7248367Z: 6ef3a031-0c2d-4504-9038-db56486668e5 - LoggerBase.cs: Looking up cache for a token...

DEBUG: [ADAL]: Verbose: 2020-07-28T09:56:34.7249076Z: 6ef3a031-0c2d-4504-9038-db56486668e5 - LoggerBase.cs: Looking up cache for a token...

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.7250027Z: 6ef3a031-0c2d-4504-9038-db56486668e5 - LoggerBase.cs: An item matching the requested resource was found in the cache

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.7250766Z: 6ef3a031-0c2d-4504-9038-db56486668e5 - LoggerBase.cs: An item matching the requested resource was found in the cache

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.7251979Z: 6ef3a031-0c2d-4504-9038-db56486668e5 - LoggerBase.cs: An expired or near expiry token was found in the cache

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.7252645Z: 6ef3a031-0c2d-4504-9038-db56486668e5 - LoggerBase.cs: An expired or near expiry token was found in the cache

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.7253263Z: 6ef3a031-0c2d-4504-9038-db56486668e5 - LoggerBase.cs: A matching item (access token or refresh token or both) was found in the cache

DEBUG: [ADAL]: Information: 2020-07-28T09:56:34.7253919Z: 6ef3a031-0c2d-4504-9038-db56486668e5 - LoggerBase.cs: A matching item (access token or refresh token or both) was found in the cache

DEBUG: [ADAL]: Verbose: 2020-07-28T09:56:34.7254628Z: 6ef3a031-0c2d-4504-9038-db56486668e5 - LoggerBase.cs: Refreshing access token...

DEBUG: [ADAL]: Verbose: 2020-07-28T09:56:34.7255269Z: 6ef3a031-0c2d-4504-9038-db56486668e5 - LoggerBase.cs: Refreshing access token...

DEBUG: [ADAL]: Error: 2020-07-28T09:56:34.9316890Z: 6ef3a031-0c2d-4504-9038-db56486668e5 - LoggerBase.cs: Exception type: Microsoft.IdentityModel.Clients.ActiveDirectory.AdalSilentTokenAcquisitionException, ErrorCode: failed_to_acquire_token_silently ---> Exception type: Microsoft.IdentityModel.Clients.ActiveDirectory.AdalServiceException, ErrorCode: invalid_grant, StatusCode: 400 ---> Exception type: System.Net.Http.HttpRequestException ---> Exception type: Microsoft.IdentityModel.Clients.ActiveDirectory.AdalException, ErrorCode: {"error":"invalid_grant","error_description":"AADSTS700082: The refresh token has expired due to inactivity. The token was issued on 2019-10-12T10:46:41.1866080Z and was inactive for 90.00:00:00.\r\nTrace ID: 7845ce02-38c1-4e1b-b2a3-7daa28f65300\r\nCorrelation ID: 6ef3a031-0c2d-4504-9038-db56486668e5\r\nTimestamp: 2020-07-28 09:56:33Z","error_codes":[700082],"timestamp":"2020-07-28 09:56:33Z","trace_id":"7845ce02-38c1-4e1b-b2a3-7daa28f65300","correlation_id":"6ef3a031-0c2d-4504-9038-db56486668e5","error_uri":"https://login.microsoftonline.com/error?code=700082"}
--- End of inner exception stack trace ---
--- End of inner exception stack trace ---
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Http.AdalHttpClient.GetResponseAsync[T](Boolean respondToDeviceAuthChallenge)
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Http.AdalHttpClient.GetResponseAsync[T]()
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.SendHttpMessageAsync(IRequestParameters requestParameters)
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.SendTokenRequestByRefreshTokenAsync(String refreshToken)
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.RefreshAccessTokenAsync(AuthenticationResultEx result)
--- End of inner exception stack trace ---
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenSilentHandler.SendTokenRequestAsync()
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.CheckAndAcquireTokenUsingBrokerAsync()
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.RunAsync()

DEBUG: [ADAL]: Error: 2020-07-28T09:56:34.9331423Z: 6ef3a031-0c2d-4504-9038-db56486668e5 - LoggerBase.cs: Microsoft.IdentityModel.Clients.ActiveDirectory.AdalSilentTokenAcquisitionException: Failed to acquire token silently as no token was found in the cache. Call method AcquireToken
 ---> Microsoft.IdentityModel.Clients.ActiveDirectory.AdalServiceException: AADSTS700082: The refresh token has expired due to inactivity. The token was issued on 2019-10-12T10:46:41.1866080Z and was inactive for 90.00:00:00.
Trace ID: 7845ce02-38c1-4e1b-b2a3-7daa28f65300
Correlation ID: 6ef3a031-0c2d-4504-9038-db56486668e5
Timestamp: 2020-07-28 09:56:33Z
 ---> System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (BadRequest).
 ---> Microsoft.IdentityModel.Clients.ActiveDirectory.AdalException: {"error":"invalid_grant","error_description":"AADSTS700082: The refresh token has expired due to inactivity. The token was issued on 2019-10-12T10:46:41.1866080Z and was inactive for 90.00:00:00.\r\nTrace ID: 7845ce02-38c1-4e1b-b2a3-7daa28f65300\r\nCorrelation ID: 6ef3a031-0c2d-4504-9038-db56486668e5\r\nTimestamp: 2020-07-28 09:56:33Z","error_codes":[700082],"timestamp":"2020-07-28 09:56:33Z","trace_id":"7845ce02-38c1-4e1b-b2a3-7daa28f65300","correlation_id":"6ef3a031-0c2d-4504-9038-db56486668e5","error_uri":"https://login.microsoftonline.com/error?code=700082"}: Unknown error
        ErrorCode: {"error":"invalid_grant","error_description":"AADSTS700082: The refresh token has expired due to inactivity. The token was issued on 2019-10-12T10:46:41.1866080Z and was inactive for 90.00:00:00.\r\nTrace ID: 7845ce02-38c1-4e1b-b2a3-7daa28f65300\r\nCorrelation ID: 6ef3a031-0c2d-4504-9038-db56486668e5\r\nTimestamp: 2020-07-28 09:56:33Z","error_codes":[700082],"timestamp":"2020-07-28 09:56:33Z","trace_id":"7845ce02-38c1-4e1b-b2a3-7daa28f65300","correlation_id":"6ef3a031-0c2d-4504-9038-db56486668e5","error_uri":"https://login.microsoftonline.com/error?code=700082"}
   --- End of inner exception stack trace ---
   --- End of inner exception stack trace ---
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Http.AdalHttpClient.GetResponseAsync[T](Boolean respondToDeviceAuthChallenge)
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Http.AdalHttpClient.GetResponseAsync[T]()
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.SendHttpMessageAsync(IRequestParameters requestParameters)
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.SendTokenRequestByRefreshTokenAsync(String refreshToken)
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.RefreshAccessTokenAsync(AuthenticationResultEx result)
        ErrorCode: invalid_grant
        StatusCode: 400
   --- End of inner exception stack trace ---
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenSilentHandler.SendTokenRequestAsync()
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.CheckAndAcquireTokenUsingBrokerAsync()
   at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.RunAsync()
        ErrorCode: failed_to_acquire_token_silently

DEBUG: AzureQoSEvent: CommandName - Connect-AzAccount; IsSuccess - True; Duration - 00:00:26.8110671;
DEBUG: Finish sending metric.
DEBUG: 10:56:35 - ConnectAzureRmAccountCommand end processing.
DEBUG: 10:56:35 - ConnectAzureRmAccountCommand begin processing with ParameterSet 'UserWithSubscriptionId'.
DEBUG: 10:56:35 - using account id 'rodolfograve@gmail.com'...
What if: Performing the operation "log in" on target "User account in environment 'AzureCloud'".
DEBUG: AzureQoSEvent: CommandName - Connect-AzAccount; IsSuccess - True; Duration - 00:00:00.0036043;
DEBUG: Finish sending metric.
DEBUG: 10:56:36 - ConnectAzureRmAccountCommand end processing.
Exception: F:\src\azure-powershell\repro.ps1:14
Line |
  14 |      Throw "I would like my tests to be able to assume Connect-ToMySub …
     |      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | I would like my tests to be able to assume Connect-ToMySubscription will always return the same value,
     | WhatIf or not

Error output

WARNING: Breaking changes in the cmdlet 'Resolve-AzError' :
WARNING:  - The `Resolve-Error` alias will be removed in a future release.  Please change any scripts that use this alias to use `Resolve-AzError` instead.

WARNING: NOTE : Go to https://aka.ms/azps-changewarnings for steps to suppress this breaking change warning, and other information on breaking changes in Azure PowerShell.

   HistoryId: -1

Message        : I would like my tests to be able to assume Connect-ToMySubscription will always return the same
                 value, WhatIf or not
StackTrace     :
Exception      : System.Management.Automation.RuntimeException
InvocationInfo : {}
Line           :        Throw "I would like my tests to be able to assume Connect-ToMySubscription will always return the
                 same value, WhatIf or not"

Position       : At F:\src\azure-powershell\repro.ps1:14 char:2
                 +     Throw "I would like my tests to be able to assume Connect-ToMySub …
                 +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
HistoryId      : -1

Message        : I would like my tests to be able to assume Connect-ToMySubscription will always return the same
                 value, WhatIf or not
StackTrace     :
Exception      : System.Management.Automation.RuntimeException
InvocationInfo : {}
Line           :        Throw "I would like my tests to be able to assume Connect-ToMySubscription will always return the
                 same value, WhatIf or not"

Position       : At F:\src\azure-powershell\repro.ps1:14 char:2
                 +     Throw "I would like my tests to be able to assume Connect-ToMySub …
                 +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
HistoryId      : -1

Message        : I would like my tests to be able to assume Connect-ToMySubscription will always return the same
                 value, WhatIf or not
StackTrace     :
Exception      : System.Management.Automation.RuntimeException
InvocationInfo : {}
Line           :        Throw "I would like my tests to be able to assume Connect-ToMySubscription will always return the
                 same value, WhatIf or not"

Position       : At F:\src\azure-powershell\repro.ps1:13 char:2
                 +     Throw "I would like my tests to be able to assume Connect-ToMySub …
                 +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
HistoryId      : -1
dingmeng-xue commented 4 years ago

@rodolfograve , what's the expected result when using WhatIf? I didn't figure out the meaning of -Whatif to Connect-AzAccount.

rodolfograve commented 4 years ago

Hi, and thanks for the response.

WhatIf is used very frequently for testing purposes, as a way to make the commands not to perform any action that would require a real resource to be affected in any way.

I agree that in the case of Connect-AzAccount it's not obvious what WhatIf should do if you look at it from the "hypothetical" excecution point of view. However, it's easier to define if we come to it from the "how would you test a script that makes use of Connect-AzAccount" angle.

I suggest something like:

"Connect-AzAccount -WhatIf" should return a fake PSAzureProfile object, either with well-known, hard-coded, fake Tenant and Subscription ids, or using random values.

In terms of code, my suggestion is that we add an else here: https://github.com/Azure/azure-powershell/blob/f1b754320ca279d65949ae18740b20440b773c89/src/Accounts/Accounts/Account/ConnectAzureRmAccount.cs#L329-L338

This is pseudo-code. I haven't looked at the classes involved to see if they have a constructor we could use, etc. but it should be possible to make those modifications:

else
{
     WriteObject(PSAzureProfile.CreateFake());
}

Another option is that I'm just wrong trying to use -WhatIf for this purpose, but I haven't found any other way to write tests for PowerShell scripts that target resources. Any suggestions that work around this issue are very welcome.

dingmeng-xue commented 4 years ago

@rodolfograve , many az powershell cmdlets support -WhatIf but they need the correct context and some operation needs real HTTP call to check status. If we return faked context, I believe other cmdlets with -WhatIfwill be failed. Could you share more why you cannot do Connect-AzAccount in test env?

@mikefrobbins , @dcaro , @markcowl for your awareness

rodolfograve commented 4 years ago

@dingmeng-xue , thanks again.

I think there are two separate issues/topics here:

  1. The fact that the behaviour of Connect-AzAccount changes with WhatIf in a way that breaks other functions: return a value vs. not.
  2. Trying to find an approach for testing scripts that use PowerShell Az

I think #⁠1 is a fundamental issue. As the author of a script that uses a script that uses a script (...) that uses Connect-AzAccount, I don't expect things to fail only because I added the WhatIf flag. Everyone expects WhatIf to change the behaviour of the script so that it doesn't perform any real operations, but not that it changes other aspects of the integration of the script with other scripts.

If possible, I would like to focus on that aspect as the most important.

As for #⁠2, the main reason is that we are trying to avoid having credentials embedded in the code. This creates a security problem, but more importantly, it makes your tests fails if the "right" environment is not available:

  1. A tenant with the right id and user/service principal
  2. A subscription with the right id.

In an attempt to illustrate this one (examples are always dangerous), imagine I want to test the Do-Something command below. Please, keep in mind that in practice the scripts are much more complicated and nested:

Function Connect-ToMySubscription {
    [CmdletBinding(SupportsShouldProcess, ConfirmImpact="Low")]
    Param()
        $Credentials = Get-MyCredentialsFromEnvironment # So that the script connects to the right subscription according to the environment

    Connect-AzAccount -Credentials $Credentials -Tenant "MyProductionTenant" -Subscription "MyProductionSubscription" -ServicePrincipal
}

Function Get-Something {
    [CmdletBinding(SupportsShouldProcess, ConfirmImpact="Low")]
    Param()
        Connect-ToMySubscription
        # Execute some Get- Az commands
        $Result = Get-....
        return $Result
}

I think issue #⁠1 is well evidenced here. Get-Something would return different things with -WhatIf than without.

⁠2 is harder to show but I hope you can see why we would like to avoid any valid Service Principal credentials available on a developer's workstation, as that would mean they could impersonate that Service Principal. This goes against some of our security guidelines:

  1. Users should not be able to act under a service account.
  2. Users should not have access to service account credentials

And it would be a shame to water down our very secure approach to managing secrets only because we are not able to test the scripts :-)

rodolfograve commented 4 years ago

Hi @dingmeng-xue . Do you have any updates on this? Maybe @mikefrobbins , @dcaro , @markcowl?

dingmeng-xue commented 4 years ago

I'm revisiting -Whatif concept and I think Azure PowerShell is using the conventional way.

-Whatif displays a message that describes the effect of the command, instead of executing the command.

PS C:\Users\dixue> $a = New-Item -ItemType File -Path .\newfile1.txt -WhatIf
What if: Performing the operation "Create File" on target "Destination: C:\Users\dixue\newfile1.txt".
PS C:\Users\dixue> $a
PS C:\Users\dixue> Connect-AzAccount -WhatIf
What if: Performing the operation "log in" on target "User account in environment 'AzureCloud'".
rodolfograve commented 4 years ago

Thanks @dingmeng-xue . That definition of -WhatIf does not mention anything about returning values and what happens when scripts interact using -WhatIf.

I think I gave a couple of arguments in my previous comment. Is there any chance the Azure PowerShell team can take a look and address those arguments?

Test-ability is a very important feature of a framework. If you see Azure PowerShell as something people use interactively then you won't care too much, but there is a huge potential for people to write complicated scripts and even entire modules that build on top of Azure PowerShell (as we are!), and the current behaviour for -WhatIf is a deal breaker for that scenario.

dingmeng-xue commented 4 years ago

@rodolfograve , I understand your point from test perspective. But I'm still confused about expected behavior. Do you have any example from PowerShell core modules for my reference?

Below I tried New-AzResourceGroup and New-Item. Neither has returning value.

PS C:\> $a = New-AzResourceGroup -Name abc -Location westus -WhatIf
What if: Performing the operation "Replacing resource group ..." on target "abc".
PS C:\> $a | fl
PS C:\> $b = New-Item -Path .\a.json -WhatIf
What if: Performing the operation "Create File" on target "Destination: C:\a.json".
PS C:\> $b | fl
rodolfograve commented 4 years ago

@dingmeng-xue apologies for the delay, I was disconnected for a few days.

I can't find any examples of commands that return a value when -WhatIf, so it looks like I'm making an unfair request to the PowerShell Az team.

That does not mean the existing pattern is right, tough. I can't think of any other way in which we can test our scripts.

At this point all I can say is that I would appreciate any guidance on:

  1. How to work around this issue.
  2. What is the right place to present my case for a change in the way -WhatIf has been implemented all around.

Thanks a lot for all your help so far.

dingmeng-xue commented 4 years ago

Sorry that we have no test approach using a mock up Connect-AzAccount. In fact, we have 2 approaches to test Azure resources.

  1. Living test, that script connects to Azure and manipulates resource directly. We compare output with expectation in scripts.
  2. A complicated way used by Azure PowerShell development. The key idea is we recorded HTTP traffic during script execution and a mocked HTTP service will replay recorded HTTP traffic during test. But one of limitations is it cannot mock Connect-AzAccount . Here is brief introduction https://github.com/Azure/azure-powershell/blob/master/documentation/testing-docs/using-azure-test-framework.md.

I cannot figure out other approaches. If you know any way in practice, please let me know.

dingmeng-xue commented 4 years ago

Close this issue now. Please contact us if you need further help.