DarkLite1
DarkLite1

Reputation: 14705

PowerShell splatting merging to one hashtable

This code does what I want it to do:

$EventParams = @{
    LogName = $LogName
    Source  = $Source
}
$EventInfoParams = $EventParams + @{
    EntryType = 'Information'
    EventID   = '0'
}
$EventWarnParams = $EventParams + @{
    EntryType = 'Warning'
    EventID   = '1'
}
$EventErrorParams = $EventParams + @{
    EntryType = 'Error'
    EventID   = '2'
}

On this blog I found out there are maybe nicer/cleaner ways of writing this in one big hashtable. So I tried the following:

$EventParams = @{
    LogName = $LogName
    Source  = $Source
    Info = @{
        EntryType = 'Information'
        EventID   = '0'
    }
    Warn = @{
        EntryType = 'Warning'
        EventID   = '1'
    }
    Error = @{
        EntryType = 'Error'
        EventID   = '2'
    }
}

$EventParams.Info

This works fine to except that I can't get the variables from in the first example $EventParams in each of the single hashtables without duplicating data. Is there a way to have it all in one big hasthable?

Upvotes: 1

Views: 191

Answers (2)

mjolinor
mjolinor

Reputation: 68273

Typically, you'd write all or most of the events from a given script to a common log and source. If you're wanting to avoid code duplication you can set this once for all the events that will be written from the script using $PSDefaultParameters at the beginning of the script:

#Set event loggin defaults
$PSDefaultParameterValues = 
 $PSDefaultParameterValues.Clone() + @{
    'Write-Eventlog:LogName' = $LogName
    'Write-Eventlog:Source' = $Source
   }

Cloning it will create a new copy in the script, inheriting whatever defaults are already set in the parent or global scope without altering the hash table in that scope. The new $PSDefaultParameterValues will be disposed when the script finishes and the settings will revert back to whatever there are in the parent scope.

If you need to write to some other log or source somewhere in the script you can do that by specifying the LogName and Source for that event, overriding the defaults.

Upvotes: 1

Martin Brandl
Martin Brandl

Reputation: 58931

As far as I understand your question, you want to reference LogName and Source within the same hashtable? I doubt that this is possible.

However, You could go with a function:

function Get-EventParams 
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true,Position=0)]
        [string]$LogName,

        [Parameter(Mandatory=$true,Position=1)]
        [string]$Source,

        [Parameter(Mandatory=$true,Position=2, ParameterSetName='info')]
        [switch]$Info,

        [Parameter(Mandatory=$true,Position=2, ParameterSetName='warn')]
        [switch]$Warn,

        [Parameter(Mandatory=$true,Position=2, ParameterSetName='error')]
        [switch]$Error

    )
        @{
            LogName = $LogName
            Source  = $Source
        }

        if ($Info)
        {
            @{
                EntryType = 'Information'
                EventID   = '0'
            }
        }
        if ($Warn)
        {
            @{
                EntryType = 'Warning'
                EventID   = '1'
            }
        }

        if ($Error)
        {
            @{
                EntryType = 'Error'
                EventID   = '2'
            }
        }
}

Now you can get the desired hashtable using for example:

Get-EventParams -LogName "Azure" -Source "Application" -Info

For convenience, you could also define a ValidateSet for your LogName and Soruce parameter.

Upvotes: 0

Related Questions