Powershell:需要转换变量编码

时间:2014-08-11 19:46:04

标签: datetime powershell character-encoding

我一直在研究Powershell脚本,以便从事件日志中获取所有6008个事件(意外关闭)。然后,我解析了$_.Message以获取关闭的日期和时间,并且我尝试将其转换为[datetime]。但是,我无法使用ParseExact格式化日期,因为日期/时间中存在隐藏字符(它们在日期中的每个月,日期和年份值之前看起来像空心方块)。我猜这是一个编码问题;什么是将变量转换为纯文本(ascii?UTF8?)的最佳方法,以便我可以将此字符串格式化为[datetime]

脚本:

$timefmt = "M/dd/yyyy h:mm:ss tt"
$Messages = (get-eventlog -LogName System -ComputerName svr-name |   Where-Object {$_.EventID -eq 6008 -AND $_.timegenerated -gt (get-date).adddays(-35) }|     select message)
$Messages | ForEach-Object { 
$Matched = $_.Message -match "([0-9]{1,2}:.*[0-9]{4})"
if ($Matched) {
    $SplitMatches = $Matches[1].split(" ")
    $time,$ampm,$on,$date = $SplitMatches
    $td = "$date $time $ampm
    [datetime]::ParseExact($td,$timefmt,$null)
}
}

我想做的是这样的事情:

[datetime]::ParseExact([ascii]$td,$timefmt,$null)

但这不是正确的,我甚至不确定ascii是我需要的。

1 个答案:

答案 0 :(得分:2)

问题是消息HEX 3F中的隐藏字符,但我们可以在RegEx中解释它,并通过它。我使用了4个捕获组,最后加入了最后3个,使日期不包括隐藏字符。

我不习惯你如何进行匹配,所以我的格式有点不同。我还在Get-EventLog cmdlet上使用-After而不是之后进行过滤,因为在提供程序中进行过滤通常要快得多。

$timefmt = "M/d/yyyy h:mm:ss tt"
$Messages = get-eventlog -LogName System -After (Get-Date).AddDays(-35) |   Where-Object {$_.EventID -eq 6008 }| select -expand message
$Messages |?{$_ -match "(\d{1,2}:\d{1,2}:\d{2} (?:A|P)M) on .(\d{1,2}/).(\d{1,2}/).(\d{4})"}| ForEach-Object { 
        $Time = $Matches[1]
        $Date = $Matches[2..4] -join ""
        [datetime]::ParseExact("$Date $Time",$timefmt,$null)
}