首页 > 系统相关 >PowerShell Deep Drive 2-正则审查O365安装日志

PowerShell Deep Drive 2-正则审查O365安装日志

时间:2023-08-17 15:36:17浏览次数:51  
标签:匹配 Office 正则表达式 Drive Deep matches O365 日志 安装

PowerShell Deep Drive 2-正则审查O365安装日志

前言

最近遇到一个问题,在安装O365客户端的时候,遇到安装失败的情况,需要检查O365的安装日志,确定问题。在 Office 365(现在称为 Microsoft 365)的安装过程中,系统会生成安装日志以记录安装操作的详细信息。这些日志对于排查安装问题、分析错误以及监控安装过程中的事件非常有用。

难点

O365的日志秉承了Windows文本日志的一贯特点,又臭又长且难以阅读。

日志的格式不易阅读和缺乏清晰的描述都是常见的问题。Office 365 安装日志中可能包含大量信息,但它们往往以原始格式出现,缺乏可读性和易于理解的结构。此外,有时重要的信息可能隐藏在繁杂的日志中,需要耗费一些精力才能找到。

背景知识

获取 Office 365 安装日志

  1. 自动日志收集: Office 365 通常会自动创建安装日志,这些日志可以在你的计算机上的特定位置找到。在安装过程中,Office 365 安装程序会在 %temp% 目录下创建一个临时文件夹,其中包含有关安装过程的详细日志。临时文件夹的名称可能类似于 SetupExe(*).log
  2. 手动查找: 你也可以手动在计算机上搜索安装日志文件。日志文件可能存储在不同的位置,具体取决于 Office 版本和操作系统。通常,日志文件会存储在以下位置之一:
  • C:\Users\<YourUsername>\AppData\Local\TempC:\Users\<YourUsername>\AppData\Local\Microsoft\Office\15.0\
  • %ProgramData%\Microsoft\ClickToRun
  • %ProgramData%\Microsoft\Office
  1. Office 日志收集工具: Microsoft 也提供了一些工具,如 Microsoft 365 日志收集工具,可以帮助你收集和分析 Office 365 安装日志以及其他相关日志信息。

日志包含什么

Office 365 安装日志可能会包含以下内容:

  • 时间戳: 记录每个操作的发生时间。
  • 文件路径: 显示正在安装的文件的路径。
  • 操作信息: 记录正在执行的安装操作,如复制文件、创建注册表项等。
  • 错误信息: 如果发生错误,安装日志会记录错误的详细信息,例如错误代码、错误消息等。
  • 组件安装: 显示每个 Office 组件的安装情况,例如 Word、Excel 等。
  • 注册表操作: 如果安装过程中修改了注册表,安装日志可能会记录这些操作。
  • 网络操作: 如果安装过程涉及从网络下载文件,安装日志可能会记录下载操作。
  • 版本信息: 安装程序可能会记录 Office 365 的版本和产品信息。

处理逻辑

为了能够更好的阅读这些日志,我写了一个脚本,这里用到了正则去处理日志。类似下面这条日志,所有信息都混杂在一起了,肉眼看起来非常麻烦,重要信息都集中在最后的{}内包含的Json字符串中。

08/14/2023 18:08:20.224	OFFICECL (0x1be8)	0x2b88		Activity	bjtco	Medium	DroppedAggregatedActivity {"Name": "Office.Experimentation.EndPoint", "CV": "DFdtk38FiUyQVvm7eIZwsw.5.1.1", "ProcessIdentifier": "OfficeClickToRun.exe_16.0.16227.20298_X86_{936D570C-057F-4C89-9056-F9BB788670B3}"}

当在 PowerShell 中处理字符串时,可以使用正则表达式和比较操作符来实现不同的需求。下面的例子会用正则来实现。

正则表达式

优点:

  1. 强大的模式匹配: 正则表达式允许你定义复杂的模式,从而可以更精确地匹配和提取数据。这对于处理包含特定格式或模式的字符串非常有用。
  2. 灵活性: 正则表达式可以处理多种不同的模式和规则,因此可以适用于各种需求,包括匹配、替换、提取等。
  3. 一次性操作: 单个正则表达式可以处理多种不同的操作,如查找、替换和提取。这可以减少代码量并提高效率。
  4. 性能: 对于较大的文本数据,适当优化的正则表达式可以在性能方面表现良好。但性能也受到正则表达式的复杂性和匹配模式的影响。

