Change XML tags within PowerShell and keep content.

徘徊边缘 提交于 2021-01-28 04:16:57

问题


I have exported data from an EventLog using PowerShell and have created a sample Schema to import the data into SQL however there is an issue of the way the data is exported from PowerShell using ConvertToXML.

The exports of the XML looks like this;

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

But it should look something like this;

<Version>0</Version>

<Qualifiers> />

<Level>0</Level>

<Task>14339</Task>

The code below identifies the start and end of the property name version and property tag and attempts to change it to but unfortunately it changes it without keeping the contents within the tag. I can't seem to kept the value.

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

回答1:


Your problem is in

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

You replace a complete tag by an empty tag. I guess you want to use the captured group in the replacement:

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

Furthermore you probably used double quotes on the regex before, because there are "" in there. This likely won't match anything because it now looks for two double quotes in a row.

Another thing, you probably want to replace all at once, so use this maybe:

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

That's not really enough, though:

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>

As you can see, Qualifiers is still not changed. So another replace:

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

Looks better now

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>



回答2:


another simple way:

[Xml]$xml=@'
<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
      }

or:

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


来源:https://stackoverflow.com/questions/8517524/change-xml-tags-within-powershell-and-keep-content

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!