Last time we looked at using PowerShell to query the state of classic Event Log entries, as well as set some limits. If you missed that article, please take a moment to get caught up. Today I want to demonstrate some techniques for backing up the event logs. I’ll cover clearing the Event Log in a future article.
Latest posts by Jeffery Hicks (see all)

## Backup an Event Log ^

If you look through the Event Log related cmdlets, you’ll notice there is no cmdlet for backing up an Event Log. This is unfortunate, but not insurmountable. You simply have to take matters into your own hands. I’ll walk you through the process. Once you understand how it works, you could create your own PowerShell script or function.

I’ll first test everything locally. To back up the Event Log file, we’ll need to use WMI so I’ll first get a log.

PS C:\> $log = get-wmiobject win32_nteventlogfile -filter "logfilename = 'Windows PowerShell'" The logfile object has a method called BackupEventlog which takes a filename as a parameter. PS C:\>$log.BackupEventlog

-------------------
System.Management.ManagementBaseObject BackupEventlog(System.String ArchiveFileName)

The file you specify for the archive backup is relative to the local computer. This will be significant when we get to backing up logs on remote computers. For now, I can backup the file to a local path.

PS C:\> $log.BackupEventlog("c:\work\powershell.evtx") __GENUS : 2 __CLASS : __PARAMETERS __SUPERCLASS : __DYNASTY : __PARAMETERS __RELPATH : __PROPERTY_COUNT : 1 __DERIVATION : {} __SERVER : __NAMESPACE : __PATH : ReturnValue : 0 PSComputerName : A return value of 0 indicates success. I could also backup to a UNC. PS C:\>$log.BackupEventlog("\\chi-fp01\it\$env:computername-powershell.evtx") One drawback to this technique is that there is no way to test the command. There is no –WhatIf. But we can get that by using Invoke-WMIMethod. PS C:\>$file = "{0}_{1}_{2}.evtx" -f (get-date -f "yyyyMMdd"),$env:computername,$log.FileName.Replace(" ","")
PS C:\> $backup = join-path "\\chi-fp01\it"$file
PS C:\> $log | Invoke-WmiMethod -Name BackupEventlog -ArgumentList$backup -whatif

If I’m satisfied I can do it for real. You can see the result below:

Event Log - Backup

I created a backup file name that used the current date, computer name and log file name with the spaces removed.

If a file with the same name already exists you will get a ReturnValue of 80. That’s why I always try to devise a unique name.

## Remote backups ^

Now let’s scale out and try this remotely with the following code:

$log = get-wmiobject win32_nteventlogfile -filter "logfilename = 'Windows PowerShell'" -ComputerName CHI-FP02$file = "{0}_{1}_{2}.evtx" -f (get-date -f "yyyyMMdd"),$log.PSComputerName,$log.FileName.Replace(" ","")
$backup = join-path "\\chi-fp01\it"$file
$log | Invoke-WmiMethod -Name BackupEventlog -ArgumentList$backup

Unfortunately, when I try to run this, I’ll get AccessDenied. That’s because I can’t make a second hop. If I change the backup file to a local folder, it will work as expected. I could mess around with CredSSP. But Instead I’ll use PowerShell remoting and add a step to authenticate to the second hop.

$cred = Get-Credential globomantics\administrator invoke-command -ScriptBlock {$log = get-wmiobject win32_nteventlogfile -filter "logfilename = 'Windows PowerShell'" -EnableAllPrivileges
$file = "{0}_{1}_{2}.evtx" -f (get-date -f "yyyyMMdd"),$log.CSName,$log.FileName.Replace(" ","") #map a PSDrive with credentials New-PSDrive -name B -PSProvider Filesystem -Root \\chi-fp01\it -Credential$using:cred | Out-Null
dir B:\*.evtx | write-host -ForegroundColor yellow
#backup path must be something Windows can see like a UNC
$backup = join-path (get-psdrive B).root$file
write-host "Backing up to $backup" -ForegroundColor cyan$r = $log | Invoke-WmiMethod -Name BackupEventlog -ArgumentList$backup
if ($r.returnValue -eq 0) { Get-Item$backup
}
else {
Throw "Backup failed with returnvalue $($r.returnvalue)"
}

} -ComputerName chi-fp02

The code I’m using is for PowerShell 3.0 so that I can take advantage of the Using: prefix. Otherwise I’d have to construct the script block to take parameters and pass values. Everything in the script block runs on the remote computer, in this case CHI-FP02. On the remote computer I create a temporary PSDrive to the shared folder, using the credential to authenticate. The use of a credential to map a PSDrive is new to PowerShell 3.0 so if you were to try this against a PowerShell 2.0 system, it will fail. It doesn’t matter what name I use for the PSDrive, but the actual backup path must be something Windows can see which is why I get the PSDrive’s Root property. I’ve also tossed in a little error handling. My result can be seen below:

Event Log - Remote backup

Here’s a more complete script that backs up the Application Event Log from a number of computers that are all running PowerShell 3.0.

#requires -version 3.0

#remote computers must be running PowerShell 3.0

$computers = "chi-dc01","chi-fp01","chi-dc04","chi-fp02"$cred = Get-Credential globomantics\administrator
$eventlog = "Application" invoke-command -ScriptBlock {$log = get-wmiobject win32_nteventlogfile -filter "logfilename = '$using:eventlog'"$file = "{0}_{1}_{2}.evtx" -f (get-date -f "yyyyMMdd"),$log.CSName,$log.FileName.Replace(" ","")

#map a PSDrive with credentials
New-PSDrive -name B -PSProvider Filesystem -Root \\chi-fp01\it -Credential $using:cred | Out-Null #backup path must be something Windows can see like a UNC$backup = join-path (get-psdrive B).root $file write-host "Backing up to$backup" -ForegroundColor cyan
$r =$log | Invoke-WmiMethod -Name BackupEventlog -ArgumentList $backup if ($r.returnValue -eq 0) {
Get-Item $backup } else { Throw "Backup failed with returnvalue$($r.returnvalue)" } } -ComputerName$computers

And here’s the result:

Event Log - Remote backup

This runs pretty quickly because the backup process occurs simultaneously on each remote system.

## Summary ^

If you don’t want to mess with credentials and remote paths, you can always create the backup locally on the remote computer and have a separate process if you need to move the files to a central location. The techniques I showed above require PowerShell 3.0 and if you have that, there are some perhaps better ways to accomplish Event Log backups. We’ll look at those next time.

Articles in series

# Event Log and PowerShell

1. Pawan Kumar 4 years ago

Thanks,

How can i get last 24 hour Eventlog of Application or System Event. Could you please tell me ?

2. Mike Schulman 4 months ago

$Log.BackupEventlog can’t find Microsoft-Windows-CAPI2/Operational, even though$logName = ‘Microsoft-Windows-CAPI2/Operational’

$log = New-Object System.Diagnostics.Eventing.Reader.EventLogConfiguration$logName
has no problem.