【问题标题】:PowerShell: Script Module variables not available outside of ISEPowerShell:脚本模块变量在 ISE 之外不可用
【发布时间】:2017-05-21 19:05:15
【问题描述】:

我一直在努力更新我编写的一些脚本。我还在学习 PowerShell,所以我想回顾一下我的旧版本,看看我是否可以改进。
我偶然发现了模块,并且非常喜欢使用它们来存储可以随时调用的不同操作的想法。

我写了一个简单的脚本来测试(或者我是这么认为的)。我应该提到我将我的模块存储在服务器共享上。

Write-Host "Testing for available variables"
Write-Host "Loading Modules"
Import-Module <path to my module on server share>.psm1
Write-Host ""
Write-Host "Done"
Write-Host "Print loaded modules"
Get-Module
Write-Host ""
Write-Host "Done"
Write-Host "================="
Write-Host ""
Write-Host "Printing variables"
Write-Host ""
Write-Host "Variable: arch: " $arch
Write-Host "Variable: WowNode: " $WowNode
Write-Host ""
Write-Host "Done"

我的模块包含

If ( "${env:ProgramFiles(x86)}" -ne "" )
 {
    $script:arch = 64
    $script:WowNode = "\Wow6432Node\"
 }
 ELSE
 {
    $script:arch = 32
    $script:WowNode = "\"
 }

当我使用 Windows Powershell ISE 运行我的脚本时,一切都按照我的想法运行。我看到了变量的内容,并且它们打印正确。
当我从 Powershell 命令行窗口运行脚本时,模块会被加载,但变量是空白的(没有打印出来)。
我一直在研究 Google,我看到的唯一可能导致此问题的原因与我用来定义变量的范围有关。
将它们定义为 $script:xx 会将它们放入全局范围(我很确定),这使得它们在整个脚本中都可用。所以我认为我正确地定义了我的变量。但我还是没有运气。

我可能遗漏了一些明显的东西,但我一生都找不到它。
关于如何解决此问题的任何建议?
我已经确认我正在运行 PowerShell 2.0 版,因为我了解到模块仅在 2.0 版中可用。

【问题讨论】:

    标签: powershell


    【解决方案1】:

    从我现在能想到的(未经测试),问题是你所说的范围。在 ISE 和控制台中运行脚本是有区别的。我猜当您在 ISE 中运行脚本时,您打开脚本并按下运行按钮。这将在控制台中逐行执行脚本,就像您直接在控制台中键入它们一样。这使得脚本本身在global(会话)变量范围内运行。由于脚本在 global 中,因此您的模块将是唯一在 script 范围内运行的模块。

    但是,当您在 powershell 控制台中运行脚本时;喜欢:

    PS > .\myscript.ps1
    

    然后您的脚本在script 范围内运行(脚本完成后每个变量都将被删除)。现在,模块将在它自己的script 范围内运行,在你的主脚本运行的范围之下。当模块完成导入时,模块的script 范围被删除,你的主脚本将在它自己的范围内运行范围,你的变量不存在。

    Global (session)
     - Script (mainscript)
       - Script (module)
         #Module completes, and scope is deleted
       #You look for $script:arch , which was actually deleted right above.
       #Powershell searches through the mainscript's scope, but finds nothing.
    

    要解决此问题,请尝试将值存储在 global(会话)范围内,例如 $global:arch。指定global 作为创建变量时的作用域(必需)和读取变量时(推荐)。

    【讨论】:

    • 谢谢!你是 100% 正确的。起初我不明白,直到我阅读了你的第二个代码块并且它是有道理的。我现在明白为什么我的变量不可用了。我在模块内将变量重新定义为 $global:arch 并重新测试了我的小测试脚本,现在我可以打印出变量的内容。为自己没有早点理解这一点而生气!再次感谢您的解释!
    • 我发现还有另一种方法可以做到这一点。您可以将变量声明为正常的“$var1 = test”。然后在您的导入语句中,您可以使用 -Global 选项并且变量应该可用:“Import-Module -Global ”。我同意 Mike Shepard 的观点——绝对是一个很好的解释!
    • 对不起,请忽略我上面关于使用“-Global”参数的评论。这实际上不起作用。我的测试有缺陷。很抱歉造成混乱!
    猜你喜欢
    • 1970-01-01
    • 2023-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-20
    相关资源
    最近更新 更多