2

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 "<xxx@xxx.de>" -Subject "$text" -Body "The GPO backup creation was completed with the following status: `n $text" -SmtpServer "xxx@xxx.de" -From "xxx@xxx.de"

I would like to submit $text

Julian05
  • 23
  • 4
  • Can you show us the code you currently have? Variables outside function scope are visible inside the function by default – Mathias R. Jessen Apr 04 '20 at 15:17
  • I have extended the post with the code – Julian05 Apr 04 '20 at 15:36
  • Does this answer your question? [Why won't Variable update?](https://stackoverflow.com/q/55403528/1701026) or [Powershell "private" scope seems not useful at all](https://stackoverflow.com/a/36347515/1701026) – iRon Apr 04 '20 at 15:47
  • If I create the variable at the top with $script: or $global:, it still won't work :( – Julian05 Apr 04 '20 at 16:06

2 Answers2

4

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 ...
Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
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
  • Using global is not prudent for this use case. Not saying it should not be used, just know when to use it. - https://www.sapien.com/blog/2013/03/06/first-rule-of-powershell-scoping-rules - 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. – postanote Apr 05 '20 at 06:48