Добавить параметры к существующей ошибке PSCustomObject «op_Addition» в powershell - PullRequest
1 голос
/ 27 февраля 2020

Попытка проанализировать шаблон параметров Azure из gihub и обновить некоторые параметры в файле в Powershell, а затем передать его обратно в github для целей автоматизации. Кажется, я ошибаюсь при добавлении новых параметров обратно в файл, извлеченный из github. Я проверил и убедился, что оба объекта одинаковы.

Я вытаскиваю файл JSON из github fine, преобразую его из JSON, компилирую свой новый объект параметров и когда я go чтобы добавить новые параметры обратно в оригинал, я получаю следующую ошибку:

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:\GitHub\Azure> $paramtemplate.GetType()
>>

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    PSCustomObject                           System.Object


PS C:\GitHub\Azure> $newparam.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    PSCustomObject                           System.Object

Я также пытался сопоставить NoteProperty одинаково для обоих, но безрезультатно. Я на PSVersion 5.1.17763.771

PS C:\GitHub\Azure> $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:\GitHub\Azure> $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=}

Ответы [ 2 ]

0 голосов
/ 27 февраля 2020

Попробуйте это:

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

Это перебирает псобъект для добавления и добавляет свойства одно за другим.

0 голосов
/ 27 февраля 2020

Вы можете сделать следующее, если хотите обновить $paramtemplate.parameters значения свойств значениями из $newparam.parameters properties.

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

Поскольку вы имеете дело с типом PSCustomObject в .parameters, .PSObject.Properties вернет все свои свойства. Свойство .Name возвращает строковое имя свойств. $_ - текущий объект, обрабатываемый в блоке сценария Foreach-Object { }.


Вы можете сделать это немного по-другому, что уродливее (IMO), но может быть пренебрежимо более производительным.

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

Примечание: Если $newparam содержит свойства, которых $paramtemplate не имеет, то нам придется добавить дополнительные логики c для обработки этого случая.

$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})
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...