Working on XML files with PowerShell

Some programs use XML files to export their settings.
These can be imported again after a reinstallation of the application.

In some cases it is needed to adjust the XML files before importing them again.

For example Forticlient uses XML files to export/import the settings again after Uninstall/Install.
In recent versions 5.4.1 -> 5.4.4 there is a bug that asks for smart-cards if you have EID/smartcard certificates on the computer.

This could be resolved if you change some values in the XML.
I will not cover the needed values, only the process that is needed to modify XML files with PowerShell.

If you only have to manage a few computers it is no problem to do this manually.
This becomes a real pain in the ass when you need to roll out the new version on more machines.

The PowerShell scripts are already set to install Forticlient in my case, so best approach is to do this in PowerShell.

So let us start.
We need to put the script in the same location as the exported XML file.
When this is done we can change the directory in the script to the directory where the script is running from.

CD $PSScriptRoot

Next step is to create a backup folder in the same location.

New-Item -Name BackupXML -ItemType directory > $null

Then we will move the xml file to the backup folder.

Move-Item -Path .\*.xml -Destination .\BackupXML > $null

After creating the backup directory and moving the file, we can now use this location in the script.
By setting the variable and pointing it to the XML in the created directory.

$filePathToTask = $PSScriptRoot + “\BackupXML\settings.xml”

The next variable to be set is an XML object.

$xml = New-Object XML

When the variable is set we can load it up with the XML file.
This is done with the XML file variable

$xml.Load($filePathToTask)

Now you can load the nodes into a variable and set the value for that Node.
The value between the quotes (InnerText) is the value that will be set in this case My Name Jeff .

$element = $xml.SelectSingleNode(“//vpn//options//usesmcardcert”)
$element.InnerText = “My Name Jeff”

Loading in Nodes can somehow be difficult.
As i stumbled into some issues.

if you have the same value but under another main or sub nodes it is only adjusting the first node it encounters.
The following nodes on the path of the script will be skipped.

The most explanations that i found online were directing at one node :

“//show_auth_cert_only”

If you need to adjust a specific node, and don’t know if there are doubles, it is important to give the directions to that exact node.

“//Main//sub//sub//sub//actual node”

The XML file can be saved after loading and setting all values to the needed nodes .

$xml.Save(“settings.xml”)

 

Once everything is in place the script or the part that you added to an existing install script would look like this:

CD $PSScriptRoot
New-Item -Name BackupXML -ItemType directory > $null
Move-Item -Path .\*.xml -Destination .\BackupXML > $null

$filePathToTask = $PSScriptRoot + “\BackupXML\settings.xml”
$xml = New-Object XML

$xml.Load($filePathToTask)
$element = $xml.SelectSingleNode(“//vpn//options//usesmcardcert”)
$element.InnerText = “My Name Jeff”
$element = $xml.SelectSingleNode(“//vpn//options//show_auth_cert_only”)
$element.InnerText = “My Name Jeff”
$element = $xml.SelectSingleNode(“//vpn//sslvpn//connections//connection//prompt_certificate”)
$element.InnerText = “My Name Jeff”
$element = $xml.SelectSingleNode(“//vpn//ipsecvpn//options//usewincert”)
$element.InnerText = “My Name Jeff”
$element = $xml.SelectSingleNode(“//vpn//ipsecvpn//options//use_win_current_user_cert”)
$element.InnerText = “My Name Jeff”
$element = $xml.SelectSingleNode(“//vpn//ipsecvpn//options//use_win_local_computer_cert”)
$element.InnerText = “My Name Jeff”
$element = $xml.SelectSingleNode(“//vpn//ipsecvpn//options//uselocalcert”)
$element.InnerText = “My Name Jeff”
$element = $xml.SelectSingleNode(“//vpn//ipsecvpn//options//check_for_cert_private_key”)
$element.InnerText = “My Name Jeff”
$element = $xml.SelectSingleNode(“//vpn//ipsecvpn//options//usesmcardcert”)
$element.InnerText = “My Name Jeff”

$xml.Save(“settings.xml”)

In case you are using this to do some tinkering with the installation, and run the install a few times.
It is advised that the XML is removed before exporting it again.
Otherwise it can go wrong if you don’t 😉

For the ones that don’t know the scene from 22 Jump Street