Search code examples
listpowershellautomationfileparsingpsobject

Powershell: Error while adding custom object to a list. Program runs without error in debug mode


Trying to parse a text file using PowerShell and create a list of sections present in the file. While executing the below code snippet, error is thrown when the object is added to the list.

Method invocation failed because [System.Management.Automation.PSObject] does not contain a method named 'op_Addition'.

The first object gets added to the list but second object onward error is thrown. Interestingly, the error does not occur if the program runs in debug mode.

function Process-Master-File {
    [CmdletBinding()]
    Param (
        [Parameter(ValueFromPipeline = $true)][String[]]$PipeValue
    )
    Begin { 
        #create new section object
        $codeSection = New-Object -TypeName psobject
        $codeSection | Add-Member -MemberType NoteProperty -Name Name -Value $null
        $codeSection | Add-Member -MemberType NoteProperty -Name SuppresionGroup -Value $null
        $codeSection | Add-Member -MemberType NoteProperty -Name Mandatory -Value $False
        $codeSection | Add-Member -MemberType NoteProperty -Name SectionBody -Value $null
        [string]$out = ""
    }
    Process {
        # Grab a line from the pipe
        [string]$line = $_

        # Find positions
        try {
            $pos = 0
            $pos = $line.IndexOf('@Section')
            if ($pos[0] -ne -1) { 
                if ($objTemp.Name) {
                    $objTemp.SectionBody = $section
                    $codeSectionList += $objTemp # Error is thrown here
                    $section = ""
                }

                $objTemp = $codeSection | Select-Object *
                $objTemp.Name = $line.Substring($line.LastIndexOf(':') + 1).TrimEnd().TrimStart()
                $objTemp.SuppresionGroup = $line.Substring($line.IndexOf('@SG') + 3, ($line.LastIndexOf(':') - $line.IndexOf('@SG') - 3)).TrimEnd().TrimStart()
                if ($line.IndexOf('@Mandatory') -ne -1) {
                    $objTemp.Mandatory = $True
                }
                $section = $line
                Write-Verbose $line
            }
            else {
                $section += $line
            }
        }
        Catch {
            Write-Host "An error occurred while processing file:"
            Write-Host $_
        }
    }
    End {
        $codeSectionList
    }
}

Solution

  • You have to initialize $codesectionlist as an array. Otherwise, you're trying to add one pscustomobject to another one.

    $codesectionlist += [pscustomobject]@{name='Joe'}
    $codesectionlist += [pscustomobject]@{name='John'}
    
    InvalidOperation: Method invocation failed because [System.Management.Automation.PSObject] does not contain a method named 'op_Addition'.
    
    $codesectionlist.gettype().fullname
    System.Management.Automation.PSCustomObject
    
    
    $codesectionlist = @()
    $codesectionlist += [pscustomobject]@{name='Joe'} 
    $codesectionlist += [pscustomobject]@{name='John'}
    
    $codesectionlist.gettype().fullname
    System.Object[]
    

    The global variable might have been in included in the question. The script uses its own script scope, with the += operator. Debugging is like dot sourcing the script.

    cat script.ps1
    $a += 1
    $a += 2
    $a
    
    $global:a = @()
    
    .\script
    3
    
    . .\script
    1
    2
    

    Weirdly, $a = $a + 1 works differently than $a += 1 in terms of scope.

    cat ./script.ps1
    $a
    $a = $a + 1
    $a = $a + 2
    $a
    
    $global:a = @()
    
    ./script
    1
    2
    

    Actually I used a script instead of a function, but everything still applies.

    Oh that's right. This is a bug I posted myself last December: +=, functions, and global variables #11297