gpt4 book ai didi

powershell - 如何检测脚本是点源的,还是使用 powershell v2+ 作为模块的一部分加载的?

转载 作者:行者123 更新时间:2023-12-02 23:47:03 25 4
gpt4 key购买 nike

给定一个 ps1 文件作为具有以下代码的模块的一部分:

function Get-Greeting {
'Hello {0}' -f $Env:Username
}
Export-ModuleMember -Function:Get-Greeting

当作为模块的一部分加载时,一切都很好。如果我点源脚本,我会得到
Export-ModuleMember : The Export-ModuleMember cmdlet can only be called from inside a module.

我知道我可以在 Export-ModuleMember 上添加一个 -ErrorAction:Ignore,但这不是重点。我想让一个脚本以不同的方式运行,无论它是导入的还是点源的。

在版本 2 中,可能会围绕 $PSScriptRoot 编写一个 hack。 ,但这只是一个 hack,在他们“修复”的版本 3 中不起作用 $PSScriptRoot永远不会为空。我试过查看 $MyInvocation 中的各种项目,但要么我错过了一些东西,要么它没有任何用处。

我也试过运行 Get-Variable内部和外部一个模块,但再次发现没有差异。

作为 Import-Module 运行时,我错过了什么?对比 . myscript.ps1 ?

最佳答案

看来我找到了答案。我在 $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 的符号链接(symbolic link),以作为直接模块加载。
cmd /c mklink .\moduledetection\moduleDetection.ps1 .\moduledetection\moduleDetection.psm1

输出显示父范围有 key 。

输出:
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。

现在我们知道如何检测我们是否在一个模块中,并且通过其他资源也可以了解我们是否被点源、直接执行和/或通过模块加载。

关于powershell - 如何检测脚本是点源的,还是使用 powershell v2+ 作为模块的一部分加载的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17867953/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com