Home > Software design >  How to update XML with reading it only once with PowerShell?
How to update XML with reading it only once with PowerShell?

Time:05-07

Can someone please help me to do the following more efficiently? I am running this code 4 times for updating specific below protocols/file types. I would like to do it in a loop or other ways to make it much more efficient!

$XMLPATH = 'C:\DefaultAssociation.xml'
$xml = [xml](Get-Content $XMLPATH  -raw)

#update .htm
   $htm = ($xml.DefaultAssociations.Association | where-Object Identifier -eq '.htm')
   $htm.SetAttribute('ProgId', "ChromeHTML")
   $htm.SetAttribute('ApplicationName', "Google Chrome")

#update .html
   $html = ($xml.DefaultAssociations.Association | where-Object Identifier -eq '.html')
   $html.SetAttribute('ProgId', "ChromeHTML")
   $html.SetAttribute('ApplicationName', "Google Chrome")

#update .https
   $https = ($xml.DefaultAssociations.Association | Where-Object Identifier -eq 'https')
   $https.SetAttribute('ProgId', "ChromeHTML")
   $https.SetAttribute('ApplicationName', "Google Chrome")

#update http
   $http = ($xml.DefaultAssociations.Association | Where-Object Identifier -eq 'http')
   $http.SetAttribute('ProgId', "ChromeHTML")
   $http.SetAttribute('ApplicationName', "Google Chrome")

   $XML.SAVE($XMLPATH)

instead of running it multiple times, I need to make it an array or some sort of loop, so it doesn't read the XML file multiple times. How can this be done more efficiently?

CodePudding user response:

To execute your statements in a loop you can do something like this: Although as mentioned in my comment it will not give you a performance benefit.

$XMLPATH = 'C:\DefaultAssociation.xml'
$xml = [xml](Get-Content $XMLPATH  -raw)
$extensions = @(".htm",".html",".http",".https")

foreach($extension in $extensions){
    $val = ($xml.DefaultAssociations.Association | where-Object Identifier -eq $extension)
    $val.SetAttribute('ProgId', "ChromeHTML")
    $val.SetAttribute('ApplicationName', "Google Chrome")
}

$XML.SAVE($XMLPATH)

CodePudding user response:

Use PowerShell's -in operator to equality-test against multiple values in a single operation, with any successful test short-circuiting further tests and returning $true overall:

$htm = $xml.DefaultAssociations.Association | 
         Where-Object Identifier -in '.htm', '.html', 'https', 'http'
$htm.SetAttribute('ProgId', "ChromeHTML")
$htm.SetAttribute('ApplicationName', "Google Chrome")

As an aside re $xml = [xml](Get-Content $XMLPATH -raw):

  • Loading XML documents this way isn't fully robust; use the following idiom instead:

    ($xml = [xml]::new()).Load((Convert-Path -LiteralPath $XMLPATH))
    
  • See this answer for background information.

  • Related