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.
But when the command is run in Azure Function, an exception occurs:
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
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.
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.
After comparison, it is found that the versions of the Powershell and az modules in the local VM and Azure Function are different.
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-AzSubscription | Get subscriptions that the current account can access |
-Tenantld | Specifies the ID of the tenant that contains subscriptions to get |
-DefaultProfile | The 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
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:
There are two solutions
az
to 5.2.0
, see Attachment for the modification methodGet-Azsubscription
command, remove the parameter -DefaultProfile $cxt