当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 使用 PSFramework 模块正确完成 PowerShell 日志记录

作者:精品下载站 日期:2024-12-14 20:52:01 浏览:16 分类:玩电脑

使用 PSFramework 模块正确完成 PowerShell 日志记录


能够跟踪 PowerShell 脚本正在执行的操作非常重要,尤其是在生产环境中。记录活动对于故障排除、审核和调查潜在安全问题至关重要。使用 PowerShell 和名为 PSFramework 的社区模块,您可以将日志记录提升到一个全新的水平,您将在本文中了解这一点!

如果您发现自己使用 Write-Host cmdlet 显示错误信息或手动注册 Windows 事件源,那么本文适合您。

如果您想要一个简单、可扩展的 PowerShell 日志记录解决方案(可以写入文本文件或集成到日志管理解决方案中),请与我们联系。

创建更好的日志消息

在决定如何最好地使用 PowerShell 生成日志之前,您首先需要了解如何生成更好的日志消息。

生成日志的原因有很多。最常见的错误消息之一是臭名昭著的错误消息。错误消息可能是有益的,也可能是有害的,具体取决于您如何看待事物。

毫无疑问,您一生中都曾是一些不良错误消息的受害者。如果您看过电影《办公空间》,PC LOAD LETTER 就是一个很好的例子。

如果您的错误消息导致某人思考“这是什么意思?”,您应该考虑重写您的消息!日志应该清晰简洁。

让活动具有可操作性

指示神秘的 PC LOAD LETTER 错误消息的日志消息本身没有多大意义。几年后,没有人会知道该消息的含义,包括您!您应该始终针对可操作的错误情况生成日志消息。

例如,使用PC LOAD LETTER消息,如果它改为“PC LOAD LETTER:检查旋转梁上的规格”,您会怎么想。如果符合规格,请联系供应商支持以获取进一步指导“?你可能会保持冷静一点,并且实际上可以快速开始解决问题。

保持日志简单且易于阅读

日志信息必须是人类可读的。包含足够的信息以使事件具有可操作性,而不是留给猜测。你可以很精确,但要确保其他人能够理解该事件的含义,即使是在基本层面上。

日志记录的复杂程度取决于您的意愿。保持日志简单可以让所有相关人员更轻松地进行故障排除。

Windows 中的日志记录选项

当您在 IT 中听到“日志”这个词时,您会想到什么?您可能会立即开始考虑日志文件。尽管日志文件确实是一种选择,并且您将在本文中了解它,但它们并不是唯一的选择。

另一种选择是 Windows 事件日志。 Windows 事件日志及其看似无穷无尽的日志源在 Windows 中无处不在。事件日志允许您编写不同严重程度、来源、类别、消息等的日志。

Windows 事件日志与日志文件不同,因为它具有结构。日志文件本身就是一个简单的文本文件。由开发人员提出日志消息的架构。 Windows 事件日志已经处理了架构。

在本文中,我们将介绍如何使用 PowerShell 来处理事件日志。我们还将介绍使用 PSFramework PowerShell 模块使用日志文件进行日志记录。

先决条件

本文的其余部分将是一个演练。如果您愿意跟随,您需要确保我们都在同一页面上。要完成本文中的每个主题,您需要:

  • Windows PowerShell 5.1
  • PowerShell 的中级知识
  • 了解基本的 Windows 事件日志记录术语

将事件写入 Windows 事件日志

使用 PowerShell 捕获日志记录信息的一种方法是使用 Windows 事件日志。如前所述,Windows 事件日志已经提供了一个可供使用的架构。它还包括 Windows 事件查看器和 PowerShell cmdlet 等 GUI 工具,用于创建和解析事件日志消息。

用于将日志事件写入 Windows 事件日志的主要 PowerShell cmdlet 是 Write-EventLog cmdlet。 Write-EventLog cmdlet 是您在现有事件日志中生成新日志事件的方法。如果您计划使用现有事件源,例如应用程序安全系统事件日志,Write-EventLog cmdlet 就是您所需要的。

Windows 事件日志有一个称为源的概念。简而言之,源只是将事件日志消息放入存储桶中的一种方法。例如,内置源用于将操作系统特定事件与软件事件分开。

如果您希望日志消息显示在默认源中,那么使用现有源来写入事件就可以了。但您也可以创建自己的源,这将有助于将自定义生成的事件日志消息与所有其他消息区分开来。

创建事件日志源

您可以使用 New-EventLog cmdlet 创建自定义事件日志源。此 cmdlet 将修改注册表,使您的事件日志成为 Windows 中的一等公民。

从管理 PowerShell 控制台,注册一个新的事件日志源,并提供名称和源,如下所示。

