Azure / azure-powershell

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

Grouping in Invoke-AzCostManagementQuery results in: You cannot call a method on a null-valued expression. #25948

Open mblaschke-daimlertruck opened 2 weeks ago

mblaschke-daimlertruck commented 2 weeks ago

Description

When using grouping in Invoke-AzCostManagementQuery and the value is no set the cmdlet fails with You cannot call a method on a null-valued expression.

seems to be related to https://stackoverflow.com/questions/75682940/azure-cmdlet-how-to-group-results-with-invoke-azcostmanagementquery

Issue script & Debug output


$aggregation = @{
    totalCost = @{
      name     = "Cost"
      function = "SUM"
    }
  }

$grouping = @(
  @{
    type = "TagKey"
    name = "owner"
  }
)

$Result = Invoke-AzCostManagementQuery `
    -Scope "/providers/Microsoft.Management/managementgroups/xxxxxx" `
    -Timeframe 'Custom' `
    -TimePeriodFrom $StartDate `
    -TimePeriodTo $EndDate `
    -Type 'ActualCost' `
    -DatasetGranularity "Monthly" `
    -DatasetAggregation $aggregation `
    -DatasetGrouping $grouping -Debug

DEBUG: 2:05:36 PM - [ConfigManager] Got nothing from [DisplaySecretsWarning], Module = [], Cmdlet = []. Returning default value [True].
DEBUG: 2:05:36 PM - [ConfigManager] Got nothing from [DisplaySecretsWarning], Module = [], Cmdlet = []. Returning default value [True].
DEBUG: 2:05:36 PM - InvokeAzRestMethodCommand begin processing with ParameterSet 'ByPath'.
DEBUG: 2:05:36 PM - using account id 'xxxx'...
DEBUG: 2:05:36 PM - [ConfigManager] Got nothing from [DisplayBreakingChangeWarning], Module = [], Cmdlet = []. Returning default value [True].
DEBUG: [Common.Authentication]: Authenticating using Account: 'xxxx', environment: 'AzureCloud', tenant: 'xxxx'
DEBUG: 2:05:36 PM - [ConfigManager] Got nothing from [DisableInstanceDiscovery], Module = [], Cmdlet = []. Returning default value [False].
DEBUG: 2:05:36 PM - [ConfigManager] Got nothing from [EnableLoginByWam], Module = [], Cmdlet = []. Returning default value [True].
DEBUG: 2:05:36 PM - [SilentAuthenticator] Calling SharedTokenCacheCredential.GetTokenAsync - TenantId:'xxxx', Scopes:'https://management.core.windows.net//.default', AuthorityHost:'https://login.microsoftonline.com/', UserId:'xxxx'
DEBUG: SharedTokenCacheCredential.GetToken invoked. Scopes: [ https://management.core.windows.net//.default ] ParentRequestId:
DEBUG: False MSAL 4.61.3.0 MSAL.CoreCLR .NET 8.0.8 MacOS [2024-08-27 12:05:36Z - xxxx] IsLegacyAdalCacheEnabled: yes
DEBUG: False MSAL 4.61.3.0 MSAL.CoreCLR .NET 8.0.8 MacOS [2024-08-27 12:05:36Z - xxxx] [Region discovery] Not using a regional authority.
DEBUG: False MSAL 4.61.3.0 MSAL.CoreCLR .NET 8.0.8 MacOS [2024-08-27 12:05:36Z - xxxx] [Region discovery] Not using a regional authority.
DEBUG: False MSAL 4.61.3.0 MSAL.CoreCLR .NET 8.0.8 MacOS [2024-08-27 12:05:36Z - xxxx] IsLegacyAdalCacheEnabled: yes
DEBUG: False MSAL 4.61.3.0 MSAL.CoreCLR .NET 8.0.8 MacOS [2024-08-27 12:05:36Z - xxxx] IsLegacyAdalCacheEnabled: yes
DEBUG: False MSAL 4.61.3.0 MSAL.CoreCLR .NET 8.0.8 MacOS [2024-08-27 12:05:36Z] Found 1 cache accounts and 0 broker accounts
DEBUG: False MSAL 4.61.3.0 MSAL.CoreCLR .NET 8.0.8 MacOS [2024-08-27 12:05:36Z] Returning 1 accounts
DEBUG: False MSAL 4.61.3.0 MSAL.CoreCLR .NET 8.0.8 MacOS [2024-08-27 12:05:36Z - xxxx] MSAL MSAL.CoreCLR with assembly version '4.61.3.0'. CorrelationId(xxxx)
DEBUG: False MSAL 4.61.3.0 MSAL.CoreCLR .NET 8.0.8 MacOS [2024-08-27 12:05:36Z - xxxx] === AcquireTokenSilent Parameters ===
DEBUG: False MSAL 4.61.3.0 MSAL.CoreCLR .NET 8.0.8 MacOS [2024-08-27 12:05:36Z - xxxx] LoginHint provided: False
DEBUG: False MSAL 4.61.3.0 MSAL.CoreCLR .NET 8.0.8 MacOS [2024-08-27 12:05:36Z - xxxx] Account provided: True
DEBUG: False MSAL 4.61.3.0 MSAL.CoreCLR .NET 8.0.8 MacOS [2024-08-27 12:05:36Z - xxxx] ForceRefresh: False
DEBUG: False MSAL 4.61.3.0 MSAL.CoreCLR .NET 8.0.8 MacOS [2024-08-27 12:05:36Z - xxxx]
=== Request Data ===
Authority Provided? - True
Scopes - https://management.core.windows.net//.default
Extra Query Params Keys (space separated) -
ApiId - AcquireTokenSilent
IsConfidentialClient - False
SendX5C - False
LoginHint ? False
IsBrokerConfigured - False
HomeAccountId - False
CorrelationId - xxxx
UserAssertion set: False
LongRunningOboCacheKey set: False
Region configured:

DEBUG: False MSAL 4.61.3.0 MSAL.CoreCLR .NET 8.0.8 MacOS [2024-08-27 12:05:36Z - xxxx] === Token Acquisition (SilentRequest) started:
     Scopes: https://management.core.windows.net//.default
    Authority Host: login.microsoftonline.com
DEBUG: False MSAL 4.61.3.0 MSAL.CoreCLR .NET 8.0.8 MacOS [2024-08-27 12:05:36Z - xxxx] [Region discovery] Not using a regional authority.
DEBUG: False MSAL 4.61.3.0 MSAL.CoreCLR .NET 8.0.8 MacOS [2024-08-27 12:05:36Z - xxxx] Access token is not expired. Returning the found cache entry. [Current time (08/27/2024 12:05:36) - Expiration Time (08/27/2024 12:45:10 +00:00) - Extended Expiration Time (08/27/2024 12:45:10 +00:00)]
DEBUG: False MSAL 4.61.3.0 MSAL.CoreCLR .NET 8.0.8 MacOS [2024-08-27 12:05:36Z - xxxx] Returning access token found in cache. RefreshOn exists ? False
DEBUG: False MSAL 4.61.3.0 MSAL.CoreCLR .NET 8.0.8 MacOS [2024-08-27 12:05:36Z - xxxx] [Region discovery] Not using a regional authority.
DEBUG: False MSAL 4.61.3.0 MSAL.CoreCLR .NET 8.0.8 MacOS [2024-08-27 12:05:36Z - xxxx]
    === Token Acquisition finished successfully:
DEBUG: False MSAL 4.61.3.0 MSAL.CoreCLR .NET 8.0.8 MacOS [2024-08-27 12:05:36Z - xxxx]  AT expiration time: 8/27/2024 12:45:10 PM +00:00, scopes: https://management.core.windows.net//.default https://management.core.windows.net//user_impersonation. source: Cache
DEBUG: SharedTokenCacheCredential.GetToken succeeded. Scopes: [ https://management.core.windows.net//.default ] ParentRequestId:  ExpiresOn: 2024-08-27T12:45:10.0000000+00:00
DEBUG: [Common.Authentication]: Received token with LoginType 'User', Tenant: 'xxxx', UserId: 'xxxx'
DEBUG: ============================ HTTP REQUEST ============================

HTTP Method:
POST

Absolute Uri:
https://management.azure.com/providers/Microsoft.Management/managementgroups/xxxxx/providers/Microsoft.CostManagement/query?api-version=2019-11-01

Headers:
Accept-Language               : en-US
x-ms-client-request-id        : xxxx

Body:
{
  "timePeriod": {
    "from": "2024-06-30T22:00:00Z",
    "to": "2024-07-31T21:59:59Z"
  },
  "dataset": {
    "granularity": "Monthly",
    "aggregation": {
      "totalCost": {
        "name": "Cost",
        "function": "SUM"
      }
    },
    "grouping": [
      {
        "type": "TagKey",
        "name": "owner"
      }
    ]
  },
  "type": "ActualCost",
  "timeframe": "Custom"
}

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

Status Code:
OK

Headers:
Cache-Control                 : no-cache
Pragma                        : no-cache
Vary                          : Accept-Encoding
session-id                    : xxxx
x-ms-request-id               : xxxx
x-ms-correlation-request-id   : xxxx
x-ms-client-request-id        : xxxx
X-Powered-By                  : ASP.NET
x-ms-ratelimit-remaining-tenant-resource-requests: 99
x-ms-routing-request-id       : SWITZERLANDNORTH:20240827T120539Z:xxxx
Strict-Transport-Security     : max-age=31536000; includeSubDomains
X-Content-Type-Options        : nosniff
X-Cache                       : CONFIG_NOCACHE
X-MSEdge-Ref                  : Ref A: 9693F0FD639046C29CBB6874D45F549B Ref B: FRA231050411029 Ref C: 2024-08-27T12:05:36Z
Date                          : Tue, 27 Aug 2024 12:05:38 GMT

Body:
{
  "id": "providers/Microsoft.Management/managementGroups/xxxxx/providers/Microsoft.CostManagement/query/xxxxx",
  "name": "xxxxx",
  "type": "Microsoft.CostManagement/query",
  "location": null,
  "sku": null,
  "eTag": null,
  "properties": {
    "nextLink": null,
    "columns": [
      {
        "name": "Cost",
        "type": "Number"
      },
      {
        "name": "BillingMonth",
        "type": "Datetime"
      },
      {
        "name": "TagKey",
        "type": "String"
      },
      {
        "name": "TagValue",
        "type": "String"
      },
      {
        "name": "Currency",
        "type": "String"
      }
    ],
    "rows": [
      // ...
      [
        1.07208,
        "2024-06-01T00:00:00",
        "owner",
        null,
        "EUR"
      ],
      // ...
    ]
  }
}

DEBUG: 2:05:39 PM - [ConfigManager] Got nothing from [DisplaySecretsWarning], Module = [], Cmdlet = []. Returning default value [True].
DEBUG: 2:05:39 PM - [ConfigManager] Got nothing from [DisplayRegionIdentified], Module = [], Cmdlet = []. Returning default value [True].
DEBUG: 2:05:39 PM - [ConfigManager] Got [False] from [CheckForUpgrade], Module = [], Cmdlet = [].
DEBUG: 2:05:39 PM - InvokeAzRestMethodCommand end processing.

Line |
  81 |  $Result = Invoke-AzCostManagementQuery `
     |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | You cannot call a method on a null-valued expression.

### Environment data

```PowerShell
Name                           Value
----                           -----
PSVersion                      7.4.5
PSEdition                      Core
GitCommitId                    7.4.5
OS                             Darwin 23.6.0 Darwin Kernel Version 23.6.0: Mon Jul 29 21:14:30 PDT 2024; root:xnu-10063.141.2~1/RELEASE_ARM64_T6000
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Module versions

ModuleType Version    PreRelease Name                                ExportedCommands
---------- -------    ---------- ----                                ----------------
Script     3.0.3                 Az.Accounts                         {Add-AzEnvironment, Clear-AzConfig, Clear-AzContext, Clear-AzDefault…}
Script     0.3.2                 Az.CostManagement                   {Get-AzCostManagementExport, Get-AzCostManagementExportExecutionHistory, Invoke…

Error output

Message        : You cannot call a method on a null-valued expression.
StackTrace     :    at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
                    at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
                    at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
                    at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
                    at System.Management.Automation.Interpreter.Interpreter.Run(InterpretedFrame frame)
                    at System.Management.Automation.Interpreter.LightLambda.RunVoid1[T0](T0 arg0)
                    at System.Management.Automation.PSScriptCmdlet.RunClause(Action`1 clause, Object dollarUnderbar, Object inputToProcess)
                    at System.Management.Automation.PSScriptCmdlet.DoProcessRecord()
                    at System.Management.Automation.CommandProcessor.ProcessRecord()
Exception      : System.Management.Automation.RuntimeException
InvocationInfo : {}
Line           :         $QueryRow.Add($Item.ToString())

Position       : At /Users/xxxx/.local/share/powershell/Modules/Az.CostManagement/0.3.2/CostManagement.Autorest/custom/Invoke-AzCostManagementQuer
                 y.ps1:268 char:9
                 +         $QueryRow.Add($Item.ToString())
                 +         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
HistoryId      : 3
hachi1030-Allen commented 2 weeks ago

This issue should have been fixed by my PR: https://github.com/Azure/azure-powershell/pull/21180

Not sure what happened there that the latest version doesn't have the changes cuz the PR was about 1.5 years ago.

I am trying to find what's happening here but if Azure PowerShell team got any answer for my question, kindly let me know.

mblaschke-daimlertruck commented 2 weeks ago

looks like a phishing attempt

isra-fel commented 1 week ago

@hachi1030-Allen thanks for pointing out to the PR. The reason was it got merged to the incorrect branch - cost management is a module generated by autorest, so the target branch of the PR should be generation instead of main. @msJinLei could you redo the fix on generation branch? Thanks