Search code examples
windowspowershell

Using variables outside a function


I am currently writing my first script in Powershell and I am already facing the first problem. I would like to read the value from a variable in a function so that I can use this variable in another cmd-let later. The problem now is that the variable is only recognized inside the function block and not outside. How do I get this to work?

Thanks for the help :-)

function Write-Log([string]$logtext, [int]$level=0)
{
  if($level -eq 0)
{
    $logtext = "[INFO] " + $logtext
    $text = "["+$logdate+"] - " + $logtext
    Write-Host $text
}
}

Send-MailMessage -To "<[email protected]>" -Subject "$text" -Body "The GPO backup creation was completed with the following status: `n $text" -SmtpServer "[email protected]" -From "[email protected]"

I would like to submit $text


Solution

  • This has to do with variable scoping behavior in PowerShell.

    By default, all variables in the caller's scope is visible inside the function. So we can do:

    function Print-X
    {
      Write-Host $X
    }
    
    $X = 123
    Print-X # prints 123
    $X = 456 
    Print-X # prints 456
    

    So far, so good. But when we start writing to variables outside the function itself, PowerShell transparently creates a new variable inside the function's own scope:

    function Print-X2
    {
      Write-Host $X   # will resolve the value of `$X` from outside the function
      $X = 999        # This creates a new `$X`, different from the one outside
      Write-Host $X   # will resolve the value of the new `$X` that new exists inside the function
    }
    
    $X = 123
    Print-X2       # Prints 123, and 999
    Write-Host $X  # But the value of `$X` outside is still 123, unchanged
    

    So, what to do? You could use a scope modifier to write to the variable outside the function, but the real solution here is to return the value from the function instead:

    function Write-Log([string]$logtext, [int]$level=0, [switch]$PassThru = $true)
    {
        if($level -eq 0)
        {
            $logtext = "[INFO] " + $logtext
            $text = "["+$logdate+"] - " + $logtext
            Write-Host $text
            if($PassThru){
                return $text
            }
        }
    }
    
    $logLine = Write-Log "Some log message" -PassThru
    
    Send-MailMessage -Subject $logLine ...