缺点:

  1. 复杂性: 正则表达式语法相对复杂,学习和理解可能需要一些时间。复杂的正则表达式可能会变得晦涩难懂。
  2. 性能: 复杂的正则表达式可能导致性能下降,尤其是在处理大量数据时。某些情况下,正则表达式可能会导致回溯问题,导致性能损失。
  3. 可读性: 由于正则表达式的复杂性,写出易于理解的正则表达式可能是一项挑战。同时,他人可能需要更多时间来理解你的正则表达式的意图。

比较操作符

优点:

  1. 简单易懂: 比较操作符的语法相对简单,易于理解和使用。这使得处理基本的字符串比较变得非常直观。
  2. 可读性: 使用比较操作符的代码通常更易于他人理解。操作符的含义和意图通常很明显。
  3. 性能: 比较操作符通常是直接的逻辑比较,因此在处理较小的数据量时,性能较好。

缺点:

  1. 限制: 比较操作符相对较简单,无法处理复杂的模式匹配需求。它们更适用于基本的相等、不相等和大小比较。
  2. 灵活性: 比较操作符不如正则表达式灵活,无法实现复杂的模式匹配、提取和替换操作。

综合考虑:

  1. 性能: 对于大量数据的基本比较,比较操作符可能会更快速。但在处理复杂模式匹配时,性能可能较低。
  2. 语法和可理解性: 比较操作符在语法和可理解性方面通常更胜一筹,特别适用于简单的需求。
  3. 复杂模式匹配: 如果需要进行复杂的模式匹配、提取和替换操作,正则表达式则是更适合的选择,尽管它可能需要更多学习和调试时间。

在实际情况中,根据具体的需求选择合适的方法是重要的。对于简单的字符串处理和比较,比较操作符可能更合适;而对于需要复杂模式匹配和高级处理的情况,正则表达式是更强大的工具。综合考虑性能、语法和可理解性,可以根据不同的情况来决定使用哪种方法。

另外正则的门槛其实非常高,入门选手更多建议大家使用比较操作符,虽然会导致代码长一些,但是阅读感是最好的。

正则举例

当解释这个正则表达式时,首先让我们看一下整个正则表达式的含义。然后,我将解释它如何将字符串拆分成不同的字段。

正则表达式:

(\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}\.\d{3})\s(.*?)\s\((.*?)\)\s(.*?)\s(.*?)\s((?!local|event|error)\S{5})\s(.*?)\s(.*?)\s(.*?)(.*)$

  1. (\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}\.\d{3}):匹配日期和时间戳,如 08/14/2023 18:08:20.224
  2. \s:匹配一个空格
  3. (.*?):匹配并捕获任意字符,非贪婪模式
  4. \s:匹配一个空格
  5. \((.*?)\):匹配并捕获括在圆括号中的内容,如 (0x1be8)
  6. \s:匹配一个空格
  7. (.*?):匹配并捕获任意字符,非贪婪模式
  8. \s:匹配一个空格
  9. (.*?):匹配并捕获任意字符,非贪婪模式
  10. \s:匹配一个空格
  11. ((?!local|event|error)\S{5}):匹配一个不是以 localeventerror 开头的长度为 5 的非空白字符序列
  12. \s:匹配一个空格
  13. (.*?):匹配并捕获任意字符,非贪婪模式
  14. \s:匹配一个空格
  15. (.*?):匹配并捕获任意字符,非贪婪模式
  16. (.*)$:匹配并捕获剩余的字符串,直到行尾

将数据应用于正则表达式后,可以将其拆分为以下字段:

  1. 时间戳:08/14/2023 18:08:20.224
  2. 进程:OFFICECL
  3. TID:(0x1be8)
  4. 区域:0x2b88
  5. 类别:Activity
  6. 事件ID:bjtco
  7. 级别:Medium
  8. 消息:DroppedAggregatedActivity
  9. 相关性:{"Name": "Office.Experimentation.EndPoint", "CV": "DFdtk38FiUyQVvm7eIZwsw.5.1.1", "ProcessIdentifier": "OfficeClickToRun.exe_16.0.16227.20298_X86_{936D570C-057F-4C89-9056-F9BB788670B3}"}

脚本实现

注意这个例子只适用于O365的安装日志。

<#
.SYNOPSIS
    该脚本用于解析和显示日志文件中的信息。
.DESCRIPTION
    此脚本提供了多个函数,用于解析日志文件中的条目,提取关键信息,以可视化方式显示日志内容,并允许用户通过对话框选择日志文件。
.AUTHOR
    zhangpengliang
.EXAMPLE
    .\O365LogParser.ps1
    - 执行此命令将弹出对话框,以便选择日志文件。选择后,将显示日志的解析结果和可视化内容。
