Reputation: 31
So, hopefully someone can help me out here. I've looked for solutions in the past and have always found something before. But this one just seems to be too odd.
I have a PowerShell function that effectively duplicates the New-ADUser Cmdlet, and it accepts multiple parameters in order to do so. Most of the parameters on this function have the "ValueFromPipelineByPropertyName" parameter attribute set to True so that I can feed CSV and other pipeline data into the function without having to write a lot of "if" and assignment statements. Or at least that was the idea.
Here's an example of my function (slimed down to illustrate the point better):
[CmdletBinding()]
Param(
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$FirstName,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$LastName,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$FullName
)
Process {
if(-not $FullName) {
$FullName = "$FirstName $LastName"
}
$user = "" | select FirstName,LastName,FullName
$user.FirstName = $FirstName
$user.LastName = $LastName
$user.FullName = $FullName
return $user
}
So when I run this against the CSV data:
FirstName,LastName
Bob,Smith
Dick,Jones
Sami,Davis
Ray,Charles
Jane,Doe
Keith,Johnson
Ruth,Willson
Genni,Gartner
I get:
FirstName LastName FullName
--------- -------- --------
Bob Smith Bob Smith
Dick Jones Bob Smith
Sami Davis Bob Smith
Ray Charles Bob Smith
Jane Doe Bob Smith
Keith Johnson Bob Smith
Ruth Willson Bob Smith
Genni Gartner Bob Smith
Now, I understand what's happening here. There isn't a specified value for FullName in the pipeline input or the function parameter, so I am setting a value in the process statement to use within that iteration. The problem is, instead of the $FullName variable then being "reset" back to a null or undefined value for the next loop iteration, it holds on to the value set.
If I change the CSV data to explicitly define a "" value for FullName, the issue goes away. But that doesn't help me when the pipeline data doesn't have the property defined.
I'm trying to avoid recoding the entire function to use different variable names or to use $_ because to add to the complexity of the function I also have parameter aliases defined so that we can take data directly from our HR program's database and pipe it into the new user function without having to massage the data manually. Which also brings me back to the inability to just add a null value parameter in the pipeline data.
I know I have been a bit long winded in my explanation, but the scenario appears to be unique (at least according to what I can dig up on the interwebs).
Upvotes: 3
Views: 1951
Reputation: 2634
you need to set the default value of FullName, so below code will work fine:
[CmdletBinding()]
Param(
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$FirstName,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$LastName,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$FullName=$null
)
Process {
if(-not $FullName) {
$FullName = "$FirstName $LastName"
}
$user = "" | select FirstName,LastName,FullName
$user.FirstName = $FirstName
$user.LastName = $LastName
$user.FullName = $FullName
return $user
}
Upvotes: 0
Reputation: 60910
why not simply 'reset' the $fullname
variable?
[CmdletBinding()]
Param(
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$FirstName,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$LastName,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$FullName
)
Process {
if([string]::IsNullOrEmpty($FullName))
{
$script:Fullname = "$FirstName $LastName"
}
$user = "" | select FirstName,LastName,FullName
$user.FirstName = $FirstName
$user.LastName = $LastName
$user.FullName = $FullName
$FullName= [string]::Empty
$user
}
Upvotes: 0
Reputation: 2529
Something tricky is going on with the variable scope here, maybe?
You could try just adding a Remove-Variable FullName
at the end of the function and see if that helps.
I understand that you don't want to use different variable names, but that may make things clearer to use a different variable to store the "generated" full name inside the function; the scope will be less messy, hopefully.
if(-not $FullName) {
$GeneratedName = "$FirstName $LastName"
} else {
$GeneratedName = $FullName
}
Upvotes: 1