Search code examples
functionpowershellpowershell-3.0

Powershell: Why doesn't this function work?


I am trying to make a script with neatly laid out functions that compare two folders items. The program:

  1. Prompts the user for the file path
  2. Check to see if the file names differ
  3. Check to see if the file sizes differ

As a test I've been comparing the same folder to itself (output should be false, false). When making step 1 ($referencepath) a function (FolderPrompt) my program doesn't work right and by that I mean I seem to get a different answer almost every time I run it.

This works:

$referencePath = Read-Host -Prompt "Enter new DTNA folder path to check" 

NameDisc
SizeDisc

function NameDisc {
    write-host "Name Discrepancy: " -NoNewline 

    if (Compare-Object -Property name (Get-ChildItem $referencePath) - DifferenceObject (Get-ChildItem P:\DTNA_201805081923))
        {return $true} 
    else
        {return $false}
}

function SizeDisc {
    write-host "Size Discrepancy: " -NoNewline 

    if (Compare-Object -Property length (Get-ChildItem $referencePath) - DifferenceObject (Get-ChildItem P:\DTNA_201805081923))
        {return $true} 
    else
        {return $false}
}     

But this does not:

FolderPrompt
NameDisc
SizeDisc

function FolderPrompt {
    $referencePath = Read-Host -Prompt "Enter new DTNA folder path to check" 
}

function NameDisc {
    write-host "Name Discrepancy: " -NoNewline 

    if (Compare-Object -Property name (Get-ChildItem $referencePath) -DifferenceObject (Get-ChildItem P:\DTNA_201805081923))
        {return $true} 
    else
        {return $false}
}

function SizeDisc {
    write-host "Size Discrepancy: " -NoNewline

    if (Compare-Object -Property length (Get-ChildItem $referencePath) - DifferenceObject (Get-ChildItem P:\DTNA_201805081923))
        {return $true} 
    else
        {return $false}
}     

I've tried:

  • Declaring the functions before calling them

  • Putting $referencePath = 0 to reset the value each time thinking that was the problem

  • Putting Return $referencePath at the end of different functions

My best guess is that I need to do something like function <name> ($referencePath) to pass the variable(?).


Solution

  • $referencepath becomes local to the function once you assign to it, so its value is lost since you don't return it. You say you tried returning it in "various functions" but it's not clear what that looked like.

    You also should not rely on the functions inheriting variables from their parent scope. Ideally you'd be passing in any needed information as parameters.

    When calling functions in PowerShell, don't use parentheses and commas for parameters, use spaces.

    function FolderPrompt {
        Read-Host -Prompt "Enter new DTNA folder path to check" 
    }
    
    function NameDisc { 
    param($referencePath)
    
        write-host "Name Discrepancy: " -NoNewline 
    
        if (Compare-Object -Property name (Get-ChildItem $referencePath) -DifferenceObject (Get-ChildItem P:\DTNA_201805081923))
            {return $true} 
        else
            {return $false}
    }
    
    function SizeDisc {
    param($referencePath)
    
        write-host "Size Discrepancy: " -NoNewline
    
        if (Compare-Object -Property length (Get-ChildItem $referencePath) - DifferenceObject (Get-ChildItem P:\DTNA_201805081923))
            {return $true} 
        else
            {return $false}
    }     
    
    $refPath = FolderPrompt
    NameDisc -referencePath $refPath
    SizeDisc -referencePath $refPath
    

    That's how your modified code would look.