Write-EventLog
.New-EventLog
for the script to create a customized LogName
.-LogName
or -Source
that are not available from the script, you will get an exception like this:PS C:\> try { Write-EventLog -LogName "Application" -Source 'NewApplication' -EventId "400" -Message "TEST MESSAGE" } catch { $_ | Format-List * -Force | Out-String }
PSMessageDetails :
Exception : System.Security.SecurityException: The source was not found, but some or all event logs could not be searched. Inaccessible logs: Security.
at System.Diagnostics.EventLog.FindSourceRegistration(String source, String machineName, Boolean readOnly, Boolean wantToCreate)
at System.Diagnostics.EventLog.SourceExists(String source, String machineName, Boolean wantToCreate)
at Microsoft.PowerShell.Commands.WriteEventLogCommand.BeginProcessing()
at System.Management.Automation.Cmdlet.DoBeginProcessing()
at System.Management.Automation.CommandProcessorBase.DoBegin()
The Zone of the assembly that failed was:
MyComputer
TargetObject :
CategoryInfo : NotSpecified: (:) [Write-EventLog], SecurityException
FullyQualifiedErrorId : System.Security.SecurityException,Microsoft.PowerShell.Commands.WriteEventLogCommand
ErrorDetails :
InvocationInfo : System.Management.Automation.InvocationInfo
ScriptStackTrace : at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {}
So I want to get lists of available -LogName
and -Source
for the script.
You can get a list of events with Get-EventLog -List
or Get-EventLog -LogName <LogName>
, but it contains -LogName
and -Source
that are unavailable for my script. It also contains only the events that are already logged to Event Log (it is not an exhaustive list of available -LogName
and -Source
).
Is there any way to get the exhaustive list of available -LogName
and -Source
for Write-EventLog
without the administrator privilege?
For example, you will get the following error when you specify unmatched -LogName
and -Source
:
PS C:\> Write-EventLog -LogName "Application" -Source "Application Popup" -EventId "1000" -Message "TEST MESSAGE"
Write-EventLog : The source 'Application Popup' is not registered in log 'Application'. (It is registered in log 'System'.) " The Source and Log properties must be matched, or you may set Log to the empty string, and it will automatically be matched to the Source property.
At line:1 char:1
+ Write-EventLog -LogName "Application" -Source "Application Popup" -Ev ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Write-EventLog], Exception
+ FullyQualifiedErrorId : The source 'Application Popup' is not registered in log 'Application'. (It is registered in log 'System'.) " The Source and Log properties must be matched, or you may set Log to the empty string, and it will automatically be matched to the Source property.,Microsoft.PowerShell.Commands.WriteEventLogCommand
But when you set an empty string to -LogName
according to the error above, you will get another error like this:
PS C:\> Write-EventLog -LogName "" -Source "Application Popup" -EventId "1000" -Message "TEST MESSAGE"
Write-EventLog : Cannot validate argument on parameter 'LogName'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At line:1 char:25
+ Write-EventLog -LogName "" -Source "Application Popup" -EventId "1000 ...
+ ~~
+ CategoryInfo : InvalidData: (:) [Write-EventLog], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.WriteEventLogCommand
You can get the list of log names that Get-EventLog
can target as follows:
$logNames =
(Get-EventLog -LogName *).Log
Source names can be discovered via the registry, on a per-log basis:
# Initialize an ordered hashtable that will contain log names as keys
# and the corresponding source names as the values.
$sourcesPerLog = [ordered] @{}
# Loop over all log names and find the names of all sources registered
# for that log.
# Exclude the 'Security' log, because its sources cannot be queried without
# elevation; however, given that this log is "for system use only", that shouldn't be a problem.
Get-EventLog -LogName * |
Where-Object Log -ne Security |
ForEach-Object {
$logName = $_.Log
$sourcesPerLog[$logName] =
(Get-ChildItem HKLM:\System\CurrentControlSet\Services\EventLog\$logName).PSChildName
}
# Output for diagnostic purposes.
$sourcesPerLog
Sample output:
Name Value
---- -----
Application {.NET Runtime, .NET Runtime Optimization Service, Application, Application Error...}
HardwareEvents
Internet Explorer
Key Management Service KmsRequests
OAlerts Microsoft Office 16 Alerts
System {ACPI, AFD, Application Management Group Policy, Application Popup...}
Windows PowerShell PowerShell
Note:
To get the array of sources registered for the Application
log, for instance, use $sourcesPerLog['Application']
or $sourcesPerLog.Application
.
Note that the Security
log is deliberately skipped, as its sources cannot be queried unless you're running with elevation (as administrator).
Caveat:
Get-EventLog
is based on deprecated Windows APIs, and that the recommendation is to use Get-WinEvent
instead; from the Get-EventLog
help topic:
Get-EventLog
uses a Win32 API that is deprecated. The results may not be accurate. Use theGet-WinEvent
cmdlet instead.
Get-EventLog
cannot query.