I am checking each folder for an HTMLreports directory and then deleting files that are over 30 days old. But when it gets to the filename for $document.Name or $image.name in the foreach loop it is not getting the filename to delete the file for the Remove-Item command.
$items = Get-ChildItem -Path "C:\Program Files (x86)\Jenkins\jobs\"
$time = (Get-Date).AddDays(-30)
$today = Get-Date
echo $today
# enumerate the items array
foreach ($item in $items) {
# if the item is a directory, then process it.
if ($item.Attributes -eq "Directory") {
Write-Host "job folder: " $item.Name
$folder = Get-ChildItem -Path ("C:\Program Files (x86)\Jenkins\jobs\" + $item.Name + "\")
if (Test-Path ("C:\Program Files (x86)\Jenkins\jobs\"+$item.Name+"\htmlreports\")) {
$reports = Get-ChildItem -Path ("C:\Program Files (x86)\Jenkins\jobs\" + $item.Name + "\htmlreports\")
foreach ($report in $reports) {
Write-Host "report folder" $report.Name
$documents = Get-ChildItem -Path ("C:\Program Files (x86)\Jenkins\jobs\" + $item.Name + "\htmlreports\" + $report.Name + "\") |
Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $time }
foreach ($document in $documents) {
if ($document.Attributes -eq "Directory") {
echo "Folder exists"
Write-Host "delete document folder" $document.Name
Remove-Item ("C:\Program Files (x86)\Jenkins\jobs\" + $item.Name + "\htmlreports\"+$report.Name+"\" + $document.Name)
} else {
echo "File exists"
Write-Host "delete document " $document.Name
Remove-Item ("C:\Program Files (x86)\Jenkins\jobs\" + $item.Name + "\htmlreports\"+$report.Name+"\" + $document.Name)
}
}
if (Test-Path ("C:\Program Files (x86)\Jenkins\jobs\" + $item.Name + "\htmlreports\" + $report.Name + "\images\")) {
echo "Image Folder exists"
$images = Get-ChildItem -Path ("C:\Program Files (x86)\Jenkins\jobs\" + $item.Name + "\htmlreports\" + $report.Name + "\images\") -Name |
Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $time }
foreach ($image in $images) {
Write-Host "delete image: C:\Program Files (x86)\Jenkins\jobs\"$item.Name"\htmlreports\"$report.Name"\images\"$image.Name
Remove-Item ("C:\Program Files (x86)\Jenkins\jobs\" + $item.Name + "\htmlreports\" + $report.Name + "\images \" + $image.Name);
}
}
}
}
}
}
Instead of repeating a long path over and over again, store it in a variable.
You erroneously have an additional space inserted several times between
C:\Program Files (x86)\Jenkins\jobs\
and also
"C:\Program Files (x86)\Jenkins\jobs\"
Previous answer removed after looking at this again.
You just seem to be wanting to remove all the files after a specific date in the jobs\htmlreport folder and it's images subfolder you can reduce your code to this...
Clear-Host
$ReportFiles = (Get-ChildItem -Path "${env:ProgramFiles(x86)}\Jenkins\jobs\htmlreports" -Recurse).FullName
($today = Get-Date)
($time = (Get-Date).AddDays(-30))
ForEach($File in (Get-ChildItem -Path $ReportFiles -File))
{
If ($File.FullName.CreationTime -lt $time)
{"Processing $($File.FullName)"}
}
… of course if there are other folders, you should just filter for those two.
Thank You everyone for all your insights, I was able to get this working with my below code. I am checking all the folders or reports in the jobs directory and for each report I am going into the htmlreports directory and deleting all files and images in the images directory that are more than 30 days old. If there is a cleaner way to do this please let me know, I am using powershell v1.0.
$items = gci "C:\Program Files (x86)\Jenkins\jobs\"
($today = Get-Date)
($time = $today.AddDays(-30))
Write-Host $today
# enumerate the items array
foreach ($item in $items) {
# if the item is a directory, then process it.
if ($item.Attributes -eq "Directory") {
Write-Host "job folder: " $item.Name
if (Test-Path ("C:\Program Files (x86)\Jenkins\jobs\"+$item.Name+"\htmlreports\")) {
$reports = Get-ChildItem -Path ("C:\Program Files (x86)\Jenkins\jobs\" + $item.Name + "\htmlreports\")
foreach ($report in $reports) {
Write-Host "report folder" $report.Name
$documents = ("C:\Program Files (x86)\Jenkins\jobs\" + $item.Name + "\htmlreports\" + $report.Name + "\")
dir -recurse $documents | where {$_.LastWriteTime -le $time} | del
if (Test-Path ("C:\Program Files (x86)\Jenkins\jobs\" + $item.Name + "\htmlreports\" + $report.Name + "\images\")) {
Write-Host "Image Folder exists"
$images = ("C:\Program Files (x86)\Jenkins\jobs\" + $item.Name + "\htmlreports\" + $report.Name + "\images\")
dir -recurse $images | where {$_.LastWriteTime -le $time} | del
}
}
}
}
}
Related
Hello I am new scripting, I am tasked with creating a script that will be deleting a file from specific folders which will be deployed through SCCM onto many computers.
The problem is I want to output the log file saying either:
"<ComputerName> File Terminated"
"<ComputerName> File Not terminated"
Here is what I have so far:
$users = "C:\Users"
$logFile = "C:\TTS\Logs\GoogleTerm.log"
$source = "\AppData\Roaming\Google"
$exclude = "Default"
$input = get-ChildItem -Path $users
foreach ($folder in $input) {
if ($exclude -notcontains $folder.Name) {
Remove-Item -Path ($Users + "\" + $folder.Name + $source) -recurse -force
}
}
echo "Google Terminated on:"$env:computername >> $logfile
Added an else to your if to handle both outcomes, and then using Add-Content instead of echo:
foreach ($folder in $input) {
if ($exclude -notcontains $folder.Name) {
Remove-Item -Path ($Users + "\" + $folder.Name + $source) -recurse -force
Add-Content $logfile "$env:computername File Terminated"
}
else {
Add-Content $logfile "$env:computername File Not Terminated"
}
}
Add-Content $logfile "Google Terminated on: $env:computername"
This was my successfull solution, thank you guys for the assistance!
$users = "C:\Users"
$logFile = "C:\TTS\Logs\GoogleTerm.log"
$exclude = "Default"
$input = get-ChildItem -Path $users
foreach ($folder in $input) {
if ($exclude -notcontains $folder.Name) {
if (Test-Path ($Users + "\" + $folder.Name + $source)){
Remove-Item -Path ($Users + "\" + $folder.Name + $source) -recurse -force
Add-Content $logFile "Google Terminated on: $env:computername UserName:$folder "
}
else{
Add-Content $logFile "Google Already Terminated on:$env:computername UserName:$folder "
}
}
else{
Add-Content $logFile "Not Terminated on: $env:computername Username:$folder"
}
}
I am unable to delete zip folders older than 14 days from a directory. The rest of my script works fine, however the following code block is failing:
It has not thrown any errors, the path has been sanity checked, however, I placed old documents in to see if they are cleared up to no avail. It prints the statement that the folder path exists however does not delete anything from the folder.
if (!(Test-Path $folderpath)) {
New-Item -ItemType Directory -Path $folderpath
Write-Host "$folderpath created"
} else {
Write-Host "$folderpath already exists, will remove old items"
$HowOld = -14
Get-ChildItem $Path -Recurse |
where {$_.LastWriteTime -lt (Get-Date).AddDays($HowOld) -and -not $_.PSIsContainer} |
% {Remove-Item $_.FullName -Force -WhatIf}
}
Here is the full script for completeness:
#Get backup folder drive letter
$letter = [System.IO.DriveInfo]::getdrives() | Where-Object {$_.DriveType -eq 'Fixed' -and $_.Name -notlike '*C*'} | Select-Object -Property Name
[string] $drive = "$letter"
$Drive2 = $null
$Drive2 = $drive.Substring($drive.IndexOf('=')+1)
$BackupDrive = $Drive2.Substring(0, $Drive2.IndexOf('}'))
#Check the programname log path.
$logspath = "C:\ProgramData\programname\programname4.0\Logs"
If (!(test-path $logspath))
{
$IQlogspath = "C:\ProgramData\programname\iQSonar4.0\Logs"
}
Else
{
$IQlogspath = "C:\ProgramData\programname\programname4.0\Logs"
}
#check if backup folder exists, clean if exists and if not create it.
$folderpath = $BackupDrive + "programname_logs"
If(!(test-path $folderpath))
{
New-Item -ItemType Directory -Path $folderpath
write-host "$folderpath created"
}
Else
{
write-host "$folderpath already exists, will remove old items"
$HowOld = -14
get-childitem $Path -recurse | where {$_.lastwritetime -lt (get-date).adddays($HowOld) -and -not $_.psiscontainer} |% {remove-item $_.fullname -force -whatif}
}
#check if todays folder exists, if not create it
$todaysdate = (Get-Date).ToString('dd-MM-yyyy')
$todaysbackup = $folderpath + "\Logs_Backup_" + $todaysdate
$todaysbackupzip = $todaysbackup + ".zip"
If(!(test-path $todaysbackup))
{
New-Item -ItemType Directory -Path $todaysbackup
write-host "$todaysbackup created, now moving items"
#select and move files to backup folder
get-childitem -Path $IQlogspath |
where-object {$_.LastWriteTime -lt (get-date).AddDays(-7) -and $_.Name -notmatch "Service"} |
move-item -destination $todaysbackup
Start-Sleep -s 10
write-host "checking for zip"
If(Test-path $todaysbackupzip) {
write-host "$todaysbackupzip already exists, changing name"
$todaysbackupzip = $null
$todaysbackupzip = $folderpath + "\Logs_Backup_" + $todaysdate + ".re-run" + ".zip"
Add-Type -assembly "system.io.compression.filesystem"
[io.compression.zipfile]::CreateFromDirectory($todaysbackup, $todaysbackupzip)
write-host "$todaysbackupzip created"
Remove-Item -Recurse -Force $todaysbackup
write-host "$todaysbackup removed"
exit
}
write-host "creating zip folder, $todaysbackupzip"
Add-Type -assembly "system.io.compression.filesystem"
[io.compression.zipfile]::CreateFromDirectory($todaysbackup, $todaysbackupzip)
write-host "$todaysbackupzip created"
Remove-Item -Recurse -Force $todaysbackup
write-host "$todaysbackup removed"
exit
}
Else
{
write-host "$todaysbackup already exists, attempting to zip"
#check if zip backup folder already exists
If(Test-path $todaysbackupzip) {
write-host "$todaysbackupzip already exists, changing name"
$todaysbackupzip = $null
$todaysbackupzip = $folderpath + "\Logs_Backup_" + $todaysdate + ".re-run" + ".zip"
[io.compression.zipfile]::CreateFromDirectory($todaysbackup, $todaysbackupzip)
write-host "$todaysbackupzip created"
Remove-Item -Recurse -Force $todaysbackup
write-host "$todaysbackup removed"
exit
}
Else
{
Start-Sleep -s 10
write-host "creating zip folder, $todaysbackupzip"
Add-Type -assembly "system.io.compression.filesystem"
[io.compression.zipfile]::CreateFromDirectory($todaysbackup, $todaysbackupzip)
write-host "$todaysbackupzip created"
Remove-Item -Recurse -Force $todaysbackup
write-host "$todaysbackup removed"
exit
}
}
#Get OS disk label
$OSDisk = Get-WmiObject Win32_OperatingSystem | Select-Object WindowsDirectory
[string] $drive = "$OSDisk"
$Drive2 = $null
$Drive2 = $drive.Substring($drive.IndexOf('=')+1)
$OSDrive = $Drive2.Substring(0, $Drive2.IndexOf('\'))
$OSDrive2 = "'$OSDrive'"
$disk = Get-WmiObject Win32_LogicalDisk -Filter "DeviceID=$OSDrive2"| Select-Object FreeSpace
[INT] $FreeSpace = $disk.FreeSpace /1GB
If ($FreeSpace -gt 5) {
write-host "no additional backup requirement, exiting script"
exit
}
Else {
write-host "Running one off clear"
$OneOff = $IQlogspath + "\Logs_One_Off_" + $todaysdate
$OneOffZip = $OneOff + ".zip"
If(!(test-path $OneOff))
{
New-Item -ItemType Directory -Path $OneOff
write-host "$OneOff created"
}
Else {
write-host "folder already exists"
}
#select and move files to backup folder
write-host "moving logs to $OneOff"
get-childitem -Path $IQlogspath |
where-object {$_.Name -notmatch "Service"} |
move-item -destination $OneOff
Start-Sleep -s 10
write-host "creating zip folder, $todaysbackupzip"
Add-Type -assembly "system.io.compression.filesystem"
[io.compression.zipfile]::CreateFromDirectory($OneOff, $OneOffZip)
write-host "$todaysbackupzip created"
Remove-Item -Recurse -Force $todaysbackup
write-host "$todaysbackup removed"
exit
}
I would like to go inside every folder recursive in some location,
for example: C:\Logs and zip files to the same folder.
I need to skip every .zip file. I don't know how to make my script to do this:
function New-Zip
{
param([string]$zipfilename)
set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
(dir $zipfilename).IsReadOnly = $false
}
function Add-Zip
{
param([string]$zipfilename)
if(-not (test-path($zipfilename)))
{
set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
(dir $zipfilename).IsReadOnly = $false
}
$shellApplication = new-object -com shell.application
$zipPackage = $shellApplication.NameSpace($zipfilename)
foreach($file in $input)
{
$zipPackage.CopyHere($file.FullName)
Start-sleep -milliseconds 500
}
}
$targetFolder = 'C:\Logs'
$now = Get-Date -Hour 0 -Minute 00 -Second 00
$days = 5
$lastWrite = $now.AddDays(-$days)
Get-ChildItem $targetFolder -Recurse -Exclude *zip* | Where-Object { $_ -is [System.IO.FileInfo] } | ForEach-Object {
If ($_.LastWriteTime -lt $lastWrite)
{
$_ | New-Zip $($targetFolder + $_.Name + ".zip" )
$_ | Add-Zip $($targetFolder + $_.Name + ".zip" )
}
}
You are currently excluding any file or folder that contains the phrase 'zip' in its name as you have a wildcard either side of it:
Get-ChildItem $targetFolder -Recurse -Exclude *zip*
To exclude zip files you just need to update your Exclude statement so that it matches only the zip file extension:
Get-ChildItem $targetFolder -Recurse -Exclude *.zip
I want to use Powershell to automate the:
1. compression of log files (.xml and .dat extensions) older than 7 days,
2. copy these compressed archives elsewhere and
3. then delete the raw log files from source.
I am using the following Powershell script which I pieced together from various resources.
function New-Zip
{
param([string]$zipfilename)
set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
(dir $zipfilename).IsReadOnly = $false
}
function Add-Zip
{
param([string]$zipfilename)
if(-not (test-path($zipfilename)))
{
set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
(dir $zipfilename).IsReadOnly = $false
}
$shellApplication = new-object -com shell.application
$zipPackage = $shellApplication.NameSpace($zipfilename)
foreach($file in $input)
{
$zipPackage.CopyHere($file.FullName)
Start-sleep -milliseconds 500
}
}
$targetFolder = 'C:\source'
$destinationFolder = 'D:\destination\'
$now = Get-Date
$days = 7
$lastWrite = $now.AddDays(-$days)
Get-ChildItem $targetFolder -Recurse | Where-Object { $_ -is [System.IO.FileInfo] } | ForEach-Object {
If ($_.LastWriteTime -lt $lastWrite)
{
$_ | New-Zip $($destinationFolder + $_.BaseName + ".zip")
$_ | Add-Zip $($destinationFolder + $_.BaseName + ".zip")
}
}
Get-ChildItem $targetFolder -Recurse -Include "*.dat", "*.xml" | WHERE {($_.CreationTime -le $(Get-Date).AddDays(-$days))} | Remove-Item -Force
This script does work reasonably well, as it archives only the files, and copies them on destination folder.
If I have a structure of C:\source\bigfolder\logfile.dat, the resulting zip file will not get the folder structure as I would like:
logfile.zip>bigfolder>logfile.dat
Instead, it just gets: logfile.zip>logfile.dat
Can someone help in figuring this out ?
To fine tune it even better, I would like if possible to build some logic, so the files are compressed only when a specific criteria is met.
The raw log files that I compress have a naming routine as following:
Folders:
emstg#12_list\randomstring.xml
Individual log files:
emstg#12_query_data.xml
emstg#12_events_cache.dat etc...
As you may see the start of these files is same with emstg#number.
How to implement a "name-detection" mechanism in script above ?
Thanks
you could zip a folder by using [System.IO.Compression]
I wrote this based on your script.
My idea is to copy the whole folder structure of the file you need to compress into a temp folder and then zip that temp folder.
For the name-detection, you just need another where-object (modify the code as you want)
function Zip
{
param(
[string]$source,
[string]$des
)
add-type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::CreateFromDirectory($source,$des,'Optimal',$true)
Start-sleep -s 1
}
$targetFolder = "C:\source"
$destinationFolder = "C:\destination"
$temp = "C:\temp"
$now = Get-Date
$days = 7
$lastWrite = $now.AddDays(-$days)
$i = 1
Get-ChildItem $targetFolder -Recurse | Where-Object { $_ -is [System.IO.FileInfo] } | Where-Object {$_ -like "*.*"} | ForEach-Object {
If ($_.LastWriteTime -lt $lastWrite) {
$halfDir = $_.DirectoryName.Trim($targetFolder)
$s = $temp + "\" + $i + "\" + $halfDir
$d = $destinationFolder + "\" + $_.BaseName + ".zip"
Copy-Item $_.DirectoryName -Destination $s
Copy-Item $_.FullName -Destination $s
Zip -source $s -des $d
$i++
}
}
I run a program in windows powershell which lists name of files which have been modified before 30 days. I need to compress these files in a zip format. What should be the code?
#List all the folders in G:\logfiles
$folders = (Get-ChildItem -Path "G:\logfiles" | Where-Object {$_.Attributes -eq "Directory"} | Select Fullname)
#looping all folders
Foreach ($folder in $folders)
{
$files = Get-ChildItem G:\logfiles\$folder | Where{$_.LastWriteTime -lt (Get-Date).AddDays(-30)
}
Foreach ($file in $files)
{
Move-Item $file G:\logfiles\$folder\$N # *To move files to a folder name $N*
}
I will refer you to powershell 5.0 and the new Compress-Archive cmdlet
Compress-Archive -DestinationPath $folderToZip
With the down function you can compress your files.
function zipFile($Source ,$DestZip ){
$folder = Get-Item -Path $Source
$ZipFileName = $DestZip + ".zip"
set-content $ZipFileName ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
# Wait for the zip file to be created.
while (!(Test-Path -PathType leaf -Path $ZipFileName))
{
Start-Sleep -Milliseconds 20
}
$ZipFile = (new-object -com shell.application).NameSpace($ZipFileName)
#BACKUP - COPY
$ZipFile.CopyHere($Source)
Write-Host "#Created zip file :" $DestZip
}