PS51> New-EventLog -LogName 'Application' -Source 'ATA_Script’'

如果您没有适当的权限或在非提升的 PowerShell 控制台会话下运行命令,您将看到如下错误。

[玩转系统] 使用 PSFramework 模块正确完成 PowerShell 日志记录

创建事件日志条目

为脚本/应用程序创建源后,您就可以开始工作并开始使用 Write-EventLog cmdlet 生成事件日志消息。

下面您可以看到使用刚刚创建的事件源 (ATA_Script) 将事件日志消息写入应用程序事件日志的示例。此消息是 ID 为 1 的信息事件。

PS51> Write-EventLog -LogName 'Application' -Source 'ATA_Script' -EntryType 'Information' -EventID 1 -Message 'Everything is broken. Everything is cool when you’re part of a team!'

创建事件后,您可以在 Windows 事件查看器中或使用 PowerShell 使用 Get-WinEventGet-EventLog cmdlet 查找该事件。以下示例使用 Get-EventLog cmdlet 通过刚刚创建的事件源查找所有信息事件。如果返回多个事件,则返回最新的事件。

PS51> Get-EventLog -LogName 'Application' -EntryType 'Information' -Source 'ATA_Script’' -Newest 1

[玩转系统] 使用 PSFramework 模块正确完成 PowerShell 日志记录

事件源最佳实践

在离开本节之前,了解这里的陷阱很重要。在上面的示例中,PowerShell 使用之前创建的任意注册源 (ATA_Script)。需要此源才能将条目写入 Windows 应用程序日志。

使用这样的自定义源非常适合简单的场景,例如:

  • 自定义 Windows 服务的事件日志记录。
  • 记录简单 PowerShell 函数的结果。
  • 为另一个进程提供触发事件。

最佳实践是,为要生成事件日志条目的每个脚本注册一个新的事件源,如第一步所示。当您这样做时,可以更轻松地跟踪生成事件日志条目的内容。想象一下您有五个脚本,每个脚本都执行一个非常具体的任务。如果它们都使用相同的事件源,您如何确定哪个脚本出现故障?注册新的事件源可以帮助您组织日志记录源。

利用 PowerShell 脚本

尽管您将要学习的方法有效,但这并不是最好的方法。稍后你就会明白为什么。

尽管当您在脚本运行时需要一些视觉反馈时,Write-Host cmdlet 很有用,但它在日志记录方面并不出色。为什么?

  • 输出特定于单个 PowerShell 会话。当您关闭会话时,输出就会消失。
  • 除了文本的前景色和背景色之外,该 cmdlet 没有太多自定义功能。

您可以在下面看到 Write-Host cmdlet 在使用中的示例。

[玩转系统] 使用 PSFramework 模块正确完成 PowerShell 日志记录

尽管默认情况下,此输出仅显示到 PowerShell 控制台,而不记录在其他任何地方,但它可以使用 PowerShell 转录本。

使用 Start-Transcript cmdlet,您可以创建捕获发送到 PowerShell 控制台的所有输出的记录(文本文件)。 Start-Transcript cmdlet 是记录 PowerShell 会话活动的好方法。

Start-Transcript cmdlet 开始将控制台活动记录到新的记录时,Stop-Transcript cmdlet 会停止它。您可以查看下面的示例。

[玩转系统] 使用 PSFramework 模块正确完成 PowerShell 日志记录

尽管使用 Write-Host cmdlet 和 PowerShell 转录在技术上可行,但这并不是最好的解决方案。请注意下面示例中的文字记录包含的内容。该日志很难阅读并且几乎无法解析!

[玩转系统] 使用 PSFramework 模块正确完成 PowerShell 日志记录

使用 PSFramework PowerShell 模块进行日志记录

正如所承诺的,是时候开始记录文本文件了!尽管您可以使用Add-ContentSet-Content和其他PowerShell cmdlet的组合来推出自己的日志文件解决方案,但没有需要。您可以使用名为 PSFramework 的免费 PowerShell 模块!

PSFramework 是一个 PowerShell 模块,允许您记录各种不同场景中的活动。

重要的 PSFramework 概念

供应商

PSFramework 模块的一个关键概念是提供者。提供程序是指向您想要存储日志的各种目的地的指针。提供程序可以是 Kiwi Log Server、Elasticsearch、loggly、Graylog 或像文件这样基本的东西(通常是文本)。

尽管可扩展,但当您第一次下载 PSFramework 模块时,您会立即获得三个可供使用的提供程序:

  • 文件系统 - 此提供商将您创建的所有消息流写入当前登录用户的 %APPDATA% 文件夹,并自动保留和轮换 7 天。文件系统是默认提供程序。
  • Gelf - 该提供程序允许 PSFramework 将日志消息流发送到名为 Graylog 的开源日志管理器。使用此选项时涉及更多设置。
  • 日志文件 - 此提供程序允许您指定一个文件来写入所有消息。由于日志文件可能有多种类型,因此默认输出为 CSV 格式。这意味着您可以使用常见的日志文件扩展名,例如 .txt.log.csv。这是你的选择。

