November 18, 2011

Powershell Export Eventlog

The Powershell function below was created as a convenient way to export Windows event logs, mainly from remote computers.

It’s 2011 and it amazes me that some enterprise WAN links are still painfully poor. When you need to troubleshoot a Windows computer in a remote location (and can’t use Remote Desktop), connecting Event viewer remotely is often not a practical option. Even Get-WinEvent –ComputerName can be too slow.

Exporting the logs to an .evtx file and copying them to local computer tends to be the best option. They can then be loaded into the local Event Viewer or queried using Get-Winevent –Path.

The function below automates the process of exporting the remote event logs and copying them to the local computer. The file naming convention allows multiple computers to be specified at once if needed.

Script “Export-EventLog.ps1”

Function Export-EventLog{
<#
.SYNOPSIS
Exports a local or remote event log to a file.

.DESCRIPTION
Uses wevtutil.exe to perform the export.
The resulting log file is $Path\$computername-$logname.evtx
The file can then be opened in Windows Event Viewer or queried directly using "Get-Winevent -Path...."

.PARAMETER  Computername
The name of the remote computer. Defaults to local machine.

.PARAMETER  Logname
The name(s) of the log file to export.

.PARAMETER  Path
The local folder path where the output file will be saved
Default = $ENV:TEMP (%TEMP%)

.PARAMETER  RemotePath
The remote folder path used to stage the exported file prior to moving it to the local folder path.
Environment variables are not supported.
Default = C:\Windows\Temp

.EXAMPLE
PS C:\> Export-EventLog -Computername "PC1" -LogName "System"

.EXAMPLE
PS C:\> Export-EventLog -Computername "PC1" -LogName "System","Application"

.EXAMPLE
PS C:\> "PC1" | Export-EventLog -LogName "System","Application","Security"

.EXAMPLE
PS C:\> Get-Winevent -Computername $Computer -Listlog * -EA 0| %{Export-EventLog -Computername $Computer}

.NOTES
Script Version: 1.0.0
Last update:
2011-10-24 : Initial release

#>
[CmdletBinding(
SupportsShouldProcess=$False,
SupportsTransactions=$False,
ConfirmImpact="Low",
DefaultParameterSetName="")]
param(
[parameter(position=0,mandatory=$false,valuefromPipeline=$true,valuefrompipelinebypropertyname=$true)]
[string]$Computername=$Env:COMPUTERNAME
,
[parameter(position=1,mandatory=$false,valuefrompipelinebypropertyname=$true)]
[string[]]$LogName=@("System","Application")
,
[parameter(position=2,mandatory=$false)]
[ValidateScript({Test-Path $_ -PathType 'Container'})] 
[string]$Path=$ENV:TEMP
,
[parameter(position=3,mandatory=$false)]
[string]$RemotePath="C:\Windows\Temp"

)
BEGIN{}
PROCESS{
Write-Progress -id 1 -Activity "Computer " -Status "$ComputerName"

# Convert <Drive>:\ to \<Drive>$ for remote connection
$RemotePath = $RemotePath -Replace '(?<Drive>[A-Za-z]+):','${Drive}$$' # c:\ = c$\

If(Test-Connection -ComputerName $Computername -Count 1 -ErrorAction SilentlyContinue){

$LogName | %{
$Log = $_

if((Get-WinEvent -LogName $Log -ComputerName $Computername -MaxEvents 1 -ErrorAction SilentlyContinue | Measure-Object).Count -lt 1){
Write-Warning -Message "$Computername::$log log is empty. Skipping export"
return
}
$OutputFileName = "$Computername-$($Log -replace "/","-").evtx"

Write-Progress -id 2 -ParentId 1 -Activity "Exporting" -Status "$Log"

if($Computername -eq $Env:COMPUTERNAME){
Write-Verbose "Local computer..."
$Cmd = "$($Env:windir)\system32\wevtutil.exe epl '$Log' '$Path\$OutputFileName' /r:$Computername /ow:True 2>&1"
$CmdResult = Invoke-Expression -Command $cmd

if($CmdResult -eq $Null){
Write-Verbose "$Computername::$log log export to '$path' = 'Success'"
}else{
Write-Error "$Computername::$log log export to '$path' = '$CmdResult'"
}

}else{
Write-Verbose "Remote computer..."
$Cmd = "$($Env:windir)\system32\wevtutil.exe epl '$Log' '\\$Computername\$RemotePath\$OutputFileName' /r:$Computername /ow:True 2>&1"
$CmdResult = Invoke-Expression -Command $cmd
if($CmdResult -eq $Null){
Write-Verbose "$Computername::$log log export to '\\$Computername\$RemotePath' = 'Success'"

Write-Progress -id 3 -ParentId 1 -Activity "Copying" -Status "$Log"
Try{
move-item -path "\\$Computername\$RemotePath\$OutputFileName" -Dest $Path -Force -ErrorAction Stop
Write-Verbose "$Computername::$log log copy to '$path' = Success"
}Catch{
Write-Error "$Computername::$log log copy to '$path' failed - '$_'"
}

}else{
Write-Error "$Computername::$log log export to '\\$Computername\$RemotePath' = '$CmdResult'"
}


}#end if

}#foreach

}else{
Write-Warning -Message "$Computername :: ping failed"
}
}#process

END{}

}#EndFunction

No comments:

Post a Comment