2012年12月20日木曜日

◆IISのログを取得する1(取得、圧縮、暗号化、分割)ソース

PowerShell: ◆IISのログを取得する1(取得、圧縮、暗号化、分割)のソース

<オプションダイアログ.ps1>

#config取得

$scriptPath = Split-Path $myInvocation.MyCommand.path

$confPath = Join-Path $scriptPath "GetLog.config"

$conf = [xml](Get-Content $confPath)

 

#CheckBoxchk*変数名を使っているので他には使わない

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 件のコメント:

コメントを投稿