- Use PowerShell splatting and PSBoundParameters to pass parameters - Wed, Nov 9 2022
- Using PowerShell with $PSStyle - Mon, Jan 24 2022
- Clean up user profiles with PowerShell - Mon, Jun 9 2014
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 OverloadDefinitions ------------------- 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.
Thanks,
How can i get last 24 hour Eventlog of Application or System Event. Could you please tell me ?
$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.