Skip to content

Instantly share code, notes, and snippets.

@aetos382
Last active December 18, 2016 17:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aetos382/c0d600da1a695c4446fc4b8e6ac60a24 to your computer and use it in GitHub Desktop.
Save aetos382/c0d600da1a695c4446fc4b8e6ac60a24 to your computer and use it in GitHub Desktop.
function Show-Hoge {
Write-Host 'Hoge'
}
$func = ${function:Show-Hoge}
Invoke-Command -Session $session -ScriptBlock {
New-Item -Path 'Function:\Show-Hoge' -Value $using:func > $null
Show-Hoge
}
$funcs = Get-ReferencingFunction ${function:Show-Hoge} -ContainSelf -Recursive
Invoke-Command -Session $session -ScriptBlock {
foreach ($func in $using:funcs) {
New-Item -Path $func.PSPath -Value $func.ScriptBlock > $null
}
Show-Hoge
}
using namespace 'System'
using namespace 'System.Management.Automation'
using namespace 'System.Management.Automation.Language'
function Get-ReferencingFunction {
[OutputType([FunctionInfo])]
param(
[Parameter(Mandatory, Position = 0)]
[scriptblock[]] $ScriptBlock,
[switch] $ContainSelf,
[switch] $Recursive)
function Get-RefefencingFunctionCore {
[OutputType([FunctionInfo])]
param(
[Parameter(Mandatory, Position = 0)]
[scriptblock[]] $ScriptBlock,
[switch] $ContainSelf,
[switch] $Recursive,
[Parameter(Mandatory)]
[Hashtable] $Context)
foreach ($sb in @($ScriptBlock)) {
$funcName = $sb.Ast.Name
# この関数はもう処理済み
if ($Context.ContainsKey($funcName)) { continue }
# 関数の中で呼んでいる関数を列挙
$elements = $sb.Ast.FindAll({
param(
[Parameter(Mandatory)]
[Ast] $ast)
# 関数呼び出しは CommandAst
if ($ast -isnot [CommandAst]) {
return $false
}
$elements = $ast.CommandElements
if (!$elements) {
return $false
}
# CommandElements の最初の要素が関数名らしい
$funcNameAst = $elements[0]
if ($funcNameAst -isnot [StringConstantExpressionAst]) {
return $false
}
$funcName = $funcNameAst.Value
if (!$funcName) {
return $false
}
# Function:\\ になるとすべての関数を取ってきてしまうので念の為避けておく
if ($funcName -eq '\') {
return $false
}
# この関数はもう処理済み
if ($Context.ContainsKey($funcName)) {
return $false
}
$funcPath = "Function:\$funcName"
return Test-Path $funcPath
}, $true)
[string[]] $funcNames = @()
if ($elements) {
# 呼んでいる関数名
$funcNames = @($elements) | ForEach-Object { $_.CommandElements[0].Value }
}
if ($ContainSelf) {
# 自分自身を追加
$funcNames += $funcName
}
# 呼んでいる関数が無かった
if ($funcNames.Length -eq 0) { continue }
foreach ($funcName in $funcNames) {
# 関数オブジェクトを取得
$funcPath = "Function:\$funcName"
$funcItem = Get-Item $funcPath
if (!$funcItem) { continue }
# この関数について再帰処理
if ($Recursive) {
Get-RefefencingFunctionCore -ScriptBlock $funcItem.ScriptBlock -Recursive -Context $Context
}
# 処理済みリストに追加
$Context[$funcName] = $funcItem
}
}
}
$context = @{}
Get-RefefencingFunctionCore @PSBoundParameters -Context $context
return $context.Values
}
# === 使い方 ===
function InnerOfInner {
}
function Inner1 {
InnerOfInner
}
function Inner2 {
InnerOfInner
}
function Outer {
Inner1
Inner2
}
$outer = ${function:Outer}
Write-Host 'Default'
Get-ReferencingFunction $outer
Write-Host 'ContainSelf'
Get-ReferencingFunction $outer -ContainSelf
Write-Host 'Recurse'
Get-ReferencingFunction $outer -Recursive
Write-Host 'Both'
Get-ReferencingFunction $outer -ContainSelf -Recursive
function Show-Hoge {
Write-Host 'Hoge'
}
Invoke-Command -Session $session -ScriptBlock {
Show-Hoge
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment