Reputation: 41
I have this PowerShell script which pulls account, Time and path from Bitvise logs
gc C:\temp\all.log |
Select-String -Pattern '<parameters path=\"([^\"]*)\"','virtualAccount=\"([^\"]*)\"' ,'time=\"([^\"]*)\"' |
select @{n='path';e={$_.Matches.Groups[1].Value}},
@{n='Account';e={$_.Matches.Groups[2].Value}},
@{n='time';e={$_.Matches.Groups[3].Value}}
logs look like
<event seq="993107" time="2019-01-30 11:00:01.903062 -0500" app="BvSshServer 7.45" name="I_SFS_LIST_DIRECTORY" desc="Virtual filesystem: list directory.">
<session id="96172" service="SSH" remoteAddress="128.2.27.11:49312" virtualAccount=CMU" windowsAccount="SERVER\BvSsh_VirtualUsers"/>
<channel type="session" id="1"/>
<sfs moduleName="FlowSfsWin" mountPath="/" code="91000" desc="Listing directory ended.">
<parameters path="C:\lyyyy\ff" timeMs="156" entriesCount="23"/>
</sfs>
</event>
<event seq="993108" time="2019-01-30 11:00:01.960986 -0500" app="BvSshServer 7.45" name="xxxx" desc="Virtual filesystem: transfer file.">
<session id="96172" service="SSH" remoteAddress="0.090.0" virtualAccount="yyyyyy" windowsAccount="server\BvSsh_VirtualUsers"/>
<channel type="session" id="1"/>
<sfs moduleName="FlowSfsWin" mountPath="/" code="90000" desc="Transferring file ended.">
<parameters path="C:\path\ttx" timeMs="109" bytesRead="0" bytesWritten="1772" readRangeOffset="0" readRangeLength="0" writeRangeOffset="0" writeRangeLength="1772" createdNewFile="false" resizedFile="true" endedBy="Client"/>
<help message="File transfer ended by client."/>
</sfs>
Its working fine but when I run to select the format its broken.
Upvotes: 0
Views: 217
Reputation: 30113
Having in mind that parsing a XML
using regular expressions definitely is not a good idea (updated for Powershell 2 and above):
$logFile = @'
<event seq="993107" time="2019-01-30 11:00:01.903062 -0500" app="BvSshServer 7.45" name="I_SFS_LIST_DIRECTORY" desc="Virtual filesystem: list directory.">
<session id="96172" service="SSH" remoteAddress="128.2.27.11:49312" virtualAccount="CMU" windowsAccount="SERVER\BvSsh_VirtualUsers"/>
<channel type="session" id="1"/>
<sfs moduleName="FlowSfsWin" mountPath="/" code="91000" desc="Listing directory ended.">
<parameters path="C:\lyyyy\ff" timeMs="156" entriesCount="23"/>
</sfs>
</event>
<event seq="993108" time="2019-01-30 11:00:01.960986 -0500" app="BvSshServer 7.45" name="xxxx" desc="Virtual filesystem: transfer file.">
<session id="96172" service="SSH" remoteAddress="0.090.0" virtualAccount="yyyyyy" windowsAccount="server\BvSsh_VirtualUsers"/>
<channel type="session" id="1"/>
<sfs moduleName="FlowSfsWin" mountPath="/" code="90000" desc="Transferring file ended.">
<parameters path="C:\path\ttx" timeMs="109" bytesRead="0" bytesWritten="1772" readRangeOffset="0" readRangeLength="0" writeRangeOffset="0" writeRangeLength="1772" createdNewFile="false" resizedFile="true" endedBy="Client"/>
<help message="File transfer ended by client."/>
</sfs>
</event>
'@
# $log = $logFile -split [System.Environment]::NewLine ### instead of Get-Content
$log = $logFile.Split( [System.Environment]::NewLine )
$logExp = $log | Select-String -Pattern 'parameters path=\"([^\"]*)\"',
'virtualAccount=\"([^\"]*)\"' ,
'time=\"([^\"]*)\"' -AllMatches
$logNew = $(0..($logExp.Count / 3 -1)) |
Select-Object @{n='path';e={$logExp[3 * $_+2].Matches[0].Groups[1].Value}},
@{n='Account'; e={$logExp[3*$_+1].Matches[0].Groups[1].Value}},
@{n='time';e={$logExp[3*$_+0].Matches[0].Groups[1].Value}}
$logNew
Result:
PS D:\PShell> D:\PShell\SO\54476444.ps1
path Account time
---- ------- ----
C:\lyyyy\ff CMU 2019-01-30 11:00:01.903062 -0500
C:\path\ttx yyyyyy 2019-01-30 11:00:01.960986 -0500
Powershell 2:
==> powershell -version 2 -noprofile -file D:\PShell\SO\54476444.ps1
path Account time
---- ------- ----
C:\lyyyy\ff CMU 2019-01-30 11:00:01.90306...
C:\path\ttx yyyyyy 2019-01-30 11:00:01.96098...
Upvotes: 1
Reputation: 61068
Once you have fixed your XML as commented, you can get the attribute values quite easily doing something like this:
# you would use Get-Content for this
$log = [xml]@"
<root>
<event seq="993107" time="2019-01-30 11:00:01.903062 -0500" app="BvSshServer 7.45" name="I_SFS_LIST_DIRECTORY" desc="Virtual filesystem: list directory.">
<session id="96172" service="SSH" remoteAddress="128.2.27.11:49312" virtualAccount="CMU" windowsAccount="SERVER\BvSsh_VirtualUsers"/>
<channel type="session" id="1"/>
<sfs moduleName="FlowSfsWin" mountPath="/" code="91000" desc="Listing directory ended.">
<parameters path="C:\lyyyy\ff" timeMs="156" entriesCount="23"/>
</sfs>
</event>
<event seq="993108" time="2019-01-30 11:00:01.960986 -0500" app="BvSshServer 7.45" name="xxxx" desc="Virtual filesystem: transfer file.">
<session id="96172" service="SSH" remoteAddress="0.090.0" virtualAccount="yyyyyy" windowsAccount="server\BvSsh_VirtualUsers"/>
<channel type="session" id="1"/>
<sfs moduleName="FlowSfsWin" mountPath="/" code="90000" desc="Transferring file ended.">
<parameters path="C:\path\ttx" timeMs="109" bytesRead="0" bytesWritten="1772" readRangeOffset="0" readRangeLength="0" writeRangeOffset="0" writeRangeLength="1772" createdNewFile="false" resizedFile="true" endedBy="Client"/>
<help message="File transfer ended by client."/>
</sfs>
</event>
</root>
"@
foreach ($node in $log.DocumentElement.ChildNodes) {
[pscustomobject]@{
'Path' = $node.sfs.parameters.path
'Account' = $node.session.virtualAccount
'Time' = $node.time
}
}
or this
foreach ($node in $log.DocumentElement.ChildNodes) {
"" | Select-Object @{name = 'Path'; expression = {$node.sfs.parameters.path}},
@{name = 'Account'; expression = {$node.session.virtualAccount}},
@{name = 'Time'; expression = {$node.time}}
}
or this
foreach ($node in $log.DocumentElement.ChildNodes) {
$node | Select-Object @{name = 'Path'; expression = {$_.sfs.parameters.path}},
@{name = 'Account'; expression = {$_.session.virtualAccount}},
@{name = 'Time'; expression = {$_.time}}
}
The result will be:
Path Account Time ---- ------- ---- C:\lyyyy\ff CMU 2019-01-30 11:00:01.903062 -0500 C:\path\ttx yyyyyy 2019-01-30 11:00:01.960986 -0500
Upvotes: 2