如何从包含在另一个模块中的被调用函数调用PowerShell模块作用域来访问变量?

tuwxkamq  于 2022-11-10  发布在  Shell
关注(0)|答案(2)|浏览(125)

运行以下命令将创建两个模块,其中一个模块在另一个模块中调用函数,其中被调用的函数尝试引用包含调用函数的模块范围内的变量:

$ModulePath = $env:PSModulePath.Split(";")[0]

New-Item -ItemType Directory -Path $ModulePath\TestModule1 -Force

@"
`$var = 1
function Write-Stuff {
    `$var
}
function Test-WriteStuff {
    Write-Stuff
    Write-Stuff2
}
"@ | Out-File $ModulePath\TestModule1\TestModule1.psm1

New-Item -ItemType Directory -Path $ModulePath\TestModule2 -Force

@"
function Write-Stuff2 {
    `$var
    "`r`nGet-Variable -Scope 0`r`n"
    Get-Variable -Scope 0

    "`r`nGet-Variable -Scope 1`r`n"
    Get-Variable -Scope 1

    "`r`nGet-Variable -Scope 2`r`n"
    Get-Variable -Scope 2

    "`r`nGet-Variable -Scope 3`r`n"
    Get-Variable -Scope 3
}
"@ | Out-File $ModulePath\TestModule2\TestModule2.psm1

这将导致以下输出,显示$Var不是被调用函数可访问的任何作用域中的可用变量:

PS C:\Users\user> Test-WriteStuff
1

Get-Variable -Scope 0

Name                           Value                                                                                                                                                                                           
----                           -----                                                                                                                                                                                           
args                           {}                                                                                                                                                                                              
false                          False                                                                                                                                                                                           
input                          System.Collections.ArrayList+ArrayListEnumeratorSimple                                                                                                                                          
MaximumAliasCount              4096                                                                                                                                                                                            
MaximumDriveCount              4096                                                                                                                                                                                            
MaximumErrorCount              256                                                                                                                                                                                             
MaximumFunctionCount           4096                                                                                                                                                                                            
MaximumVariableCount           4096                                                                                                                                                                                            
MyInvocation                   System.Management.Automation.InvocationInfo                                                                                                                                                     
null                                                                                                                                                                                                                           
PSBoundParameters              {}                                                                                                                                                                                              
PSCommandPath                  C:\Users\cmagnuson\OneDrive - tervis.com\Documents\WindowsPowerShell\Modules\testmodule2\testmodule2.psm1                                                                                       
PSScriptRoot                   C:\Users\cmagnuson\OneDrive - tervis.com\Documents\WindowsPowerShell\Modules\testmodule2                                                                                                        
true                           True                                                                                                                                                                                            

Get-Variable -Scope 1

args                           {}                                                                                                                                                                                              
Error                          {}                                                                                                                                                                                              
false                          False                                                                                                                                                                                           
MaximumAliasCount              4096                                                                                                                                                                                            
MaximumDriveCount              4096                                                                                                                                                                                            
MaximumErrorCount              256                                                                                                                                                                                             
MaximumFunctionCount           4096                                                                                                                                                                                            
MaximumVariableCount           4096                                                                                                                                                                                            
MyInvocation                   System.Management.Automation.InvocationInfo                                                                                                                                                     
null                                                                                                                                                                                                                           
PSCommandPath                  C:\Users\cmagnuson\OneDrive - tervis.com\Documents\WindowsPowerShell\Modules\testmodule2\testmodule2.psm1                                                                                       
PSDefaultParameterValues       {}                                                                                                                                                                                              
PSScriptRoot                   C:\Users\cmagnuson\OneDrive - tervis.com\Documents\WindowsPowerShell\Modules\testmodule2                                                                                                        
true                           True                                                                                                                                                                                            

Get-Variable -Scope 2

$                              testmodule2                                                                                                                                                                                     
?                              True                                                                                                                                                                                            
^                              ipmo                                                                                                                                                                                            
args                           {}                                                                                                                                                                                              
ConfirmPreference              High                                                                                                                                                                                            
ConsoleFileName                                                                                                                                                                                                                
DebugPreference                SilentlyContinue                                                                                                                                                                                
Error                          {The scope number '3' exceeds the number of active scopes....                                                                                                                                   
ErrorActionPreference          Continue                                                                                                                                                                                        
ErrorView                      NormalView                                                                                                                                                                                      
ExecutionContext               System.Management.Automation.EngineIntrinsics                                                                                                                                                   
false                          False                                                                                                                                                                                           
FormatEnumerationLimit         4                                                                                                                                                                                               
HOME                           C:\Users\cmagnuson                                                                                                                                                                              
Host                           System.Management.Automation.Internal.Host.InternalHost                                                                                                                                         
InformationPreference          SilentlyContinue                                                                                                                                                                                
input                          System.Collections.ArrayList+ArrayListEnumeratorSimple                                                                                                                                          
MaximumAliasCount              4096                                                                                                                                                                                            
MaximumDriveCount              4096                                                                                                                                                                                            
MaximumErrorCount              256                                                                                                                                                                                             
MaximumFunctionCount           4096                                                                                                                                                                                            
MaximumHistoryCount            4096                                                                                                                                                                                            
MaximumVariableCount           4096                                                                                                                                                                                            
ModulePath                     C:\Users\cmagnuson\OneDrive - tervis.com\Documents\WindowsPowerShell\Modules                                                                                                                    
MyInvocation                   System.Management.Automation.InvocationInfo                                                                                                                                                     
NestedPromptLevel              0                                                                                                                                                                                               
null                                                                                                                                                                                                                           
OutputEncoding                 System.Text.SBCSCodePageEncoding                                                                                                                                                                
PID                            9552                                                                                                                                                                                            
profile                        C:\Users\cmagnuson\OneDrive - tervis.com\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1                                                                                        
ProgressPreference             Continue                                                                                                                                                                                        
PSBoundParameters              {}                                                                                                                                                                                              
PSCommandPath                                                                                                                                                                                                                  
PSCulture                      en-US                                                                                                                                                                                           
PSDefaultParameterValues       {}                                                                                                                                                                                              
PSEdition                      Desktop                                                                                                                                                                                         
PSEmailServer                                                                                                                                                                                                                  
PSHOME                         C:\Windows\System32\WindowsPowerShell\v1.0                                                                                                                                                      
psISE                          Microsoft.PowerShell.Host.ISE.ObjectModelRoot                                                                                                                                                   
PSScriptRoot                                                                                                                                                                                                                   
PSSessionApplicationName       wsman                                                                                                                                                                                           
PSSessionConfigurationName     http://schemas.microsoft.com/powershell/Microsoft.PowerShell                                                                                                                                    
PSSessionOption                System.Management.Automation.Remoting.PSSessionOption                                                                                                                                           
PSUICulture                    en-US                                                                                                                                                                                           
psUnsupportedConsoleApplica... {wmic, wmic.exe, cmd, cmd.exe...}                                                                                                                                                               
PSVersionTable                 {PSVersion, PSEdition, PSCompatibleVersions, BuildVersion...}                                                                                                                                   
PWD                            C:\Users\cmagnuson                                                                                                                                                                              
ShellId                        Microsoft.PowerShell                                                                                                                                                                            
StackTrace                        at System.Management.Automation.SessionStateInternal.GetScopeByID(Int32 scopeID)...                                                                                                          
true                           True                                                                                                                                                                                            
VerbosePreference              SilentlyContinue                                                                                                                                                                                
WarningPreference              Continue                                                                                                                                                                                        
WhatIfPreference               False                                                                                                                                                                                           

Get-Variable -Scope 3

Get-Variable : The scope number '3' exceeds the number of active scopes.
Parameter name: scopeID
Actual value was 3.
At C:\Users\cmagnuson\OneDrive - tervis.com\Documents\WindowsPowerShell\Modules\testmodule2\testmodule2.psm1:21 char:5
+     Get-Variable -Scope 3
+     ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-Variable], PSArgumentOutOfRangeException
    + FullyQualifiedErrorId : ArgumentOutOfRange,Microsoft.PowerShell.Commands.GetVariableCommand

尝试这样做的原因是使PSTemplateEngine能够正常工作,而不需要有人传入一个包含变量名称和值的哈希表或类似-ArgumentsList的内容,然后要求他们在模板中有一个参数块。
Invoke-ProcessTemplatePath特别可能指向具有多个文件的树结构,每个文件都包含多个变量。单个虚构的-ArgumentsList可能包含40个值,并且每个模板文件必须具有长达40个参数的参数块,因为这些参数是按位置传递的。哈希表会工作得更好,但如果可能的话,我还是想避免它。
如何从被调用函数访问调用函数模块作用域中的变量$Var,而不传递哈希表、$Var的值、值为$(Get-Variable)的参数等?

7vux5j2d

7vux5j2d1#

模块存在于它们自己的世界中;它不是一个作用域,但它的行为有点像作用域。From about_Scopes
会话、模块和嵌套提示是自包含的环境,但它们不是会话中全局作用域的子范围。
模块的隐私行为类似于作用域,但将模块添加到会话不会更改作用域。此外,该模块没有自己的作用域,尽管该模块中的脚本与所有Windows PowerShell脚本一样都有自己的作用域。
因此,您将无法使用作用域语义从一个模块中访问另一个模块中的变量。
You can export a variable from one of the modules using Export-ModuleMember -Variable
我不完全理解模板引擎是什么或做什么,但从表面上看,您试图做的事情听起来非常错误。
将值作为参数传递可能是将数据传递给函数的正确方式。

djmepvbi

djmepvbi2#

由于OP没有提到他们实际上是如何解决这个问题的(只提到了一个哈希表,但没有描述它是如何完成的),所以我将充实它的一种方法,因为它可能并不明显。
首先,我创建了一个用于测试的变量,因为您的环境将包含其他变量,我想演示如何访问其中一个变量。下一行加载一个哈希表,其中引用了可从当前作用域访问的所有变量。然后可以将哈希表传递给任何函数。

$x = 'Some value'
$a = Get-ChildItem variable:|&{begin{$h=@{}}process{$h[$_.name]=$_}end{$h}}

因为哈希表存储引用,所以可以修改变量的内容。

$a['x'].value = 'A different value'

因此,OP代码的工作副本可能如下所示:

$ModulePath = $env:PSModulePath.Split(";")[0]

@'
$var = 1
function Write-Stuff {
    $var
}
function Test-WriteStuff {
    Write-Stuff
    $a = Get-ChildItem variable:|&{begin{$h=@{}}process{$h[$_.name]=$_}end{$h}}
    Write-Stuff2 $a
    Write-Stuff
}
'@ | Out-File $ModulePath\TestModule1\TestModule1.psm1

@'
function Write-Stuff2 {
    param ($all)
    $all['var'].value
    $all['var'].value=101
}
'@ | Out-File $ModulePath\TestModule2\TestModule2.psm1

结果会是什么?

1
1
101

相关问题