.EXAMPLE
    .\O365LogParser.ps1 -LogFilePath "C:\Path\To\Your\LogFile.log"
    - 使用此命令可以直接指定日志文件的路径,而无需通过对话框选择。将显示日志的解析结果和可视化内容。
#>


function Parse-LogEntry {
    param (
        [string]$logEntry
    )

    $regex = '(\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}\.\d{3})\s(.*?)\s\((.*?)\)\s(.*?)\s(.*?)\s((?!local|event|error)\S{5})\s(.*?)\s(.*?)\s(.*?)(.*)$'

    if ($logEntry -match $regex) {
        $matches
    }
}

function Convert-To-ExtractedObject {
    param (
        [hashtable]$matches
    )

    $extractedObject = [PSCustomObject]@{
        Timestamp   = $matches[1]
        Process     = $matches[2]
        TID         = $matches[3]
        Area        = $matches[4]
        Category    = $matches[5]
        EventID     = $matches[6]
        Level       = $matches[7]
        Message     = $matches[8] + ' ' + $matches[9]
        Correlation = $matches[10]
    }

       $tempmatch = $matches[10].split('	')[0]
    if ($tempmatch -match "^{" -and $tempmatch -match "ContextData") {
        $tempvalue = ($tempmatch | ConvertFrom-Json).ContextData
        $extractedObject | Add-Member -MemberType NoteProperty -Name "EXTString" -Value $tempvalue
    }

    $extractedObject
}

function Import-Log {
    param (
        [Parameter(Mandatory = $true)]
        [string]$LogFilePath
    )

    $c2rlog = Get-Content $LogFilePath -Encoding UTF8

    $extractedObjects = @()

    foreach ($logEntry in $c2rlog) {
        $matches = Parse-LogEntry -logEntry $logEntry
        if ($matches) {
            $extractedObject = Convert-To-ExtractedObject -matches $matches
            $extractedObjects += $extractedObject
        }
    }

    return $extractedObjects
}

function Convert-CorrelationToJson {
    param (
        [PSCustomObject]$object
    )

    if ($object.Correlation -match "^{") {
        $object.Correlation = $object.Correlation | ConvertFrom-Json
        if ($object.Correlation.ContextData -match "^{") {
            $object.Correlation.ContextData = $object.Correlation.ContextData | ConvertFrom-Json
        }
    }

    $object
}

function Display-Log {
    param (
        [Parameter(Mandatory = $true)]
        [object[]]$LogObjects,

        [Parameter(Mandatory = $false)]
        [switch]$UseGridView
    )

    if ($UseGridView) {
        $selectedObjects = $LogObjects | Out-GridView -PassThru -Title "Log Objects"
        if ($selectedObjects) {
            Write-Host -ForegroundColor Green "选择的日志进行转换输出"
            $convertedObjects = $selectedObjects | ForEach-Object {
                Convert-CorrelationToJson -object $_
            }
            $convertedObjects | ConvertTo-Json -Depth 4
            $global:tempselectedObjects = $convertedObjects
        }
    }
    else {
        $LogObjects
    }
}

