在Invoke Command中调用自定义日志功能

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

我写了一个自定义的写日志功能。如果我在Invoke中使用Write-Log函数,我收到以下错误消息“远程执行时出错:术语'Write-Log'不被识别为cmdlet,函数,脚本文件或可操作程序的名称。检查名称的拼写,或者如果包含路径,请验证路径是否正确,然后重试。“

我正在使用Powershell 5.1。我确实尝试使用$ {function:Write-Log},但它没有用。

Function Write-Log([string]$ComputerList,$message, $level="INFO") {
    $date_stamp = Get-Date -Format s
    $log_entry = "$date_stamp - $level - $message"
    $log_file = "$tmp_dir\upgrade_powershell.log"
    Write-Verbose -Message $log_entry
    Add-Content -Path $log_file -Value $log_entry
}

Function Start-Process ($ComputerList) {    
    Return Invoke-Command -computername $Computer -ScriptBlock {
                Param($file)
                $Application = $args[0]
                $ApplicationName = $Application.Substring($Application.LastIndexOf('\')+1)
                $ApplicationFolderPath = $Application.Substring(0,$Application.LastIndexOf('\'))
                $ApplicationExt = $Application.Substring($Application.LastIndexOf('.')+1)
    Write-Log -message "Installing $file on $($env:COMPUTERNAME)"
    $p = Start-Process $file -Wait -Passthru

    $p.WaitForExit()
                $p.WaitForExit()
                if ($p.ExitCode -ne 0) {
                    Write-Log -message "Failed installing with error code $($p.ExitCode)"  -level "ERROR"
                    $Return = $($env:COMPUTERNAME)
                }
                else{
                    $Return = 0

        if ($p.ExitCode -ne 0 -and $p.ExitCode -ne 3010) {
        $log_msg = "$($error_msg): exit code $p.ExitCode"
        Write-Log  -message $log_msg -level "ERROR"
        #throw $log_msg
        return
      }
    if ($p.ExitCode-eq 3010) {
        Reboot-AndResume
        break
    }}


}
}
powershell
2个回答
0
投票

尝试在scriptblock中包含自定义函数定义,有点像这样

invoke-command -scriptblock {
    param (
        your params
    )

    begin {
        function write-log (etc) {
            the function code
        }
    }

    process {
        your main scriptblock stuff
    }

    end {}
}

0
投票

我确实尝试使用${function:Write-Log}但它没有用。

qazxsw poi使用qazxsw poi将qazxsw poi函数体作为脚本块。

由于你正在使用远程处理(你将${function:Write-Log}参数传递给namespace variable notation),你要么必须将该脚本块作为参数传递给远程执行的脚本块,要么 - 更方便地 - 利用Write-Log(PSv3 +)来使远程可用的局部变量值。

遗憾的是,从Windows PowerShell v5.1 / PowerShell Core 6.2.0开始,-ComputerName不能与命名空间变量表示法结合使用 - 请参阅Invoke-Command

因此,在出现错误的情况下,将脚本块引用为$using: scope无法直接使用,但您可以使用中间变量,然后使用它来使用简化方案来调整$using:

注意:要运行此代码,通过连接到同一台计算机来模拟远程处理,请确保计算机上的this GitHub issue,并以管理员身份调用代码。

${using:function:Write-Log}

以上应该返回this excellent answer


当然,如果remoting is enabled源代码是:

  • 随时可用,和
  • 你不介意在脚本块中复制它,

你可以让函数定义成为远程执行脚本块的一部分:

function Write-Log { 
  param([string] $ComputerList, $message, $level="INFO")      
  # For testing simply echo the arguments
  "$ComputerList, $message, $level"
}

# Recreate the function's full source code as a string.
$funcDef = "function Write-Log { ${function:Write-Log} }"

Invoke-Command -Computer . -ScriptBlock {

  # Define the Write-Log function using Invoke-Expression
  # Note: This is a rare case where use of Invoke-Expression is
  #       justified; generally, it is to be AVOIDED - see
  #       https://blogs.msdn.microsoft.com/powershell/2011/06/03/invoke-expression-considered-harmful/
  Invoke-Expression $using:funcDef

  # Now you can call it as you would locally.
  Write-Log 'ws1 ws2' testing DEBUG

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