Windows PowerShell: Sometimes, Text Is Best
You don’t have to overthink the problem when you can use Windows PowerShell to get things done quickly and easily.
After a year of taking your Windows PowerShell questions, it seemed like a good idea to review some of the earliest questions. This one from those early days really highlights some of the ways Windows PowerShell helps you get stuff done. It also shows how it can pay to not overthink the problem.
To paraphrase the question, this reader had an XML file that included a comment:
<!-- <tag attribute="value">Data</tag> -->
As you can see, the comment tags (the “<!--” and the “-->”) enclose an XML tag. His goal was to un-comment that, so the resulting XML would have the tag “active” rather than “commented out.” He started by using Get-Content to read in the file, but cast the result as a Windows PowerShell XML data type:
[xml]$file = Get-Content myfile.xml
What some folks don’t understand about this trick is that it forces Windows PowerShell, via the Microsoft .NET Framework, to parse the XML file and construct an object hierarchy representing the XML file’s contents. It’s not all that different from using Import-CliXML, although this particular trick will read any valid, well-formed XML file. Import-CliXML is intended to read the specific XML format created by Export-CliXML.
Anyway, the problem with treating the file’s contents as XML is that XML can be a pain in the neck to work with. In order to locate a comment and un-comment it, you actually have to do quite a bit of coding. And this is code I’m not at all personally familiar with.
The Pragmatic Approach
Let me step back for a moment and offer a bit of philosophical advice. While I’ve done software development in the past, I’ve never been a professional, trained developer. At heart, I’ve always been an admin. One of my first IT jobs was as an AS/400 sysop. Admins, I find, are pragmatic creatures. “See the problem, fix the problem and then go home for the day,” is how I often describe the general admin attitude.
Developers, on the other hand, have an ingrained desire to do what’s “right.” They might produce some ugly-looking code while they’re prototyping and figuring out how something works, but they almost always go back and rewrite or tweak it to be “right.” So a developer, faced with the need to modify the XML as I’ve described, would probably spend as long as it takes to figure out the “right” way to accomplish the task. That would probably involve manipulating the XML via magical .NET Framework XML black-box stuff.
That’s not my approach. I just don’t have that kind of time. What I do have is a way to get the task done regardless. My suggestion was to stop treating the file as XML. After all, we don’t really need to mess with any of the data in the file, so why make Windows PowerShell parse it all out of the XML format? We just need to do a little simple modification of the raw text:
$text = Get-Content myfile.xml $text = $text –replace '<!--','' $text = $text –replace '-->','' $text | Out-File newfile.xml
The reader wanted every XML comment removed, and that’s what my solution does. It simply looks for every instance of the comment tag characters and replaces them with an empty string. This effectively removes the comment and makes the enclosed XML tag “active” for whatever process was actually reading and using that XML file.
So my solution was to disregard the fact that the file was XML. I didn’t need to do anything “XML-ish.” I just needed to remove a few characters. By treating it as plain text (notice that I didn’t cast it to [xml] when getting the content), I could use the perfectly capable Windows PowerShell text-manipulation operators to accomplish the task.
This philosophy of mine sometimes ticks people off. Sometimes people will ask, “How can you modify file and folder permissions in Windows PowerShell?” I’ll shrug and say, “XCacls.” It runs in Windows PowerShell, I know how to use it and it gets the job done.
The alternatives—Get-ACL and Set-ACL—are overly complicated. They require deeper knowledge of a lot of .NET Framework stuff that, frankly, I’m not interested in learning right now. Why bother when there’s already a perfectly good way of getting the job done?
Obviously, my philosophy is one shared by the Windows PowerShell team. Why else did they work so hard to make sure that external executables like XCacls, Ipconfig, Ping and the like all work from inside Windows PowerShell? They knew that we already know how to use those tools, and making them work inside Windows PowerShell gives us a head start in getting our jobs done.
Nobody’s learning Windows PowerShell “just because.” We learn it because it makes our jobs easier. That only happens, though, if it still lets us use the tools we already know. You’re welcome to disagree with my approach to “see the problem, fix the problem and go home.” Lots of people do. However, I find it’s a practical approach when you’ve just got a job to do, and you don’t care how pretty or ugly the solution is as long as the job gets done.
Don Jones is a Microsoft MVP Award recipient and author of “Learn Windows PowerShell in a Month of Lunches” (Manning Publications, 2011), a book designed to help any administrator become effective with Windows PowerShell. Jones also offers public and on-site Windows PowerShell training. Contact him through ConcentratedTech.com or bit.ly/AskDon.