3

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

4
  • Can you show us the code you currently have? Variables outside function scope are visible inside the function by default Commented Apr 4, 2020 at 15:17
  • I have extended the post with the code Commented Apr 4, 2020 at 15:36
  • Does this answer your question? Why won't Variable update? or Powershell "private" scope seems not useful at all Commented Apr 4, 2020 at 15:47
  • If I create the variable at the top with $script: or $global:, it still won't work :( Commented Apr 4, 2020 at 16:06

3 Answers 3

5

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 ...
Sign up to request clarification or add additional context in comments.

Comments

2

if you need to access a variable outside a function in Powershell you might need to use the global variable.

$global:myglobalvariable="This is a PowerShell global variable"

or if its a null

$global:myglobalvariable2 = $null

1 Comment

Using global is not prudent for this use case. Not saying it should not be used, just know when to use it. - sapien.com/blog/2013/03/06/… - Ideally, Items defined when PowerShell opens are set at the global scope. These items include system-created objects like PowerShell drives and also anything you have defined in a PowerShell profile since your profile runs at startup. The most common use of PowerShell global variables is to use PowerShell global variables between scripts, otherwise, the practice leans toward using a script. scope.
0

The old array trick
I ended up using an array to get around this problem:

$lastRun = @($null) # array so function can edit
function Delay() {
    if ($lastRun[0] -ne $null) {
        ...
    }

    $lastRun[0] = Get-Date
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.