Combine multiple log files to archive using PoSh and 7zip












0














I am trying to join multiple log files into a single archive file, then move that archive file to another location, in an effort to both clean up old log files, and save hard drive space. We have a bunch of tools that all log to the same root, with a per-tool folder for their logs. (E.g.,




  1. C:ServerLogs

  2. C:ServerLogsApp1

  3. C:ServerLogs2ndApp


each of which will have log files inside, like




  1. C:ServerLogsApp1June1.log

  2. C:ServerLogsApp1June2.log

  3. C:ServerLogs2ndAppJune1.log

  4. C:ServerLogs2ndAppJune2.log


I want to go into each of these subfolders, archive up all the files older than 5 days, then move the archive to another (long-term storage) drive and delete the now-zipped files. The tools I'm using are PowerShell and 7zip. The below code is using test locations.



I have cobbled together two scripts from various sources online, over the course of two full shifts, but neither one works right. Here's the first:



# Alias for 7-zip 
if (-not (test-path "$env:ProgramFiles7-Zip7z.exe")) {throw "$env:ProgramFiles7-Zip7z.exe needed"}
set-alias 7zip "$env:ProgramFiles7-Zip7z.exe"
$Days = 5 #minimum age of files to archive; in other words, newer than this many days ago are ignored
$SourcePath = C:WorkingFolderFolderSource
$DestinationPath = C:Temp
$LogsToArchive = Get-ChildItem -Recurse -Path $SourcePath | Where-Object {$_.lastwritetime -le (get-date).addDays(-$Days)}
$archive = $DestinationPath + $now + ".7z"

#endregion

foreach ($log in $LogsToArchive) {
#define Args
$Args = a -mx9 $archive $log
$Command = 7zip
#write-verbose $command

#invoke the command
invoke-expression -command $Command $Args


The problem with this one is that I get errors trying to invoke the expression. I've tried restructuring it, but then I get errors because my $Args have an "a"



So I abandoned this method (despite it being my preferred), and tried this set.



#region Params
param(
[Parameter(Position=0, Mandatory=$true)]
[ValidateScript({Test-Path -Path $_ -PathType 'container'})]
[System.String]
$SourceDirectory,
[Parameter(Position=1, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[System.String]
$DestinationDirectory
)
#endregion

function Compress-File{
#region Params
param(
[Parameter(Position=0, Mandatory=$true)]
[ValidateScript({Test-Path -Path $_ -PathType 'leaf'})]
[System.String]
$InputFile,
[Parameter(Position=1, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[System.String]
$OutputFile
)
#endregion

try{
#Creating buffer with size 50MB
$bytesGZipFileBuffer = New-Object -TypeName byte(52428800)

$streamGZipFileInput = New-Object -TypeName System.IO.FileStream($InputFile,[System.IO.FileMode]::Open,[System.IO.FileAccess]::Read)
$streamGZipFileOutput = New-Object -TypeName System.IO.FileStream($OutputFile,[System.IO.FileMode]::Create,[System.IO.FileAccess]::Write)
$streamGZipFileArchive = New-Object -TypeName System.IO.Compression.GZipStream($streamGZipFileOutput,[System.IO.Compression.CompressionMode]::Compress)

for($iBytes = $streamGZipFileInput.Read($bytesGZipFileBuffer, 0,$bytesGZipFileBuffer.Count);
$iBytes -gt 0;
$iBytes = $streamGZipFileInput.Read($bytesGZipFileBuffer, 0,$bytesGZipFileBuffer.Count)){

$streamGZipFileArchive.Write($bytesGZipFileBuffer,0,$iBytes)
}

$streamGZipFileArchive.Dispose()
$streamGZipFileInput.Close()
$streamGZipFileOutput.Close()

Get-Item $OutputFile
}
catch { throw $_ }
}


Get-ChildItem -Path $SourceDirectory -Recurse -Exclude "*.7z"|ForEach-Object{
if($($_.Attributes -band [System.IO.FileAttributes]::Directory) -ne [System.IO.FileAttributes]::Directory){
#Current file
$curFile = $_

#Check the file wasn't modified recently
if($curFile.LastWriteTime.Date -le (get-date).adddays(-5)){

$containedDir=$curFile.Directory.FullName.Replace($SourceDirectory,$DestinationDirectory)

#if target directory doesn't exist - create
if($(Test-Path -Path "$containedDir") -eq $false){
New-Item -Path "$containedDir" -ItemType directory
}

Write-Host $("Archiving " + $curFile.FullName)
Compress-File -InputFile $curFile.FullName -OutputFile $("$containedDir" + $curFile.Name + ".7z")
Remove-Item -Path $curFile.FullName
}
}
}


This actually seems to work, insofar as it creates individual archives for each eligible log, but I need to "bundle" up the logs into one mega-archive, and I can't seem to figure out how to recurse (to get sub-level items) and do a foreach (to confirm age) without having that foreach produce individual archives.



I haven't even gotten into the Move and Delete phase, because I can't seem to get the archiving stage to work properly, but I certainly don't mind grinding away at that once this gets figured out (I've already spent two full days trying to figure this one!).



I greatly appreciate any and all suggestions! If I've not explained something, or been a bit unclear, please let me know!



EDIT1: Part of the requirement, which I completely forgot to mention, is that I need to keep the structure in the new location. So the new location will have




  1. C:ServerLogs --> C:Archive

  2. C:ServerLogsApp1 --> C:ArchiveApp1

  3. C:ServerLogs2ndApp --> C:Archive2ndApp


  4. C:Archive


  5. C:ArchiveApp1archivedlogs.zip

  6. C:Archive2ndApparchivedlogs.zip

    And I have absolutely no idea how to specify that the logs from App1 need to go to App1.


EDIT2: For this latter part, I used Robocopy - It maintains the folder structure, and if you feed it ".zip" as an argument, it'll only do the .zip files.










share|improve this question
























  • i think this line $Args = a -mx9 $archive $log needs to have the value wrapped in double quotes OR each non-variable wrapped in quotes with a comma between each so that you get an array of args. ///// also, why not use the built in commands? see Get-Command *archive* for the list.
    – Lee_Dailey
    Nov 6 at 15:00










  • You can use call operator instead of invoke-expression: foreach ($log in $LogsToArchive) { & 7zip a -mx9 $archive $log }
    – James C.
    Nov 6 at 15:18












  • @JamesC. I tried that, and I got (for each eligible log file) a "Warning: The system cannot find the file specified" and (oddly!) an empty archive in the target destination. Which, on balance, is progress of a sort!
    – RSchreib
    Nov 6 at 15:44










  • @Lee_Dailey I'll have a bit of playtime with quotes on the arguments, but as for using 7zip, that was dictated by higher-ups, so I'm stuck with it (I think it was a question of performance, maybe?). But I'll try to fiddle with it and see if I can't get "Compresss-Archive" to accept multiple files into one archive.
    – RSchreib
    Nov 6 at 15:46










  • @RSchreib - you may have to move the files into one dir to get them into one archive without lots of fiddling. as for the builtin archive cmdlets ... they are always there in ps4+ [or maybe 3], so it's a more predictable thing to use.
    – Lee_Dailey
    Nov 6 at 16:01
















0














I am trying to join multiple log files into a single archive file, then move that archive file to another location, in an effort to both clean up old log files, and save hard drive space. We have a bunch of tools that all log to the same root, with a per-tool folder for their logs. (E.g.,




  1. C:ServerLogs

  2. C:ServerLogsApp1

  3. C:ServerLogs2ndApp


each of which will have log files inside, like




  1. C:ServerLogsApp1June1.log

  2. C:ServerLogsApp1June2.log

  3. C:ServerLogs2ndAppJune1.log

  4. C:ServerLogs2ndAppJune2.log


I want to go into each of these subfolders, archive up all the files older than 5 days, then move the archive to another (long-term storage) drive and delete the now-zipped files. The tools I'm using are PowerShell and 7zip. The below code is using test locations.



I have cobbled together two scripts from various sources online, over the course of two full shifts, but neither one works right. Here's the first:



# Alias for 7-zip 
if (-not (test-path "$env:ProgramFiles7-Zip7z.exe")) {throw "$env:ProgramFiles7-Zip7z.exe needed"}
set-alias 7zip "$env:ProgramFiles7-Zip7z.exe"
$Days = 5 #minimum age of files to archive; in other words, newer than this many days ago are ignored
$SourcePath = C:WorkingFolderFolderSource
$DestinationPath = C:Temp
$LogsToArchive = Get-ChildItem -Recurse -Path $SourcePath | Where-Object {$_.lastwritetime -le (get-date).addDays(-$Days)}
$archive = $DestinationPath + $now + ".7z"

#endregion

foreach ($log in $LogsToArchive) {
#define Args
$Args = a -mx9 $archive $log
$Command = 7zip
#write-verbose $command

#invoke the command
invoke-expression -command $Command $Args


The problem with this one is that I get errors trying to invoke the expression. I've tried restructuring it, but then I get errors because my $Args have an "a"



So I abandoned this method (despite it being my preferred), and tried this set.



#region Params
param(
[Parameter(Position=0, Mandatory=$true)]
[ValidateScript({Test-Path -Path $_ -PathType 'container'})]
[System.String]
$SourceDirectory,
[Parameter(Position=1, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[System.String]
$DestinationDirectory
)
#endregion

function Compress-File{
#region Params
param(
[Parameter(Position=0, Mandatory=$true)]
[ValidateScript({Test-Path -Path $_ -PathType 'leaf'})]
[System.String]
$InputFile,
[Parameter(Position=1, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[System.String]
$OutputFile
)
#endregion

try{
#Creating buffer with size 50MB
$bytesGZipFileBuffer = New-Object -TypeName byte(52428800)

$streamGZipFileInput = New-Object -TypeName System.IO.FileStream($InputFile,[System.IO.FileMode]::Open,[System.IO.FileAccess]::Read)
$streamGZipFileOutput = New-Object -TypeName System.IO.FileStream($OutputFile,[System.IO.FileMode]::Create,[System.IO.FileAccess]::Write)
$streamGZipFileArchive = New-Object -TypeName System.IO.Compression.GZipStream($streamGZipFileOutput,[System.IO.Compression.CompressionMode]::Compress)

for($iBytes = $streamGZipFileInput.Read($bytesGZipFileBuffer, 0,$bytesGZipFileBuffer.Count);
$iBytes -gt 0;
$iBytes = $streamGZipFileInput.Read($bytesGZipFileBuffer, 0,$bytesGZipFileBuffer.Count)){

$streamGZipFileArchive.Write($bytesGZipFileBuffer,0,$iBytes)
}

$streamGZipFileArchive.Dispose()
$streamGZipFileInput.Close()
$streamGZipFileOutput.Close()

Get-Item $OutputFile
}
catch { throw $_ }
}


Get-ChildItem -Path $SourceDirectory -Recurse -Exclude "*.7z"|ForEach-Object{
if($($_.Attributes -band [System.IO.FileAttributes]::Directory) -ne [System.IO.FileAttributes]::Directory){
#Current file
$curFile = $_

#Check the file wasn't modified recently
if($curFile.LastWriteTime.Date -le (get-date).adddays(-5)){

$containedDir=$curFile.Directory.FullName.Replace($SourceDirectory,$DestinationDirectory)

#if target directory doesn't exist - create
if($(Test-Path -Path "$containedDir") -eq $false){
New-Item -Path "$containedDir" -ItemType directory
}

Write-Host $("Archiving " + $curFile.FullName)
Compress-File -InputFile $curFile.FullName -OutputFile $("$containedDir" + $curFile.Name + ".7z")
Remove-Item -Path $curFile.FullName
}
}
}


This actually seems to work, insofar as it creates individual archives for each eligible log, but I need to "bundle" up the logs into one mega-archive, and I can't seem to figure out how to recurse (to get sub-level items) and do a foreach (to confirm age) without having that foreach produce individual archives.



I haven't even gotten into the Move and Delete phase, because I can't seem to get the archiving stage to work properly, but I certainly don't mind grinding away at that once this gets figured out (I've already spent two full days trying to figure this one!).



I greatly appreciate any and all suggestions! If I've not explained something, or been a bit unclear, please let me know!



EDIT1: Part of the requirement, which I completely forgot to mention, is that I need to keep the structure in the new location. So the new location will have




  1. C:ServerLogs --> C:Archive

  2. C:ServerLogsApp1 --> C:ArchiveApp1

  3. C:ServerLogs2ndApp --> C:Archive2ndApp


  4. C:Archive


  5. C:ArchiveApp1archivedlogs.zip

  6. C:Archive2ndApparchivedlogs.zip

    And I have absolutely no idea how to specify that the logs from App1 need to go to App1.


EDIT2: For this latter part, I used Robocopy - It maintains the folder structure, and if you feed it ".zip" as an argument, it'll only do the .zip files.










share|improve this question
























  • i think this line $Args = a -mx9 $archive $log needs to have the value wrapped in double quotes OR each non-variable wrapped in quotes with a comma between each so that you get an array of args. ///// also, why not use the built in commands? see Get-Command *archive* for the list.
    – Lee_Dailey
    Nov 6 at 15:00










  • You can use call operator instead of invoke-expression: foreach ($log in $LogsToArchive) { & 7zip a -mx9 $archive $log }
    – James C.
    Nov 6 at 15:18












  • @JamesC. I tried that, and I got (for each eligible log file) a "Warning: The system cannot find the file specified" and (oddly!) an empty archive in the target destination. Which, on balance, is progress of a sort!
    – RSchreib
    Nov 6 at 15:44










  • @Lee_Dailey I'll have a bit of playtime with quotes on the arguments, but as for using 7zip, that was dictated by higher-ups, so I'm stuck with it (I think it was a question of performance, maybe?). But I'll try to fiddle with it and see if I can't get "Compresss-Archive" to accept multiple files into one archive.
    – RSchreib
    Nov 6 at 15:46










  • @RSchreib - you may have to move the files into one dir to get them into one archive without lots of fiddling. as for the builtin archive cmdlets ... they are always there in ps4+ [or maybe 3], so it's a more predictable thing to use.
    – Lee_Dailey
    Nov 6 at 16:01














0












0








0


1





I am trying to join multiple log files into a single archive file, then move that archive file to another location, in an effort to both clean up old log files, and save hard drive space. We have a bunch of tools that all log to the same root, with a per-tool folder for their logs. (E.g.,




  1. C:ServerLogs

  2. C:ServerLogsApp1

  3. C:ServerLogs2ndApp


each of which will have log files inside, like




  1. C:ServerLogsApp1June1.log

  2. C:ServerLogsApp1June2.log

  3. C:ServerLogs2ndAppJune1.log

  4. C:ServerLogs2ndAppJune2.log


I want to go into each of these subfolders, archive up all the files older than 5 days, then move the archive to another (long-term storage) drive and delete the now-zipped files. The tools I'm using are PowerShell and 7zip. The below code is using test locations.



I have cobbled together two scripts from various sources online, over the course of two full shifts, but neither one works right. Here's the first:



# Alias for 7-zip 
if (-not (test-path "$env:ProgramFiles7-Zip7z.exe")) {throw "$env:ProgramFiles7-Zip7z.exe needed"}
set-alias 7zip "$env:ProgramFiles7-Zip7z.exe"
$Days = 5 #minimum age of files to archive; in other words, newer than this many days ago are ignored
$SourcePath = C:WorkingFolderFolderSource
$DestinationPath = C:Temp
$LogsToArchive = Get-ChildItem -Recurse -Path $SourcePath | Where-Object {$_.lastwritetime -le (get-date).addDays(-$Days)}
$archive = $DestinationPath + $now + ".7z"

#endregion

foreach ($log in $LogsToArchive) {
#define Args
$Args = a -mx9 $archive $log
$Command = 7zip
#write-verbose $command

#invoke the command
invoke-expression -command $Command $Args


The problem with this one is that I get errors trying to invoke the expression. I've tried restructuring it, but then I get errors because my $Args have an "a"



So I abandoned this method (despite it being my preferred), and tried this set.



#region Params
param(
[Parameter(Position=0, Mandatory=$true)]
[ValidateScript({Test-Path -Path $_ -PathType 'container'})]
[System.String]
$SourceDirectory,
[Parameter(Position=1, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[System.String]
$DestinationDirectory
)
#endregion

function Compress-File{
#region Params
param(
[Parameter(Position=0, Mandatory=$true)]
[ValidateScript({Test-Path -Path $_ -PathType 'leaf'})]
[System.String]
$InputFile,
[Parameter(Position=1, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[System.String]
$OutputFile
)
#endregion

try{
#Creating buffer with size 50MB
$bytesGZipFileBuffer = New-Object -TypeName byte(52428800)

$streamGZipFileInput = New-Object -TypeName System.IO.FileStream($InputFile,[System.IO.FileMode]::Open,[System.IO.FileAccess]::Read)
$streamGZipFileOutput = New-Object -TypeName System.IO.FileStream($OutputFile,[System.IO.FileMode]::Create,[System.IO.FileAccess]::Write)
$streamGZipFileArchive = New-Object -TypeName System.IO.Compression.GZipStream($streamGZipFileOutput,[System.IO.Compression.CompressionMode]::Compress)

for($iBytes = $streamGZipFileInput.Read($bytesGZipFileBuffer, 0,$bytesGZipFileBuffer.Count);
$iBytes -gt 0;
$iBytes = $streamGZipFileInput.Read($bytesGZipFileBuffer, 0,$bytesGZipFileBuffer.Count)){

$streamGZipFileArchive.Write($bytesGZipFileBuffer,0,$iBytes)
}

$streamGZipFileArchive.Dispose()
$streamGZipFileInput.Close()
$streamGZipFileOutput.Close()

Get-Item $OutputFile
}
catch { throw $_ }
}


Get-ChildItem -Path $SourceDirectory -Recurse -Exclude "*.7z"|ForEach-Object{
if($($_.Attributes -band [System.IO.FileAttributes]::Directory) -ne [System.IO.FileAttributes]::Directory){
#Current file
$curFile = $_

#Check the file wasn't modified recently
if($curFile.LastWriteTime.Date -le (get-date).adddays(-5)){

$containedDir=$curFile.Directory.FullName.Replace($SourceDirectory,$DestinationDirectory)

#if target directory doesn't exist - create
if($(Test-Path -Path "$containedDir") -eq $false){
New-Item -Path "$containedDir" -ItemType directory
}

Write-Host $("Archiving " + $curFile.FullName)
Compress-File -InputFile $curFile.FullName -OutputFile $("$containedDir" + $curFile.Name + ".7z")
Remove-Item -Path $curFile.FullName
}
}
}


This actually seems to work, insofar as it creates individual archives for each eligible log, but I need to "bundle" up the logs into one mega-archive, and I can't seem to figure out how to recurse (to get sub-level items) and do a foreach (to confirm age) without having that foreach produce individual archives.



I haven't even gotten into the Move and Delete phase, because I can't seem to get the archiving stage to work properly, but I certainly don't mind grinding away at that once this gets figured out (I've already spent two full days trying to figure this one!).



I greatly appreciate any and all suggestions! If I've not explained something, or been a bit unclear, please let me know!



EDIT1: Part of the requirement, which I completely forgot to mention, is that I need to keep the structure in the new location. So the new location will have




  1. C:ServerLogs --> C:Archive

  2. C:ServerLogsApp1 --> C:ArchiveApp1

  3. C:ServerLogs2ndApp --> C:Archive2ndApp


  4. C:Archive


  5. C:ArchiveApp1archivedlogs.zip

  6. C:Archive2ndApparchivedlogs.zip

    And I have absolutely no idea how to specify that the logs from App1 need to go to App1.


EDIT2: For this latter part, I used Robocopy - It maintains the folder structure, and if you feed it ".zip" as an argument, it'll only do the .zip files.










share|improve this question















I am trying to join multiple log files into a single archive file, then move that archive file to another location, in an effort to both clean up old log files, and save hard drive space. We have a bunch of tools that all log to the same root, with a per-tool folder for their logs. (E.g.,




  1. C:ServerLogs

  2. C:ServerLogsApp1

  3. C:ServerLogs2ndApp


each of which will have log files inside, like




  1. C:ServerLogsApp1June1.log

  2. C:ServerLogsApp1June2.log

  3. C:ServerLogs2ndAppJune1.log

  4. C:ServerLogs2ndAppJune2.log


I want to go into each of these subfolders, archive up all the files older than 5 days, then move the archive to another (long-term storage) drive and delete the now-zipped files. The tools I'm using are PowerShell and 7zip. The below code is using test locations.



I have cobbled together two scripts from various sources online, over the course of two full shifts, but neither one works right. Here's the first:



# Alias for 7-zip 
if (-not (test-path "$env:ProgramFiles7-Zip7z.exe")) {throw "$env:ProgramFiles7-Zip7z.exe needed"}
set-alias 7zip "$env:ProgramFiles7-Zip7z.exe"
$Days = 5 #minimum age of files to archive; in other words, newer than this many days ago are ignored
$SourcePath = C:WorkingFolderFolderSource
$DestinationPath = C:Temp
$LogsToArchive = Get-ChildItem -Recurse -Path $SourcePath | Where-Object {$_.lastwritetime -le (get-date).addDays(-$Days)}
$archive = $DestinationPath + $now + ".7z"

#endregion

foreach ($log in $LogsToArchive) {
#define Args
$Args = a -mx9 $archive $log
$Command = 7zip
#write-verbose $command

#invoke the command
invoke-expression -command $Command $Args


The problem with this one is that I get errors trying to invoke the expression. I've tried restructuring it, but then I get errors because my $Args have an "a"



So I abandoned this method (despite it being my preferred), and tried this set.



#region Params
param(
[Parameter(Position=0, Mandatory=$true)]
[ValidateScript({Test-Path -Path $_ -PathType 'container'})]
[System.String]
$SourceDirectory,
[Parameter(Position=1, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[System.String]
$DestinationDirectory
)
#endregion

function Compress-File{
#region Params
param(
[Parameter(Position=0, Mandatory=$true)]
[ValidateScript({Test-Path -Path $_ -PathType 'leaf'})]
[System.String]
$InputFile,
[Parameter(Position=1, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[System.String]
$OutputFile
)
#endregion

try{
#Creating buffer with size 50MB
$bytesGZipFileBuffer = New-Object -TypeName byte(52428800)

$streamGZipFileInput = New-Object -TypeName System.IO.FileStream($InputFile,[System.IO.FileMode]::Open,[System.IO.FileAccess]::Read)
$streamGZipFileOutput = New-Object -TypeName System.IO.FileStream($OutputFile,[System.IO.FileMode]::Create,[System.IO.FileAccess]::Write)
$streamGZipFileArchive = New-Object -TypeName System.IO.Compression.GZipStream($streamGZipFileOutput,[System.IO.Compression.CompressionMode]::Compress)

for($iBytes = $streamGZipFileInput.Read($bytesGZipFileBuffer, 0,$bytesGZipFileBuffer.Count);
$iBytes -gt 0;
$iBytes = $streamGZipFileInput.Read($bytesGZipFileBuffer, 0,$bytesGZipFileBuffer.Count)){

$streamGZipFileArchive.Write($bytesGZipFileBuffer,0,$iBytes)
}

$streamGZipFileArchive.Dispose()
$streamGZipFileInput.Close()
$streamGZipFileOutput.Close()

Get-Item $OutputFile
}
catch { throw $_ }
}


Get-ChildItem -Path $SourceDirectory -Recurse -Exclude "*.7z"|ForEach-Object{
if($($_.Attributes -band [System.IO.FileAttributes]::Directory) -ne [System.IO.FileAttributes]::Directory){
#Current file
$curFile = $_

#Check the file wasn't modified recently
if($curFile.LastWriteTime.Date -le (get-date).adddays(-5)){

$containedDir=$curFile.Directory.FullName.Replace($SourceDirectory,$DestinationDirectory)

#if target directory doesn't exist - create
if($(Test-Path -Path "$containedDir") -eq $false){
New-Item -Path "$containedDir" -ItemType directory
}

Write-Host $("Archiving " + $curFile.FullName)
Compress-File -InputFile $curFile.FullName -OutputFile $("$containedDir" + $curFile.Name + ".7z")
Remove-Item -Path $curFile.FullName
}
}
}


This actually seems to work, insofar as it creates individual archives for each eligible log, but I need to "bundle" up the logs into one mega-archive, and I can't seem to figure out how to recurse (to get sub-level items) and do a foreach (to confirm age) without having that foreach produce individual archives.



I haven't even gotten into the Move and Delete phase, because I can't seem to get the archiving stage to work properly, but I certainly don't mind grinding away at that once this gets figured out (I've already spent two full days trying to figure this one!).



I greatly appreciate any and all suggestions! If I've not explained something, or been a bit unclear, please let me know!



EDIT1: Part of the requirement, which I completely forgot to mention, is that I need to keep the structure in the new location. So the new location will have




  1. C:ServerLogs --> C:Archive

  2. C:ServerLogsApp1 --> C:ArchiveApp1

  3. C:ServerLogs2ndApp --> C:Archive2ndApp


  4. C:Archive


  5. C:ArchiveApp1archivedlogs.zip

  6. C:Archive2ndApparchivedlogs.zip

    And I have absolutely no idea how to specify that the logs from App1 need to go to App1.


EDIT2: For this latter part, I used Robocopy - It maintains the folder structure, and if you feed it ".zip" as an argument, it'll only do the .zip files.







powershell logging archive 7zip






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 9 at 10:07

























asked Nov 6 at 14:28









RSchreib

84




84












  • i think this line $Args = a -mx9 $archive $log needs to have the value wrapped in double quotes OR each non-variable wrapped in quotes with a comma between each so that you get an array of args. ///// also, why not use the built in commands? see Get-Command *archive* for the list.
    – Lee_Dailey
    Nov 6 at 15:00










  • You can use call operator instead of invoke-expression: foreach ($log in $LogsToArchive) { & 7zip a -mx9 $archive $log }
    – James C.
    Nov 6 at 15:18












  • @JamesC. I tried that, and I got (for each eligible log file) a "Warning: The system cannot find the file specified" and (oddly!) an empty archive in the target destination. Which, on balance, is progress of a sort!
    – RSchreib
    Nov 6 at 15:44










  • @Lee_Dailey I'll have a bit of playtime with quotes on the arguments, but as for using 7zip, that was dictated by higher-ups, so I'm stuck with it (I think it was a question of performance, maybe?). But I'll try to fiddle with it and see if I can't get "Compresss-Archive" to accept multiple files into one archive.
    – RSchreib
    Nov 6 at 15:46










  • @RSchreib - you may have to move the files into one dir to get them into one archive without lots of fiddling. as for the builtin archive cmdlets ... they are always there in ps4+ [or maybe 3], so it's a more predictable thing to use.
    – Lee_Dailey
    Nov 6 at 16:01


















  • i think this line $Args = a -mx9 $archive $log needs to have the value wrapped in double quotes OR each non-variable wrapped in quotes with a comma between each so that you get an array of args. ///// also, why not use the built in commands? see Get-Command *archive* for the list.
    – Lee_Dailey
    Nov 6 at 15:00










  • You can use call operator instead of invoke-expression: foreach ($log in $LogsToArchive) { & 7zip a -mx9 $archive $log }
    – James C.
    Nov 6 at 15:18












  • @JamesC. I tried that, and I got (for each eligible log file) a "Warning: The system cannot find the file specified" and (oddly!) an empty archive in the target destination. Which, on balance, is progress of a sort!
    – RSchreib
    Nov 6 at 15:44










  • @Lee_Dailey I'll have a bit of playtime with quotes on the arguments, but as for using 7zip, that was dictated by higher-ups, so I'm stuck with it (I think it was a question of performance, maybe?). But I'll try to fiddle with it and see if I can't get "Compresss-Archive" to accept multiple files into one archive.
    – RSchreib
    Nov 6 at 15:46










  • @RSchreib - you may have to move the files into one dir to get them into one archive without lots of fiddling. as for the builtin archive cmdlets ... they are always there in ps4+ [or maybe 3], so it's a more predictable thing to use.
    – Lee_Dailey
    Nov 6 at 16:01
















i think this line $Args = a -mx9 $archive $log needs to have the value wrapped in double quotes OR each non-variable wrapped in quotes with a comma between each so that you get an array of args. ///// also, why not use the built in commands? see Get-Command *archive* for the list.
– Lee_Dailey
Nov 6 at 15:00




i think this line $Args = a -mx9 $archive $log needs to have the value wrapped in double quotes OR each non-variable wrapped in quotes with a comma between each so that you get an array of args. ///// also, why not use the built in commands? see Get-Command *archive* for the list.
– Lee_Dailey
Nov 6 at 15:00












You can use call operator instead of invoke-expression: foreach ($log in $LogsToArchive) { & 7zip a -mx9 $archive $log }
– James C.
Nov 6 at 15:18






You can use call operator instead of invoke-expression: foreach ($log in $LogsToArchive) { & 7zip a -mx9 $archive $log }
– James C.
Nov 6 at 15:18














@JamesC. I tried that, and I got (for each eligible log file) a "Warning: The system cannot find the file specified" and (oddly!) an empty archive in the target destination. Which, on balance, is progress of a sort!
– RSchreib
Nov 6 at 15:44




@JamesC. I tried that, and I got (for each eligible log file) a "Warning: The system cannot find the file specified" and (oddly!) an empty archive in the target destination. Which, on balance, is progress of a sort!
– RSchreib
Nov 6 at 15:44












@Lee_Dailey I'll have a bit of playtime with quotes on the arguments, but as for using 7zip, that was dictated by higher-ups, so I'm stuck with it (I think it was a question of performance, maybe?). But I'll try to fiddle with it and see if I can't get "Compresss-Archive" to accept multiple files into one archive.
– RSchreib
Nov 6 at 15:46




@Lee_Dailey I'll have a bit of playtime with quotes on the arguments, but as for using 7zip, that was dictated by higher-ups, so I'm stuck with it (I think it was a question of performance, maybe?). But I'll try to fiddle with it and see if I can't get "Compresss-Archive" to accept multiple files into one archive.
– RSchreib
Nov 6 at 15:46












@RSchreib - you may have to move the files into one dir to get them into one archive without lots of fiddling. as for the builtin archive cmdlets ... they are always there in ps4+ [or maybe 3], so it's a more predictable thing to use.
– Lee_Dailey
Nov 6 at 16:01




@RSchreib - you may have to move the files into one dir to get them into one archive without lots of fiddling. as for the builtin archive cmdlets ... they are always there in ps4+ [or maybe 3], so it's a more predictable thing to use.
– Lee_Dailey
Nov 6 at 16:01












1 Answer
1






active

oldest

votes


















0














this line $Args = a -mx9 $archive $log likely needs to have the right side value wrapped in double quotes OR each non-variable wrapped in quotes with a comma between each so that you get an array of args.



another method would be to declare an array of args explicitly. something like this ...



$ArgList = @(
'a'
'-mx9'
$archive
$log
)




i also recommend you NOT use an automatic $Var name. take a look at Get-Help about_Automatic_Variables and you will see that $Args is one of those. you are strongly recommended NOT to use any of them for anything other than reading. writing to them is iffy. [grin]






share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53173933%2fcombine-multiple-log-files-to-archive-using-posh-and-7zip%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    this line $Args = a -mx9 $archive $log likely needs to have the right side value wrapped in double quotes OR each non-variable wrapped in quotes with a comma between each so that you get an array of args.



    another method would be to declare an array of args explicitly. something like this ...



    $ArgList = @(
    'a'
    '-mx9'
    $archive
    $log
    )




    i also recommend you NOT use an automatic $Var name. take a look at Get-Help about_Automatic_Variables and you will see that $Args is one of those. you are strongly recommended NOT to use any of them for anything other than reading. writing to them is iffy. [grin]






    share|improve this answer


























      0














      this line $Args = a -mx9 $archive $log likely needs to have the right side value wrapped in double quotes OR each non-variable wrapped in quotes with a comma between each so that you get an array of args.



      another method would be to declare an array of args explicitly. something like this ...



      $ArgList = @(
      'a'
      '-mx9'
      $archive
      $log
      )




      i also recommend you NOT use an automatic $Var name. take a look at Get-Help about_Automatic_Variables and you will see that $Args is one of those. you are strongly recommended NOT to use any of them for anything other than reading. writing to them is iffy. [grin]






      share|improve this answer
























        0












        0








        0






        this line $Args = a -mx9 $archive $log likely needs to have the right side value wrapped in double quotes OR each non-variable wrapped in quotes with a comma between each so that you get an array of args.



        another method would be to declare an array of args explicitly. something like this ...



        $ArgList = @(
        'a'
        '-mx9'
        $archive
        $log
        )




        i also recommend you NOT use an automatic $Var name. take a look at Get-Help about_Automatic_Variables and you will see that $Args is one of those. you are strongly recommended NOT to use any of them for anything other than reading. writing to them is iffy. [grin]






        share|improve this answer












        this line $Args = a -mx9 $archive $log likely needs to have the right side value wrapped in double quotes OR each non-variable wrapped in quotes with a comma between each so that you get an array of args.



        another method would be to declare an array of args explicitly. something like this ...



        $ArgList = @(
        'a'
        '-mx9'
        $archive
        $log
        )




        i also recommend you NOT use an automatic $Var name. take a look at Get-Help about_Automatic_Variables and you will see that $Args is one of those. you are strongly recommended NOT to use any of them for anything other than reading. writing to them is iffy. [grin]







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 22 at 17:28









        Lee_Dailey

        1,31777




        1,31777






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53173933%2fcombine-multiple-log-files-to-archive-using-posh-and-7zip%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Lallio

            Futebolista

            Jornalista