Can someone explain the behavior in this Script Example?

Craig Glaser 0 Reputation points
2023-03-27T15:07:48.3833333+00:00

While writing a script last week, I came across on odd behavior while tracking down a bug. I've created the following example code which represents the issue. The main question I have is: Why does the $Report variable get 2 extra objects in it when I DON'T explicitly assign the return value from the 'Set-CommonValues' function.

Example Code - The code below works as intended, I get two objects in the $Report variable after running it.

Function Set-CommonValues
{
	param
	(
		[Parameter(Mandatory)]
		[object] $UserReportObj
	)
	
	$UserReportObj | Add-Member -Type NoteProperty -Name "Set Value 1" -Value $True -Force
	$UserReportObj | Add-Member -Type NoteProperty -Name "Set Value 2" -Value $True -Force
	
	Return $UserReportObj
}
Function Process-UserObject
{
	
	param
	(
		[Parameter(Mandatory)]
		[object] $UserReportObj
	)
	
	$UserReportObj | Add-Member -Type NoteProperty -Name "Ad Domain" -Value "contoso.com" -Force
	
#	Set-CommonValues -UserReportObj $UserReportObj
	$UserReportObj = Set-CommonValues -UserReportObj $UserReportObj
	
	return $UserReportObj	
}
$Names = ("John Doe", "Jane Doe")
$Report = @()
foreach($Name in $Names)
{
	$UserObj = New-Object -TypeName PSObject
	$UserObj | Add-Member -Type NoteProperty -Name "Name" -Value $Name -Force
	
	$UserObj = Process-UserObject -UserReportObj $UserObj
	
	$Report+= $UserObj
}
return $report

If I run the script as shown above, it works as intended. I get two objects in the $Report variable. However, if I uncomment the line in the function 'Process-UserObject' and then comment out the line below it so it looks like the code below, I get 4 objects in the $Reports variable. My Expectation would be that when I don't explicitly assign the return value from the 'Set-CommonValues' function, the properties set by that function simply aren't included in the objects I later assign to $Reports, OR, if powershell treats objects as references, me explicitly assigning the return value isn't even needed. The Add-Member command modifies the passed object and I don't need to explicitly assign the object back to the $UserObj variable. Instead, I somehow get 2 extra objects in the $Report variable. Can someone explain to me why this occurs?




Example Code - Don't understand why the $Report variable get's 4 objects in the below example.

Function Set-CommonValues
{
	param
	(
		[Parameter(Mandatory)]
		[object] $UserReportObj
	)
	
	$UserReportObj | Add-Member -Type NoteProperty -Name "Set Value 1" -Value $True -Force
	$UserReportObj | Add-Member -Type NoteProperty -Name "Set Value 2" -Value $True -Force
	
	Return $UserReportObj
}

Function Process-UserObject
{
	
	param
	(
		[Parameter(Mandatory)]
		[object] $UserReportObj
	)
	
	$UserReportObj | Add-Member -Type NoteProperty -Name "Ad Domain" -Value "contoso.com" -Force
	
	Set-CommonValues -UserReportObj $UserReportObj
#	$UserReportObj = Set-CommonValues -UserReportObj $UserReportObj
	
	return $UserReportObj	
}

$Names = ("John Doe", "Jane Doe")
$Report = @()

foreach($Name in $Names)
{
	$UserObj = New-Object -TypeName PSObject
	$UserObj | Add-Member -Type NoteProperty -Name "Name" -Value $Name -Force
	
	$UserObj = Process-UserObject -UserReportObj $UserObj
	
	$Report+= $UserObj
}

return $report

PowerShell
PowerShell
A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
2,468 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Rich Matheisen 46,561 Reputation points
    2023-03-27T22:51:31.12+00:00

    When you call Set-CommonValues, that function returns an object. However, the object isn't assigned to a variable (i.e., it's not consumed) so it's emitted into the "Success" steam (i.e., the pipeline). You then "return $UserReportObj" which is also emitted to the pipeline!

    Remove the "return" in the Process-Object, or assign the value returned from Set-CommonValues to $UserReportObj, and the problem goes away.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.