We took a break last month to talk about the new features in the next version of Windows PowerShell, now available for technology preview. This month we get back to hands-on applications you can use to find content in a file, edit a file, create a file or even replace the contents of a file. Note that although I'm discussing these cmdlets in the context of files, they work with other object types as well.
Get-item, introduced in a previous column, doesn't return the contents of the item you're getting, just the object (file, registry key, etc.) itself. To get the actual content and work with it, you'll need the related get-content cmdlet. At its simplest, you feed get-content the path of the file whose contents you want to retrieve, like this:
Get-content –path c:scriptslogfile.txt
This command will output the contents of this file to the PowerShell window one line at a time. What if you want to retrieve only part of a large file? To do that, you must add the –totalcount parameter to get-content. When returning content, be careful about what you do with it. Get-content is really intended to pipe content to a storage location for further evaluation. If you don't provide an alternative location for it, then it will pipe the output to the PowerShell window. You really do not want to send the entire contents of a 2 MB log file to the PowerShell window. Instead, you should assign this content to a variable or use it in combination with another cmdlet, such as add-content.
Adding content to existing files
Say you've got a whole bunch of Web pages that you need to add some specialized content to, but have no tools to do it with. Well, fortunately, you have PowerShell. We'll use it here to add a legal disclaimer to the bottom of all Web pages in a folder, using the add-content cmdlet.
One way to use add-content is to put the content you want to add in the command itself, like this command to add a line to all Web pages in the named folder. Because HTML tags are text-based, you can even get a little fancy and add some formatting. Since add-content always places the content you supply at the end of the document right where any existing text leaves off, I've added a paragraph break before my text to create some separation.
add-content c:scripts*.htm "<p><i>some additional text</i>"
As you can see, it's not too arduous to add a little HTML tagging to the string you supply to add-content, but there are upper limits on how much you want to include. For more consistent results with complex formatting or long text, it's better to store the contents of the text you want to add in a file, retrieve the contents of that file with get-content, then pipe them to the appropriate documents. Assuming that the formatted text is stored in legal.txt and you want to apply it to all Web pages in c:scripts, the command would look like this:
get-content c:scriptslegal.txt | add-content -path c:scripts*.htm
So what's the catch to all this? Well, like get-content, add-content doesn't work when the document includes formatting. However, unlike get-content, with add-content the consequences can be destructive. Do not use add-content to add content to files you want to keep without checking the results first. Add-content works fine for text-based files, including Web pages and log files, but it doesn't work for Office 2007 files (for example) and can have some serious repercussions.
At a minimum, after you've made the edit, you will get an error message telling you there is unreadable content in the file and asking if you want to recover. If you recover, your changes will be discarded and you will no longer be able to save changes to that file name -- it would act as though it's read-only. At worst, you would no longer be able to open the file at all. Text files are fine, but anything else is unlikely to work.
Creating new files
So far, you've seen how to get a file's content and append additional content to an existing file. How about creating a new file? We've been using the –content cmdlets, but since we're starting from scratch, we'll need to build a new item.
One method of creating a new file is to type its starting value from the command line, like this command that creates newfile.txt and populates it with the string passed to the –value parameter. The –itemtype parameter tells PowerShell what kind of file to create. If you don't include it, PowerShell will prompt you for the object type:
new-item -path c:scriptsnewfile.txt -value "this file was created on 12/3." -itemtype file
When you type this, you'll get a report back from PowerShell with the size of the file, write date and name. You can't overwrite an existing file with new-item; if an object of the selected type with that name already exists, then the cmdlet will return an error. To overwrite an existing file, use set-content.
Replacing file content
To replace the content of an existing file, you'll use set-content. It works in much the same way as the other cmdlets we've looked at so far this month, meaning that you provide the path to the file or files you want to edit, then the text you want to include, whether piped from another cmdlet or typed into the command line. Execute the script, and the file(s) you selected will now contain the text you supplied.
set-content c:scripts*.htm "holy new text, batman!"
That, of course, is the catch. Set-content is inherently destructive because it replaces text. The file isn't deleted (and it wouldn't matter if it was, since a file deleted with remove-item doesn't go to the Recycle Bin), it's just overwritten. Particularly, if you're using wildcards to select files, always use set-content in combination with –whatif so you can be sure of the results of your actions. Remember, set-content affects not only files; it affects any kind of item.
This month, we've seen how to use Windows PowerShell to programmatically get content and set content of text files, including logs and Web pages. Next time, we'll look at some other ways you can apply this information by searching content you've retrieved with get-content.
Miss a column? Check out the Scripting School archive.
ABOUT THE AUTHOR: Christa Anderson
A Terminal Services MVP, Christa Anderson is a program manager on the Terminal Services team at Microsoft. She is an internationally known authority on scripting, the author of Windows Terminal Services, The Definitive Guide to MetaFrame XP, and co-author of the book Mastering Windows 2003 Server. If you have a scripting question for Christa, please email her at editor@SearchWincomputing.com. She often uses these emails as fodder for her scripting columns.