我有一个函数可以给我一些Get-WinEvent
的结果,效果很好。使用它作为另一个函数的输入并尝试迭代该数组,我注意到,该数组的构建方式如下:
-1 ProviderName: Microsoft-Windows-FailoverClustering TimeCreated Id LevelDisplayName Message ----------- -- ---------------- ------- 07.08.2019 01:14:23 1538 Information The backup operation for the cluster configuration data completed successfully. The snapshot ID is '47cda23b-c446-43dc-9b5d-dfdbaca2be8c'.
很显然,我不想拥有“ -1”和“ ProviderName:Microsoft-Windows-FailoverClustering”。
如何正确处理?
function Get-ClusterLogEntries {
Param(
[Parameter(Position=0, Mandatory=$true)]
[int] $server_id,
[Parameter(Position=1, Mandatory=$true)]
[string] $clusterName
)
$conn = New-Object System.Data.SqlClient.SqlConnection
$conn.ConnectionString = "Server=xxxx\yyyy;Database=zzzz;Integrated Security=True"
$conn.Open() | Out-Null
$cmd = New-Object System.Data.SqlClient.SqlCommand("extern.xxxx", $conn)
$cmd.CommandType = [System.Data.CommandType]::StoredProcedure
$cmd.Parameters.Add("@server_id", [System.Data.SqlDbType]::int) | Out-Null
$cmd.Parameters['@server_id'].Direction = [System.Data.ParameterDirection]::Input
$cmd.Parameters['@server_id'].Value = $server_id #local server
$cmd.Parameters.Add("@clusterName", [System.Data.SqlDbType]::VarChar, 10) | Out-Null
$cmd.Parameters['@clusterName'].Direction = [System.Data.ParameterDirection]::Input
$cmd.Parameters['@clusterName'].Value = $clusterName
$cmd.Parameters.Add("@timeCreated", [System.Data.SqlDbType]::DateTime) | Out-Null
$cmd.Parameters['@timeCreated'].Direction = [System.Data.ParameterDirection]::Output
$cmd.ExecuteNonQuery()
$conn.Close()
$conn.Dispose()
$timeCreated = $cmd.Parameters["@timeCreated"].Value
$startdatum = $timeCreated
return [array]$clusterLogEntries = Get-WinEvent -FilterHashTable @{
logname = 'Microsoft-Windows-FailoverClustering/Operational';
starttime = $startdatum
}
}
和使用功能:
function Write-ClusterLog {
Param(
[Parameter(Position=0, Mandatory=$true)]
[int] $server_id,
[Parameter(Position=1, Mandatory=$true)]
[string] $computer,
[Parameter(Position=2, Mandatory=$true)]
[string] $clusterName,
[Parameter(Position=3, Mandatory=$true)]
[array] $clusterLogs
)
$conn = New-Object System.Data.SqlClient.SqlConnection
$conn.ConnectionString = "Server=xxxx;Database=yyyyy;Integrated Security=True"
$conn.Open() | Out-Null
$cmd = New-Object System.Data.SqlClient.SqlCommand("extern.zzzzzz", $conn)
$cmd.CommandType = [System.Data.CommandType]::StoredProcedure
foreach ($clusterLog in $clusterLogs) {
$cmd.Parameters.Add("@server_id", [System.Data.SqlDbType]::int) | Out-Null
$cmd.Parameters['@server_id'].Direction = [System.Data.ParameterDirection]::Input
$cmd.Parameters['@server_id'].Value = $server_id
$cmd.Parameters.Add("@servername", [System.Data.SqlDbType]::VarChar, 10) | Out-Null
$cmd.Parameters['@servername'].Direction = [System.Data.ParameterDirection]::Input
$cmd.Parameters['@servername'].Value = $computer #local server
$cmd.Parameters.Add("@clustername", [System.Data.SqlDbType]::VarChar, 10) | Out-Null
$cmd.Parameters['@clustername'].Direction = [System.Data.ParameterDirection]::Input
$cmd.Parameters['@clustername'].Value = $clusterName
$cmd.Parameters.Add("@timecreated", [System.Data.SqlDbType]::DateTime) | Out-Null
$cmd.Parameters['@timecreated'].Direction = [System.Data.ParameterDirection]::Input
$cmd.Parameters['@timecreated'].Value = $clusterLog.TimeCreated
$cmd.Parameters.Add("@eventID", [System.Data.SqlDbType]::int) | Out-Null
$cmd.Parameters['@eventID'].Direction = [System.Data.ParameterDirection]::Input
$cmd.Parameters['@eventID'].Value = $clusterLog.ID
$cmd.Parameters.Add("@levelDisplayName", [System.Data.SqlDbType]::varchar, 50) | Out-Null
$cmd.Parameters['@levelDisplayName'].Direction = [System.Data.ParameterDirection]::Input
$cmd.Parameters['@levelDisplayName'].Value = $clusterLog.LevelDisplayName
$cmd.Parameters.Add("@message", [System.Data.SqlDbType]::VarChar, 4000) | Out-Null
$cmd.Parameters['@message'].Direction = [System.Data.ParameterDirection]::Input
$cmd.Parameters['@message'].Value = $clusterLog.Message
$cmd.ExecuteNonQuery()
$cmd.Parameters.Clear()
}
$conn.Close()
$conn.Dispose()
}
答案 0 :(得分:2)
此声明:
$cmd.ExecuteNonQuery()
return an integer将指示受INSERT或UPDATE操作影响的行数-对于非修改操作,它将返回 -1 !
将其更改为:
[void]$cmd.ExecuteNonQuery()
# or
$cmd.ExecuteNonQuery() |Out-Null
答案 1 :(得分:2)
@ MathiasR.Jessen的答案对于-1的来源是正确的。
“提供者名称:Microsoft-Windows-FailoverClustering”来自Get-WinEvent
返回(EventLogRecord
)类型的对象的默认输出格式。这与输出Get-ChildItem时看到“目录:X:\ foo”的原因相同。
要修复此问题,您需要选择字段而不是返回整个对象:
Get-WinEvent -FilterHashTable @{
logname = 'Microsoft-Windows-FailoverClustering/Operational';
starttime = $startdatum
} | Select-Object TimeCreated, Id, LevelDisplayName, Message
如果需要所有属性,可以改为指定Select-Object *
,但是由于要显示的属性数量,您将获得列表输出。
如果您需要EventLogRecord
类上的方法,则不能这样做,因为带有Select-Object
参数的-Property
会将对象类型更改为PSCustomObject
。您正在从对象的基类中展开对象。如果需要方法,并且需要不显示提供程序名称,则必须修改Types.ps1xml
文件,以描述EventLogRecord类型的对象的格式。您几乎可以肯定不想这样做。参见Get-Help about_Types.ps1xml
。