2015-10-01 51 views
1
$timelimit = (get-date).AddMinutes(-65) 
$logpath = "C:\_SCRIPT_\_SCHED_\_Eventlog_to_SQL.txt" 
$now = get-date 
$nowstring = "{0:yyyy-MM-dd-HH:mm:ss}" -f $now 
$dbServer = "myserver" 
$dbDatabase = "logdb" 
$dbuid = "logdbuser" 
$dbpwd = "logdbpass" 

$dbTableFWevents = "dbo.fwevents" 
$FWEvents = Get-WinEvent -logname ForwardedEvents | where-object {$_.timecreated -ge $timelimit} | Select * | Sort-Object TimeCreated 
$FWEventsstat = $FWEvents | Measure-Object 

$dbConnection = New-Object System.Data.SqlClient.SqlConnection 
$dbConnectionString = "Server=$dbServer;Database=$dbDatabase;Integrated Security=True;User ID=$dbuid;Password=$dbpwd;Connect Timeout=0" 
$dbconnection.ConnectionString = $dbConnectionString 
$dbconnection.Open() 
$transaction = $dbConnection.BeginTransaction("LogParserUpload") 

$nowstring + " ---START---" | out-file $logpath -Append 
$nowstring + " EVENT COUNT: " +$FWEventsstat.Count | out-file $logpath -Append 
foreach ($evnt in $FWEvents) 
    { 
    $Command = $dbconnection.CreateCommand() 
    $Command.CommandText = "INSERT INTO "+$dbDatabase+"."+$dbTableFWevents+" (Message, Id, Level, ProviderName, LogName, ProcessId, ThreadId, MachineName, UserId, TimeCreated, LevelDisplayName) VALUES (@Message, @Id, @Level, @ProviderName, @LogName, @ProcessId, @ThreadId, @MachineName, @UserId, @TimeCreated, @LevelDisplayName)"; 
    if ([string]$evnt.message){$Command.Parameters.Add("@Message", [string]$evnt.Message);}else{$Command.Parameters.Add("@Message", [DBNull]::Value);} 
    if ([string]$evnt.id){$Command.Parameters.Add("@Id", [string]$evnt.id);}else{$Command.Parameters.Add("@Id", [DBNull]::Value);} 
    if ([string]$evnt.level){$Command.Parameters.Add("@Level", [string]$evnt.level);}else{$Command.Parameters.Add("@Level", [DBNull]::Value);} 
    if ([string]$evnt.providername){$Command.Parameters.Add("@ProviderName", [string]$evnt.ProviderName);}else{$Command.Parameters.Add("@ProviderName", [DBNull]::Value);} 
    if ([string]$evnt.logname){$Command.Parameters.Add("@LogName", [string]$evnt.LogName);}else{$Command.Parameters.Add("@LogName", [DBNull]::Value);} 
    if ([string]$evnt.processid){$Command.Parameters.Add("@ProcessId", [string]$evnt.ProcessId);}else{$Command.Parameters.Add("@ProcessId", [DBNull]::Value);} 
    if ([string]$evnt.threadid){$Command.Parameters.Add("@ThreadId", [string]$evnt.threadId);}else{$Command.Parameters.Add("@ThreadId", [DBNull]::Value);} 
    if ([string]$evnt.machinename){$Command.Parameters.Add("@MachineName", [string]$evnt.MachineName);}else{$Command.Parameters.Add("@MachineName", [DBNull]::Value);} 
    if ([string]$evnt.userid){$Command.Parameters.Add("@UserId", [string]$evnt.UserId);}else{$Command.Parameters.Add("@UserId", [DBNull]::Value);} 
    if ([string]$evnt.timecreated){$Command.Parameters.Add("@TimeCreated", [string]$evnt.TimeCreated);}else{$Command.Parameters.Add("@TimeCreated", [DBNull]::Value);} 
    if ([string]$evnt.leveldisplayname){$Command.Parameters.Add("@LevelDisplayName", [string]$evnt.LevelDisplayName);}else{$Command.Parameters.Add("@LevelDisplayName", [DBNull]::Value);} 
    $Command.Transaction = $transaction 
    $eredmenyin = $Command.ExecuteNonQuery() 
    $nowstring + " INSERT RESULT: " +$eredmenyin | out-file $logpath -Append 
    } 

$eredmenytr = $transaction.Commit() 
$nowstring + " TRANSACTION RESULT: " +$eredmenyin | out-file $logpath -Append 
$nowstring + " ---END---" | out-file $logpath -Append 
#$transaction.Rollback() 
$dbconnection.Close() 

Hello guys。 由于历史原因,我们通过Windows服务器Forwarded Event解决方案收集了一堆服务器信息。 转发事件并不容易从收集计算机收集,因为logparser和其他解决方案很难访问它。 所以我决定收集并上传它与Powershell。Powershell SQL插入随机失败

脚本每60分钟按计划运行一次,向后收集事件65分钟。

脚本运行良好。但有时会跳过1-2行。我不懂为什么。它不会跳过整个会话 - 但例如,如果在65分钟的时间间隔内有5个事件,则会上传4.下次,它流利地运行。下次再次从10个事件2中随机跳过。

我想知道为什么。但我不明白原因,我不知道如何记录实际的插入命令来修复它,或创建其他错误处理。 (你可以看到我也实现了交易 - 希望不会错,而交易也可以)。

不知道如何找到错误的原因和/或来源。

+0

您是否检查过表上的模式?也许您试图将null传递给字段那些被标记为非空? – ewahner

回答

0

第一列是uniqid - 允许空是“否” - 因为它的行标识符。 其他行是 - Allow Nulls“yes”。 (顺便说一句,因为我告诉skript的作品 - 由于70-80%的evenlogs上传,但只有20-30%缺失 - absolutley随机...)

所以我怀疑这是问题的根源。

我怀疑有两种方法可以找到问题。

1)从$ command变量记录实际的SQL命令 - 但我没有发现如何做到这一点。 write-host $ command.parameters 只写入$ Command.CommandText的内容 - 表示没有任何信息只有其中的####变量。所以我不知道,如果实际的INSERT不是“错误”,如何重新检查

2)以某种方式使用事务日志(或其他资源)来确定实际的INSERT命令是否“到达”,如果“ “如果它被拒绝并且出于何种原因。因为我不是一个真正的SQL专家,这种魔法超出了我的理解(而且谷歌也没有帮我解决:()