Question

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?

Was it helpful?

Solution 2

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"
}

OTHER TIPS

# 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");
if ([System.Diagnostics.EventLog]::SourceExists("Visual Studio") -eq $False) {
    New-EventLog -LogName "Visual Studio Builds" -Source "Visual Studio"
}

Check the Exists method:

[System.Diagnostics.EventLog]::Exists('Visual Studio Builds')

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!"

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"
    }

Less complex:

 if (!(Get-Eventlog -LogName "Application" -Source "YourLog")){
      New-Eventlog -LogName "Application" -Source "YourLog"
 }

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
}

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
$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).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top