Copy, unzip and rename files

by richlionel at 2012-08-25 09:10:13

Hi Everyone

My first post on this forum :slight_smile:

I have a solution I am trying to figure out. THis is the situation :

We have five applications servers (, etc). Within each server, there is an application log folder located in D:\Applications\MyApplication1\logs.

There are various types of zipped log files:, etc are those from MyApp,, and so on are from apps I am not interested in.

I have a central reporting server (Report1) running Powershell v2. From Report1, I’d like to:

a) Pull the last 7 days of MyApp-XXX.log files from each application server into a folder on the D: drive that is named after each server
b) Unzip them
c) Rename each file to MyApp1.log, MyApp2.log and so on.

Is this possible?
by willsteele at 2012-08-25 09:30:15
richlionel, this can certainly be done. I have a few questions:

1) are you using a zip/unzip program? Or, are you trying to do this purely with Windows?
2) When the files unzip, where do you want to store the contents? Also, is it possible when you unzip them there will be potential naming conflicts?
3) lastly, how often do you plan to run this script? If you grab some of the zips from the same 7 day period, it seems you will have dupliclate .zips after the renaming process. Am I understanding the process correctly?
by richlionel at 2012-08-25 09:38:49
Hey Will
Thanks for responding…here are the answers to the questions:

1) If possible, can we do using Windows? Or alternatively, we have WinRAR installed on the machine
2) On the reporting server, within the D: drive, there is already a folder named Server1, Server2, Server3 etc. I would like the files from each server to go into the corresponding folder please. There will be no naming conflicts
3) I should have mentioned, we will run this every week :slight_smile:

One extra thing - the location of the files on the application servers themselves (at the moment, D:\Applications\MyApplication1\logs for most). Can we hardcode this into the script per server? Because we will be bringing more servers online, and some only have C: drives, and I would like to expand this script for them too.

Thanks again!
by poshoholic at 2012-08-28 18:44:17
Here’s a high-level overview of how you might break this down into chunks. They would have to be combined together for the larger script. Note, these are untested. I’m sharing them to give you a solid nudge in the right direction.

1. Store the list of servers you want to process in an array.
$servers = @(‘’,‘’,…,‘’)
As an alternative here you could put each server name on a separate line in a text file and read it in with this command:
$servers = Get-Content -Path C]
2. Get the application logs that are 7 days old or less from a single server:
$path = “\$server\d`$\Applications\MyApplication1\logs”
$now = Get-Date
$recentLogs = Get-ChildItem -LiteralPath $path | Where-Object {$.LastWriteTime -gt $now.AddDays(-7)}

3. Copy the recent log files to a local directory that matches the server name.
$localPath = “D:$server”
$recentLogs | Copy-Item -Destination $localPath

4. Identify any zip files that were copied over and unzip them.

There’s a script over here that shows how to unzip files.

5. Rename the application log files.

Use Get-ChildItem with .log in the -Filter parameter to get the log files and keep an index to track the index of the file you’re using as the next name to use. Use Test-Path to verify the file does not exist first. If it does, increment the index and try again.

This does not include packaging it up with a foreach loop to run against each server. It does not handle some servers having D drives and others having C drives. It is not tested. But it gives you a few of the principles to help start you on your way to putting this together.
by richlionel at 2012-09-23 11:40:10
Thanks that is really helpful!

I am stuck on #5 though, I’m quite new to Powershell and I’ve been playing around but not sure of the best way to do this?

Thanks again for any help.
by poshoholic at 2012-09-23 18:51:49
For the fifth item, that can be a little tricky. It would probably look something like this:
# Get the current count of MyApp
.log files in the $localPath folder (where * is a numeric value)
$myAppLogIndex = @(Get-ChildItem -LiteralPath $localPath -Filter MyApp*.log | Where-Object {$
.Name -match ‘^MyApp\d+.log$’}).Count
# Get the *.log files that are in the local folder and that don’t have a name in the format “MyApp1.log”, “MyApp2.log”, etc.
Get-ChildItem -LiteralPath $localPath -Filter *.log | Where-Object {($.Extension -eq ‘.log’ )-and ($.Name -notmatch ‘^MyApp\d+.log$’)} | ForEach-Object {
# Identify the new name for the file, testing to make sure it does not exist first (if it exists, increment our index and try the next one)
do {
$newName = “MyApp${myAppLogIndex}.log”
} while (Join-Path -Path $localPath -ChildPath $newName | Test-Path)
# Rename the file
$_ | Rename-Item -NewName $newName

This is mostly untested, but I did a few simple tests and it looks like it should work. Give that a try and see how you make out.