xDscDiagnostics icon indicating copy to clipboard operation
xDscDiagnostics copied to clipboard

Enhancement Request: Add -Tail switch to Get-xDscOperation

Open dennisl68-castra opened this issue 4 years ago • 0 comments

Details of the scenario you tried and the problem that is occurring

When getting data using Get-xDscOperation the output isn't continous.

Steps to reproduce the problem

Get-xDscOperation

ComputerName   SequenceId TimeCreated           Result   JobID                                 AllEvents
------------   ---------- -----------           ------   -----                                 ---------
VM-SP-SERVER    1          8/12/2021 9:12:56 AM  Failure  b2c455b5-fb3c-11eb-8c8d-00155d301163  {@{Message=Operati...
VM-SP-SERVER    2          8/12/2021 9:12:49 AM  Success                                        {@{Message=; TimeC...
VM-SP-SERVER    3          8/12/2021 9:12:49 AM  Failure                                        {@{Message=DSC Eng...
VM-SP-SERVER    4          8/12/2021 9:12:49 AM  Failure  9e25c130-fb3c-11eb-8c8d-00155d301163  {@{Message=Operati...
VM-SP-SERVER    5          8/12/2021 9:12:14 AM  Success                                        {@{Message=; TimeC...
VM-SP-SERVER    6          8/12/2021 9:12:14 AM  Success                                        {@{Message=; TimeC...
VM-SP-SERVER    7          8/12/2021 8:57:47 AM  Failure  85b704f7-fb3a-11eb-8c8d-00155d301163  {@{Message=Operati...
VM-SP-SERVER    8          8/12/2021 8:42:53 AM  Failure  7ec64f6e-fb38-11eb-8c8d-00155d301163  {@{Message=Operati...
VM-SP-SERVER    9          8/12/2021 8:42:43 AM  Failure  6d42ae8f-fb38-11eb-8c8d-00155d301163  {@{Message=Operati...
VM-SP-SERVER    10         8/12/2021 8:27:45 AM  Failure  54d12727-fb36-11eb-8c8d-00155d301163  {@{Message=Operati...

Expected behavior

Get-xDscOperation -Tail | ft -Wrap

TimeCreated                     Id LevelDisplayName Message
-----------                     -- ---------------- -------
8/11/2021 11:12:50 PM         4255 Information      Job {CC703B34-FAE8-11EB-8C8D-00155D301163} :
                                                    Activity LCM
                                                    CurrentOperation [VM-SP-SERVER] Set
                                                    StatusDescription Applying Configuration
                                                     PercentComplete 74
                                                     SecondsRemaining 11
8/12/2021 8:42:53 AM          4131 Error            Job DscTimerConsistencyOperationResult :
                                                    DSC Engine Error :
                                                         Error Message: NULL                                            
                                                        Error Code : 1                                                  
8/11/2021 11:12:50 PM         4132 Information      Job {CC703B34-FAE8-11EB-8C8D-00155D301163} :
                                                    Getting a registration instance for MSFT_RoleResource
...

Will keep the command running in an endless loop, outputing new events as they occurs.

Current behavior

As designed

Suggested solution to the issue

Implement a -Tail feature that waits for new DSC events and continually outputs them as they occurs...

Example code from current generic script I'm using...

function Get-EventLogTail {
    param(
        [string]$ComputerName,

        [string[]]$LogName = 'Application',

        [string]$FilterXPath,

        [switch]$PowerShell,

        [switch]$Dsc,

        [switch]$SimpleOut,

        [string[]]$ActivateLog
    )

    if ($PowerShell){ $LogName = 'Microsoft-Windows-PowerShell/Operational'}

    if ($Dsc) {
        $LogName = 'Microsoft-Windows-Dsc/Operational','Microsoft-Windows-Dsc/Analytic','Microsoft-Windows-Dsc/Debug'
        $ActivateLog = $LogName
    }

    if ($ActivateLog){ #activate the logs
        foreach ($Log in $ActivateLog) {
            $logObj = New-Object System.Diagnostics.Eventing.Reader.EventLogConfiguration $Log
                
                if (!$LogObj.IsEnabled){# enable log
                    $LogObj.IsEnabled = $true
                    $LogObj.SaveChanges()
                }#end if
        }
    }# end activate logs
    
    if (!$FilterXPath){# create one
        if ($ComputerName){# use param
            $thisrecord = (get-winevent -ComputerName $ComputerName -LogName $LogName -Oldest | select -Last 1).RecordId -1
        }
        else {# look up localy
            $thisrecord = (get-winevent -LogName $LogName -Oldest | select -Last 1).RecordId -1
        }

        $FilterXPath = "*[System[EventRecordID=$thisrecord]]"
    }

    while ($true -and $ComputerName){# run forever if ComputerName
        if ($event = get-winevent -ComputerName $ComputerName -LogName $LogName -FilterXPath $FilterXPath -Oldest -ea SilentlyContinue){
            if ($Dsc) {
                $event 
            }

            if ($PowerShell -and !$SimpleOut){
                $event | where {
                    $_.Id -eq 4100 -or  #Executing Pipeline
                    $_.Id -eq 4103 -or  #Executing Pipeline
                    $_.Id -eq 4104 -or  #Executing Remote Command
                    $_.Id -eq 54504     #PowerShell Named Pipe IPC
                } | select *,@{n='User';e={([wmi]"Win32_SID.SID='$($_.UserID)'").ReferencedDomainName +"\"+ ([wmi]"Win32_SID.SID='$($_.UserID)'").AccountName}}
                #fl TimeCreated,MachineName,RecordId,@{n='User';e={([wmi]"Win32_SID.SID='$($_.UserID)'").ReferencedDomainName +"\"+ ([wmi]"Win32_SID.SID='$($_.UserID)'").AccountName}},ProviderName,Id,Message;
            }

            if ($PowerShell -and $SimpleOut){
                $event | where {
                    $_.Id -eq 4100 -or  #Executing Pipeline
                    $_.Id -eq 4103 -or  #Executing Pipeline
                    $_.Id -eq 4104 -or  #Executing Remote Command
                    $_.Id -eq 54504     #PowerShell Named Pipe IPC
                } | select TimeCreated,MachineName,RecordId,@{n='User';e={([wmi]"Win32_SID.SID='$($_.UserID)'").ReferencedDomainName +"\"+ ([wmi]"Win32_SID.SID='$($_.UserID)'").AccountName}},ProviderName,Id,Message;
            }

            if (!$PowerShell) {
                $event
            }#end PowerShell
            
            $thisrecord += 1; 
            $FilterXPath = "*[System[EventRecordID=$thisrecord]]"
            
        }#end event

    sleep -milliseconds 500

    }#end while using ComputerName

    while ($true -and !$ComputerName){# run forever if no ComputerName
        if ($event = get-winevent -LogName $LogName -FilterXPath $FilterXPath -Oldest -ea SilentlyContinue){
            if ($Dsc){}
            
            if ($PowerShell -and !$SimpleOut){
                $event | where {
                    $_.Id -eq 4100 -or  #Executing Pipeline
                    $_.Id -eq 4103 -or  #Executing Pipeline
                    $_.Id -eq 4104 -or  #Executing Remote Command
                    $_.Id -eq 54504     #PowerShell Named Pipe IPC
                } | select *,@{n='User';e={([wmi]"Win32_SID.SID='$($_.UserID)'").ReferencedDomainName +"\"+ ([wmi]"Win32_SID.SID='$($_.UserID)'").AccountName}}
                #fl TimeCreated,MachineName,RecordId,@{n='User';e={([wmi]"Win32_SID.SID='$($_.UserID)'").ReferencedDomainName +"\"+ ([wmi]"Win32_SID.SID='$($_.UserID)'").AccountName}},ProviderName,Id,Message;
            }

            if ($PowerShell -and $SimpleOut){
                $event | where {
                    $_.Id -eq 4100 -or  #Executing Pipeline
                    $_.Id -eq 4103 -or  #Executing Pipeline
                    $_.Id -eq 4104 -or  #Executing Remote Command
                    $_.Id -eq 54504     #PowerShell Named Pipe IPC
                } | select TimeCreated,MachineName,RecordId,@{n='User';e={([wmi]"Win32_SID.SID='$($_.UserID)'").ReferencedDomainName +"\"+ ([wmi]"Win32_SID.SID='$($_.UserID)'").AccountName}},ProviderName,Id,Message;
            }

            if (!$PowerShell) {
                $event
            }#end PowerShell
            
            $thisrecord += 1; 
            $FilterXPath = "*[System[EventRecordID=$thisrecord]]"
            
        }#end event

    sleep -milliseconds 500

    }#end while using no ComputerName

<#
.SYNOPSIS
    Continuosly outputs trace from one or more event log(s).

.DESCRIPTION
    This function will output specified event log(s) as a continous trace specifed on
    computer, eventlog name and a filter.

    The filter contains a switch for using predifined settings for tracing PowerShell
    usage or DSC events.

.PARAMETER ComputerName
    If not used, local computer will be used.

.PARAMETER Logname
    Name of EventLog(s) to trace.
    Defaults to the Application log if omitted.

.PARAMETER FilterXPath
    Filter string to use to target specific parts of the event log.
    Defaults to the last record available in the EventLog(s) specified if omitted.

.PARAMETER PowerShell
    Switch for using predefined filter to get PowerShell Script Block Logging

    Requires Group Policy Computer - Administrative Templates - Windows Components - Windows PowerShell
    Turn on PowerShell Script Block Logging

.PARAMETER Simple
    Switch used in combiantion with PowerShell to simplify the output by only providing a minmum
    of necessary objects.

.PARAMETER Dsc
    Switch for using predefined filter to get DSC event logs.

.PARAMETER ActivateLog
    EXPERIMENTAL!
    String with log names to activate logging.

.EXAMPLE
    PS C:\> Get-EventLogTail

       ProviderName: realmjoin

    TimeCreated                     Id LevelDisplayName Message
    -----------                     -- ---------------- -------
    2021-02-03 15:12:49              0 Information      Service started successfully.
    2021-02-03 15:12:49              0 Information      2021-02-03 15:12:49.1960|INFO|RealmJoin...

.EXAMPLE
    PS C:\> Get-EventLogTail -PowerShell -SimpleOut

    TimeCreated  : 2021-02-03 15:15:12
    MachineName  : MYMACHINE
    RecordId     : 2433689
    User         : MYDOMAIN\MYACCOUNT
    ProviderName : Microsoft-Windows-PowerShell
    Id           : 4104
    Message      : Creating Scriptblock text (1 of 1):
                Get-EventLogTail -PowerShell -SimpleOut

                ScriptBlock ID: 066e2aa1-dc88-46d8-ad55-d8f93dade541
                Path:

.EXAMPLE 
    PS C:> Get-EventLogTail -Dsc | where LevelDisplayName -ne 'Information' | ft -Wrap

    TimeCreated                     Id LevelDisplayName Message
    -----------                     -- ---------------- -------
    8/11/2021 11:13:08 PM         4131 Error            Job DscTimerConsistencyOperationResult :
                                                        DSC Engine Error :
                                                            Error Message: NULL                                            
                                                            Error Code : 1                                                  
    8/11/2021 10:57:52 PM         4098 Warning          Job {B3FDC269-FAE6-11EB-8C8D-00155D301163} :
                                                        Displaying messages from built-in DSC resources:
                                                            WMI channel 1                                                  
                                                            ResourceID: [File]SetupSourceTools                             
                                                            Message : [VM-SP-SERVER]:                                      
                                                        [[File]SetupSourceTools] The destination object was found and no
                                                        action is required.

.NOTES
    Should be awesome :)
    Dennis
#>

}


The operating system the target node is running

Get-CimInstance win32_operatingsystem | select Caption, OSLanguage

Caption                                 OSLanguage
-------                                 ----------
Microsoft Windows Server 2019 Standard        1033

Version and build of PowerShell the target node is running

Name                           Value
----                           -----
PSVersion                      5.1.17763.592
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.17763.592
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

Version of the module that was used

Get-Module -Name 'xDscDiagnostics' -ListAvailable | ft Name,Version,Path

Name            Version Path
----            ------- ----
xDscDiagnostics 2.8.0   C:\Program Files\WindowsPowerShell\Modules\xDscDiagnostics\2.8.0\xDscDiagnostics.psd1

dennisl68-castra avatar Aug 12 '21 07:08 dennisl68-castra