How to determine if an EventLog already exists
Asked Answered
C

10

44

I'm using the following line to create a new event log

new-eventlog -LogName "Visual Studio Builds" -Source "Visual Studio"

I want to run this every time, because if I run a build from a new computer, I'd still like to see the event logs.

The problem is that every time the script is run after the log is already created, it throws an error.

New-EventLog : The "Visual Studio" source is already registered on the "localhost" computer.
At E:\Projects\MyApp\bootstrap.ps1:14 char:13
+ new-eventlog <<<<  -LogName "Visual Studio Builds" -Source "Visual Studio"
    + CategoryInfo          : InvalidOperation: (:) [New-EventLog], InvalidOperationException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.NewEventLogCommand

Now I know that I can "search" for the event log

Get-EventLog -list | Where-Object {$_.logdisplayname -eq "Visual Studio Builds"} 

But now how do I determine if it exists?

Chaumont answered 13/12, 2012 at 1:33 Comment(1)
see also: #28431120 - I've posted sample code for a wrapper method (though currently there's a bug - hence posting here)Mallina
C
26

So I was on the right path with Get-EventLog.

Instead of just reading it, I stored it in a variable. Then I checked if the variable was null.

This has achieved what I was looking to do.

$logFileExists = Get-EventLog -list | Where-Object {$_.logdisplayname -eq "Visual Studio Builds"} 
if (! $logFileExists) {
    New-EventLog -LogName "Visual Studio Builds" -Source "Visual Studio"
}
Chaumont answered 13/12, 2012 at 1:33 Comment(1)
NB: Only works if the event log/source has been written to; if it was created but not written to you'll gen an "already exists" exception.Mallina
Z
64
# Check if Log exists
# Ref: http://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog.exists(v=vs.110).aspx
[System.Diagnostics.EventLog]::Exists('Application');


# Ref: http://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog.sourceexists(v=vs.110).aspx
# Check if Source exists
[System.Diagnostics.EventLog]::SourceExists("YourLogSource");
Zurek answered 23/9, 2014 at 20:22 Comment(3)
This answer is the most complete in terms of checking whether both a log and/or source exist. It's important to remember that using Get-EventLog and filtering/searching from there depends on the fact that an event has been written to the target log in order for it to show up.Filose
VERY CLEAN! Nice one-liner.Sasha
Thanks. You can even take off the 'system.'.Ordonnance
C
26

So I was on the right path with Get-EventLog.

Instead of just reading it, I stored it in a variable. Then I checked if the variable was null.

This has achieved what I was looking to do.

$logFileExists = Get-EventLog -list | Where-Object {$_.logdisplayname -eq "Visual Studio Builds"} 
if (! $logFileExists) {
    New-EventLog -LogName "Visual Studio Builds" -Source "Visual Studio"
}
Chaumont answered 13/12, 2012 at 1:33 Comment(1)
NB: Only works if the event log/source has been written to; if it was created but not written to you'll gen an "already exists" exception.Mallina
S
23
if ([System.Diagnostics.EventLog]::SourceExists("Visual Studio") -eq $False) {
    New-EventLog -LogName "Visual Studio Builds" -Source "Visual Studio"
}
Sulemasulf answered 6/1, 2015 at 16:51 Comment(3)
We expect answer to be a little bit more verbose. Teaching how to fish is better than just spoon feed the OP.Poulin
Brilliant! this is the only answer that actually checks if the source value exists & doesnt resort to scanning the event log.Pietrek
Note that this script will require local admin rights to work. Otherwise some eventlogs - such as securty - can't be accessed, resulting in a exception. The exception is thrown in both cases (true and false), so you can't determine if the log exists by catching.Bray
J
14

Check the Exists method:

[System.Diagnostics.EventLog]::Exists('Visual Studio Builds')
Jensen answered 13/12, 2012 at 6:46 Comment(1)
Thanks, I'll test it next time I get a chance.Chaumont
W
3

To simply check if exists:

$EventLogName = "LogName"
if ( !($(Get-EventLog -List).Log.Contains($EventLogName)))
{}

But to create the new one you'll need "As Administrator" privilege. To solve this I used to call a subprocess:

Start-Process -verb runAs powershell.exe  -ArgumentList "-file $PSScriptRoot\CreateLog.ps1" -wait

With simple CreateLog.ps1:

New-EventLog -LogName ScriptCheck -Source ScriptCheck
Write-EventLog –LogName ScriptCheck `
–Source ScriptCheck –EntryType Information –EventID 100 `
–Message "Start logging!"
Waylin answered 9/4, 2015 at 8:52 Comment(2)
This is valid, thanks. When it comes to Admin, I do a bit different approach, I Assert that they are Admin, and throw an exception if not. This forces the script to be run in an admin console before it starts.Chaumont
my approach is mostly intended to be used in a scheduler :)Waylin
R
3

Get-/Test-EventLogSource

The System.Diagnostics methods are limiting. There can be only one source on a computer. Different computers may have the same source, but in different logs. In my experience you start running into issues after working with these methods and creating/removing logs and sources. I wrote the following to verify my custom log/source.

Set-StrictMode -Version Latest

