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])";
}
}
}