2017-06-02 49 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 
    } 
} 

在您的情況下,這可能根本不起作用,但我認爲我把它作爲選項放在那裏。

相關問題