消息流

消息流包含命令的输出。它们用于对日志中记录的信息进行分类。常见的流有详细、调试、信息、错误和警告。您可以使用 Help about_psf_message 阅读有关可用流的更多信息。

现在让我们开始实际使用 PSFramework 模块,看看它能做什么!

安装PS框架

第一个任务是下载并安装该模块。为此,请运行 Install-Module -Name PSFramework -Scope CurrentUser 从 PowerShell 库下载它。这会将模块放置在我的用户配置文件中,而不是系统路径中。如果您想让系统上的所有用户都可以使用该模块,请不要使用 Scope 参数。

安装后,您现在可以访问本文其余部分演示的代码示例所需的所有 cmdlet。

设置提供商

默认 PSFramework 配置有三个已注册和安装的提供程序可供选择 - 文件系统日志文件greylog。如果您想使用其他提供程序,您将首先在 PSFramework 中注册并安装该提供程序。在开始写入日志之前,您必须启用这些提供程序之一。

启用提供程序的命令是Set-PSFLoggingProvider。此 cmdlet 有两个必需参数 - NameEnable。您将使用每个参数来启用您希望合作的一个或多个提供商。

如果您计划使用自己的提供程序,则需要运行 Register-PSFLoggingProviderInstall-PSFLoggingProvider cmdlet。这些 cmdlet 和场景超出了本文的预期范围。如果您想进一步探索此选项,请查阅该模块提供的内置帮助。有一些示例可以引导您扩展现有功能,并让您更深入地了解日志记录的工作原理。

在本演示中,您将使用日志文件提供程序。由于该提供程序默认处于关闭状态,因此您必须首先启用该提供程序,以便可以向其发送消息流。使用 Set-PSFLoggingProvider 命令,您可以毫不费力地做到这一点:

Set-PSFLoggingProvider -Name 'logfile' -Enable $true

如果您想坚持使用文件系统提供程序,则无需执行任何操作,因为它已默认启用。

要查看当前注册的所有提供程序,请运行 Get-PSFLoggingProvider 命令。此命令应返回类似于下面的屏幕截图的输出。

[玩转系统] 使用 PSFramework 模块正确完成 PowerShell 日志记录

现在您已经启用了提供程序,您可以开始将消息流发送到您希望用于日志记录解决方案的提供程序。

使用文件系统提供程序进行日志记录

文件系统提供程序提供了一种快速启动日志记录的方法,而无需配置日志文件的存储位置。它非常适合短期日志记录需求,但不适用于需要长期诊断日志记录的情况。

在文件系统提供程序的演示中,您将学习如何使用 Write-PSFMessage cmdlet。假设您有一个现有的 PowerShell 脚本,可以在远程主机上启动服务。有时,服务由于某种原因无法启动,并且生成的错误未被捕获。您可以查看下面的示例。

Invoke-Command -ComputerName 'Lab01.domain.local' -ScriptBlock { Start-Service -Name 'BITS' }

您想知道 Start-Service 命令是否能够成功启动服务以及何时失败。为此,您强制 Start-Service 返回终止错误,然后添加 try/catch 块以捕获发生的任何错误。

try {
    Invoke-Command -ComputerName 'Lab01.domain.local' -ScriptBlock { Start-Service -Name 'BITS' } -ErrorAction Stop
} catch {

}

现在,您需要记录 Start-Service 成功和失败的时间。您知道,如果 Invoke-Command 失败,PowerShell 将运行 catch 块内的代码,而不是 Invoke-Command 运行后的任何代码。

将该行为与成功运行 Invoke-Command 之后的代码进行对比。您决定在适当的位置运行Write-PSFMessage 命令。

如下所示,如果代码成功执行,Write-PSFMessage 将记录一条有用的消息,级别为 Important 并标记为 Success

try {
    Invoke-Command -ComputerName 'Lab01.domain.local' -ScriptBlock { Start-Service -Name 'BITS' } -ErrorAction Stop

    Write-PSFMessage -Level Important -Message 'Successfully started BITS.' -Tag 'Success'
} catch {
    Write-PSFMessage -Level Warning -Message 'Error starting BITS.' -Tag 'Failure' -ErrorRecord $_
}

上面您看到了标签功能的使用。标签是可选的,但它确实使需要排序和搜索日志时变得更容易。标签是自由文本,允许您定义自己的文本。一些常见的标签有成功、失败、错误和信息。