function Get-EventLogSource {
    [CmdletBinding()]
    param(
        [string]$LogFile = '*',
        [string]$Source = '*'
    )

    Get-CimInstance -Class Win32_NTEventLOgFile -Verbose:$false | ForEach-Object {

        $_logName = $PSItem.FileName
 
        $PSItem.Sources | ForEach-Object {
 
            $oResult = New-Object PSCustomObject -Property @{
                Source  = $PSItem
                LogName = $_logName
            } | Select-Object  -Property Source, LogName

            Write-Output $oResult
        }
    } | Sort-Object -Property Source | Where-Object { $PSItem.Source -like $Source -and $PSItem.LogName -like $LogFile }    
}

function Test-EventLogSource {
    [CmdletBinding()]
    param(
        [string]$LogFile = '*',
        [Parameter(Mandatory)]
        [string]$Source
    )
    $_result = Get-EventLogSource -LogFile $LogFile -Source $Source
    return ($null -ne $_result)
}

Clear-Host

#Test-EventLogSource -LogFile 'System' -Source '.NET*' -Verbose
#Test-EventLogSource -LogFile 'Application' -Source '.NET*' -Verbose
#Test-EventLogSource -LogFile 'dummy' -Source '.NET*' -Verbose
#Test-EventLogSource -LogFile '*' -Source '.NET*' -Verbose
#Test-EventLogSource -Source '.NET*' -Verbose

#Test-EventLogSource -LogFile 'Application' -Source 'vs' -Verbose
#Test-EventLogSource -LogFile '*' -Source 'vss' -Verbose

#Test-EventLogSource -Source '*power*'


#Get-EventLogSource
#Get-EventLogSource -LogFile 'System' -Source '.NET*' -Verbose | Format-Table
#Get-EventLogSource -LogFile 'Application' -Source '.NET*' -Verbose | Format-Table
#Get-EventLogSource -LogFile 'dummy' -Source '.NET*' -Verbose | Format-Table
#Get-EventLogSource -LogFile '*' -Source '.NET*' -Verbose | Format-Table
#Get-EventLogSource -Source '.NET*' -Verbose | Format-Table

#Get-EventLogSource -LogFile 'Application' -Source 'vs' -Verbose | Format-Table
#Get-EventLogSource -LogFile '*' -Source 'vss' -Verbose | Format-Table

#Get-EventLogSource -Source '*power*'| Format-Table

Using Get-WinEvent

Get-WinEvent -ListProvider * -ErrorAction SilentlyContinue |
    Select-Object -Property Name -ExpandProperty LogLinks | 
    Select-Object -Property Name, LogName |
    Sort-Object -Property Name
Rana answered 12/10, 2020 at 18:33 Comment(1)
Surprised this hasn't got more votes - it's the only way I've found to code a test for the source without getting a warning about not accessing the Security logs if you;re not admin.Buccaneer
C
2

I think below approach could reduce the workload of filter with where

    try
    {
        Get-EventLog -LogName "Visual Studio Builds" -ErrorAction Ignore| Out-Null
    }
    catch {
        New-EventLog -LogName "Visual Studio Builds" -Source "Visual Studio"
    }
Companionship answered 13/12, 2012 at 5:34 Comment(2)
on an application with heavy workload, yes you want to optimize filtering clauses... for a script... not that much. try/catch feels icky.Chaumont
Chase is correct, you simply don't ever want to use exception handling as part of your logic. Jonathan Donahue's answer is the most complete in terms of checking whether both a log and/or source exist.Filose
M
2

Less complex:

 if (!(Get-Eventlog -LogName "Application" -Source "YourLog")){
      New-Eventlog -LogName "Application" -Source "YourLog"
 }
Masurium answered 25/7, 2013 at 9:23 Comment(2)
Contrary to all intuition, Get-EventLog does not have a -Source parameter. Sorry, but -1.Helaine
@Helaine Get-EventLog has indeed a -Source parameter. (See official documentation). However the proposed solution is listing actual events in the event log, so -1.Bisectrix
P
2

This one worked for me. Hope it helps somebody.

$EventLog = "SLAPS"
If ([System.Diagnostics.EventLog]::SourceExists("$EventLog") -eq $false) {
    New-EventLog -LogName "SLAPS_PasswordRotation" -Source "$EventLog"
    Write-EventLog -LogName "SLAPS_PasswordRotation" -Source "$EventLog" -Message "EventLog Succesfully Created" -EventId 10000 -EntryType SuccessAudit
}
Else {
    Write-EventLog -LogName "SLAPS_PasswordRotation" -Source "$EventLog" -Message "New Rotation Started Succesfully" -EventId 1 -EntryType SuccessAudit
}
Placida answered 8/5, 2020 at 0:38 Comment(0)
P
0
$SourceExists = [System.Diagnostics.Eventlog]::SourceExists("XYZ")
if($SourceExists -eq $false){
    [System.Diagnostics.EventLog]::CreateEventSource("XYZ", "Application")
}

Just doing this is not enough. Even though you've created the event source, $SourceExists will always be false. I tested it also by running CreateEventSource then Remove-EventLog, and removing it failed. After creating an event source, you must write something to it. Append this after running CreateEventSource.

Write-EventLog -LogName "Application" -Source "XYZ" -EventID 0 -EntryType Information -Message "XYZ source has been created."

Thanks to https://stackoverflow.com/users/361842/johnlbevan pointing this out (in the comments).

Poinsettia answered 14/3, 2018 at 15:45 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.