flolilo
flolilo

Reputation: 194

Array with PSCustomObjects changes values even if not called

I wrote a script (PowerShell ≥ 3) that basically looks for certain files, then checks if their name is already used in the path where the files later should get copied to and if so, it adds _OutCopy to the name. It does more than that, but that is of no concern for this question.

#requires -version 3

Function Start-FileSearch(){
    param(
        [string]$InputPath = $(throw 'InputPath not set'),
        [string]$Format = $(throw 'Format not set')
    )
    $InFiles = @()
    $InFiles = @(Get-ChildItem -LiteralPath $InputPath -Filter $Format -Recurse -File | ForEach-Object {
        [PSCustomObject]@{
            InFullName = $_.FullName
            OutName = "ZYX"
        }
    })
    return $InFiles
}

Function Start-OverwriteProtection(){
    param(
        [string]$OutputPath = $(throw 'OutputPath not set'),
        [array]$InFiles = $(throw 'InFiles not set')
    )

    $NewFiles = $InFiles

    for($i=0; $i -lt $NewFiles.Length; $i++){
        $NewFiles[$i].OutName = "$($NewFiles[$i].OutName)_OutCopy"  # this, of course, is simplified. 
    }
    return $NewFiles
}

Function Start-AllStuff() {
    $InFiles = @(Start-FileSearch -InputPath "D:\Temp\In_Test" -Format "*.jpg")
    $InFiles | Format-Table -AutoSize -Property OutName,InFullName | Out-Host

    $NewFiles = @(Start-OverwriteProtection -OutputPath "D:\Temp" -InFiles $InFiles)
    $InFiles | Format-Table -AutoSize -Property OutName,InFullName | Out-Host
    $NewFiles | Format-Table -AutoSize -Property OutName,InFullName | Out-Host
}

Start-AllStuff

Clearly, the second $InFiles | Format-Table should also output "ZYX" for .OutName - however, it includes the already changed values.

What I tried:

Nothing helps.

My understanding, as of now, was that it is impossible for a variable to change when not called directly. (E.g. $InFiles = $OutFiles should change the variable on the left, not the one on the right.)

What am I missing here?

For everyone that wonders: Yes, I dug further into the problems of my previous question ("Compare-Object does not work with PSCustomObjects from another script") and found that this is must be the reason why it won't work - at least it is one of the reasons.

Upvotes: 2

Views: 274

Answers (1)

Drew
Drew

Reputation: 4020

iRon was correct, you need to make a clone of the PSObject, code below.

$NewFiles = $InFiles
$NewInFiles = $InFiles | select *

for($i=0; $i -lt $NewFiles.Length; $i++){
.........................
$NewFiles = @(Start-OverwriteProtection -OutputPath "D:\" -InFiles $InFiles)
$NewInFiles | Format-Table -AutoSize -Property OutName,InFullName | Out-Host
$NewFiles | Format-Table -AutoSize -Property OutName,InFullName | Out-Host

Looks like your for loop was modifying the $InFiles, check out my results. Tested with random images.

$Infiles outside For loop

$Infiles inside For loop

Upvotes: 1

Related Questions