Lee
Lee

Reputation: 13

What am I doing wrong on PowerShell function parameters?

I would really appreciate it if somebody could point out what I am doing wrong in passing parameters from a function back to the mainline code. I have a variable which has been successfully extracted in a function, but I cannot seem to pass that back to the mainline code

This is the code I am using:

function get-field ($field, $heading) {
    $fieldPos = $script:source.AllElements.InnerText.IndexOf($heading) +1
    $field = $script:source.AllElements.InnerText[$fieldPos]    

    # If states "Not Available", or contains a heading, process as if not found.
    if ($field -eq "Not Available ") {$fieldPos = 0}
    if ($field -eq $heading) {$fieldPos = 0}

    # Check that a valid entry was received
    if ($fieldPos -eq 0) {
        Write-Host "Warning:" $heading "was not found" 
    } else {
        $field = $field.Trim()
    }

    return $field
}    

get-field $email "Name"
get-field $address "Address"

I have verified that within the function, the $field and $heading parameters contain the correct information, so why aren't the $email and $address fields being populated?

Upvotes: 1

Views: 207

Answers (2)

Ansgar Wiechers
Ansgar Wiechers

Reputation: 200193

Parameters in PowerShell are normally used for passing values into a function. The output of a function must be assigned to a variable in the statement that invokes the function. Also, it's bad design to use global variables inside a function, because that makes debugging significantly more difficult.

Your code should look somewhat like this:

function Get-Field ($data, $heading) {
    $fieldPos = $data.IndexOf($heading) + 1
    $field    = $data[$fieldPos].Trim()

    # If states "Not Available", or contains a heading, process as if not found.
    if ($field -eq 'Not Available' -or $field -eq $heading) {
        Write-Host "Warning: ${heading} was not found" 
    }

    $field
}    

$email   = Get-Field $script:source.AllElements.InnerText 'Name'
$address = Get-Field $script:source.AllElements.InnerText 'Address'

You can have out parameters if you want to, but they're rather uncommon in PowerShell, probably because they're not as straight-forward to use as one would like.

function Get-Field ([ref]$field, $data, $heading) {
    $fieldPos    = $data.IndexOf($heading) + 1
    $field.Value = $data[$fieldPos].Trim()

    # If states "Not Available", or contains a heading, process as if not found.
    if ($field -eq 'Not Available' -or $field -eq $heading) {
        Write-Host "Warning: ${heading} was not found" 
    }
}    

$email = $null
Get-Field ([ref]$email) $script:source.AllElements.InnerText 'Name'
$address = $null
Get-Field ([ref]$address) $script:source.AllElements.InnerText 'Address'

Upvotes: 0

TobyU
TobyU

Reputation: 3908

You're not doing it totally wrong.

Have a look at this example:

function get-field ($field, $heading) {

    return "$field - $heading"
}

$address = get-field "AddressFiled" "AddressHeading"
$address

to catch the returned value in a variable for further use, you should call the function like in the above example.

Upvotes: 2

Related Questions