首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将PowerShell命令记录到LogFile

将PowerShell命令记录到LogFile
EN

Stack Overflow用户
提问于 2022-11-07 18:36:49
回答 1查看 93关注 0票数 2

我有带有日志功能的基本PowerShell脚本和一些要运行的命令。我正在寻找一种登录日志文件命令的解决方案。

目前,我只知道这一点,但是复制+粘贴所有命令以被记录是非常烦人的:

代码语言:javascript
复制
$LogPath        = "C:\Logs"
$FileName       = (Get-Item $PSCommandPath).Basename                                                        
$LogFile        = $LogPath + "\" + $FileName + ".log"

Function WriteLog
{
Param ([string]$LogString)
$Stamp      = (Get-Date).toString("yyyy-MM-dd HH:mm:ss")
$LogMessage = "$Stamp $LogString"
Add-content $LogFile -value $LogMessage
}

WriteLog "***********************"
WriteLog ""

WriteLog "Command1"
Command1

WriteLog "Command2"
Command2

WriteLog "Command3"
Command3

WriteLog "Command4"
Command4

WriteLog "Command5"
Command5

WriteLog ""
WriteLog "***********************"
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-07 22:25:52

我建议如下:

  • 修改函数以另一种方式接受表示要执行的命令的脚本块 ({ ... })。
  • 如果给出一个脚本块,使用它的字符串表示作为日志消息,然后执行它。
代码语言:javascript
复制
# Create the logging function in a *dynamic module* (see below).
# Place this at the top of your script.
$null = New-Module {

  # Define the log-file path.
  $LogPath        = 'C:\Logs'
  $FileName       = (Get-Item $PSCommandPath).Basename                                                        
  $LogFile        = $LogPath + '\' + $FileName + '.log'
  
  # Create / truncate the file.
  New-Item -Force -ErrorAction Stop $LogFile

  function Add-LogMessage {
    [CmdletBinding(DefaultParameterSetName = 'String')]
    param(
      [Parameter(Position = 0, Mandatory, ParameterSetName = 'ScriptBlock')]
      [scriptblock] $ScriptBlock
      ,
      [Parameter(Position = 0, ParameterSetName = 'String')]
      [string] $String
    )

    # If a script block was given, use its string representation
    # as the log string.
    if ($ScriptBlock) {
      # Make the string representation single-line by replacing newlines
      # (and line-leading whitespace) with "; " 
      $String = $ScriptBlock.ToString().Trim() -replace '\r?\n *', '; '
    }

    # Create a timestamped message and append it to the log file.
    $stamp = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
    $logMessage = "$stamp $String"
    Add-Content -LiteralPath $LogFile -Value $logMessage

    # If a script block was given, execute it now.
    if ($ScriptBlock) {
      # Because this function is defined in a (dynamic) module,
      # its invocation doesn't create a child scope of the *caller's* scope,
      # and invoking the given script block, which is bound to the caller's scope,
      # with . (dot-sourcing) runs it *directly in the caller's scope*.
      . $ScriptBlock
    }
  }
}

注意:

  • 函数名遵循PowerShell的动词-名词惯例,使用的是Add,这是一个认可动词;但是,为了简洁起见,也执行执行的方面( Invoke将是已批准的动词)没有反映在名称中。

然后,您的脚本将如下所示:

代码语言:javascript
复制
Add-LogMessage "***********************"
Add-LogMessage ""

Add-LogMessage { Command1 }

Add-LogMessage { Command2 }

# ... 

Add-LogMessage "***********************"

注意:

  • 通过将函数放置在通过模块创建的(动态的、瞬态的) New-Module中,它的调用不会创建调用方作用域的子作用域。
  • 当传入调用方作用域中由文字({ ... })创建的脚本块时,可以使用.调用它,点源运算符直接在调用方的作用域中执行它,这意味着脚本块的代码可以自由地修改脚本的变量,就像将该代码直接放在脚本中一样。
  • 如果您希望函数也记录给定脚本块的输出(同时仍将其打印到显示器),您可以使用Tee-Object,如下所示(为了简单起见,我假设相同的目标日志文件,根据需要进行调整): 。$ScriptBlock / Tee-Object -Append -FilePath $LogFile
代码语言:javascript
复制
- **Caveat**: As of PowerShell 7.2.x, `Tee-Object` uses a _fixed_ character encoding, namely UTF-16LE ("Unicode") in _Windows PowerShell_ and BOM-less UTF-8 in _PowerShell (Core) 7+_. [GitHub issue #11104](https://github.com/PowerShell/PowerShell/issues/11104) suggests adding an `-Encoding` parameter (which only future _PowerShell (Core)_ versions would benefit from).
代码语言:javascript
复制
- Therefore, if you're using _Windows PowerShell_ and you're targeting the _same_ log file for capturing the output, be sure to modify the `Add-Content` call with `-Encoding Unicode` as follows:

Add- -Encoding Unicode -LiteralPath $LogFile -Value $logMessage

代码语言:javascript
复制
- Alternatively, if you want to avoid UTF-16LE ("Unicode") files for their size (with all-ASCII characters, they're twice the size of ANSI and UTF-8 files), you can use one of the **workarounds** discussed in [this answer](https://stackoverflow.com/a/58922982/45375).
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74351332

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档