locked
XML and writing back to my file RRS feed

  • Question

  • I have always struggled with XML. So please if you just want to tell me to go learn it (first I am trying) second just please don't answer.

    I have a XML file (see screenshot below).  I want to modify the tags to add the actual OU the computer is in to the tags.

    1) I have it as far as reading and parsing the XML.

    2) pulling the Tags and computer name from the XML.

    3) finding the OU and adding it to the Tags and writing it out on the screen.

    How the heck to I write it back to the XML file.

    See below for (My first XML script so be kind) and the screen shot of as snip of the XML file I am working with.

    Thanks so much for any guidance

    [xml]$MyXMLFile = Get-Content "c:\temp\Terminals.xml"
    
    
    $MyXMLFile.favorites.favorite | % {
    "-----------------------Start------------------------------------"
    $servername =  $_.serverName
    $tags = $_.tags
    
    "$servername" 
    
    
    
    $serverinfo =  Get-ADComputer $servername -Properties *
    $DistinguishedName = $serverinfo.DistinguishedName
    $DistinguishedName = $DistinguishedName -replace "CN=$servername,OU=","" -replace ",.*",""
    $DistinguishedName
    
    $tags = "$tags,$DistinguishedName"
    $tags
    "-----------------------End------------------------------------"
    }
    
    
    
    
    
    


    Lishron

    Wednesday, October 7, 2015 5:50 PM

Answers

  • Is this what you are trying to do?

    [xml]$xml=@'
    <?xml version="1.0" encoding="utf-8"?>
    <favorites>
    	<favorite>
    		<protocol>RDP</protocol>
    		<port>3389</port>
    		<serverName>my-computer-name</serverName>
    		<url>rdp://my-computer-name:3389/</url>
    		<name>my-computer-name</name>
    		<credential />
    		<domainName>foo</domainName>
    		<userName>TSMITH</userName>
    		<password>MyPassword</password>
    		<notes />
    		<desktopSize>AutoScale</desktopSize>
    		<desktopSizeHeight>600</desktopSizeHeight>
    		<desktopSizeWidth>800</desktopSizeWidth>
    		<colors>Bit16</colors>
    		<sounds>DontPlay</sounds>
    		<redirectClipboard>True</redirectClipboard>
    		<enableTLSAuthentication>True</enableTLSAuthentication>
    		<enableNLAAuthentication>True</enableNLAAuthentication>
    		<idleTimeout>240</idleTimeout>
    		<overallTimeout>600</overallTimeout>
    		<connectionTimeout>600</connectionTimeout>
    		<shutdownTimeout>10</shutdownTimeout>
    		<tags>Desktop, Rons</tags>
    		<newWindow>False</newWindow>
    		<toolBarIcon />
    		<bitmapPeristence>RDP</bitmapPeristence>
    	</favorite>
    	<favorite>
    		<protocol>RDP</protocol>
    		<port>3389</port>
    		<serverName>MySecondCompouterName</serverName>
    		<url>rdp://MySecondCompouterName:3389/</url>
    		<name>MySecondCompouterName</name>
    		<credential />
    		<domainName>foo</domainName>
    		<userName>TSMITH</userName>
    		<password>MyPassword</password>
    		<notes />
    		<desktopSize>AutoScale</desktopSize>
    		<desktopSizeHeight>600</desktopSizeHeight>
    		<desktopSizeWidth>800</desktopSizeWidth>
    		<colors>Bit16</colors>
    		<sounds>DontPlay</sounds>
    		<redirectClipboard>True</redirectClipboard>
    		<enableTLSAuthentication>True</enableTLSAuthentication>
    		<enableNLAAuthentication>True</enableNLAAuthentication>
    		<idleTimeout>240</idleTimeout>
    		<overallTimeout>600</overallTimeout>
    		<connectionTimeout>600</connectionTimeout>
    		<shutdownTimeout>10</shutdownTimeout>
    		<tags>Laptop</tags>
    		<newWindow>False</newWindow>
    		<toolBarIcon />
    		<bitmapPeristence>RDP</bitmapPeristence>
    	</favorite>
    </favorites>
    '@
    
    $xml.SelectNodes('//favorite') |
    ForEach-Object{
           $serverinfo = Get-ADComputer $_.ServerName
    	$DistinguishedName = $serverinfo.DistinguishedName -replace "CN=$($_.ServerName),OU=", "" -replace ",.*", ""
    	$_.tags+=$DistinguishedName
    }
    $xml.Save("c:\temp\changed.xml")
    
    


    \_(ツ)_/



    • Edited by jrv Wednesday, October 7, 2015 7:45 PM
    • Marked as answer by Lishron Thursday, October 8, 2015 11:16 AM
    Wednesday, October 7, 2015 7:44 PM

