Search code examples
powershellvariablesappend

PowerShell append objects to variable list


Fairly new to PowerShell and wanting to learn how to append objects to a variable list. Below is the error message:

Method invocation failed because [System.IO.FileInfo] does not contain a method named 'op_Addition'.
At C:\Users\Username\Desktop\Sandbox\New folder\BoxProjectFiles.ps1:117 char:4
+             $MechDWGFile += $file
+             ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Addition:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

and code:

LogWrite "`n-------------Mechanical Drawing(s)------------"
foreach ($file in $MechDWGList)
{
    # Where the file name contains one of these filters
    foreach($filter in $MechDWGFilterList)
    {
        if($file.Name -like $filter)
        {
            $MechDWGFile += $file # this is where the error is happening, so I know it is probably something simple
            LogWrite $file.FullName
        }
    }
}

PowerShell 5.1 and Windows 10 OS is being used.

Could someone help me understand what's wrong with my syntax?


Solution

  • Based on the error message, $MechDWGFile already contains a single [FileInfo] object - the type of object returned by Get-Item or Get-ChildItem.

    The += operator is overloaded in PowerShell, meaning its behavior depends on the type of object you have on the left-hand side - in this case $MechDWGFile which contains a [FileInfo] object.

    $file also contains such an object, but [FileInfo] + [FileInfo] doesn't make any sense, which is why you see the error.

    To make the += operator work, you need to create an array with the @() array subexpression operator:

    $MechDWGFile = @()
    
    # ...
    
    # This now works
    $MechDWGFile += $file
    

    If you've initialized $MechDWGFile with output from Get-Item or Get-ChildItem, simply nest the existing pipeline in @():

    # `Get-ChildItem |Select -First 1` will only output 1 object, 
    # but the @(...) makes PowerShell treat it as a 1-item array
    # which in turn allows you to use `+=` later
    $MechDWGFile = @(Get-ChildItem -Recurse -File |Select -First 1)