首页 > 解决方案 > 为什么变量不会更新?

问题描述

我目前正在为 AD 编辑我们的新员工脚本,但遇到了一个问题,我为主文件夹添加了 2 个单选按钮,一个单选按钮将 BaseHomeFolderPath 更新为 Path1,第二个单选按钮将其更新为 Path2,我导出变量到 csv 以验证它是否有效,但它一直显示为空白。我不知道这是范围问题还是我做错了什么,任何帮助将不胜感激!下面是代码的副本。

我尝试使用 $script: 并且它也不起作用。

$BaseHomeFolderPath = ''

Set-Variable -Name $BaseHomeFolderPath -Scope Global

$radiobuttonAtlas_MouseClick = [System.Windows.Forms.MouseEventHandler]{
#Event Argument: $_ = [System.Windows.Forms.MouseEventArgs]
    #TODO: Place custom script here
    $BaseHomeFolderPath = '\\path1\users'
}


$radiobuttonCerberus_MouseClick=[System.Windows.Forms.MouseEventHandler]{
#Event Argument: $_ = [System.Windows.Forms.MouseEventArgs]
    #TODO: Place custom script here
    $BaseHomeFolderPath = '\\path2\users'
}

$buttonRun_MouseClick=[System.Windows.Forms.MouseEventHandler]{
#Event Argument: $_ = [System.Windows.Forms.MouseEventArgs]
    #TODO: Place custom script here
    $TestValue = New-Object System.Object
    $TestValue | Add-Member -MemberType NoteProperty -Name "Path" -Value $BaseHomeFolderPath
    $TestValue | Export-CSV -NoTypeInformation -Path "C:\Users\testuser\Desktop\Testcsv.csv"
}

我希望 BaseHomeFolderPath 变量更新为选择的单选按钮。

标签: powershellvariablesscope

解决方案


tl;博士

为了更新脚本范围(或本地以外的任何范围)中的$BaseHomeFolderPath变量,您必须在该范围内显式引用它:

$script:BaseHomeFolderPath = '\\path1\users'

否则,如果没有诸如 之类的范围说明符$script:,您将在当前范围中隐式创建一个该名称的变量,在您的情况下,它是您的事件处理程序运行的子范围


在 PowerShell 中,当您使用分配给变量时$var = ...,您可以:

  • 更新在同一范围内创建的预先存在的变量。

  • 或在当前范围内隐式创建一个新变量。

棘手的部分是,即使子作用域看到在父作用域中创建的变量并且只能通过名称获取它们的值,但通过名称分配给它们只会创建一个的作用域局部变量,并且该新变量然后会隐藏原始变量当前范围和所有子范围。

一个简单的演示,使用调用运算符在子范围内&执行脚本块 ( ):{ ... }

$var = 'parent'
"in parent: before: $var"
& {
  "in child: before: $var" # sees $var from parent scope 
  $var = 'child'           # creates new $var in current scope
  "in child: after: $var"  # sees new $var, which shadows the parent's
}
"in parent: after: $var"   # still has original value

这打印:

in parent: before: parent
in child: before: parent
in child: after: child
in parent: after: parent

笔记:

  • 除了固定的-target 范围说明符$script:和之外$global:,您还可以使用带有参数的Get-Variable/ Set-Variablecmdlet来定位对于当前-Scope范围的变量(在调用堆栈上)。

  • 为了促进模块化和可维护性,通常最好避免跨范围边界访问变量- 最好改为传递

有关更多信息,请参阅:


推荐阅读