Question:
Background
I’ve created a wrapper function around Write-EventLog
so that I can easily call it without having to concern myself with checking for & creating an event log/source each time. By simply adding a -Force
parameter, I want it to create the log if it doesn’t exist; if I don’t add that parameter it should behave as normal (which reduces overhead of multiple checks if called from code where I know that log will exist).
I’ve copied the list of parameters available to write-eventlog
such that I have the full functionality available to my wrapper. However; if I don’t supply values to some of these parameters (e.g. RawData), they default to null; then I end up trying to pass null for this parameter; which is different to not supplying it. I don’t want to have to list every possible iteration of parameter combinations with checks for whether those values were supplied before calling the appropriate method signature.
Question
Is there a way to only pass values to parameters of write-eventlog
where those parameters had been passed to write-eventlog2
?
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
cls $myLog = 'Application' $mySource = 'My PS Script' $myEventId = 1 [System.Diagnostics.EventLogEntryType]$myEntryType = [System.Diagnostics.EventLogEntryType]::Error $myMessage = 'This is a test message' function Write-EventLog2 { [cmdletbinding()] param( [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] [String]$LogName , [Parameter(Position=1,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] [String]$Source , [Parameter(Position=3,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] [Int32]$EventId , [Parameter(Position=4,Mandatory=$false,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] [System.Diagnostics.EventLogEntryType]$EntryType = [System.Diagnostics.EventLogEntryType]::Information , [Parameter(Position=5,Mandatory=$false,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] [String]$Message , [Parameter(Position=6,Mandatory=$false,ValueFromPipeline=$false,ValueFromPipelineByPropertyName=$true)] [Int16]$Category = 1 , [Parameter(Position=7,Mandatory=$false,ValueFromPipeline=$false,ValueFromPipelineByPropertyName=$true)] [String]$ComputerName = $env:COMPUTERNAME , [Parameter(Position=8,Mandatory=$false,ValueFromPipeline=$false,ValueFromPipelineByPropertyName=$true)] [Byte[]]$RawData , [Parameter(Position=9,Mandatory=$false,ValueFromPipeline=$false,ValueFromPipelineByPropertyName=$true)] [switch]$Force ) begin { if($Force.IsPresent) { if (! ([System.Diagnostics.EventLog]::Exists($LogName) -and [System.Diagnostics.EventLog]::SourceExists($Source) )) { New-EventLog -LogName $LogName -Source $Source } } } process { Write-EventLog -LogName $LogName -Source $Source -EventId $EventId -EntryType $EntryType -Message $Message -Category $Category -ComputerName $ComputerName -RawData $RawData } #end{} #no ending actions required } Write-EventLog2 $myLog $mySource $myEventId $myEntryType $myMessage -Force |
Error
1 2 3 4 5 |
Write-EventLog : Cannot validate argument on parameter 'RawData'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again. At line:51 char:167 |
Answer:
I would consider splatting for something like this as you could account for null / empty without changing too much of the code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
begin { if($Force.IsPresent) { if (! ([System.Diagnostics.EventLog]::Exists($LogName) -and [System.Diagnostics.EventLog]::SourceExists($Source) )) { New-EventLog -LogName $LogName -Source $Source } } if($rawdata){ $rawdataparameter = @{ RawData = $rawdata } } } process { Write-EventLog -LogName $LogName -Source $Source -EventId $EventId -EntryType $EntryType -Message $Message -Category $Category -ComputerName $ComputerName @RawDataParameter } |
Conditionally build a small hashtable that contains the parameter by name and the value. The use the at sign varialbe notation to splat the Write-Log
command. In practice, with Get-ChildItem
, if the table contains no pairs or is null it is ignored.