function Select-LogFilePath {
    param (
        [string]$CommandPath
    )

    [void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
    $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
    $OpenFileDialog.Title = "请选择日志文件"
    $OpenFileDialog.InitialDirectory = $CommandPath
    $OpenFileDialog.Filter = "日志文件 (*.log)|*.log|所有文件 (*.*)|*.*"
    $OpenFileDialog.ShowDialog() | Out-Null
    return $OpenFileDialog.FileName
}


$commandpath = Split-Path $MyInvocation.MyCommand.Path
$LogFilePath = Select-LogFilePath -CommandPath $commandpath

 
if ($LogFilePath) {
    $logs = Import-Log -LogFilePath $LogFilePath
    Display-Log -LogObjects $logs -UseGridView 
}
else {
    Write-Host "未选择日志文件" 
}

作者简介

九叔,《微软SystemCenter2012R2私有云部署实战》图书作者,往届微软MVP,关注云和PowerShell。

免责

本文仅代表个人观点,不代表任何组织、机构或公司的立场。所提供的信息仅供参考和一般性信息之用途。尽管本文力图提供准确、全面的信息,但不能保证其准确性、完整性、及时性或适用性。

读者在采取本文提供的任何行动或依赖所包含的信息时,应自行承担风险。作者和OpenAI不对任何直接或间接引起的损失或损害承担责任。

本文中提到的任何产品、服务、公司或组织的商标、标识、图像等知识产权归其各自所有者所有。

读者应自行进行进一步的研究和咨询,以便做出明智的决策。对于任何与本文相关的具体问题,请咨询相关领域的专业人士或权威机构。

最后,本文的目的是提供一般性信息,并不构成任何形式的专业建议。读者在使用本文提供的信息时应行使谨慎和判断力。

感谢阅读本文,并理解其中的免责声明。

标签:匹配,Office,正则表达式,Drive,Deep,matches,O365,日志,安装
From: https://blog.51cto.com/jiushu/7123181

相关文章

  • PowerShell Deep Drive 1-禁用Windows更新服务
    防挨打Windows更新服务的必要性在以下几个方面得到超级可爱的体现哦~(。♥‿♥。)安全性:Windows更新服务是守护计算机系统安全的关键宝宝哦!微软定期发布安全补丁和更新,修修补补已知漏洞、填填系统安全缺口,......
  • 软件测试|Chrome 115之后的版本,如何更新driver?
    2023年8月,chrome自动更新到115版本了,而从https://registry.npmmirror.com/binary.html?path=chromedriver/处只能下载114版本的driver,无法工作。参考:https://blog.csdn.net/Tester_muller/article/details/132086996  找到https://googlechromelabs.github.io/chrome-for......
  • webdriver 的三种等待方式(强制等待、隐式等待、显示等待)
    在自动化测试脚本的运行过程中,webdriver操作浏览器的时候,对于元素的定位是有一定的超时时间,大致应该在1-3秒的样子,如果这个时间内仍然定位不到元素,就会抛出异常,中止脚本执行。我们可以通过在脚本中设置等待的方式来避免由于网络延迟或浏览器卡顿导致的偶然失败,常用的等待方式有三......
  • deepin下构建多个deb包为一个deb
    原文链接:deepin下构建多个deb包为一个debhello,大家好啊,今天给大家带来在deepin操作系统下构建多个deb包围一个deb包的教程,以此来满足在特殊环境下的deb安装调试的场景,构建过程主要使用dpkg-deb命令,欢迎大家浏览分享转发。1、下载百度网盘、wps、谷歌浏览器的deb包2、使用dpkg-deb-......
  • 38 pinctrl(四)pinctrl driver
    前言一些使用技巧查看设备支持的pinctrlls/sys/kernel/debug/pinctrl/查看pinctrl中支持的引脚、组、functioncat/sys/kernel/debug/pinctrl/20e0000.iomuxc/pinscat/sys/kernel/debug/pinctrl/20e0000.iomuxc/pingroupscat/sys/kernel/debug/pinctrl/20e0000.io......
  • 论文解读(TAT)《 Transferable Adversarial Training: A General Approach to Adapting
    Note:[wechat:Y466551|可加勿骚扰,付费咨询]论文信息论文标题:TransferableAdversarialTraining:AGeneralApproachtoAdaptingDeepClassifiers论文作者:HongLiu,MingshengLong,JianminWang,MichaelI.Jordan论文来源:ICML2019论文地址:download 论文代码:download......
  • 当打开百度,定位输入报错怎么解决driver.find_element_by_id('kw').send_keys("seleniu
    报错如下: 解决方案,改变编写方式,引入fromselenium.webdriver.common.byimportBy  源码:例子说明: 打开百度,输入selenium进行搜索。fromseleniumimportwebdriverfromtimeimportsleepfromselenium.webdriver.common.byimportBydriver=webdriver.Chrome()d......
  • Hybrid-SORT起飞 | 超过DeepSORT将近10个点的多目标跟踪香不香?
    前言 多目标跟踪(MOT)旨在在帧间检测和关联所有所需的目标。大多数方法通过明确或隐式地利用强大的线索(即空间和外观信息)来完成任务,这些线索表现出强大的实例级别判别能力。然而,当出现目标遮挡和聚类时,由于目标之间的高度重叠,空间和外观信息同时变得模糊不清。在本文中,作者证明MOT......
  • Golang - 原生go-sql-driver:出现invalid connection报错
    在使用go-sql-driver/msqyl驱动过程中,偶现invalidconnection错误,字面上看就是无效连接的意思。开始以为是数据库压力问题或是网络不好,后来发现服务器和数据库是走内网的,网络出现问题几率非常小;只是在测试服务器上跑,没多少连接,不存在压力问题。golang数据库驱动维护一个连接池,如......
  • minio报错:Unable to use the drive /data: Drive /data: found backend type fs, expe
    docker安装minio,minio是最新的,使用命令:dockerpullminio/minio如下:启动命令:dockerrun-d-p9000:9000-p9001:9001--nameminio1-v/home/minio/data:/data-v/home/minio/config:/root/.minio-e"MINIO_ROOT_USER=admin"-e"MINIO_ROOT_PASSWORD=123456&quo......