我試圖解析存檔安全日誌以跟蹤更改權限的問題。該腳本通過+10天之前的.evtx文件進行查詢。它目前輸出我想要的內容,但是當它清理舊日誌時(每天大約50GB,未壓縮,每個都通過午夜運行的另一個腳本存檔到它們自己的日常文件夾中),它開始抱怨日誌是在使用中並且不能被刪除。當我嘗試通過資源管理器刪除文件時,似乎正在使用的進程是DHCP客戶端或事件查看器,同時停止這兩種服務,但顯然我無法在沒有eventvwr的情況下運行。 DHCP客戶端用於網絡的好處,但不是必需的。如何解析和刪除Powershell中的存檔事件日誌
接觸.evtx文件的唯一東西就是這個腳本,它們沒有備份,它們不受其他任何東西的監控,它們不會被事件日誌服務自動分析,它們只是被存儲在磁盤上等待。
該腳本最初刪除的東西,因爲它去了,但後來失敗所有刪除被移動到最後,然後到KillLogWithFire()函數。即使計時器似乎沒有幫助。我也嘗試將文件移動到Processed子文件夾,但這不起作用的原因相同。
我認爲有一些方法可以釋放此腳本在任何文件上打開的任何句柄,但試圖在循環中的EventLog變量的.close()或.dispose()不起作用。
$XPath = @'
*[System[Provider/@Name='Microsoft-Windows-Security-Auditing']]
and
*[System/EventID=4670]
'@
$DeletableLogs = @()
$logfile = "L:\PermChanges.txt"
$AdminUsers = ("List","of","Admin","Users")
$today = Get-Date
$marker = "
-------------
$today
-------------
"
write-output $marker >> $logfile
Function KillLogWithFire($log){
Try {
remove-item $log
}
Catch [writeerror]{
$Timer += 1
sleep $timer
write-output "Killing log $log in $timer seconds"
KillLogWithFire($log)
}
}
Function LogPermissionChange($PermChanges){
ForEach($PermChange in $PermChanges){
$Change = @{}
$Change.ChangedBy = $PermChange.properties[1].value.tostring()
#Filter out normal non-admin users
if ($AdminUsers -notcontains $Change.ChangedBy){continue}
$Change.FileChanged = $PermChange.properties[6].value.tostring()
#Ignore temporary files
if ($Change.FileChanged.EndsWith(".tmp")){continue}
elseif ($Change.FileChanged.EndsWith(".partial")){continue}
$Change.MadeOn = $PermChange.TimeCreated.tostring()
$Change.OriginalPermissions = $PermChange.properties[8].value.tostring()
$Change.NewPermissions = $PermChange.properties[9].value.tostring()
write-output "{" >> $logfile
write-output ("Changed By : "+ $Change.ChangedBy) >> $logfile
write-output ("File Changed : "+ $Change.FileChanged) >> $logfile
write-output ("Change Made : "+ $Change.MadeOn) >> $logfile
write-output ("Original Permissions :
"+ $Change.OriginalPermissions) >> $logfile
write-output ("New Permissions :
"+ $Change.NewPermissions) >> $logfile
"}
" >> $logfile
}
}
GCI -include Archive-Security*.evtx -path L:\Security\$Today.AddDays(-10) -recurse | ForEach-Object{
Try{
$PermChanges = Get-WinEvent -Path $_ -FilterXPath $XPath -ErrorAction Stop
}
Catch [Exception]{
if ($_.Exception -match "No events were found that match the specified selection criteria."){
}
else {
Throw $_
}
}
LogPermissionChange($PermChanges)
$PermChanges = $Null
$DeletableLogs += $_
}
foreach ($log in $DeletableLogs){
$Timer = 0
Try{
remove-item $log
}
Catch [IOException]{
KillLogWithFire($log)
}
}
UPDATE
而不是編輯原始代碼,因爲我已經被告知不要做,我想後完整的代碼,現在使用作爲一個單獨的答案。初始部分,其解析日誌和運行每30分鐘是大多與上述相同:
$XPath = @'
*[System[Provider/@Name='Microsoft-Windows-Security-Auditing']]
and
*[System/EventID=4670]
'@
$DeletableLogs = @()
$logfile = "L:\PermChanges.txt"
$DeleteList = "L:\DeletableLogs.txt"
$AdminUsers = ("List","Of","Admins")
$today = Get-Date
$marker = "
-------------
$today
-------------
"
write-output $marker >> $logfile
Function LogPermissionChange($PermChanges){
ForEach($PermChange in $PermChanges){
$Change = @{}
$Change.ChangedBy = $PermChange.properties[1].value.tostring()
#Filter out normal non-admin users
if ($AdminUsers -notcontains $Change.ChangedBy){continue}
$Change.FileChanged = $PermChange.properties[6].value.tostring()
#Ignore temporary files
if ($Change.FileChanged.EndsWith(".tmp")){continue}
elseif ($Change.FileChanged.EndsWith(".partial")){continue}
$Change.MadeOn = $PermChange.TimeCreated.tostring()
$Change.OriginalPermissions = $PermChange.properties[8].value.tostring()
$Change.NewPermissions = $PermChange.properties[9].value.tostring()
write-output "{" >> $logfile
write-output ("Changed By : "+ $Change.ChangedBy) >> $logfile
write-output ("File Changed : "+ $Change.FileChanged) >> $logfile
write-output ("Change Made : "+ $Change.MadeOn) >> $logfile
write-output ("Original Permissions :
"+ $Change.OriginalPermissions) >> $logfile
write-output ("New Permissions :
"+ $Change.NewPermissions) >> $logfile
"}
" >> $logfile
}
}
GCI -include Archive-Security*.evtx -path L:\Security\ -recurse | ForEach-Object{
Try{
$PermChanges = Get-WinEvent -Path $_ -FilterXPath $XPath -ErrorAction Stop
}
Catch [Exception]{
if ($_.Exception -match "No events were found that match the specified selection criteria."){
}
else {
Throw $_
}
}
LogPermissionChange($PermChanges)
$PermChanges = $Null
$DeletableLogs += $_
}
foreach ($log in $DeletableLogs){
write-output $log.FullName >> $DeleteList
}
第二部分不刪除,包括上面承蒙TheMadTechnician提供的輔助函數。該代碼仍然是循環的直刪除比函數快,但並不總是成功的文件後,甚至年齡還沒有被觸動:
# Log Cleanup script. Works around open log issues caused by PS parsing of
# saved logs in EventLogParser.ps1
$DeleteList = "L:\DeletableLogs.txt"
$DeletableLogs = get-content $DeleteList
Function Close-LockedFile{
Param(
[Parameter(Mandatory=$true,ValueFromPipeline=$true)][String[]]$Filename
)
Begin{
$HandleApp = 'C:\sysinternals\Handle.exe'
If(!(Test-Path $HandleApp)){Write-Host "Handle.exe not found at $HandleApp`nPlease download it from www.sysinternals.com and save it in the afore mentioned location.";break}
}
Process{
$HandleOut = Invoke-Expression ($HandleApp+' '+$Filename)
$Locks = $HandleOut |?{$_ -match "(.+?)\s+pid: (\d+?)\s+type: File\s+(\w+?): (.+)\s*$"}|%{
[PSCustomObject]@{
'AppName' = $Matches[1]
'PID' = $Matches[2]
'FileHandle' = $Matches[3]
'FilePath' = $Matches[4]
}
}
ForEach($Lock in $Locks){
Invoke-Expression ($HandleApp + " -p " + $Lock.PID + " -c " + $Lock.FileHandle + " -y") | Out-Null
If (! $LastexitCode) { "Successfully closed " + $Lock.AppName + "'s lock on " + $Lock.FilePath}
}
}
}
Function KillLogWithFire($log){
Try {
Close-LockedFile $Log -
}
Catch [System.IO.IOException]{
$Timer += 1
sleep $timer
write-host "Killing $Log in $Timer seconds with fire."
KillLogWithFire($Log)
}
}
foreach ($log in $DeletableLogs){
Try {
remove-item $log -ErrorAction Stop
}
Catch [System.IO.IOException]{
$Timer = 0
KillLogWithFire($Log)
}
}
remove-item $DeleteList
謝謝,遺憾的是根據句柄問題的文件沒有打開,所以這並沒有幫助我。 :(但它確實向我展示瞭如何在交互式/不可讀的輸出方式中使用Handle,所以請注意這一點。再次感謝。 – 2014-09-03 16:34:27
所以,只需要清楚,你可以在函數中添加一行, Close-LockedFile $ log'就在你的'Remove-Item $ log'這行之前?或者你只是在腳本的外部看着Handle的文件,並且看不到任何東西鎖定它們?不批評,只是想在同一頁面上。 – TheMadTechnician 2014-09-03 17:24:07
昨天我在處理Handle,並沒有顯示任何文件被鎖定,而PS窗口反覆吐出文件中的使用錯誤;我沒有嘗試將此代碼添加到上面的腳本中,但是我嘗試過代碼在不同的腳本中,並且還沒有打開關於打開文件的任何阻塞錯誤,這在我之前一直都有。如果你想知道,我不介意測試上述內容嗎? – 2014-09-03 17:49:25