如何在Invoke-Command ScriptBlock中调用自定义函数?
问题原因
Invoke-Command的脚本块是在目标远程服务器的独立PowerShell会话中执行的,你本地定义的Write-GreenConsole函数并不会自动同步到远程会话,所以远程机器无法识别该命令,触发CommandNotFoundException。
另外你原代码里的Write-GreenConsole函数存在一个小问题:变量$ServerName未定义,会导致日志中的服务器名称为空,需要修正。
解决方案
方案1:远程获取数据,本地执行日志(推荐)
将远程服务器的组成员信息返回本地后,再调用本地的日志函数。这种方式无需在远程机器上部署函数,且网络日志路径由本地访问更合理:
# 修正后的日志函数(添加$ServerName参数,避免未定义问题) function Write-GreenConsole ( $Details, $ServerName ) { $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 ) { # 远程执行仅获取组成员数据,返回本地 $groupMembers = Invoke-Command -ComputerName $svrName -ScriptBlock { (Get-LocalGroupMember -Group 'Remote Desktop Users').Name } # 本地调用日志函数,传入服务器名称和成员信息 Write-GreenConsole "Group members = $($groupMembers -join ', ')" -ServerName $svrName }
方案2:将日志函数同步到远程会话执行
如果确实需要在远程机器上执行日志操作(比如日志写入远程本地路径),可以将函数定义包含在远程脚本块中,或者通过$using:引用本地函数:
方式A:在远程会话中重新定义函数
function Get-RDPGoupMembers ( $svrName ) { Invoke-Command -ComputerName $svrName -ScriptBlock { # 在远程会话中定义日志函数 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" # 使用远程机器的计算机名 $ServerName = $env:COMPUTERNAME $Results = Write-Output "[$LogDate] [$LogLevel] [$ServerName]: $Details" $Results | Out-File -FilePath $LogPath -Append Write-Host "[$LogDate] [$LogLevel] [$ServerName]: $Details" -ForegroundColor Green -BackgroundColor Black } # 获取组成员并调用日志函数 $members = (Get-LocalGroupMember -Group 'Remote Desktop Users').Name -join ', ' Write-GreenConsole "Group members = $members" } }
方式B:通过$using:传递本地函数(PowerShell 3.0+支持)
function Get-RDPGoupMembers ( $svrName ) { Invoke-Command -ComputerName $svrName -ScriptBlock { # 引用本地的日志函数 $logFunction = $using:Write-GreenConsole # 获取远程组成员 $members = (Get-LocalGroupMember -Group 'Remote Desktop Users').Name -join ', ' # 调用函数时传入远程机器名和成员信息 & $logFunction "Group members = $members" -ServerName $env:COMPUTERNAME } }
注意:使用此方式时,需确保远程服务器有权限访问
\\Network_Path日志共享目录。
内容的提问来源于stack exchange,提问作者FlyingSubieSTi
相关产品推荐
相关产品推荐

