仅在提供值时传递参数

Joh*_*van 3 parameters powershell optional-parameters powershell-4.0

背景

我已经创建了一个包装器函数,Write-EventLog这样我就可以轻松地调用它,而不必每次都关心检查和创建事件日志/源.通过简单地添加一个-Force参数,我希望它创建日志,如果它不存在; 如果我不添加该参数,它应该正常运行(如果从我知道日志将存在的代码调用,这可以减少多次检查的开销).

我已经复制了可用参数列表,write-eventlog以便我可以使用包装器的全部功能.然而; 如果我不为这些参数中的某些参数提供值(例如RawData),则它们默认为null; 然后我最终尝试为此参数传递null; 这与不供应不同.我不想列出每个可能的参数组合迭代,并检查在调用适当的方法签名之前是否提供了这些值.

有没有办法只将值write-eventlog传递给传递这些参数的参数write-eventlog2

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
Run Code Online (Sandbox Code Playgroud)

错误

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
Run Code Online (Sandbox Code Playgroud)

Mat*_*att 9

我会考虑使用这样的东西进行splatting,因为你可以在不改变太多代码的情况下解释null/empty.

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
    }
Run Code Online (Sandbox Code Playgroud)

有条件地构建一个小的哈希表,其中包含按名称和值的参数.使用at符号varialbe表示法来splat Write-Log命令.实际上,Get-ChildItem如果表中不包含任何对或为null,则忽略它.