仅在提供值时传递参数
Only pass parameter if value supplied
背景
我围绕 Write-EventLog
创建了一个包装函数,这样我就可以轻松地调用它,而不必担心自己每次都检查和创建事件 log/source。通过简单地添加一个 -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
错误
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
我会考虑 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
}
}
<b> if($rawdata){
$rawdataparameter = @{
RawData = $rawdata
}</b>
}
}
process {
Write-EventLog -LogName $LogName -Source $Source -EventId $EventId -EntryType $EntryType -Message $Message -Category $Category -ComputerName $ComputerName <b>@RawDataParameter</b>
}
有条件地构建一个小散列table,其中包含按名称和值的参数。使用 at 符号 varialbe 符号来拼写 Write-Log
命令。实际上,对于 Get-ChildItem
,如果 table 不包含任何对或为 null,则它会被忽略。
感谢 Matt 让我意识到 unassigned/declared 变量不同于 null,这让我发现了 Remove-Variable
。
http://ss64.com/ps/remove-variable.html
这会将变量从简单地具有值 $null
更改为不存在;因此即使列为已通过也不会通过。
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
,
[Parameter(Position=5,Mandatory=$false,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[String]$Message
,
[Parameter(Position=6,Mandatory=$false,ValueFromPipeline=$false,ValueFromPipelineByPropertyName=$true)]
[Int16]$Category
,
[Parameter(Position=7,Mandatory=$false,ValueFromPipeline=$false,ValueFromPipelineByPropertyName=$true)]
[String]$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 {
if(!$EntryType) {Remove-Variable EntryType};
if(!$Message) {Remove-Variable Message};
if(!$Category) {Remove-Variable Category};
if(!$ComputerName) {Remove-Variable ComputerName};
if(!$RawData) {Remove-Variable RawData};
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
背景
我围绕 Write-EventLog
创建了一个包装函数,这样我就可以轻松地调用它,而不必担心自己每次都检查和创建事件 log/source。通过简单地添加一个 -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
错误
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
我会考虑 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
}
}
<b> if($rawdata){
$rawdataparameter = @{
RawData = $rawdata
}</b>
}
}
process {
Write-EventLog -LogName $LogName -Source $Source -EventId $EventId -EntryType $EntryType -Message $Message -Category $Category -ComputerName $ComputerName <b>@RawDataParameter</b>
}
有条件地构建一个小散列table,其中包含按名称和值的参数。使用 at 符号 varialbe 符号来拼写 Write-Log
命令。实际上,对于 Get-ChildItem
,如果 table 不包含任何对或为 null,则它会被忽略。
感谢 Matt 让我意识到 unassigned/declared 变量不同于 null,这让我发现了 Remove-Variable
。
http://ss64.com/ps/remove-variable.html
这会将变量从简单地具有值 $null
更改为不存在;因此即使列为已通过也不会通过。
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
,
[Parameter(Position=5,Mandatory=$false,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[String]$Message
,
[Parameter(Position=6,Mandatory=$false,ValueFromPipeline=$false,ValueFromPipelineByPropertyName=$true)]
[Int16]$Category
,
[Parameter(Position=7,Mandatory=$false,ValueFromPipeline=$false,ValueFromPipelineByPropertyName=$true)]
[String]$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 {
if(!$EntryType) {Remove-Variable EntryType};
if(!$Message) {Remove-Variable Message};
if(!$Category) {Remove-Variable Category};
if(!$ComputerName) {Remove-Variable ComputerName};
if(!$RawData) {Remove-Variable RawData};
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