Windows マシン (Windows Server 2008 R2、または Win10 にコピーできます) にログ ファイルがいっぱい入ったフォルダーがあり、それらを日付別に圧縮したいと考えています。何もインストールせずに、ネイティブの方法 (CMD/BAT、Powershell など) でこれを実行したいのですが。検索用語が一般的すぎるのかもしれません。これを行うための魔法の呪文を見つけるのに苦労しています。
混合ファイルタイプで動作でき、使用する日付を選択できる必要があります。
したがって、サンプル セット (米国の日付形式) は次のようになります。
log1.log Created 1/1/19 12:59p Last Modified 1/2/19 1:09a
log2.txt Created 1/2/19 8:00a Last Modified 1/2/19 8:00a
log3.log Created 1/2/19 12:59p Last Modified 1/3/19 1:09a
次のようになる:
190102.zip
log1.log
log2.txt
190103.zip
log3.log
または:
190101.zip
log1.log
190102.zip
log2.txt
log3.log
答え1
上記の私のコメントにあるように、人々は通常これをしませんが、今回は、これをどのように進めてそこから学ぶかについて私が何を意味しているかを皆さんに理解してもらうために、これを実行します。
以下からわかるように、誰かがすでに書いて投稿していない限り、この種のものは 1 か所にまとめられることはありません。また、すべてに異なるアプローチがある可能性があります。したがって、長期的に受け入れて対処するつもりのものを見つける必要があります。
前回のコメントからの分岐です。
<#
What you are after for full understanding is a multi-staged effort, using:
Get-ChildItem
PowerShell Date Formatting
Compress-Archive or .Net (depending on what PowerShell versio you are using)
Example:
if ($PSVersionTable.PSVersion.Major -ge 5)...
{
Compress-Archive -Path $FileSource -DestinationPath $ZipDestination...
}
else
{
# If PowerShell version is below 5x
Add-Type -assembly "system.io.compression.filesystem"
[io.compression.zipfile]::CreateFromDirectory($FileSource, $ZipDestination) ...
}
#>
# Define file source and zip destation paths
$FileSource = 'F:\Temp'
$ZipDestination = 'F:\Temp\Archive'
# Get the first file and check for all properties to see what can be used
(Get-ChildItem -Path $FileSource -File)[0] |
Select-Object -Property '*' | Format-List -Force
<#
PSPath : Microsoft.PowerShell.Core\FileSystem::F:\Temp\CombinedSources07Jun2017.txt
PSParentPath : Microsoft.PowerShell.Core\FileSystem::F:\Temp
PSChildName : CombinedSources07Jun2017.txt
PSDrive : F
PSProvider : Microsoft.PowerShell.Core\FileSystem
PSIsContainer : False
Mode : -a----
VersionInfo : File: F:\Temp\CombinedSources07Jun2017.txt
InternalName:
OriginalFilename:
FileVersion:
FileDescription:
Product:
ProductVersion:
Debug: False
Patched: False
PreRelease: False
PrivateBuild: False
SpecialBuild: False
Language:
BaseName : CombinedSources07Jun2017
Target : {}
LinkType :
Name : CombinedSources07Jun2017.txt
Length : 774
DirectoryName : F:\Temp
Directory : F:\Temp
IsReadOnly : False
Exists : True
FullName : F:\Temp\CombinedSources07Jun2017.txt
Extension : .txt
CreationTime : 12/7/2017 12:38:36 PM
CreationTimeUtc : 12/7/2017 8:38:36 PM
LastAccessTime : 3/23/2019 3:51:12 PM
LastAccessTimeUtc : 3/23/2019 10:51:12 PM
LastWriteTime : 3/23/2019 3:51:12 PM
LastWriteTimeUtc : 3/23/2019 10:51:12 PM
Attributes : Archive
Note that there is no Last Modified property, it's called LastWriteTime
Figure out how to format that LastWriteTime into a string you can use for your
filename using PowerShell date formatting
#>
(Get-ChildItem -Path $FileSource -File)[0] |
Select-Object -Property FullName,
@{Name = 'ZipFileName';Expression = {$($PSitem.LastWriteTime).ToString('ddMMyy')}}
<#
FullName ZipFileName
-------- -----------
F:\Temp\CombinedSources07Jun2017.txt 230319
#>
# Then check for all file and group file by that string
Get-ChildItem -Path $FileSource -File |
Select-Object -Property @{Name = 'FileName';Expression = {$PSItem.FullName}},
@{Name = 'ZipFileName';Expression = {$($PSitem.LastWriteTime).ToString('ddMMyy')}} |
Group-Object -Property ZipFileName
<#
Count Name Group
----- ---- -----
2 230319 {@{FileName=F:\Temp\CombinedSources07Jun2017.txt; ZipFileName=230319}, @{FileName=F:\Temp\CombinedSources07Ju...
1 251017 {@{FileName=F:\Temp\duplicates.csv; ZipFileName=251017}}
1 181117 {@{FileName=F:\Temp\fsoVolume.docx; ZipFileName=181117}}
2 160519 {@{FileName=F:\Temp\g4.txt; ZipFileName=160519}, @{FileName=F:\Temp\log.txt; ZipFileName=160519}}
1 021117 {@{FileName=F:\Temp\groups.csv; ZipFileName=021117}}
1 150617 {@{FileName=F:\Temp\HostData.xml; ZipFileName=150617}}
4 170519 {@{FileName=F:\Temp\key.txt; ZipFileName=170519}, @{FileName=F:\Temp\secrets - Copy.txt; ZipFileName=170519},...
1 130617 {@{FileName=F:\Temp\msinfo.txt; ZipFileName=130617}}
1 260717 {@{FileName=F:\Temp\msinfo.txt - Shortcut.lnk; ZipFileName=260717}}
1 290917 {@{FileName=F:\Temp\MyCsvData.csv; ZipFileName=290917}}
1 271117 {@{FileName=F:\Temp\output.csv; ZipFileName=271117}}
1 201117 {@{FileName=F:\Temp\Serverreport.csv; ZipFileName=201117}}
3 060617 {@{FileName=F:\Temp\TestFile_1.txt; ZipFileName=060617}, @{FileName=F:\Temp\TestFile_2.txt; ZipFileName=06061...
#>
# Check source and destination objects
(Get-ChildItem -Path $FileSource).Count
# 22
(Get-ChildItem -Path $ZipDestination).Count
<#
The below error will occur becasue the folder is empty, thus ignore or
write error code to handle it.
The property 'Count' cannot be found on this object. Verify that the property exists.
At line:1 char:1
#>
<#
Process archive source to destination,
loop and compress the results to $ZipDestination
#>
Get-ChildItem -Path $FileSource -File |
Select-Object -Property @{Name = 'FileName';Expression = {$PSItem.FullName}},
@{Name = 'ZipFileName';Expression = {$($PSitem.LastWriteTime).ToString('ddMMyy')}} |
Group-Object -Property ZipFileName |
ForEach {
if ($PSVersionTable.PSVersion.Major -ge 5)
{
# Using PowerShell Splatting for human readability
$compressArchiveSplat = @{
Confirm = $true
Path = $($PSItem.Group.FileName)
WhatIf = $true
CompressionLevel = 'Optimal'
DestinationPath = "$ZipDestination\$($PSItem.Name).Zip"
# Force = $true
}
Compress-Archive @compressArchiveSplat
}
else
{
<#
Add-Type -assembly "system.io.compression.filesystem"
[io.compression.zipfile]::CreateFromDirectory($($PSItem.Group.FileName), "$ZipDestination\$($PSItem.Name).Zip")
#>
}
}
<#
What if: Performing the operation "Compress-Archive" on target "
F:\Temp\CombinedSources07Jun2017.txt
F:\Temp\CombinedSources07Jun2017.txt - Shortcut.lnk".
What if: Performing the operation "Compress-Archive" on target "F:\Temp\duplicates.csv".
What if: Performing the operation "Compress-Archive" on target "F:\Temp\fsoVolume.docx".
What if: Performing the operation "Compress-Archive" on target "
F:\Temp\g4.txt
F:\Temp\log.txt".
What if: Performing the operation "Compress-Archive" on target "F:\Temp\groups.csv".
What if: Performing the operation "Compress-Archive" on target "F:\Temp\HostData.xml".
What if: Performing the operation "Compress-Archive" on target "
F:\Temp\key.txt
F:\Temp\secrets - Copy.txt
F:\Temp\secrets.txt
F:\Temp\Test.htm".
What if: Performing the operation "Compress-Archive" on target "F:\Temp\msinfo.txt".
What if: Performing the operation "Compress-Archive" on target "F:\Temp\msinfo.txt - Shortcut.lnk".
What if: Performing the operation "Compress-Archive" on target "F:\Temp\MyCsvData.csv".
What if: Performing the operation "Compress-Archive" on target "F:\Temp\output.csv".
What if: Performing the operation "Compress-Archive" on target "F:\Temp\Serverreport.csv".
What if: Performing the operation "Compress-Archive" on target "
F:\Temp\TestFile_1.txt
F:\Temp\TestFile_2.txt
F:\Temp\TestFile_3.txt".
If you want the above to actually do anything, delete or comment out the
-WhatIf and -Confirm, then uncommnet the -force
#>
# Check source and destination objects
(Get-ChildItem -Path $FileSource).Count
# 22
(Get-ChildItem -Path $ZipDestination).Count
<#
The below error will occur becasue the folder is empty, thus ignore or
write error code to handle it.
The property 'Count' cannot be found on this object. Verify that the property exists.
At line:1 char:1
#>
<#
Process archive source to destination,
loop and compress the results to $ZipDestination
#>
Get-ChildItem -Path $FileSource -File |
Select-Object -Property @{Name = 'FileName';Expression = {$PSItem.FullName}},
@{Name = 'ZipFileName';Expression = {$($PSitem.LastWriteTime).ToString('ddMMyy')}} |
Group-Object -Property ZipFileName |
ForEach {
if ($PSVersionTable.PSVersion.Major -ge 5)
{
# Using PowerShell Splatting for human readability
$compressArchiveSplat = @{
Path = $($PSItem.Group.FileName)
CompressionLevel = 'Optimal'
DestinationPath = "$ZipDestination\$($PSItem.Name).Zip"
Force = $true
}
Compress-Archive @compressArchiveSplat
}
else
{
Add-Type -assembly "system.io.compression.filesystem" |
Out-Null
[io.compression.zipfile]::CreateFromDirectory(
$($PSItem.Group.FileName),
"$ZipDestination\$($PSItem.Name).Zip"
)
}
}
# Check source and destination objects
(Get-ChildItem -Path $FileSource).Count
# 22
(Get-ChildItem -Path $ZipDestination).Count
# 13
# Check the archive object
Get-ChildItem -Path $ZipDestination
<#
Directory: F:\Temp\Archive
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 5/23/2019 1:22 PM 491206 021117.Zip
-a---- 5/23/2019 1:22 PM 650 060617.Zip
-a---- 5/23/2019 1:22 PM 93326 130617.Zip
-a---- 5/23/2019 1:22 PM 202549 150617.Zip
-a---- 5/23/2019 1:22 PM 5911 160519.Zip
-a---- 5/23/2019 1:22 PM 1164 170519.Zip
-a---- 5/23/2019 1:22 PM 9109 181117.Zip
-a---- 5/23/2019 1:22 PM 336 201117.Zip
-a---- 5/23/2019 1:22 PM 1057 230319.Zip
-a---- 5/23/2019 1:22 PM 334 251017.Zip
-a---- 5/23/2019 1:22 PM 685 260717.Zip
-a---- 5/23/2019 1:22 PM 756 271117.Zip
-a---- 5/23/2019 1:22 PM 183 290917.Zip
#>
<#
Verify Check the file count in each archive.
There is no cmdlet for this, so you need .Net namespace
#>
[Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem') |
Out-Null
ForEach($archive in (Get-ChildItem -Path $ZipDestination))
{
<#
This will get only files.
If you wanted files and folder count,
if any were there becasue of using -recurse, then more code is needed.
#>
"Checking contents of $($archive.Name) contains : " +
"$(([IO.Compression.ZipFile]::OpenRead($($archive.FullName)).Entries).Count) file(s)."
}
<#
Checking contents of 021117.Zip contains : 1 file(s).
Checking contents of 060617.Zip contains : 3 file(s).
Checking contents of 130617.Zip contains : 1 file(s).
Checking contents of 150617.Zip contains : 1 file(s).
Checking contents of 160519.Zip contains : 2 file(s).
Checking contents of 170519.Zip contains : 4 file(s).
Checking contents of 181117.Zip contains : 1 file(s).
Checking contents of 201117.Zip contains : 1 file(s).
Checking contents of 230319.Zip contains : 2 file(s).
Checking contents of 251017.Zip contains : 1 file(s).
Checking contents of 260717.Zip contains : 1 file(s).
Checking contents of 271117.Zip contains : 1 file(s).
Checking contents of 290917.Zip contains : 1 file(s).
#>