PowerShell ScriptBlock和多个功能



我写了以下代码:

cls
function GetFoo() { 
    function GetBar() {
        $bar = "bar"
        $bar
    }
    $foo = "foo"
    $bar = GetBar
    $foo
    $bar
}

$cred = Get-Credential "firmwidesrabhi_adm"
$result = Invoke-Command -Credential $cred -ComputerName localhost 
-ScriptBlock ${function:GetFoo}
Write-Host $result[0]
Write-Host $result[1]

它有效,但我不想定义GetFoo内部的GetBar

我可以做这样的事情吗?

cls
function GetBar() {
    $bar = "bar"
    $bar
}
function GetFoo() {     
    $foo = "foo"
    $bar = GetBar
    $foo
    $bar
}

$cred = Get-Credential "firmwidesrabhi_adm"
$result = Invoke-Command -Credential $cred -ComputerName localhost 
-ScriptBlock ${function:GetFoo; function:GetBar; call GetFoo}
Write-Host $result[0]
Write-Host $result[1]

基本上,我选择性地将我想要的功能放在脚本块中,然后调用其中一个。这样,我就不必在功能内定义函数,可以通过注入我想成为该脚本屏蔽的一部分的函数来构造脚本键。

问题是Invoke-Command只能看到ScriptBlock内部的内容,它看不到外部的功能。如果您真的想要 - 您可以按一行运行所有内容,例如:

$result = Invoke-Command  -ComputerName localhost  -ScriptBlock { function GetBar() { $bar = "bar"; $bar }; function GetFoo() { $foo = "foo"; $bar = GetBar; $foo;  $bar }; GetFoo }

,但我个人建议您将功能保存在脚本中,并使用-FilePath参数调用Invoke-Command,例如:

$result = Invoke-Command  -ComputerName localhost  -FilePath "1.ps1"

我最近有效:

function GetBar() {
    $bar = "bar"
    $bar
}
function GetFoo() {     
    $foo = "foo"
    $bar = GetBar
    $foo
    $bar
}
$NewScriptBlock = [scriptblock]::Create("function GetBar() { ${function:GetBar} } function GetFoo() { ${function:GetFoo} } GetFoo")
Invoke-Command -ComputerName localhost -ScriptBlock $NewScriptBlock

另外,您可以使用以下方式备用一行:

Invoke-Command -ComputerName localhost -ScriptBlock ([scriptblock]::Create("function GetBar() { ${function:GetBar} } function GetFoo() { ${function:GetFoo} } GetFoo"))

诀窍是ScriptBlock类的创建方法添加了函数的代码 inter和最终括号中不添加代码。您需要自己添加,加上最终调用。

我知道这是一个旧线程,但我希望它对某人有帮助。

[CmdletBinding()]
param()
$barScriptBlock = {
    function GetBar() {
        $bar = "bar"
        $bar
    }
}
$fooScriptBlock = {
    function GetFoo() {     
        $foo = "foo"
        $bar = GetBar
        $foo
        $bar
    }
}
# Concatenate all functions into a script block; add a parameter for extra credit.
$scriptBlockString = @"
param(`$hello)
$($barScriptBlock.ToString())
$($fooScriptBlock.ToString())
`$hello
GetFoo
"@
Write-Verbose $scriptBlockString
# Convert combined string to script block.
$finalScriptBlock = [ScriptBlock]::Create($scriptBlockString)
# Run synchronously, passing runtime parameter.
$result = & $finalScriptBlock "Hola"
# (Async results would not be reiably accessed here yet.)
Write-Host $result[0]
Write-Host $result[1]
Write-Host $result[2]

在乔·扎莫拉(Joe Zamora)的答案中构建的构建,这是我认为更适合这个问题的命令:

$result = Invoke-Command -Credential $cred -ScriptBlock ([ScriptBlock]::Create("${function:GetFoo}; ${function:GetBar}; GetFoo"))

这就是我的方式:

#get my script path
$this_Script = $MyInvocation.MyCommand.path
#get get all my location functions and filters
$this_functions = Get-Item FUNCTION:* | Where-Object { $_.ScriptBlock.File -eq $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath( $this_Script  ) }
$mything | ForeachObject -Parallel {
    
    $this_functions = $using:this_functions

    $this_functions | Foreach-Object {  
        #create function scriptblocks
        $sb = "$($_.CommandType) $($_.name) {$($_.ScriptBlock) }" ; 
    
        Invoke-Expression $sb ;
    }
}

以上仅在PWSH核心中使用。

相关内容

  • 没有找到相关文章

最新更新