We've talked about how to use the file system provider cmdlets to selectively delete files and folders and edit their content. This time, we'll continue to explore Windows PowerShell scripting by looking at another application for the file system provider's new-item cmdlet: archiving data.
As an administrator, there are several times when you will save log data, but to keep storage needs down, the system does not keep all logs (NTBackup logging is one that comes to mind). Consultants, however, may need that log data to demonstrate to their clients that the backups were successful. What you need is a way to copy the log files to a safe location so that you have them when you need them. At the same time, you don't want them cluttering up the log file directory, and neither do you want them to be overwritten when NTBackup thinks they've been there long enough and it wants to write new log files.
Preparing to time-stamp new folders
The first step is to create new folders with a distinctive name. One way to distinguish data among everything that's been saved is to include the current date in the name of the folder. That way, even if you edit the contents later you will always be able to easily determine when you originally archived the data. Windows PowerShell makes it easy to include a date in a folder name.
You first need to programmatically get the current date so you won't have to update the script each time you want to archive data. To do this, you'll use the get-date cmdlet and assign its contents to the variable $date. Note that you can name this variable almost anything you want to, but I find it easier to name variables after their contents. Get-date retrieves the current date and time in long form, like this:
Saturday, January 19, 2008 4:05:33 PM
That's kind of long to be part of a folder name, though. If the only date information you need is the current month, day and time, then you can restrict get-date with the –format parameter like this: get-date –format d. This format strips out the excess data so the output looks like this:
To set the value of $date to this shortened format, make the assignment like so:
$date=get-date –format d
Now before you go any further, look at that formatting. The default date formatting uses forward slashes, which, of course, to a cmdlet creating a new folder, look like an invitation to create a subfolder. If you don't tweak that date format slightly, you'll get a somewhat unexpected result: one folder called "archived on 1/" and a subfolder to that folder called "19." Therefore, you'll want to clean up $date before plugging it into this script by replacing its slashes with dashes that won't confuse the file system provider. There's a way to programmatically change the default date separator, but it's kind of a pain and not really necessary. You can get the same effect with the –replace parameter when creating $date, like this:
$date=get-date –format –d | $date=$date -replace "/", "-"
The output of $date (you can check it with write-host $date) is now 1-19-2008 and the folder name will use this date formatting.
Create new folders
You are now ready to create the new folder labeled with the date using the new-item cmdlet. New-item works for any kind of provider object. For example, If you're using the registry provider, it will create a new registry key. When working with the file system provider, it will create new files (by default) or new folders if you specify that you want a folder. To make the new folder, you'll need the path for where you want to store it, the name you want to call it and the type of item -- in this case, a directory.
When naming the new item, you can use a string, variables, or some combination of the above. We could just name our new folder with the date we've already stored, but a little helper text might be nice for the sake of your successor. When you've gone on to bigger and better things and they're trying to figure out what these files are for and the significance of the date, they will be glad you did this. Concatenating text and variables with Windows PowerShell is easier than with VBScript. With VBScript, you have to use concatenation operators and commas and quotes and all the rest of it, and it's pretty easy to miss a comma and have to start over. With PowerShell, you just put the string-variable combination within double quotes. PowerShell will dump the value of the variable rather than its name.
If for any reason you want to show the variable, all you have to do is enclose the string and variable in single quotes. To see the difference:
Write-host "Today is $date." will output
Today is 1/19/08.
Write-host 'Today is $date.' will output
Today is $date.
One way to name the new folder is to use double quotes.
new-item -path c:scripts -name "archived on $date" -type directory
Even easier, in case we need to reference that path later, we could make the name of the new directory a variable itself. That can be simpler to reference.
$destpath = "archived on $date"
Copying files from their original location to the new folder
Now that you've got the folder in place, you can archive the files in their new location, either by moving them with the move-item cmdlet or by copying them to their new home (if you still need the files in their original location) with copy-item.
We've named the new folder with the information we wanted to use, so the final command is pretty simple:
move-item -path c:logfiles*.log -destination c:old$destpath
The entire script looks like this:
$date=get-date –format d
$date=$date -replace "/", "-"
$destpath = "archived on $date"
$storage=new-item -path c:old -name $destpath -type directory
move-item -path c:logs*.log -destination $storage
Save this as a .ps1 file as described in my previous column on how to save and run scripts with Windows PowerShell, and you can reuse it every time you want to archive data. You now know how to use variables to store pertinent data and combine it with file-system provider cmdlets to make it part of your archiving system. I'll expand on this example in future columns.
Miss a column? Check out the Scripting School archive.
|ABOUT THE AUTHOR:|
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.