7

I have an XML doccument that looks like this:

<Task>
    <Settings>
    </Settings>
    <Sub>foo</Sub>
    <Body>bar</Body>
</Task>

From PowerShell I can happily get the contents of 'Sub' and 'Body' using:

$Body = $XMLFile.Task.Body

But I am trying to REMOVE the 'Sub' and 'Body' Tags completely so the XML would be:

<Task>
    <Settings>
    </Settings>
</Task>

I have already Tried many things, Including:

  • Using the .RemoveChild() method (Threw an exeption relating to Object reference)
  • Removing with an XPath Statement and adding a Pipe to remove in one line
  • Even opening the file as a text file and trying:

    Get-Content $_.FullName -notmatch "<Sub>" | out-file $_.FullName

^^ This does nothing at all

Also for this application of script I would be unable to use any third party modules

1 Answer 1

12

You can use Where-Object to find the Child nodes you want to remove and then call RemoveChild():

$Input = "C:\path\task.xml"
$Output = "C:\path\newtask.xml"

# Load the existing document
$Doc = [xml](Get-Content $Input)

# Specify tag names to delete and then find them
$DeleteNames = "Sub","Body"
($Doc.Task.ChildNodes |Where-Object { $DeleteNames -contains $_.Name }) | ForEach-Object {
    # Remove each node from its parent
    [void]$_.ParentNode.RemoveChild($_)
}

# Save the modified document
$Doc.Save($Output)
Sign up to request clarification or add additional context in comments.

5 Comments

In general I think it's better to use $_.ParentNode.RemoveChild($_), so the code inside the loop doesn't need to know the absolute path of the node being removed. However, for that to work the selection must be completed before removing any node, e.g. by running it in an expression: ($Doc.Task.ChildNodes | Where-Object {...}) | ...
Addendum: I think the same applies to your code. Running it as-is removed only the Sub child node, not the Body child node. Tested on PowerShell v4.
@AnsgarWiechers nice catch, I just reproduced the same behavior on v4, updating answer
How can this run in "Constrained Language Mode"?
Usually you'd configure CLM via an application control policy (eg. by enabling AppLocker or SRP) or as part of a remote endpoint configuration. In all three cases, you can allow specific modules or scripts to load. For AppLocker/SRP: update policy rules; for a constrained remoting endpoint: add a script or module containing the above code to the session configuration file

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.