将参数追加到电源外壳中的现有 PSCustomObject 'op_Addition'错误



尝试从gihub解析Azure参数模板,并将一些参数更新到Powershell中的文件,然后将其提交回github以实现自动化。我似乎在将新参数添加回从github提取的文件时出错了。我已经检查过了,确保这两个物体都是一样的。

我从github fine中提取JSON文件,将其从JSON转换,编译我的新参数对象,当我将新参数添加回原始参数时,我收到以下错误:

Method invocation failed because [System.Management.Automation.PSObject] does not contain a method named 'op_Addition'.
At line:1 char:1
+ $paramTemplate.parameters += $newparam
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidOperation: (op_Addition:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound

Powerhell代码:

#Get Content
$paramContent = (Invoke-WebRequest -Uri $parameterUri -Headers $headers -UseBasicParsing).content 
$paramTemplate = $paramContent | ConvertFrom-Json
#define parameters in JSON Format
$addnewparam = @"
{
"parameters": {
"virtualMachineRG": {
"value": "$virtualMachineRG"
},
"virtualMachineName": {
"value": "$virtualMachineName"
},
"virtualMachineSize" : {
"value": "$virtualMachineSize"
},
"diagnosticsStorageAccountName": {
"value": "$diagnosticsStorageAccountName"
}
}
}
"@
$newparam = $addnewparam | ConvertFrom-JSON
$paramTemplate.parameters += $newparam

任何见解都将不胜感激!


PS C:GitHubAzure> $paramtemplate.GetType()
>>
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    PSCustomObject                           System.Object

PS C:GitHubAzure> $newparam.GetType()
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    PSCustomObject                           System.Object

我还尝试过将NoteProperty匹配为相同的,但都没有用。我在PSV版本5.1.17763.71 上

PS C:GitHubAzure> $paramtemplate | get-member

TypeName: System.Management.Automation.PSCustomObject
Name           MemberType   Definition
----           ----------   ----------
Equals         Method       bool Equals(System.Object obj)
GetHashCode    Method       int GetHashCode()
GetType        Method       type GetType()
ToString       Method       string ToString()
$schema        NoteProperty string $schema=https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#
contentVersion NoteProperty string contentVersion=1.0.0.0
parameters     NoteProperty System.Management.Automation.PSCustomObject parameters=@{subnetName=; virtualNetworkId=; virtualMachineName=; virtualMachineRG=; osDiskType=; virtualMachineSize=; admi...

PS C:GitHubAzure> $newparam | Get-Member

TypeName: System.Management.Automation.PSCustomObject
Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
parameters  NoteProperty System.Management.Automation.PSCustomObject parameters=@{virtualMachineRG=; virtualMachineName=; virtualMachineSize=; diagnosticsStorageAccountName=}

如果要使用$newparam.parameters属性中的值更新$paramtemplate.parameters属性值,可以执行以下操作。

$newparam.parameters.PSObject.Properties.Name | Foreach-Object { 
$paramtemplate.parameters.$_ = $newparam.parameters.$_
}

由于在.parameters中处理的是PSCustomObject类型,因此.PSObject.Properties将返回其所有属性。.Name属性返回属性的字符串名称。$_是在Foreach-Object { }脚本块中正在处理的当前对象。


你可以用稍微不同的方式来做这件事,这更丑陋(IMO(,但可能更具可忽略不计的性能。

$newparam.parameters.PSObject.Properties | Foreach-Object { 
$paramtemplate.parameters.$($_.Name) = $_.Value
}

注意:如果$newparam包含$paramtemplate没有的属性,那么我们将不得不添加更多的逻辑来处理这种情况。

$newparam.parameters.PSObject.Properties | Foreach-Object { 
if ($paramtemplate.parameters.PSObject.Properties.Name -contains $_.Name) {
$paramtemplate.parameters.$($_.Name) = $_.Value
}
else {
$paramtemplate.parameters | Add-Member -Type NoteProperty -Name $_.Name -Value $_.Value
}
}

关于您收到的错误消息,发生这种情况是因为您试图将PSCustomObject添加到另一个PSCustomObject。这种类型的操作要求您的第一个对象是集合。在添加下一个对象之前,可以使用一元运算符,将对象转换为集合。语法如下:

$object1 = ,$object1 + $object2

编辑

仔细观察这些对象,似乎所有属性都包含另一个PSCustomObject,该属性名为Value,具有您将提供的某个值。在这种情况下,以下内容将用于更新模板。

$newparam.parameters.PSObject.Properties | Foreach-Object { 
if ($paramtemplate.parameters.PSObject.Properties.Name -contains $_.Name) {
$paramtemplate.parameters.$($_.Name).Value = $_.Value.Value
}
else {
$paramtemplate.parameters | Add-Member -Type NoteProperty -Name $_.Name -Value ([pscustomobject]@{Value = $_.Value.Value})
}
}

试试这个:

$newparam | ForEach {
$paramtemplate.parameters | Add-Member -MemberType NoteProperty -Name $_.Name -Value $_.Value
}

这将遍历psobject以逐个添加和添加属性。

最新更新