如何在函数内部、Invoke-Command ScriptBlock 内部调用函数?

问题描述 投票:0回答:1

我一直在绞尽脑汁地思考这个问题,并在互联网上寻找答案,但我似乎找不到任何适合我的具体情况的信息。我创建了一组函数,可以帮助我从 Win2016 服务器上的本地“远程桌面用户”组中远程添加/删除用户和组。它们本身工作得很好,但我试图将它们添加到我正在开发的菜单脚本中,以便其他管理员可以使用它们,而无需手动运行它们。

我遇到的问题是,在我的脚本设置中,我创建了一组日志记录函数,我试图在添加/删除用户函数内部使用这些函数,这些函数需要在 Invoke-Command -ScriptBlock 内部使用。但是,这是我得到的错误:

The term 'Write-GreenConsole' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try 
again.
    + CategoryInfo          : ObjectNotFound: (Write-GreenConsole:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
    + PSComputerName        : SERVER01

以下是我试图协同工作的两个功能。第一个是日志记录功能,第二个是添加/删除功能。

function Write-GreenConsole ( $Details ) {
    $today = Get-Date -UFormat %d%b%Y
    $LogPath = "\\Network_Path\RDP_Logs_$today.log"
    $LogDate = Get-Date -UFormat "%D %T"
    $LogLevel = "INFO"
    $Results =  Write-Output "[$LogDate] [$LogLevel] [$ServerName]: $Details"
    $Results | Out-File -FilePath $LogPath -Append
Write-Host "[$LogDate] [$LogLevel] [$ServerName]: $Details" -ForegroundColor Green -BackgroundColor Black
}
function Get-RDPGoupMembers ( $svrName ) {
  Invoke-Command -ComputerName $svrName -ScriptBlock { 
    Write-GreenConsole "[ Group members for Server $env:COMPUTERNAME =" (Get-LocalGroupMember -Group 'Remote Desktop Users').Name "]"
  }
}

“$svrName”变量来自基于菜单中用户输入的主脚本。如果您需要更多详细信息,请告诉我。任何想法将不胜感激,谢谢!

powershell function logging scripting invoke-command
1个回答
0
投票

远程执行的脚本块不与调用者共享任何状态,因此您传递给

Invoke-Command -ComputerName ...
的脚本块不知道调用者的
Write-GreenHost
函数。

因此,您必须将 函数定义传递给脚本块并在那里重新创建函数

function Get-RDPGoupMembers ($svrName) {
  $funcDef = ${function:Write-GreenConsole} # aux. variable that stores the function body.
  Invoke-Command -ComputerName $svrName -ScriptBlock { 
    ${function:Write-GreenConsole} = $using:funcDef # recreate the function
    Write-GreenConsole "[ Group members for Server $env:COMPUTERNAME =" (Get-LocalGroupMember -Group 'Remote Desktop Users').Name "]"
  }
}

注:

  • ${function:Write-GreenConsole}
    命名空间变量表示法的示例 - 请参阅此答案了解背景信息。

  • 注意aux 的使用。变量

    $funcDef
    ,将函数体存储在调用者的作用域中,然后通过
    $using:
    作用域
    在远程脚本块中引用该函数体。

    • 原因是当前尝试将

      $using:
      与命名空间变量表示法结合起来(从 PowerShell (Core) 7.3.x 开始)会导致 syntax 错误;也就是说,
      ${using:function:Write-GreenConsole}
      不起作用。

    • 可以说,它

      应该,特别是考虑到它确实Start-Job

      一起工作。

© www.soinside.com 2019 - 2024. All rights reserved.