powershell - 将日志记录快速添加到现有的 powershell 脚本集

标签 powershell logging

我有一组 powershell 脚本,其中一些脚本调用其他脚本。其中一些下标也可以根据需要单独调用。如何快速向所有脚本添加日志记录,以便任何脚本调用都会生成日志文件以供以后检查?

有很多与日志记录有关的问题,其中有一些很好的答案,like this one 。但我想看看我们能想出什么办法:

  • 需要对现有 powershell 文件进行最少的修改
  • 自动处理脚本 A.ps1 调用脚本 B.ps1。如果你打电话 A.ps1,A.ps1需要开始和完成日志记录。但如果你调用 B.ps1 直接,B.ps1 就可以。

我在下面提出了我的答案,并想分享并看看是否有其他关于如何解决这个问题的想法,或者改进我的答案的建议。

最佳答案

我编写的支持代码(进一步向下)允许将以下内容添加到每个 ps1 文件中。无论脚本是在顶层还是由另一个脚本调用,它都会自动向我提供日志记录:

#any params for script
. "$PSScriptRoot\ps_support.ps1"
StartTranscriptIfAppropriate
try
{
#all of the original script
}
finally
{
ConditionalStopTranscript
}

支持此功能的代码位于 ps_support.ps1 中,位于我需要日志记录的 powershell 文件集合旁边。它使用 Get-Variable 和 Set-Variable 在调用者的作用域级别操作几个变量:

  • Logging__TranscriptStarted 是正常的,因此子范围可以看到 日志记录已经发生,不要尝试再次启动它。
  • Logging__TranscriptStartedPrivate 是私有(private)的,因此范围可以知道是否 它负责停止日志记录。

这是 ps_support.ps1:

Set-Variable -name TranscriptStartedPropertyName -opt ReadOnly -value 'Logging__TranscriptStarted'
Set-Variable -name TranscriptStartedPrivatePropertyName -opt ReadOnly -value 'Logging__TranscriptStartedPrivate'

function StartTranscriptIfAppropriate
{
    $transcriptStarted = [bool](Get-Variable -name $TranscriptStartedPropertyName -ErrorAction Ignore)
    if (-not $transcriptStarted)
    {
        $callstack = get-pscallstack
        $fullPath = $callstack[$callstack.count-2].ScriptName
        $name = Split-Path -Path $fullPath -Leaf
        $directory = Split-Path -Path $fullPath
        $logDirectory = [IO.Path]::GetFullPath("$directory\..\scripts_logs")
        md -force $logDirectory | out-null
        $logFinalPath = "$logDirectory\$(Get-Date -Format o | foreach {$_ -replace ":", "."})_$name.log"
        Set-Variable -scope 1 -name $TranscriptStartedPropertyName -value $True
        Set-Variable -scope 1 -option private -name $TranscriptStartedPrivatePropertyName -value $True
        Start-Transcript $logFinalPath | Write-Host
    }
    $immediateCallerPath = Get-Variable -scope 1 -name PSCommandPath -ValueOnly
    Write-Host "Starting script at $immediateCallerPath"
}

function ConditionalStopTranscript
{
    $immediateCallerPath = Get-Variable -scope 1 -name PSCommandPath -ValueOnly
    Write-Host "Stopping script at $immediateCallerPath"
    $transcriptStartedByMe = [bool](Get-Variable -scope 1 -name $TranscriptStartedPrivatePropertyName -ErrorAction Ignore)
    if ($transcriptStartedByMe)
    {
        Stop-Transcript | Write-Host
    }
}   

关于powershell - 将日志记录快速添加到现有的 powershell 脚本集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45496274/

相关文章:

powershell - 如何使用Get-ChildItem在具有特定名称的目录中查找文件?

java - hadoop 覆盖每个作业的 log4j.properties

java - 如何在不更改代码的情况下更改tomcat中eclipselink的日志级别?

.net - TFS 项目可以相互引用吗?

powershell - Get-ChildItem和Copy-Item说明

powershell - 获取CPU使用率的脚本

java - Logback忽略父包的记录器

linux - 跨平台应用程序的标准日志位置

powershell - Powershell:通过字符串数组过滤文件的内容

powershell - 启动 psexec 后获取进程 ID