【问题标题】:CSV comparison of Windows ServicesWindows 服务的 CSV 比较
【发布时间】:2021-12-19 15:07:43
【问题描述】:

我对 Powershell 还很陌生,我被一个更大的脚本的这一部分困住了。我需要拉出所有 Windows 服务并比较它们以查看它们的启动状态类型是否已更改。如果有任何变化,我需要对它们进行计数,以便可以将该值放入电子邮件的正文中。另外,我需要附上一份 HTML 报告,显示已更改的 Windows 服务的先前和当前状态。

我所做的如下:

这段代码会生成一个 CSV 文件,显示服务的当前状态。

Get-Service | Select-Object -Property Name,DisplayName,StartType,ServiceType,Status | Export-Csv -Path "C:\logs\after.csv"

然后我声明两个变量,一个用于当前状态,另一个用于“模板”,即所有 Windows 服务所需的状态。

$before = Import-Csv -Path "C:\logs\before.csv"
$after = Import-Csv -Path "C:\logs\after.csv"

然后,我比较它们,只解析那些已更改的服务,并基于此生成 CSS 样式的 HTML 报告

Compare-Object $before $after -Property Name,DisplayName,StartType,ServiceType,Status | ConvertTo-html -Head $css | Set-Content "C:\logs\comparison.html"

这是我得到的:

它应该是这样的:

基本上,我想在原始 CSV 报告的状态列之后的新列中显示后一个 CSV 报告的状态。之后我还想计算行数,这样我就可以发送一封电子邮件报告有多少服务发生了任何变化。

任何帮助将不胜感激。

【问题讨论】:

    标签: windows powershell csv service


    【解决方案1】:

    您可以在Compare-Object 之后使用Group-Object 并从中解析出您需要的列。

    $before = Import-Csv -Path "C:\logs\before.csv"
    $after  = Import-Csv -Path "C:\logs\after.csv"
    
    # find the differences in the StartType and Status columns. Use -PassThru to be able to process further
    $groups = Compare-Object -DifferenceObject $before -ReferenceObject $after -Property StartType, Status -PassThru | 
              Sort-Object Name | Group-Object Name
    
    $result = foreach ($group in $groups) {
        $refGroup = $after | Where-Object { $_.Name -eq $group.Name }
        # output an object with new StartType_* and  Status_* columns and capture that in variable $result
        $group.Group[0] | 
        Select-Object *, @{Name = 'StartType_Before'; Expression = {$_.StartType}},
                         @{Name = 'StartType_After'; Expression = {$refGroup.StartType}},
                         @{Name = 'Status_Before'; Expression = {$_.Status}},
                         @{Name = 'Status_After'; Expression = {$refGroup.Status}} -ExcludeProperty StartType,Status, SideIndicator
    }
    
    # now convert the $result to HTML and add a summary line with the number of services that have changed
    $result | ConvertTo-Html -Head $css -PostContent "<br />Services affected: $($result.Count)" | 
              Set-Content "C:\logs\comparison.html"
    

    如果您还想在控制台中输出:

    $result | Format-Table -AutoSize
    

    当然也可以不使用Compare-Object,像下面那样做(会慢一些,但我猜更容易理解):

    $before = Import-Csv -Path "C:\logs\before.csv"
    $after  = Import-Csv -Path "C:\logs\after.csv"
    
    $result = foreach ($item in $before) {
        $diff = $after | Where-Object { $_.Name -eq $item.Name -and 
                                       ($_.StartType -ne $item.StartType -or $_.Status -ne $item.Status) }
        if ($diff) {
            $item | Select-Object *, @{Name = 'StartType_Before'; Expression = {$item.StartType}},
                                     @{Name = 'StartType_After'; Expression = {$diff.StartType}},
                                     @{Name = 'Status_Before'; Expression = {$item.Status}},
                                     @{Name = 'Status_After'; Expression = {$diff.Status}} -ExcludeProperty StartType,Status
        }
    }
    
    # output to console
    $result | Format-Table -AutoSize
    
    # convert to HTML
    $result | ConvertTo-Html -Head $css -PostContent "<br />Services affected: $($result.Count)" | 
              Set-Content "C:\logs\comparison.html"
    

    屏幕上的输出看起来像

    Name            DisplayName                                             ServiceType     StartType_Before StartType_After Status_Before Status_After
    ----            -----------                                             -----------     ---------------- --------------- ------------- ------------
    AarSvc_8246b1   Agent Activation Runtime_8246b1                         224             Manual           Automatic       Stopped       Stopped     
    AdobeARMservice Adobe Acrobat Update Service                            Win32OwnProcess Automatic        Automatic       Running       Stopped     
    ALG             Application Layer Gateway Service                       Win32OwnProcess Manual           Automatic       Stopped       Stopped     
    WdNisSvc        Microsoft Defender Antivirus Network Inspection Service Win32OwnProcess Manual           Manual          Running       Stopped  
    

    【讨论】:

    • 西奥,非常感谢!这创造了奇迹。对不起,我是个新手,但我怎么能设法对 Start Type 属性做同样的事情呢?我的最终目标是在“状态”列中对“开始类型”列执行相同的操作,即在“开始类型_后”列旁边有一个“开始类型_前”。再次感谢您。
    • @RubénAndrésGarcía 啊……我错过了那部分。现在在手机上,但我明天会把它放上去。
    • @RubénAndrésGarcía 请试试我编辑的答案
    • @RubénAndrésGarcía BTW。刚接触 SO 你可能不知道这一点,但如果你觉得我的回答解决了你的问题,习惯上点击左侧的 图标accept 它。这将帮助其他有类似问题的人更轻松地找到它,并有助于激发人们回答您的问题。
    • Theo,您的解决方案效果很好,非常感谢!我已经将问题标记为已解决/已回答。我还有其他方法可以投票给你吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-18
    相关资源
    最近更新 更多