PowerShell: ◆IISのログを取得する1(取得、圧縮、暗号化、分割)のソース
<オプションダイアログ.ps1>
#config取得 $scriptPath = Split-Path $myInvocation.MyCommand.path $confPath = Join-Path $scriptPath "GetLog.config" $conf = [xml](Get-Content $confPath)
#CheckBoxにchk*変数名を使っているので他には使わない Remove-Variable chk*
$frmCls = "System.Windows.Forms" Add-Type -AssemblyName $frmCls $ctrlArray = New-Object System.Collections.ArrayList
function CreateObj($ctrl){ $obj = New-Object $ctrl $obj.Left = 10 if($obj -is [System.Windows.Forms.Label]){ $obj.Height -= 10 } [void]$ctrlArray.Add($obj) return $obj } $form = New-Object $frmCls".Form" $form.Text = "オプション指定" $form.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
#コントロール $chk1 = createObj $frmCls".CheckBox" $chk1.Text = "圧縮";$chk1.Checked = $true $chk2 = createObj $frmCls".CheckBox" $chk2.Text = "暗号化";$chk2.Checked = $false $chk3 = createObj $frmCls".CheckBox" $chk3.Text = "分割(KB)";$chk3.Checked = $false $chk3.add_CheckedChanged({ $txt2.Enabled = $chk3.Checked }) $txt2 = CreateObj $frmCls".TextBox" $txt2.Text = 500 $txt2.TextAlign = "Right" $txt2.Enabled = $chk3.Checked
$chk4 = createObj $frmCls".CheckBox" $chk4.Text = "イベントログ(全部)";$chk4.Checked = $true $chk4.add_CheckedChanged({ $chk5.Enabled = !$chk4.Checked }) $chk5 = createObj $frmCls".CheckBox" $chk5.Text = "イベントログ(範囲抽出)" $chk5.Enabled = $false $chk5.add_CheckedChanged({ $chk4.Enabled = !$chk5.Checked if($chk5.Checked){$chk4.Checked = $false} $dp1.Enabled = $dp2.Enabled = $chk5.Checked })
$lb1 = CreateObj $frmCls".Label" $lb1.Text = "イベントログ抽出開始日" $dp1 = CreateObj $frmCls".DateTimePicker" $dp1.Enabled = $false
$lb2 = CreateObj $frmCls".Label" $lb2.Text = "イベントログ抽出終了日" $dp2 = CreateObj $frmCls".DateTimePicker" $dp2.Enabled = $false
#configから抽出項目列挙(オプション) $counterChkBox = Get-Variable | ?{$_.Value -is [System.Windows.Forms.CheckBox]} | measure | select -ExpandProperty count $conf.root.iislogs.log | %{ ++$counterChkBox $currentObj = Set-Variable -Name chk$counterChkBox -Value ( createObj $frmCls".CheckBox") -PassThru $currentObj.Value.Text = $_.name $currentObj.Value.Checked = $true }
#出力先用フォルダー選択ダイアログ $lbl3 = CreateObj $frmCls".Label" $lbl3.Text = "出力場所" $txt1 = CreateObj $frmCls".TextBox" $deskPath = [environment]::GetFolderPath("desktop") $txt1.Text = $deskPath $btnFolder = CreateObj $frmCls".Button" $btnFolder.Text = "..." $btnFolder.add_Click({ $shell = New-Object -com Shell.Application
$folderPath = $shell.BrowseForFolder(0,"対象フォルダーを選択してください",0,$deskPath) if($folderPath){$txt1.Text = $folderPath.Self.Path}
})
#「OK」「Cancel」ボタン $btnOK = CreateObj $frmCls".Button" $btnOK.Text = "OK" $btnCancel = CreateObj $frmCls".Button" $btnCancel.Text = "キャンセル" $form.AcceptButton = $btnOK ; $form.CancelButton = $btnCancel $btnOK.add_Click({ $ret = $true $txt1.BackColor = $txt2.BackColor = "White" if(!($txt1.Text -and (Test-Path $txt1.Text))) { $txt1.BackColor = "Pink";$ret = $false } if($chk3.Checked -and ![int]::TryParse($txt2.Text,[ref]$null)){ $txt2.BackColor = "Pink";$ret = $false } if($ret){ $form.Close() $form.set_DialogResult([System.Windows.Forms.DialogResult]::OK) } }) $btnCancel.add_Click({$form.Close()})
$ctrlArray.ToArray() | ?{$_ -is [System.Windows.Forms.Control]} | %{$yPos=5}{ $_.Width = 200 $_.Top = $yPos $yPos += $_.Height + 5 $form.Controls.Add($_) $form.Height = $yPos + 50 #タイトルバーを簡便的に50程度と扱う }
#ボタンレイアウト調整 $btnFolder.Width = 30;$btnFolder.top = $txt1.top $btnFolder.Left = $txt1.Left + $txt1.Width + 5 $btnFolder.Height = $txt1.Height $btnCancel.Top = $btnOK.Top $btnOK.Width = $btnCancel.Width = 100 $btnCancel.Left = $btnOK.Right + 10
#ダイアログ結果リターン $dialogReturn = $false if($form.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK){ $dialogReturn = $true $dlgOutPath = $txt1.Text $dlgSelectFromDay = $dp1.Value $dlgSelectEndDay = $dp2.Value $dlgsplitSize = 1024 * $txt2.Text $dlgOptions = Get-Variable chk* -ValueOnly | select -ExpandProperty Checked } $form.Dispose()
#ダイアログボタン結果,出力パス,イベントログ抽出開始日,終了日,分割サイズ, #チェックボックス値(圧縮, # 暗号化,分割,イベントログ全部,イベントログ一部,ログオプション・・・・) return $dialogReturn,$dlgOutPath,$dlgSelectFromDay, $dlgSelectEndDay,$dlgSplitSize,$dlgOptions |
<GetLogメイン.ps1>
param( [string]$OutPath="desktop", [switch]$EventLog, [datetime]$FromEvent, [datetime]$ToEvent, [switch]$Compress, [switch]$Encrypt, [switch]$Split, [long]$SplitSizeKB=500, [bool[]]$Options ) $currntPath = Split-Path $myInvocation.MyCommand.path Start-Transcript (Join-Path $currntPath "GetLog.log") $confPath = Join-Path $currntPath "GetLog.config" $conf = [xml](Get-Content $confPath) $confOptions = $conf.root.iislogs.log
if($PSBoundParameters.get_Count()){ if(!($EventLog -or $FromEvent -or $ToEvent -or $Options.Count)){ Write-Error "Enter target log.";return } $P_OutPath = $OutPath $P_EventLog = $EventLog $P_FromEvent = $FromEvent $P_ToEvent = $ToEvent $P_Compress = $Compress $P_Encrypt = $Encrypt $P_Split = $Split $P_SplitSize = $SplitSizeKB * 1kb $P_Options = 1..$confOptions.Count | %{$false} #falseの配列を作る if($Options){ 0..($Options.Count-1) | %{$P_Options[$_] = $Options[$_]} } # $P_Options = $Options }else{ $dialogParam = & (Join-Path $currntPath "オプションダイアログ.ps1") $dialogReturn,$dlgOutPath,$dlgSelectFromDay, $dlgSelectEndDay,$dlgSplitSize,$dlgOptions = $dialogParam if($dialogReturn){ $P_OutPath = $dlgOutPath $P_EventLog = $dlgOptions[3] #イベントログ(全部) if($dlgOptions[4]){ #イベントログ(範囲抽出) $P_FromEvent = $dlgSelectFromDay $P_ToEvent = $dlgSelectEndDay }else{ $P_FromEvent = $P_ToEvent = $null } $P_Compress = $dlgOptions[0] #圧縮 $P_Encrypt = $dlgOptions[1] #暗号化 $P_Split = $dlgOptions[2] #分割 $P_SplitSize = $dlgSplitSize #分割サイズ #IISログ+その他オプションログ $P_Options = $dlgOptions[5..($dlgOptions.count-1)] }else{ exit } }
$bunkatuPath = Join-Path $currntPath "分割.ps1"
& $bunkatuPath $P_OutPath $P_EventLog $P_FromEvent $P_ToEvent ` $P_Compress $P_Encrypt $P_Split $P_SplitSize $P_Options $conf Write-Host "Script End" -ForegroundColor Cyan Stop-Transcript |
<分割.ps1>
param( [string]$OutPath, $EventLog, $FromEvent, $ToEvent, $Compress, $Encrypt, $Split, [long]$SplitSize, [bool[]]$Options, [xml]$conf )
function MakeDir($path){ $f = mkdir $path Write-Host "mkdir $path" -ForegroundColor Cyan }
$filterString = @" Event/System/TimeCreated[@SystemTime>='{0}'] and Event/System/TimeCreated[@SystemTime<'{1}'] "@
$currntPath = Split-Path $myInvocation.MyCommand.path $confPath = Join-Path $currntPath "GetLog.config" #プログレスバー $evlogTotal = $conf.root.eventlogs.log.count if($conf.root.eventlogs.text -eq "true"){$evlogTotal = $evlogTotal * 2} $evLogCounter = 0 function WriteProgress($currentOperation,$endflg){ <# $script:evLogCounter++ if($endflg){ $percent = 100 }else{ $percent = [Math]::Min(($script:evLogCounter * 100 / $evlogTotal),90) } Write-Progress -Activity ログ取得 -Status "取得しています" ` -CurrentOperation (Split-Path $currentOperation -Leaf) ` -PercentComplete $percent #> }
#出力先フォルダ作成 if((Test-Path $OutPath) -eq $false){ $spcialFolder = [environment+specialfolder] | Get-Member -Static -type property | select -expand name if($spcialFolder -contains $OutPath){ $OutPath = [Environment]::GetFolderPath($OutPath) }else{ Write-Error "◆出力パス誤り◆";return } } $outPathRoot = Join-Path $OutPath ("ログ" + (Get-Date).ToString("yyyyMMdd_HHmmss")) MakeDir $outPathRoot | Out-Null $plainPath = Join-Path $outPathRoot "オリジナル" MakeDir $plainPath | Out-Null
#◆◆◆ イベントログ抽出◆◆◆◆◆◆◆ $filter = $null if($EventLog){ #全部抽出 $filter = "*" }elseif($FromEvent){ #日付範囲で抽出 $startTime = $FromEvent.ToString("yyyy/MM/dd 00:00:00") if($ToEvent -eq $null){$ToEvent = Get-Date} $endTime = $ToEvent.AddDays(1).ToString("yyyy/MM/dd 00:00:00") $startUtcTime = [System.TimeZoneInfo]::ConvertTimeToUtc( $startTime).ToString("yyyy-MM-ddTHH:mm:ssZ") $endUtcTime = [System.TimeZoneInfo]::ConvertTimeToUtc( $endTime).ToString("yyyy-MM-ddTHH:mm:ssZ")
$filter = $filterString -f $startUtcTime,$endUtcTime }
if($filter){ $evsession = New-Object -TypeName System.Diagnostics.Eventing.Reader.EventLogSession #イベントログ用フォルダ作成 $evLogFolder = Join-Path $plainPath "イベントログ" MakeDir $evLogFolder #抽出対象ログ名称取得し、それぞれにFilterを適用しながらGet $conf.root.eventlogs.log | %{ #初期処理 $dateRange=$null if(!$EventLog){ $dateRange = $FromEvent.ToString("yyyyMMdd") + "-" + $ToEvent.ToString("yyyyMMdd") } }{ #ログ種類毎の処理 #イベントログ形式で出力 $evLogFullName = Join-Path $evLogFolder ($_.name + $dateRange + ".evtx") $evsession.ExportLog($_.name,"LogName",$filter,$evLogFullName) Write-Host "出力しました $evLogFullName" -ForegroundColor Cyan WriteProgress $evLogFullName #テキストで出力 if($conf.root.eventlogs.text -eq "true"){ $filterHash = @{} $filterHash.LogName = $_.name if(!$EvnetLog){ $filterHash.StartTime = $startTime $filterHash.EndTime = $endTime } Get-WinEvent -FilterHashtable $filterHash | %{ $csvPath = [IO.Path]::ChangeExtension($evLogFullName,"txt") $sw = New-Object System.IO.StreamWriter( $csvPath,$false,[Text.Encoding]::UTF8) $sw.WriteLine( ("レベル","日付と時刻","ソース","イベント ID", "タスクのカテゴリ","メッセージ" -join "`t")) }{ if($_.task -eq 0){$task = "なし"}else{$task = $_.task} $sw.WriteLine( ($_.LevelDisplayName,$_.TimeCreated,$_.ProviderName, $_.Id,$task,$_.message -join "`t")) }{ $sw.Close() Write-Host "出力しました $csvPath" -ForegroundColor Cyan WriteProgress $csvPath } }
} }
#◆◆◆ IISログコピー◆◆◆◆◆◆ $optionCtr = 0 $conf.root.iislogs.log | %{ if($Options[$optionCtr++]){ $logPath = Join-Path $plainPath $_.name MakeDir $logPath | Out-Null if($_.day){ $day = (Get-Date).AddDays(-($_.day)).ToString("yyyy/MM/dd") }else{ $day = [DateTime]::MinValue.ToString("yyyy/MM/dd") }
$targetPath = $_.Path if($_.sitename){ #IISアクセスログはパスにサイトIDを付加する $siteName = $_.sitename $iis = New-Object DirectoryServices.DirectoryEntry("IIS://localhost/W3SVC") $siteID = $iis.children | ?{$_.schemaClassName -eq "IIsWebServer"} | ?{$_.serverComment -eq $siteName} | select -expand name
$targetPath = $targetPath -replace '\(id\)',$siteID } dir $targetPath | ?{!$_.PSIsContainer} | ?{$_.LastWriteTime -gt $day} | copy -Destination $logPath -PassThru | %{"コピーしました $_"} | Write-Host -ForegroundColor Cyan } }
WriteProgress "終了" $true
#◆圧縮◆◆◆◆◆◆ if($Compress -or $Encrypt){ $zipFolder = Join-Path $outPathRoot "圧縮" MakeDir $zipFolder | Out-Null $outZipFile = Join-Path $zipFolder "ログ.zip" $dllPath = Join-Path $currntPath "ICSharpCode.SharpZipLib.dll" [Void][Reflection.Assembly]::LoadFile($dllPath) $zipFile = New-Object ICSharpCode.SharpZipLib.Zip.FastZip $zipFile.CreateEmptyDirectories = $true $zipFile.CreateZip($outZipFile,$plainPath,$true,$null,$null) Write-Host "圧縮しました $outZipFile" -ForegroundColor Cyan }
#◆暗号化◆◆◆◆◆◆ if($Encrypt){ $encFolder = Join-Path $outPathRoot "暗号化" MakeDir $encFolder $outEncFile = Join-Path $encFolder "ログ.dat" $KEYFilePath = Join-Path $currntPath "KEY.dat" $IVFilePath = Join-Path $currntPath "IV.dat" if((Test-Path $KEYFilePath) -and (Test-Path $IVFilePath)){ $desKey = [System.IO.File]::ReadAllBytes($KEYFilePath) $desIV = [System.IO.File]::ReadAllBytes($IVFilePath) }else{ $desKey = [byte[]](1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1) $desIV = [byte[]](0,0,0,0,0,0,0,0) }
$src = [System.IO.File]::ReadAllBytes($outZipFile) $desProvider = New-Object System.Security.Cryptography.TripleDESCryptoServiceProvider $encryptor = $desProvider.CreateEncryptor($desKey,$desIV) $ms = New-Object System.IO.MemoryStream $cs = New-Object System.Security.Cryptography.CryptoStream( $ms, $encryptor, [System.Security.Cryptography.CryptoStreamMode]::Write) $cs.Write($src,0,$src.Length) $cs.Close() [System.IO.File]::WriteAllBytes($outEncFile,$ms.ToArray()) Write-Host "暗号化しました $outEncFile" -ForegroundColor Cyan }
#◆分割◆◆◆◆◆ if($Split -and ($Compress -or $Encrypt)){ $splitFolder = Join-Path $outPathRoot "分割" MakeDir $splitFolder if($Encrypt){ $outSplitFileBase = Join-Path $splitFolder "DAT" }else{ $outSplitFileBase = Join-Path $splitFolder "ZIP" } if($Encrypt){ $splitTargetFile = Get-Item $outEncFile }else{ $splitTargetFile = Get-Item $outZipFile } if($splitTargetFile.Length -gt $SplitSize) { $src = [System.IO.File]::ReadAllBytes($splitTargetFile) $num = 0 for ($remain = $src.length; $remain -gt 0; $remain -= $SplitSize) { $length = [System.Math]::Min($SplitSize,$remain) $dest = New-Object byte[] $Length [System.Array]::Copy($src,$num * $SplitSize,$dest,0,$length) $num++ $exName = ".{0:D3}" -f $num $splitName = $outSplitFileBase + $exName [System.IO.File]::WriteAllBytes($splitName,$dest) Write-Host "分割しました $splitName" -ForegroundColor Cyan } }else{ Write-Host $splitTargetFile -ForegroundColor Yellow Write-Host $outSplitFileBase -ForegroundColor Yellow Copy $splitTargetFile ($outSplitFileBase + ".001") } }
Write-Host "◆◆◆ 終了しました ◆◆◆" -ForegroundColor Magenta |
0 件のコメント:
コメントを投稿