看来我找到了答案。我在 中遗漏了一些东西$MyInvocation
,因为我在寻找错误的范围。给定以下文件:
# .\moduleDetection\moduleDetection.ps1
$ErrorActionPreference = 'SilentlyContinue';
'=== Parent Invocation.MyCommand: [{0}]' -f (Get-Variable -Name:MyInvocation -Scope:1 -ValueOnly | Select -Expand MyCommand) | Out-Host;
.
# .\moduleDotSource\moduleDotSource.psm1
. "$PSScriptRoot\..\moduleDetection\moduleDetection.ps1"
.
# .\module-test.ps1
$Error.Clear()
Write-Host "Powershell Version 3:"
Write-Host "Powershell -Command Import-Module (direct)"
powershell -nologo -noprofile -Command { Import-Module .\moduledetection }
Write-Host "Powershell -Command Import-Module (dot-source)"
powershell -nologo -noprofile -Command { Import-Module .\moduleDotSource }
Write-Host "Powershell -File ...moduledetection.ps1"
powershell -nologo -noprofile -File .\moduledetection\moduleDetection.ps1
Write-Host "Powershell Dot-Source"
powershell -nologo -noprofile -Command { . .\moduledetection\moduleDetection.ps1 }
Write-Host ""
Write-Host "Powershell Version 2:"
Write-Host "Powershell -Version 2 -Command Import-Module"
powershell -version 2.0 -nologo -noprofile -Command { Import-Module .\moduledetection }
Write-Host "Powershell -Version 2 -Command Import-Module (dot-source)"
powershell -version 2.0 -nologo -noprofile -Command { Import-Module .\moduleDotSource }
Write-Host "Powershell -Version 2 -File ...moduledetection.ps1"
powershell -version 2.0 -nologo -noprofile -File .\moduledetection\moduleDetection.ps1
Write-Host "Powershell -Version 2 Dot-Source"
powershell -version 2.0 -nologo -noprofile -Command { . .\moduledetection\moduleDetection.ps1 }
最后,创建一个从原始 ps1 到具有正确名称的 psm1 的符号链接,以作为直接模块加载。
cmd /c mklink .\moduledetection\moduleDetection.ps1 .\moduledetection\moduleDetection.psm1
输出显示父范围具有密钥。
输出:
Powershell Version 3:
Powershell -Command Import-Module (direct)
=== Parent Invocation.MyCommand: [ Import-Module .\moduledetection ]
Powershell -Command Import-Module (dot-source)
=== Parent Invocation.MyCommand: [ Import-Module .\moduleDotSource ]
Powershell -File ...moduledetection.ps1
Powershell Dot-Source
Powershell Version 2:
Powershell -Version 2 -Command Import-Module
=== Parent Invocation.MyCommand: [ Import-Module .\moduledetection ]
Powershell -Version 2 -Command Import-Module (dot-source)
=== Parent Invocation.MyCommand: [ Import-Module .\moduleDotSource ]
Powershell -Version 2 -File ...moduledetection.ps1
Powershell -Version 2 Dot-Source
从显示的输出中我们可以看到(在 Server 2008 R2 上运行),父作用域$MyInvocation.MyCommand
包含导入模块语句。我还没有测试它,但我由此推断,如果它是通过链式点源的多重间接,我们可以继续采用父作用域,直到我们得到 Null 或 Import-Module。
现在我们知道如何检测我们是否在一个模块中,并且通过其他资源也可以了解我们是否被点源、直接执行和/或通过模块加载。