2017-06-02 29 views
2

有没有办法找到引用给定模块(.psm1)的脚本文件列表?换句话说,获取脚本代码中使用模块中定义的至少一个cmdlet的所有文件。获取对给定PowerShell模块的所有引用

很显然,由于PowerShell 3.0及以上版本的原因,我的大多数脚本文件在代码中没有明确的Import-Module MODULE_NAME,所以我无法使用该文本进行搜索。

我知道我可以使用Get-ChildItem -Path '...' -Recurse | Select-String 'TextToSearchFor'搜索文件中的特定字符串,但这与搜索对模块的任何cmdlet的任何引用不同。我可以在模块中搜索每一个cmdlet,但我想知道是否有更好的方法。

澄清:我只是在一个受控环境中寻找一个文件位置的所有脚本。

+1

PowerShell不是一种静态语言。从字面上看,在任何给定的环境中,“Verb-Noun”cmdlet将来自哪里(除非你控制环境,或者脚本包含明确的“#requires” )。鉴于此,字符串匹配实际上并不是一种方法的坏处。任何更复杂的事情都不可能给出更准确的结果(如果脚本想要钝化,那么问题通常是无法解决的)。 –

+0

这不会是一个100%的万无一失的方法来实现这一点。您可以使用AST来解析文件,但是您必须记住,脚本可以稍后导入之前未导入的模块,它可以在运行时生成或下载新脚本,然后导入它,它可以使用' Invoke-Expression'等等。你可以做的最全面的方法是执行每个脚本,然后在前后编译加载的模块,但即使这样也容易出错;如果某个函数引用了一个cmdlet,但是您从不调用该函数。也许你可以和Pester一起做点什么,嘲弄? – briantist

+0

我想我应该提出的一个解释是,我只在一个受控环境中寻找一个文件位置的所有脚本。字符串搜索可能仍然是最好的方法,但我不知道如何以一种有效的方式来完成。我想为我的环境中的100多个模块执行此操作,以查看哪些模块可能不再使用,因此我不想通过每个模块并手动输入每个cmdlet。 –

回答

1

根据情况,调用堆栈可能会很有趣。在这种情况下,您需要修改您想要查找的函数,以便在运行时收集有关callstack的信息并将其记录在某处。随着时间的推移,你可能有足够的日志来做出一些好的假设。

function yourfunction { 
    $stack = Get-PSCallStack 
    if ($stack.Count -gt 1) { 
     $stack[1] # log this to a file or whatever you need 
    } 
} 

在您的情况下,这可能根本不起作用,但我认为我把它作为选项放在那里。

相关问题