我正在使用一些代码,这些代码将获取一系列性能计数器,然后将计数器放入.csv文件中,每次达到1MB时都会滚动。
$Folder="C:PerflogsBBCRMLogs" # Change the bit in the quotation marks to whatever directory you want the log file stored in
$Computer = $env:COMPUTERNAME
$1GBInBytes = 1GB
$p = LOTS OF COUNTERS;
# If you want to change the performance counters, change the above list. However, these are the recommended counters for a client machine.
$num = 0
$file = "$FolderSQL_log_${num}.csv"
if( !(test-path $folder)) {New-Item $Folder -type directory}
Get-Counter -counter $p -SampleInterval 2 -Continuous | Foreach {
if ((Get-Item $file -ErrorAction SilentlyContinue ).Length -gt 1mb)
{
$num +=1
$file = "$FolderSQL_log_${num}.csv"
}
$_
} | Foreach-Object { $_ | Export-Csv $file -Force -Append}
现在,它工作得很好。迭代工作得很好,并且每次.csv达到1MB时都会创建一个新文件。但是,第一个. csv文件之后的每个. csv文件都是在2分钟后以1MB的大小创建的,这将导致创建一个新文件。我不太确定为什么会发生这种情况,尽管我相信这是因为Powershell每次创建csv时都会重写整个。csv。
[我把这个作为一个新的答案而不是编辑原来的答案,因为它是完全不同的。替换或追加原答案会使随后的讨论变得混乱。[/em>
您需要做的是使用正则表达式从Get-Counter输出的读数属性中提取值,并从时间戳和这些值手动构造CSV输出。将最后一行更改为(根据您喜欢的样式格式):
| %{'"' + (Get-Date $_.Timestamp -f 's') + '","' + (([regex]::matches($_.Readings, '(?<=\\.+?:n)(.+?)(?=n)') | select -ExpandProperty Value) -join '","') + '"'} | Out-File $file -Append -Encoding ASCII
分解:
-
(Get-Date $_.Timestamp -f 's')
这部分不是严格必要的,尽管我认为它会使您的结果更容易遵循。's'格式将日期置于ISO 8601可排序模式中。您可以将'u'替换为另一种可排序的格式,或者使用您喜欢的自定义格式字符串。或者将其替换为$_。时间戳保留原始格式 -
[regex]::matches($_.Readings, '(?<=\\.+?:n)(.+?)(?=n)')
regex匹配任何以\开头并以:结束的行(您想要摆脱的那些讨厌的计数器名称)的内容。请注意,我使用的是[regex]::matches,它执行全局匹配,而不是[regex]::match或-match,它只会给您每个字符串的第一个匹配(读数属性是单个字符串,因此只会返回第一个计数器读数)。 -
| select -ExpandProperty Value
生成所有匹配项的数组,然后您可以将其与","连接,并将"环绕以生成CSV输出。
由于没有使用转换函数,因此还需要构造标题行。在管道的正上方添加这一行:
`'"Timestamp","' + ($p -join '","') + '"' | Out-File $file -Append -Encoding ASCII`
假设$p是一个数组(它应该是)。如果它是一个字符串,那么根据格式的不同,您可以直接使用它,也可以将拆分为并以CSV格式重新连接。
将最后一行更改为这样,将每行转换为CSV格式,然后将其附加到输出文件:
} | Foreach-Object {($_ | ConvertTo-Csv -NoTypeInformation)[1] | Out-File $file -Append -Encoding ASCII}.
注意事项:
-
-Encoding ASCII
不是严格必要的,但你可能有问题与Unicode CSV文件在一些应用程序(Excel,例如,默认情况下不会打开它作为CSV文件,一切都将在列a) -
($_ | ConvertTo-Csv -NoTypeInformation)[1]
中索引的原因是ConvertTo-Csv -NoTypeInformation
每次仍然输出标题行,所以您想要获取两行输出的第二行(($_ | ConvertTo-Csv -NoTypeInformation)[0]
是标题行) - 由于您没有输出标题行,因此需要在循环 之前向$file输出一行。