2011-12-15 3 views
2

PowerShell을 사용하여 EventLog에서 데이터를 내보내고 데이터를 SQL로 가져 오는 샘플 스키마를 만들었지 만 ConvertToXML을 사용하여 PowerShell에서 데이터를 내보내는 방식에 문제가 있습니다.PowerShell에서 XML 태그를 변경하고 콘텐츠를 유지하십시오.

XML 내보내기는 다음과 같습니다.

<Property Name="Version">0</Property> 

<Property Name="Qualifiers" /> 

<Property Name="Level">0</Property> 

<Property Name="Task">14339</Property> 

<Property Name="Opcode">0</Property> 

<Property Name="Keywords">-9218868437227405312</Property> 

<Property Name="RecordId">57963203</Property> 

<Property Name="ProviderName">Microsoft-Windows-Security-Auditing</Property> 

하지만 다음과 같이 보일 것입니다.

<Version>0</Version> 

<Qualifiers> /> 

<Level>0</Level> 

<Task>14339</Task> 

는 아래의 코드는 속성 이름 버전과 재산 태그 의 시작과 끝을 식별하고 그것에을 변경하려고하지만 불행히도 그것은 태그 내의 내용을 유지하지 않고 변경됩니다. 나는 그 가치를 지키지 못하는 것 같습니다.

$EventLog = (Get-WinEvent -ComputerName xxxxxxx-FilterXML $Query) | ConvertTo-Xml -NoTypeInformation 

$EventLogModify = (Get-Content P:\EventTracking\Events.xml) | foreach{$_ -replace '(<Property Name=""Version"">(.*?)</Property>)', "<Version></Version>" };Set-Content P:\EventTracking\Events.xml $EventLogModify; 

답변

3

귀하의 문제는

-replace '(<Property Name=""Version"">(.*?)</Property>)', "<Version></Version>" 

에 당신은 빈 태그에 의해 완전한 태그를 교체합니다. 난 당신이 교체에 캡처 그룹을 사용하려는 생각 :

-replace '(<Property Name=""Version"">(.*?)</Property>)', '<Version>$2</Version>' 

또한 당신은 아마 사용 따옴표를 정규식에 전에, 거기에 ""이 때문이다. 이것은 이제 두 개의 큰 따옴표가 연속적으로 보이기 때문에 아무 것도 맞지 않을 것입니다. Qualifiers는 여전히,

PS> $xml -replace '<Property Name="([^"]+)">([^<]+)</Property>', '<$1>$2</$1>' 
<Version>0</Version> 
<Property Name="Qualifiers" /> 
<Level>0</Level> 
<Task>14339</Task> 
<Opcode>0</Opcode> 
<Keywords>-9218868437227405312</Keywords> 
<RecordId>57963203</RecordId> 
<ProviderName>Microsoft-Windows-Security-Auditing</ProviderName> 

당신이 볼 수 있듯이 :

-replace '<Property Name="([^"]+)">([^<]+)</Property>', '<$1>$2</$1>' 

을하지만, 정말 충분하지 않습니다 그 :

또 다른 것은, 당신은 아마 한 번에 모든 교체, 그래서 아마이를 사용하려면 변경되지 않았습니다. 그래서 다른 대체 :

-replace '<Property Name="([^"]+)"\s*/>','<$1/>' 

지금보다 나은

PS> $xml -replace '<Property Name="([^"]+)">([^<]+)</Property>', '<$1>$2</$1>' -replace '<Property Name="([^"]+)"\s*/>','<$1/>' 
<Version>0</Version> 
<Qualifiers/> 
<Level>0</Level> 
<Task>14339</Task> 
<Opcode>0</Opcode> 
<Keywords>-9218868437227405312</Keywords> 
<RecordId>57963203</RecordId> 
<ProviderName>Microsoft-Windows-Security-Auditing</ProviderName> 
+0

와우. 그것은 절대적으로 아름답습니다. 이것은 지금 내 코드입니다. $ EventLogModify = (Get-Content P : \ EventTracking \ Events.xml) | foreach {$ _ -replace '<속성 이름 = "([^"] +) "> ([^ <] +)', '<$1> $ 2') "\ s * /> ','<$1/> '}; 설정 내용 P : \ EventTracking \ Events.xml $ EventLogModify; 정말 고마워요. –

+0

이것은 절대적으로 환상적입니다. 고맙습니다. 이것은 내 마지막 코드입니다. –

+0

글쎄, 적절한 방법은 아마도 XML API를 사용하는 것이지만 실제로 XML을 사용하는 것은 다소 까다 롭습니다. 기본적으로 스 니펫을 다른 태그로 묶고 XML로 모두 구문 분석하고 DOM의 요소 이름에 대한 변형을 작성한 다음 XML로 다시 작성한 다음 나중에 불필요한 주변 태그를 제거해야합니다.좋지는 않지만 재밌지는 않지만 regexes를 사용하는 것보다 안전 할 것입니다. (물론 내가하는 일은 충분히 안전합니다.) – Joey

0

또 다른 간단한 방법을 보이는 :

[Xml][email protected]' 
<root> 
<Property Name="Version">0</Property> 
<Property Name="Qualifiers" /> 
<Property Name="Level">0</Property> 
<Property Name="Task">14339</Property> 
<Property Name="Opcode">0</Property> 
<Property Name="Keywords">-9218868437227405312</Property> 
<Property Name="RecordId">57963203</Property> 
<Property Name="ProviderName">Microsoft-Windows-Security-Auditing</Property> 
</root> 
'@ 



$xml.SelectNodes('//Property') | ForEach ` 
-begin { 
     $h = New-Object xml 
     $r = $h.CreateElement("ROOT") 
     $null=$h.AppendChild($r) 
    } ` 
-process { 
    if($_.'#text') { 
     $n = $h.CreateElement($_.Name) 
     $n.InnerText = $_.'#text' 
     $null=$r.AppendChild($n) 
    } 
    else { 
     $n = $h.CreateElement($_.Name) 
     $null=$r.AppendChild($n) 
     } 
    } ` 
-End { 
     $h.OuterXml 
     } 

나 :

$xml.SelectNodes('//Property')|% { 
if($_.'#text') { "<{0}>{1}</{0}>" -f $_.name,$_.'#text' } else {"<$($_.name)/>"} 
} 
관련 문제