现在,如果命令失败,您将看到写入 PowerShell 控制台的警告,如下所示。

[玩转系统] 使用 PSFramework 模块正确完成 PowerShell 日志记录

查看文件系统日志

使用文件系统提供程序编写一些消息流后,您可以使用 Get-PSFMessage cmdlet 来查询日志。

如果上面示例中的代码生成了 Warning 级别的日志消息,您可以通过使用 LevelWarning 值来读取所有这些消息代码>参数。您可以查看如何执行此操作的示例以及您将收到的输出类型。

PS51> Get-PSFMessage -Level Warning

[玩转系统] 使用 PSFramework 模块正确完成 PowerShell 日志记录

使用日志文件提供程序进行日志记录

现在您已经了解了文件系统提供程序的工作原理,让我们检查一下日志文件提供程序。日志文件提供程序允许您将消息流写入纯文本文件(默认情况下为 CSV 格式)。

要使用日志文件提供程序,您首先必须告诉 PSFramework 不要使用默认提供程序(文件系统)并设置一个文件来记录消息。为此,请使用 Set-PSFLoggingProvider cmdlet。您可以在下面的示例中看到如何执行此操作。

  • 通过 Name 参数提供的提供商名称(日志文件)
  • Enabled 属性设置为 True
  • 将目标文件设置为 FilePath 的值
PS51> Set-PSFLoggingProvider -Name logfile -Enabled $true -FilePath 'C:\My_Events.log'

注意:请务必在脚本的开头设置提供程序!

当像以前一样通过运行 Write-PSFMessage 命令接收到消息时,PSFramework 将记录该消息。该消息将包含日期格式 mm:dd:yyyy、脚本名称(源)、消息级别、详细消息、标签(可选)和错误记录。

以下示例展示了 Windows 记事本中非结构化格式的单个日志消息的外观。

[玩转系统] 使用 PSFramework 模块正确完成 PowerShell 日志记录

要利用 CSV 格式,请在 Microsoft Excel 中打开日志文件,输出将看起来更好,如下所示。

[玩转系统] 使用 PSFramework 模块正确完成 PowerShell 日志记录

我选择使用日志文件提供程序而不是文件系统提供程序是因为需要保留长期运行历史记录并将信息导入 Excel。输出的格式使得生成图表和过滤数据以进行报告变得轻而易举。

奖励:通过运行空间查询日志

PSFramework 模块的一项高级功能是使用运行空间。 PowerShell 运行空间是一种常见的方法,您可以通过旋转线程来并行运行进程。

由于您可能在不同的运行空间中同时运行多个日志记录流,因此 PSFramework 允许您实时查看多个日志。这些日志可以通过使用运行空间来自许多来源。此功能非常有用,因为您可以在后台运行多个命令或脚本时保持单个 PowerShell 会话打开。

如果您知道运行空间 ID,则可以使用 Get-PSFMessage 命令上的 Runspace 参数指定它,如下所示。

Get-PSFMessage -Runspace a2346978-d324-4886-89b8-bd14769be78f

运行空间可能是一个难以掌握的复杂主题。如果您想了解更多信息,请查看有关使用运行空间的 Microsoft DevBlog 系列。

在现实世界中使用 PSFramework:作者的注释

我已经使用 PSFramework 模块几个月了,它增强了我的维护脚本并迫使我编写更好的代码。

它迫使我编写更好的错误处理代码,并养成在 cmdlet 上将常见 ErrorAction 参数设置为 True 以创建终止错误的习惯。

我立即开始看到好处。甚至还有一个持续存在的问题,我最终能够使用生成的日志文件解决。

我遇到了一个错误,该错误仅在使用计划作业执行脚本时发生。手动执行时该脚本可以正常运行。事实证明,这个问题是凭证和时间问题。由于错误记录 ID 位于日志文件中,错误消息很清晰并且使用标签,因此我能够立即缩小范围。

尝试过其他方法来生成日志文件,这个模块是迄今为止最容易使用的。

PSFramework 模块运行良好、可靠,并且使您可以最大程度地控制详细消息。

概括

正如您在本文中了解到的那样,日志记录应该是自动化流程的关键组成部分。使用信息丰富且可操作的日志建立清晰的日志记录指南,再加上了解日志记录选项,将会大有帮助。

如果您尚未使用过 PSFramework 模块并且尚未完成此处提供的演示,请这样做。这个有用的模块允许您在记录日志时使用许多不同的选项,这最终将有助于故障排除、审核和安全分析。

进一步阅读

  • PSFramework 文档
  • Friedrich Weinmann:登录 DevOps 世界
  • 如何使用 PowerShell 脚本,作者:Adam Bertram

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