选择格式被打破

时间:2019-02-01 09:23:21

标签: powershell

我有这个PowerShell脚本,可从Bitvise日志中提取帐户,时间和路径

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}}

日志看起来像

<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>

它工作正常,但是当我尝试选择其格式损坏时。

enter image description here

2 个答案:

答案 0 :(得分:2)

在将XML修改为注释后,可以很容易地获得属性值,例如:

# 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
    }
}

或这个

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}}
}

或这个

foreach ($node in $log.DocumentElement.ChildNodes) {
    $node | Select-Object @{name = 'Path'; expression = {$_.sfs.parameters.path}},
                          @{name = 'Account'; expression = {$_.session.virtualAccount}},
                          @{name = 'Time'; expression = {$_.time}}
}

结果将是:

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

答案 1 :(得分:1)

请记住,使用正则表达式解析XML绝对不是一个好主意(对于Powershell 2及更高版本,已更新):

$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

结果

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...