Exporting Event Logs in Server 2003

I still have to support a smattering of boxes that run Server 2003 (yes, it’s EOLed.  No, that’s not going to help.)  Vista and up have wevtutil.exe, which is wonderful.  Here’s a sample blog post extolling its crunchy-goodness.

https://blogs.msdn.com/b/ericfitz/archive/2008/07/16/wevtutil-scripting.aspx

Me, I’m still using two sticks to make a fire for these boxes.  Here’s a way to dump any given event log onto the local drive for the machine.  Why the local drive?  because it’s next-to-impossible for PowerShell remoting to write to a \\net\share, like a filer.  PowerShell is very secure, sometimes to it’s own detriment.

Anyhow, here’s the code.  It’s very ill-behaved, creating a local folder.  It’s not multithreaded (-AsJob), but that’s going to be in V2.

 

function Export-EventLogToCSV {
     param (
         [String[]]$LogName = @('Application'),
         [Parameter(ValueFromPipeline = $true)][String[]]$ComputerName = @($env:COMPUTERNAME),
         [string]$RemoteTempDir = "c:\temp",
         [switch]$list
     );
    
     begin {

         # output a PSAutomation object with the requisite data
         function Out-Record {
             param (
                 [string]$ComputerName = $(throw "Out-Record -ComputerName not specified"),
                 [string]$LogName      = $(throw "Out-Record -LogName not specified"),
                 [string]$FilePath     = $(throw "Out-Record -FilePath not specified")
             );
            
             New-Object -TypeName PSObject -Property @{
                 ComputerName = $ComputerName;
                 LogName      = $LogName;
                 FilePath     = $FilePath;
             } | Select-Object -Property ComputerName, LogName, FilePath;
         }
        
         $scriptBlock = {
             param (
                 [string]$LogName,
                 [string]$TempDir
             );
            
             if (!(Test-Path -Path $TempDir)) { New-Item -ItemType Directory -ErrorAction SilentlyContinue -Path $TempDir | Out-Null; }
             if (Test-Path -Path $TempDir) {
                 $FilePath = Join-Path -Path $TempDir -ChildPath "$env:ComputerName-$LogName-$(Get-Date -Format yyyy-MM-dd).csv";
                 Get-EventLog -LogName $LogName | Export-Csv -NoTypeInformation -Path $FilePath;
                 if (Test-Path -Path $FilePath) { "\\$env:ComputerName\$FilePath".ToLower() -replace ':', '$'; }
             } 
         }
    
         # for pinging the target box
         $ping = New-Object System.Net.NetworkInformation.Ping;
         $pingTimeout = 1000;
        
         # for problem children
         $problemRequests = @();
         $delim = [char]7;
     }
    
     process {
         $ComputerName | % {
             $myComputerName = $_;
            
             Write-Progress "$(Get-Date) $myComputerName" "pinging";
             try { $status = $ping.Send($myComputerName, $pingTimeout).Status; } catch { }
             if ($status -eq 'Success') {
                
                 # get list of event logs on computer
                 Write-Progress "$(Get-Date) $myComputerName" "listing logs";
                 $logNames = Get-EventLog -List -ComputerName $myComputerName -ErrorAction SilentlyContinue | % { $_.Log.ToLower(); }
                
#$Host.EnterNestedPrompt();

                 if ($logNames) {
                     if ($list) {
                    
                         # if we are getting only a list of event log names
                         $logNames | % { Out-Record -ComputerName $myComputerName -LogName $_ -FilePath ""; }
                        
                     } else 
                     {
                    
                         # save the logs to CSV
                         $LogName | % {
                             $myLogName = $_.ToLower();
                             if ([array]::IndexOf($logNames, $myLogName) -eq -1) {
                            
                                 # event log not found
                                 $FilePath = "LOG_NOT_FOUND($myLogName)";
                                 Out-Record -ComputerName $myComputerName -LogName $myLogName -FilePath $FilePath;
                                 $problemRequests += "$myComputerName$delim$myLogName$delim$FilePath)";
                                
                             } else 
                             {
                            
                                 # yay! we actually get to save the logfile!!!
                                 Write-Progress "$(Get-Date) $myComputerName" "Saving '$myLogName' event log";
                                 if ($myComputerName -eq $env:COMPUTERNAME) {
                                
                                     $FilePath = Invoke-Command -ScriptBlock $scriptBlock -ArgumentList $myLogName, $RemoteTempDir;
                                
                                 } else 
                                 {
                                
                                     $FilePath = Invoke-Command -ScriptBlock $scriptBlock -ArgumentList $myLogName, $RemoteTempDir -ComputerName $myComputerName;

                                 }
                                
                                 Out-Record -ComputerName $myComputerName -LogName $myLogName -FilePath $FilePath;
                                
                             }
                         }
                        
                     }
                
                 } else 
                 {
                
                     # host not pingable
                     $LogName | % {
                         $myLogName = $_;
                         $FilePath = "HOST_NOT_PINGABLE";
                         Out-Record -ComputerName $myComputerName -LogName $myLogName -FilePath $FilePath;
                         $problemRequests += "$myComputerName$delim$myLogName$delim$FilePath)";
                     }

                 }
             } else 
             {
                
                 # host does not return list of logs
                 $LogName | % {
                     $myLogName = $_;
                     $FilePath = "LOG_NAMES_NOT_AVAILABLE";
                     Out-Record -ComputerName $myComputerName -LogName "" -FilePath $FilePath;
                     $problemRequests += "$myComputerName$delim$myLogName$delim$FilePath)";
                 }
                
             }
         }
     }
    
     end {
         $problemRequests | % {
             $problemRequest = $_.Split($delim);
             Write-Warning "$($problemRequest[0]) cannot save $($problemRequest[1]) event log: $($problemRequest[2])";
         }
     }
}