All replies

  • It does absolutely no good to post a picture of the XML.  Post the XML as code please.


    \_(ツ)_/

    Wednesday, October 7, 2015 6:06 PM
  • To save XML just use $xml.Save(<filename>)

    \_(ツ)_/

    Wednesday, October 7, 2015 6:07 PM
  • You have not posted enough information to guess at what you are asking other than how to save the XML.

    \_(ツ)_/

    Wednesday, October 7, 2015 6:09 PM
  • I do
    apologies allow me to repost the xml portion

    I did

    $MyXMLFile.Save("c:\temp\changed.xml")

    But
    apparently my crappy code is not writing back to the XML string


    <?xml version="1.0" encoding="utf-8"?>
    <favorites>
      <favorite>
        <protocol>RDP</protocol>
        <port>3389</port>
        <serverName>my-computer-name</serverName>
        <url>rdp://my-computer-name:3389/</url>
        <name>my-computer-name</name>
        <credential />
        <domainName>foo</domainName>
        <userName>TSMITH</userName>
        <password>MyPassword</password>
        <notes />
        <desktopSize>AutoScale</desktopSize>
        <desktopSizeHeight>600</desktopSizeHeight>
        <desktopSizeWidth>800</desktopSizeWidth>
        <colors>Bit16</colors>
        <sounds>DontPlay</sounds>
        <redirectClipboard>True</redirectClipboard>
        <enableTLSAuthentication>True</enableTLSAuthentication>
        <enableNLAAuthentication>True</enableNLAAuthentication>
        <idleTimeout>240</idleTimeout>
        <overallTimeout>600</overallTimeout>
        <connectionTimeout>600</connectionTimeout>
        <shutdownTimeout>10</shutdownTimeout>
        <tags>Desktop,Rons</tags>
        <newWindow>False</newWindow>
        <toolBarIcon />
        <bitmapPeristence>RDP</bitmapPeristence>
      </favorite>
      <favorite>
        <protocol>RDP</protocol>
        <port>3389</port>
        <serverName>MySecondCompouterName</serverName>
        <url>rdp://MySecondCompouterName:3389/</url>
        <name>MySecondCompouterName</name>
        <credential />
        <domainName>foo</domainName>
        <userName>TSMITH</userName>
        <password>MyPassword</password>
        <notes />
        <desktopSize>AutoScale</desktopSize>
        <desktopSizeHeight>600</desktopSizeHeight>
        <desktopSizeWidth>800</desktopSizeWidth>
        <colors>Bit16</colors>
        <sounds>DontPlay</sounds>
        <redirectClipboard>True</redirectClipboard>
        <enableTLSAuthentication>True</enableTLSAuthentication>
        <enableNLAAuthentication>True</enableNLAAuthentication>
        <idleTimeout>240</idleTimeout>
        <overallTimeout>600</overallTimeout>
        <connectionTimeout>600</connectionTimeout>
        <shutdownTimeout>10</shutdownTimeout>
        <tags>Laptop</tags>
        <newWindow>False</newWindow>
        <toolBarIcon />
        <bitmapPeristence>RDP</bitmapPeristence>
      </favorite>
          </favorites>


    Lishron


    • Edited by Lishron Wednesday, October 7, 2015 6:18 PM
    Wednesday, October 7, 2015 6:16 PM
  •  You have to get the node and assign the value.

    Like this:

    [xml]$xml=@'
    <?xml version="1.0" encoding="utf-8"?>
    <favorites>
    	<favorite>
    		<protocol>RDP</protocol>
    		<port>3389</port>
    		<serverName>my-computer-name</serverName>
    		<url>rdp://my-computer-name:3389/</url>
    		<name>my-computer-name</name>
    		<credential />
    		<domainName>foo</domainName>
    		<userName>TSMITH</userName>
    		<password>MyPassword</password>
    		<notes />
    		<desktopSize>AutoScale</desktopSize>
    		<desktopSizeHeight>600</desktopSizeHeight>
    		<desktopSizeWidth>800</desktopSizeWidth>
    		<colors>Bit16</colors>
    		<sounds>DontPlay</sounds>
    		<redirectClipboard>True</redirectClipboard>
    		<enableTLSAuthentication>True</enableTLSAuthentication>
    		<enableNLAAuthentication>True</enableNLAAuthentication>
    		<idleTimeout>240</idleTimeout>
    		<overallTimeout>600</overallTimeout>
    		<connectionTimeout>600</connectionTimeout>
    		<shutdownTimeout>10</shutdownTimeout>
    		<tags>Desktop, Rons</tags>
    		<newWindow>False</newWindow>
    		<toolBarIcon />
    		<bitmapPeristence>RDP</bitmapPeristence>
    	</favorite>
    	<favorite>
    		<protocol>RDP</protocol>
    		<port>3389</port>
    		<serverName>MySecondCompouterName</serverName>
    		<url>rdp://MySecondCompouterName:3389/</url>
    		<name>MySecondCompouterName</name>
    		<credential />
    		<domainName>foo</domainName>
    		<userName>TSMITH</userName>
    		<password>MyPassword</password>
    		<notes />
    		<desktopSize>AutoScale</desktopSize>
    		<desktopSizeHeight>600</desktopSizeHeight>
    		<desktopSizeWidth>800</desktopSizeWidth>
    		<colors>Bit16</colors>
    		<sounds>DontPlay</sounds>
    		<redirectClipboard>True</redirectClipboard>
    		<enableTLSAuthentication>True</enableTLSAuthentication>
    		<enableNLAAuthentication>True</enableNLAAuthentication>
    		<idleTimeout>240</idleTimeout>
    		<overallTimeout>600</overallTimeout>
    		<connectionTimeout>600</connectionTimeout>
    		<shutdownTimeout>10</shutdownTimeout>
    		<tags>Laptop</tags>
    		<newWindow>False</newWindow>
    		<toolBarIcon />
    		<bitmapPeristence>RDP</bitmapPeristence>
    	</favorite>
    </favorites>
    '@
    
    $node = $xml.SelectSingleNode('//favorite')
    $node.serverName='new server name'
    

    Now look at node:

    PS C:\scripts> $node


    protocol                : RDP
    port                    : 3389
    serverName              : new server name
    url                     : rdp://my-computer-name:3389/
    name                    : my-computer-name
    credential              :
    domainName              : foo
    userName                : TSMITH
    password                : MyPassword
    notes                   :
    desktopSize             : AutoScale
    desktopSizeHeight       : 600
    desktopSizeWidth        : 800
    colors                  : Bit16
    sounds                  : DontPlay
    redirectClipboard       : True
    enableTLSAuthentication : True
    enableNLAAuthentication : True
    idleTimeout             : 240
    overallTimeout          : 600
    connectionTimeout       : 600
    shutdownTimeout         : 10
    tags                    : Desktop, Rons
    newWindow               : False
    toolBarIcon             :
    bitmapPeristence        : RDP

    Now you can save it and review the change.

    $xml.Save("$pwd\newfile.xml")
    . "pwd\newfile.xml"


    \_(ツ)_/

    Wednesday, October 7, 2015 6:28 PM
  • Here is something to consider.

    [xml]$xml=@'
    <?xml version="1.0" encoding="utf-8"?>
    <favorites>
    	<favorite id="1">
    		<protocol>RDP</protocol>
    		<port>3389</port>
    		<serverName>my-computer-name</serverName>
    		<url>rdp://my-computer-name:3389/</url>
    		<name>my-computer-name</name>
    		<credential />
    		<domainName>foo</domainName>
    		<userName>TSMITH</userName>
    		<password>MyPassword</password>
    		<notes />
    		<desktopSize>AutoScale</desktopSize>
    		<desktopSizeHeight>600</desktopSizeHeight>
    		<desktopSizeWidth>800</desktopSizeWidth>
    		<colors>Bit16</colors>
    		<sounds>DontPlay</sounds>
    		<redirectClipboard>True</redirectClipboard>
    		<enableTLSAuthentication>True</enableTLSAuthentication>
    		<enableNLAAuthentication>True</enableNLAAuthentication>
    		<idleTimeout>240</idleTimeout>
    		<overallTimeout>600</overallTimeout>
    		<connectionTimeout>600</connectionTimeout>
    		<shutdownTimeout>10</shutdownTimeout>
    		<tags>Desktop, Rons</tags>
    		<newWindow>False</newWindow>
    		<toolBarIcon />
    		<bitmapPeristence>RDP</bitmapPeristence>
    	</favorite>
    	<favorite id="2">
    		<protocol>RDP</protocol>
    		<port>3389</port>
    		<serverName>MySecondCompouterName</serverName>
    		<url>rdp://MySecondCompouterName:3389/</url>
    		<name>MySecondCompouterName</name>
    		<credential />
    		<domainName>foo</domainName>
    		<userName>TSMITH</userName>
    		<password>MyPassword</password>
    		<notes />
    		<desktopSize>AutoScale</desktopSize>
    		<desktopSizeHeight>600</desktopSizeHeight>
    		<desktopSizeWidth>800</desktopSizeWidth>
    		<colors>Bit16</colors>
    		<sounds>DontPlay</sounds>
    		<redirectClipboard>True</redirectClipboard>
    		<enableTLSAuthentication>True</enableTLSAuthentication>
    		<enableNLAAuthentication>True</enableNLAAuthentication>
    		<idleTimeout>240</idleTimeout>
    		<overallTimeout>600</overallTimeout>
    		<connectionTimeout>600</connectionTimeout>
    		<shutdownTimeout>10</shutdownTimeout>
    		<tags>Laptop</tags>
    		<newWindow>False</newWindow>
    		<toolBarIcon />
    		<bitmapPeristence>RDP</bitmapPeristence>
    	</favorite>
    </favorites>
    '@
    
    $node = $xml.SelectSingleNode('//favorite[@id="2"')
    $node.serverName='SERVER NAME 2'
    
    
    

    This allows you to directly select.  You can also use  names or any child element value.

    \_(ツ)_/

    Wednesday, October 7, 2015 6:42 PM
  • I am trying.

    I have always struggled so hard with XML.

    I would pay for a class on XML and PowerShell I would. 

    God I know you have given me the answer and I cant make it work. 

    This is good stuff thought thanks so much 


    Lishron

    Wednesday, October 7, 2015 7:01 PM
  • This XML file is 44000 lines I guess I have to put that in the script.


    Lishron

    Wednesday, October 7, 2015 7:02 PM
  • This XML file is 44000 lines I guess I have to put that in the script.


    Lishron

    You don't need to, you can read in the file like so:

    http://www.codeproject.com/Articles/61900/PowerShell-and-XML


    Wednesday, October 7, 2015 7:07 PM
  • [xml]$xml=Get-Content My-44000-line-file.xml

    44000 lines is not very big.  Just add it as above.

    The bigger issue is that you have no unique selector.  Without that you will have to figure out how t find things.  What is the criteria for recognizing a setting?

    Here is the school: http://www.w3schools.com/xml/default.asp


    \_(ツ)_/

    Wednesday, October 7, 2015 7:13 PM
  • [xml]$MyXMLFile = Get-Content "c:\temp\Terminals.xml"
    
    
    
    $MyXMLFile.favorites.favorite | % {
    "-----------------------Start------------------------------------"
    $servername =  $_.serverName
    $tags = $_.tags
    $serverinfo =  Get-ADComputer $servername -Properties *
    $DistinguishedName = $serverinfo.DistinguishedName
    $DistinguishedName = $DistinguishedName -replace "CN=$servername,OU=","" -replace ",.*",""
    $tags = "$tags,$DistinguishedName"
    
    
    $node = $xml.SelectSingleNode('//favorite')
    $node.tags="$tags"
    $node
    
    "-----------------------End------------------------------------"
    }
    
    $MyXMLFile.Save("c:\temp\changed.xml")
    

    closer it is now writing the correct info on the screen I just need to write back to the XML or a new XML, 


    Lishron

    Wednesday, October 7, 2015 7:19 PM
  • The script below will go through each node.  It selects the computer name and looks for the OU it is in.  It then adds that

    to the tags line.  Thanks to your guidance it now is the correct info but I cant get it to write back to the xml file.  Thank you again.

    [xml]$MyXMLFile = Get-Content "c:\temp\Terminals.xml"
    
    
    
    $MyXMLFile.favorites.favorite | % {
    "-----------------------Start------------------------------------"
    $servername =  $_.serverName
    $tags = $_.tags
    $serverinfo =  Get-ADComputer $servername -Properties *
    $DistinguishedName = $serverinfo.DistinguishedName
    $DistinguishedName = $DistinguishedName -replace "CN=$servername,OU=","" -replace ",.*",""
    $tags = "$tags,$DistinguishedName"
    
    
    $node = $xml.SelectSingleNode('//favorite')
    $node.tags="$tags"
    $node | out-File -FilePath c:\temp\proc1.xml -Append
    
    "-----------------------End------------------------------------"
    }
    
    $MyXMLFile.Save("c:\temp\changed.xml")
    
    
    
    


    Lishron

    Wednesday, October 7, 2015 7:31 PM
  • you cannot do it that way as you have already seen.

    It can only be done by direct assignment to the node.

    What are you trying to change?  Do you want every node to have the same value?  That doesn't make much sense.

    You can select any single node with SelectSingleNode .  TO select all nodes matching a criteria use SelectNodes.

    $xml.SelectNodes('//favorite')

    You also have to look at what you are doing.  You have been asking these questions for months. Variables don't just magically appear and disappear.

    I used $xml.  What did you use?


    \_(ツ)_/

    Wednesday, October 7, 2015 7:36 PM
  • The script below will go through each node.  It selects the computer name and looks for the OU it is in.  It then adds that

    to the tags line.  Thanks to your guidance it now is the correct info but I cant get it to write back to the xml file.  Thank you again.

    [xml]$MyXMLFile = Get-Content "c:\temp\Terminals.xml"
    
    
    
    $MyXMLFile.favorites.favorite | % {
    "-----------------------Start------------------------------------"
    $servername =  $_.serverName
    $tags = $_.tags
    $serverinfo =  Get-ADComputer $servername -Properties *
    $DistinguishedName = $serverinfo.DistinguishedName
    $DistinguishedName = $DistinguishedName -replace "CN=$servername,OU=","" -replace ",.*",""
    $tags = "$tags,$DistinguishedName"
    
    
    $node = $xml.SelectSingleNode('//favorite')
    $node.tags="$tags"
    $node | out-File -FilePath c:\temp\proc1.xml -Append
    
    "-----------------------End------------------------------------"
    }
    
    $MyXMLFile.Save("c:\temp\changed.xml")
    
    
    


    Lishron

    Are you trying to say you are copying the value of ne element of a selected node t another element called "tags"?


    \_(ツ)_/

    Wednesday, October 7, 2015 7:38 PM
  • Is this what you are trying to do?

    [xml]$xml=@'
    <?xml version="1.0" encoding="utf-8"?>
    <favorites>
    	<favorite>
    		<protocol>RDP</protocol>
    		<port>3389</port>
    		<serverName>my-computer-name</serverName>
    		<url>rdp://my-computer-name:3389/</url>
    		<name>my-computer-name</name>
    		<credential />
    		<domainName>foo</domainName>
    		<userName>TSMITH</userName>
    		<password>MyPassword</password>
    		<notes />
    		<desktopSize>AutoScale</desktopSize>
    		<desktopSizeHeight>600</desktopSizeHeight>
    		<desktopSizeWidth>800</desktopSizeWidth>
    		<colors>Bit16</colors>
    		<sounds>DontPlay</sounds>
    		<redirectClipboard>True</redirectClipboard>
    		<enableTLSAuthentication>True</enableTLSAuthentication>
    		<enableNLAAuthentication>True</enableNLAAuthentication>
    		<idleTimeout>240</idleTimeout>
    		<overallTimeout>600</overallTimeout>
    		<connectionTimeout>600</connectionTimeout>
    		<shutdownTimeout>10</shutdownTimeout>
    		<tags>Desktop, Rons</tags>
    		<newWindow>False</newWindow>
    		<toolBarIcon />
    		<bitmapPeristence>RDP</bitmapPeristence>
    	</favorite>
    	<favorite>
    		<protocol>RDP</protocol>
    		<port>3389</port>
    		<serverName>MySecondCompouterName</serverName>
    		<url>rdp://MySecondCompouterName:3389/</url>
    		<name>MySecondCompouterName</name>
    		<credential />
    		<domainName>foo</domainName>
    		<userName>TSMITH</userName>
    		<password>MyPassword</password>
    		<notes />
    		<desktopSize>AutoScale</desktopSize>
    		<desktopSizeHeight>600</desktopSizeHeight>
    		<desktopSizeWidth>800</desktopSizeWidth>
    		<colors>Bit16</colors>
    		<sounds>DontPlay</sounds>
    		<redirectClipboard>True</redirectClipboard>
    		<enableTLSAuthentication>True</enableTLSAuthentication>
    		<enableNLAAuthentication>True</enableNLAAuthentication>
    		<idleTimeout>240</idleTimeout>
    		<overallTimeout>600</overallTimeout>
    		<connectionTimeout>600</connectionTimeout>
    		<shutdownTimeout>10</shutdownTimeout>
    		<tags>Laptop</tags>
    		<newWindow>False</newWindow>
    		<toolBarIcon />
    		<bitmapPeristence>RDP</bitmapPeristence>
    	</favorite>
    </favorites>
    '@
    
    $xml.SelectNodes('//favorite') |
    ForEach-Object{
           $serverinfo = Get-ADComputer $_.ServerName
    	$DistinguishedName = $serverinfo.DistinguishedName -replace "CN=$($_.ServerName),OU=", "" -replace ",.*", ""
    	$_.tags+=$DistinguishedName
    }
    $xml.Save("c:\temp\changed.xml")
    
    


    \_(ツ)_/



    • Edited by jrv Wednesday, October 7, 2015 7:45 PM
    • Marked as answer by Lishron Thursday, October 8, 2015 11:16 AM
    Wednesday, October 7, 2015 7:44 PM
  • Thank you so very much.

    That was absolutely what I was trying to do.

    I have learned more about XML in this on exercise then well wow.

    Thank you again

    MY / Your completed code

    if (test-path c:\temp\changed.xml) {remove-item -force "c:\temp\changed.xml"}
    
    
    [xml]$xml = Get-Content "c:\temp\Terminals.xml"
    
    
    $xml.SelectNodes('//favorite') |
    ForEach-Object{
           $serverinfo = Get-ADComputer $_.ServerName
        
    	$DistinguishedName = $serverinfo.DistinguishedName -replace "CN=$($_.ServerName),OU=", "" -replace ",.*", ""
    	$_.tags+=",$DistinguishedName"
         $_.tag
    }
    $xml.Save("c:\temp\changed.xml")
    


    Lishron

    Thursday, October 8, 2015 11:19 AM