Error getting value from 'Tags' on 'Microsoft.Azure.Commands.Profile.Models.PSAzureSubscription

created at 07-10-2021 views: 3

Problem Description

Use the PowerShell script to execute the command to get the Azure subscription list (Get-Azsubscription -TenantId tenantID -DefaultProfilecxt). After local debugging, the instruction runs successfully.

 runs successfully

But when the command is run in Azure Function, an exception occurs:

ERROR prompt

The completed error message is: "

Error getting value from'Tags' on'Microsoft.Azure.Commands.Profile.Models.PSAzureSubscription'."
Microsoft.Azure.WebJobs.Script.Workers.Rpc.RpcException : Result: ERROR: Error getting value from 'Tags' on 'Microsoft.Azure.Commands.Profile.Models.PSAzureSubscription'.

Exception             : 
    Type           : Newtonsoft.Json.JsonSerializationException
    TargetSite     : 
        Name          : GetValue
        DeclaringType : Newtonsoft.Json.Serialization.ExpressionValueProvider
        MemberType    : Method
        Module        : Newtonsoft.Json.dll
    StackTrace     : 
   at Newtonsoft.Json.Serialization.ExpressionValueProvider.GetValue(Object target)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues(JsonWriter writer, Object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, JsonContract& memberContract, Object& memberValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeDictionary(JsonWriter writer, IDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
   at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
   at Newtonsoft.Json.JsonConvert.SerializeObjectInternal(Object value, Type type, JsonSerializer jsonSerializer)
   at Newtonsoft.Json.JsonConvert.SerializeObject(Object value, Type type, Formatting formatting, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.SerializeObject(Object value, Formatting formatting, JsonConverter[] converters)
   at Microsoft.Azure.Commands.Common.Authentication.Models.AzureRmProfile.ToString(Boolean serializeCache)
   at Microsoft.Azure.Commands.Common.Authentication.Models.AzureRmProfile.ToString()
   at System.Management.Automation.ParameterBinderBase.CoerceTypeAsNeeded(CommandParameterInternal argument, String parameterName, Type toType, ParameterCollectionTypeInformation collectionTypeInfo, Object currentValue)
   at System.Management.Automation.ParameterBinderBase.BindParameter(CommandParameterInternal parameter, CompiledCommandParameter parameterMetadata, ParameterBindingFlags flags)
   at System.Management.Automation.CmdletParameterBinderController.BindParameter(CommandParameterInternal argument, MergedCompiledCommandParameter parameter, ParameterBindingFlags flags)
   at System.Management.Automation.CmdletParameterBinderController.BindParameter(UInt32 parameterSets, CommandParameterInternal argument, MergedCompiledCommandParameter parameter, ParameterBindingFlags flags)
   at System.Management.Automation.CmdletParameterBinderController.BindParameters(UInt32 parameterSets, Collection`1 arguments)
   at System.Management.Automation.CmdletParameterBinderController.BindCommandLineParametersNoValidation(Collection`1 arguments)
   at System.Management.Automation.CmdletParameterBinderController.BindCommandLineParameters(Collection`1 arguments)
   at System.Management.Automation.CommandProcessor.BindCommandLineParameters()
   at System.Management.Automation.CommandProcessor.Prepare(IDictionary psDefaultParameterValues)
   at System.Management.Automation.CommandProcessorBase.DoPrepare(IDictionary psDefaultParameterValues)
   at System.Management.Automation.Internal.PipelineProcessor.Start(Boolean incomingStream)
   at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input)
   at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
   at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
    Message        : Error getting value from 'Tags' on 'Microsoft.Azure.Commands.Profile.Models.PSAzureSubscription'.
    Data           : System.Collections.ListDictionaryInternal
    InnerException : 
        Type       : System.ArgumentNullException
        Message    : Value cannot be null. (Parameter 'value')
        ParamName  : value
        TargetSite : 
            Name          : ArgumentNotNull
            DeclaringType : Newtonsoft.Json.Utilities.ValidationUtils, Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed
            MemberType    : Method
            Module        : Newtonsoft.Json.dll
        StackTrace : 
   at Newtonsoft.Json.Utilities.ValidationUtils.ArgumentNotNull(Object value, String parameterName)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value)
   at Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureSubscriptionExtensions.GetTags(IAzureSubscription subscription)
   at lambda_method(Closure , Object )
   at Newtonsoft.Json.Serialization.ExpressionValueProvider.GetValue(Object target)
        Source     : Newtonsoft.Json
        HResult    : -2147467261
    Source         : Newtonsoft.Json
    HResult        : -2146233088
CategoryInfo          : OperationStopped: (:) [], JsonSerializationException
FullyQualifiedErrorId : Newtonsoft.Json.JsonSerializationException
InvocationInfo        : 
    ScriptLineNumber : 26
    OffsetInLine     : 1
    HistoryId        : -1
    ScriptName       : D:\home\site\wwwroot\HttpTrigger1\run.ps1
    Line             : $subs = Get-Azsubscription -TenantId $tenantID -DefaultProfile $cxt

    PositionMessage  : At D:\home\site\wwwroot\HttpTrigger1\run.ps1:26 char:1
                       + $subs = Get-Azsubscription -TenantId $tenantID -DefaultProfile $cxt
                       + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    PSScriptRoot     : D:\home\site\wwwroot\HttpTrigger1
    PSCommandPath    : D:\home\site\wwwroot\HttpTrigger1\run.ps1
    CommandOrigin    : Internal
ScriptStackTrace      : at <ScriptBlock>, D:\home\site\wwwroot\HttpTrigger1\run.ps1: line 26

analysis and solutions

Compared with the above, it can run successfully locally, but JSON format parsing error does occur in Azure Function, so check the PowerShell script error problem. Then locate the environmental problem of running the script.

1: Check the PowerShell version and the version of the az module

Use $PSVersionTable to print out the PowerShell version, and use Get-InstalledModule -name az and Get-InstalledModule -name az.* to print out the version number of the current environment.

version number of the current environment.

After comparison, it is found that the versions of the Powershell and az modules in the local VM and Azure Function are different.

2: Find a temporary solution

Because the version of PowerShell in Azure Function cannot be changed from the platform level (you can modify the version of the az module used in the PS script, see Annex 1 for the modification method). So the main search is: Based on the current version, how about finding Workaround from the Get-Azsubscription command itself? Check the Get-Azsubscription command and find that it uses the permissions of the currently logged-in user to obtain all subscription numbers. Specifying TenantID means that only all subscription numbers under the current TenantID are obtained. The parameter DefaultProfile also only carries user authentication information, which is the same as all authentication information of the currently logged-in user.

Get-AzSubscriptionGet subscriptions that the current account can access
-TenantldSpecifies the ID of the tenant that contains subscriptions to get
-DefaultProfileThe credentials, tenant and subscription used for communication with azure

If you don't add the -DefaultProfile parameter, is it also caused by the exception? It is verified that the execution is successful and the result is correct. So the code as Workaround is:

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

$User = "XXXXXXXXXXXXXxxxxxxxx"
$PWord = ConvertTo-SecureString -String "XXXXXXXXXXXXXxxxxxxxx" -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential($User, $PWord)

Connect-AzAccount -Environment AzureChinaCloud -Credential $Credential

Write-Host "login successfully"

$tenantID = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$cxt = Set-AzContext -Tenant $tenantID
write-host $cxt

write-host "no defaultprofile"
Write-Host "Get-Azsubscription -TenantId $tenantID"
#$subs = Get-Azsubscription -TenantId $tenantID -DefaultProfile $cxt
Get-Azsubscription -TenantId $tenantID
write-host "========================="
write-host $subs

Attachment: Modify the version number

Modify the version number of az in Azure Funciton to 5.2.0, the problem is also solved.
On the Azure Function portal page, click the "App Service Editor (Preview)" directory to enter the Editor page. In the requirements.psd1 file, modify the version number of az to 5.2.0. After saving, return to the Azure Function page. Restart Function. Modify the page as follows:

Azure Function page

Conclusion

There are two solutions

  1. Modify the version number of az to 5.2.0, see Attachment for the modification method
  2. Modify the Get-Azsubscription command, remove the parameter -DefaultProfile $cxt
Please log in to leave a comment.