I am trying to copy, and rename multiple files to miltiple folders. The folders will be labeled sequentially like the files. For example I need to copy Reports.txt change the name to Reports_NW01_20120219.txt to a folder called NW01 then the same process for NW02-NW18. The folder and file names increase by 1. I am new to powershell so please spare me. I have pasted what I have below. I am attempting to read in the date and then append it to the file name. I am at a complete loss now. So any help is appreciated:
$date = read-host "Enter date of the report YYYYMMDD"
write-host $date
for ($Counter = 1; $Counter -le 1; $Counter++)
{
#Destination for files
$DropDirectory = "C:\Users\dh0520\Documents\Powershell Staging\"
#Current Location of the files
$file = Get-ChildItem -Path "C:\Users\dh0520\Documents\Powershell Test\NW01\Reports.txt"
if ($Counter -lt 10) {
$Destination = $DropDirectory+'NW0' + $Counter
$file = Get-ChildItem -Path "C:\Users\dh0520\Documents\Powershell Test\NW0" + $Counter + "\Reports.txt"
Copy-Item $file.FullName ($Destination + $file.BaseName + "_NW0" + $Counter + "_" + $date +".txt")
}
If ($Counter -ge 10) {
$Destination = $DropDirectory+'NW' + $Counter
$file = Get-ChildItem -Path "C:\Users\dh0520\Documents\Powershell Test\NW" + $Counter + "\Reports.txt"
Copy-Item $file.FullName ($Destination + $file.BaseName + "_NW" + $Counter + "_" + $date +".txt")
}
}
I assume you are getting errors with the get-childItem. It is because you cant build the path like that. Try it this way:
$file = Get-ChildItem -Path "C:\test\NW0$($Counter)\Reports.txt"
and this way:
$file = Get-ChildItem -Path "C:\test\NW$($Counter)\Reports.txt"
Related
We deal with over a thousand files. I want to use Powershell to automate removing files older than a year for each folder path after checking to see if it exists in the archive location. It it does, it removes from backup. It if does not, it moves the file from backup to archive locations. I am not sure what is wrong with my code. It does not give me an error message that I can go off on. When I find the value for each variable, everything looks fine to me. What is happening is that the files are not being moved over.
Function Delete-Files ($src)
{
#finding date to remove i.e, if today's date is 5/19/2021, then the code would only be looking at files that are before 5/19/2020 12:00:00 AM
$date2remove = (Get-Date).Date.AddYears(-1)
$clientLocation = "\\fileshare\test\test\test\Backup\Client\"
#getting Client folder #
$clients = (Get-ChildItem $clientLocation -Directory).name
foreach ($client in $clients)
{
$srcparent = $clientLocation + $client + $src -join "\"
#ignoring the paths that do not contain $src
if (Test-Path $srcparent)
{
#getting files that are older than a year
$files2remove = Get-ChildItem $srcparent | Where-Object {( $_.LastWriteTime -lt $date2remove)}
foreach ($file2remove in $files2remove)
{
#getting the year for the last write time for each file
$year2remove = $file2remove.LastWriteTime.Year
$archive = '\\fileshare\test\test\test\archive\' + $year2remove + '\Client\' + $client + $src -join '\'
#if archive folder doesn't exist, create
if (!(Test-Path $archive))
{
New-Item -Path $archive
}
#getting the name of each file that needs to be removed
$fileName2remove = $file2remove.name
$archiveFile = $archive + $fileName2remove -join '\'
$srcFile = $srcparent + $fileName2remove -join '\'
#if file exists in archive, remove
if (Test-Path $archiveFile)
{
Remove-Item -Path $srcFile
"$srcFile"
}
#if file does not exist, move file from backup to archive
else
{
Move-Item -Path $srcFile -Destination $archive
"$archiveFile"
}
}
}
}
}
$src = "\folder1\"
Delete-Files $src
$src = "\folder1\folder2\"
Delete-Files $src
$src = "\folder3\"
Delete-Files $src
Below is the script which works locally under powershell ISE. But same under SAM Component ie Windows powershell monitor not working
Script checks for doc file under path1 and if exist. It takes copy of the file from path1 and move to Path2 by renaming with timestamp.
$directory = 'path1'
$filter = '*.doc'
$msg = ' '
$com = ","
$count = 0
$stamp = Get-Date -F yyyy-MM-dd_HH-mm
Get-ChildItem -Path $directory -Filter $filter | Foreach-Object {
$msg = $msg + $com + $_.FullName
$dest = "path1" + $_.Name
$newName = "path1" + "$($_.BaseName)_$stamp$($_.Extension)"
Copy-Item -Path $_.FullName -Destination $newName
$count = $count + 1
}
if($count -gt 0)
{
write-host 'Statistic.FileMonitor:' $count;
write-host "Message.FileMonitor: $count file found and moved, Filenames- $msg"
exit 0
}
else
{
write-host 'Statistic.FileMonitor:' $count;
write-host "Message.FileMonitor: $count files found, Filenames- $msg"
exit 0
}
When execution mode is set as Local Host. It execute. But it says no file found. Eventhough file exist under path1
When execution mode is seet as Remote. I am getting result as Down
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've written a PowerShell script to copy new files across to a shared folder on a server.
I am wondering if there is a way that after I get the list of new files in the sub folders, I can copy them over together - other than using for-each and copying them one at a time - so that I can add a progress bar.
something like this could be a starting point
# define source and destination folders
$source = 'C:\temp\music'
$dest = 'C:\temp\new'
# get all files in source (not empty directories)
$files = Get-ChildItem $source -Recurse -File
$index = 0
$total = $files.Count
$starttime = $lasttime = Get-Date
$results = $files | % {
$index++
$currtime = (Get-Date) - $starttime
$avg = $currtime.TotalSeconds / $index
$last = ((Get-Date) - $lasttime).TotalSeconds
$left = $total - $index
$WrPrgParam = #{
Activity = (
"Copying files $(Get-Date -f s)",
"Total: $($currtime -replace '\..*')",
"Avg: $('{0:N2}' -f $avg)",
"Last: $('{0:N2}' -f $last)",
"ETA: $('{0:N2}' -f ($avg * $left / 60))",
"min ($([string](Get-Date).AddSeconds($avg*$left) -replace '^.* '))"
) -join ' '
Status = "$index of $total ($left left) [$('{0:N2}' -f ($index / $total * 100))%]"
CurrentOperation = "File: $_"
PercentComplete = ($index/$total)*100
}
Write-Progress #WrPrgParam
$lasttime = Get-Date
# build destination path for this file
$destdir = Join-Path $dest $($(Split-Path $_.fullname) -replace [regex]::Escape($source))
# if it doesn't exist, create it
if (!(Test-Path $destdir)) {
$null = md $destdir
}
# if the file.txt already exists, rename it to file-1.txt and so on
$num = 1
$base = $_.basename
$ext = $_.extension
$newname = Join-Path $destdir "$base$ext"
while (Test-Path $newname) {
$newname = Join-Path $destdir "$base-$num$ext"
$num++
}
# log the source and destination files to the $results variable
Write-Output $([pscustomobject]#{
SourceFile = $_.fullname
DestFile = $newname
})
# finally, copy the file to its new location
copy $_.fullname $newname
}
# export a list of source files
$results | Export-Csv c:\temp\copylog.csv -NoTypeInformation
NOTE: that will show progress for total files regardless of size. ex: you have 2 files, one is 1 mb and the other is 50 mb. when the first file is copied, progress will be 50% because half the files are copied. if you want progress by total bytes, i highly recommend giving this function a try. just give it a source and destination. works when given a single file or a whole folder to copy
https://github.com/gangstanthony/PowerShell/blob/master/Copy-File.ps1
screenshot: http://i.imgur.com/hT8yoUm.jpg
hi i am trying to unzip folders and sub folders i have tried different ways and script but no luck.
Can some one help on this
$Date = Get-Date
#
$folder_date = $Date.ToString("yyyy-MM-dd_HHmmss")
$content = get-childitem 'C:\Deployments'
$sortedContent = $content | Sort-Object LastWriteTime -Descending
# 1. LIST BACKUPS
write-host "This is the list of all the Deployments :"
$count = 1
foreach ($item in $sortedContent)
{
#Edit: Now with auto-incrementing counter
Write-Host ("{0}: {1}" -f $count, $item.Name)
$count++
}
$itemNumber = Read-Host "Please select which deployments you want to copy "
$itemNumber = $itemNumber -1
if($sortedContent[$itemNumber].PSIsContainer -eq $true)
{
$src = $sortedContent[$itemNumber].FullName + "\"
$Date = Get-Date
$folder_date = $Date.ToString("yyyy-MM-dd_HHmm")
$tempPath = 'C:\_Temp\Restore' + $folder_date
if (!(Test-Path -path $tempPath))
{
New-Item $tempPath -type directory
}
$TabletzipPath = $src + "table.zip"
$AdminzipPath = $src + "admin.zip"
.\unzip.ps1 $src $tempPath
.\unzip.ps1 $TabletzipPath $tempPath
.\unzip.ps1 $AdminzipPath $tempPath
}
$Shell = new-object -com shell.application
$Zip = $Shell.NameSpace($PathToZip)
ForEach($Item in $Zip.items())
{
$Shell.Namespace($ExtractPath).copyhere($Item)
}
If your just looking for an easy & quick way of doing this.
You can use this function:
Unzip-File -File C:\location.zip -Destination E:\destination
Need this script:
http://gallery.technet.microsoft.com/scriptcenter/PowerShell-Function-to-727d6200
Using jar unzipping: copy-paste it into PowerShell ISE or create a .ps1 file with this code:
#choose directory where your script is
cd $PSScriptRoot
#do for each file in your directory, -recurse stands for all subfolders, *.jar stands for all files with jar extension
foreach ($file in (dir -Recurse *.jar))
{
#Uncomment this to check files this script is going to unzip (don't forget to comment 7z line below to avoid operation)
#Write-Host ("Dir for file " + $file.Name + " is " + $file.Directory)
#put here full path to 7z if there is no system env (or just make it) for that
#x stands for eXtract files with full paths
#-o is for output folder (example of usage -oc:\test\)
7z x $file.FullName ("-o"+$file.Directory)
}
It should unzip everything you need directly to the folder where your .jar (or any other archive) is.