I'm relatively new to PowerShell and have only been doing "light" scripting to automate a few tasks at work.
Most of the time, I can Google and get the answer(s) I need, with maybe some minor tweaking/experimenting.
But I need some help with this one as I can't find the answer I'm looking so hoping someone here might be able to help me.
DETAILS:
I am provided a directory link on the network drive to either sub-folders containing ".zips" or a folder with ".zips" only.
The latter case works for my current script (will be provided further down) to do it's job but the former is where I'm struggling.
TL;DR - I need the script to go into each folder, extract each ".zip" into a "Temp" folder and then look for a "backup" image file (file type may vary) and then copy it out to the sub-folder and rename to the same as the ".zip" it was extracted from.
Again, my script works if I'm physically in the folder with the ".zip" files but not if the ".zip" files are in sub-folders as I can't get it recursively go into each folder and run the script.
EXAMPLE SETUP:
FolderA\FolderB\1.zip
FolderA\FolderB\2.zip
FolderA\FolderB\3.zip
FolderA\FolderC\1.zip
FolderA\FolderC\1.zip
FolderA\FolderC\1.zip
Script below:
#Current Directory of ".zip" files
$fileLocation = read-host "Type/Paste location of creatives"
#replace server path with drive letter
if (Test-Path \\server\path\* -PathType Leaf) {
$serverPathName = "\\server\path\"
$driveLetter = "D:\"
$fileLocation = ($fileLocation -replace [regex]::Escape($serverPathName),$driveLetter)
}
$fileLocation = Resolve-Path $fileLocation
Write-Output $fileLocation
#change directory to the one provided
$zipFilesPath = cd "$fileLocation"
$currentDirectory = pwd
#File type of backup
#Note: `n = new line
write-host "`nChoose Creative Backup File Type"
Write-Host "1. JPG"
Write-host "2. JPEG"
Write-Host "3. PNG"
Write-Host "4. GIF"
$typeFilter = Read-Host "`nType? 1/2/3/4"
if($typeFilter -eq '1'){
$typeFilter = 'jpg'
}
elseif($typeFilter -eq '2'){
$typeFilter = 'jpeg'
}
elseif($typeFilter -eq '3'){
$typeFilter = 'png'
}
elseif($typeFilter -eq '4'){
$typeFilter = 'gif'
}
else {
write-host "ERROR! Incorrect Input!"
Write-Host "Exiting Script..."
start-sleep -seconds 1.5
Exit
}
#Files Location
$ZipFilesPath = "$currentDirectory\*.zip"
#Unzip To Same Location
$UnzipPath = "$currentDirectory"
#Check if Temp Folder exists
$TempCheck = Test-Path "$currentDirectory\Temp"
If ($TempCheck -eq $false) {
#Create Temp Folder
New-Item -ItemType directory -Path "$currentDirectory\Temp" -Force
}
$TempPath = "$currentDirectory\Temp"
$Shell = New-Object -com Shell.Application
$Location = $Shell.NameSpace($TempPath)
$ZipFiles = Get-Childitem $ZipFilesPath -Recurse -Include *.ZIP
$FileCounter = 1
#Clear Initilisation Vars from Console
clear
foreach ($ZipFile in $ZipFiles) {
#Get The Base Filename without the extension
$ZipFileActualName = [io.path]::GetFileNameWithoutExtension($ZipFile.FullName)
write-host File: $ZipFileActualName
$ZipFolder = $Shell.NameSpace($ZipFile.fullname)
$Location.Copyhere($ZipFolder.items(), 1040)
#Find and rename backups
$BackupFiles = Get-ChildItem $TempPath -Filter *backup*.$typeFilter -Recurse
$BackupFiles |% {Move-Item $_.Fullname $UnzipPath/$ZipFileActualName'_backup'.$typefilter}
#Clear Temp Folder
Get-ChildItem -Path "$currentDirectory\Temp" -Include *.* -File -Recurse | foreach { $_.Delete()}
#Move Along to Next File
$FileCounter++
}
#Delete Temp Folder
Remove-Item "$currentDirectory\Temp" -Force -Recurse
#Clear Console
clear
#Read-Host -Prompt “Press Enter to exit”
#start .\
I'm open to any suggestions provided or areas of improvement. If I need to completely change the code, I don't mind. Long as it works for both scenarios.
Thanks.
UPDATE
Modified script as per HAL9256's instruction:
#Current Directory of creatives
$fileLocation = read-host "Type/Paste location of creatives"
if (Test-Path \\server\path\* -PathType Leaf) {
$serverPathName = "\\server\path\"
$driveLetter = "D:\"
$fileLocation = ($fileLocation -replace [regex]::Escape($serverPathName),$driveLetter)
}
$fileLocation = Resolve-Path $fileLocation
Write-Output $fileLocation
$zipFilesPath = cd "$fileLocation"
$currentDirectory = pwd
#File type of backup
#Note: `n = new line
write-host "`nChoose Creative Backup File Type"
Write-Host "1. JPG"
Write-host "2. JPEG"
Write-Host "3. PNG"
Write-Host "4. GIF"
$typeFilter = Read-Host "`nType? 1/2/3/4"
if($typeFilter -eq '1'){
$typeFilter = 'jpg'
}
elseif($typeFilter -eq '2'){
$typeFilter = 'jpeg'
}
elseif($typeFilter -eq '3'){
$typeFilter = 'png'
}
elseif($typeFilter -eq '4'){
$typeFilter = 'gif'
}
else {
write-host "ERROR! Incorrect Input!"
Write-Host "Exiting Script..."
start-sleep -seconds 1.5
Exit
}
#Files Location
$ZipFilesPath = "$currentDirectory"
#Unzip To Same Location
$UnzipPath = "$currentDirectory"
#Check if Temp Folder exists
$TempCheck = Test-Path "$currentDirectory\Temp"
If ($TempCheck -eq $false) {
#Create Temp Folder
New-Item -ItemType directory -Path "$currentDirectory\Temp" -Force
}
$TempPath = "$currentDirectory\Temp"
$Shell = New-Object -com Shell.Application
$Location = $Shell.NameSpace($TempPath)
$ZipFiles = Get-Childitem $ZipFilesPath -Recurse -Include *.ZIP
$FileCounter = 1
#Clear Initilisation Vars from Console
clear
foreach ($ZipFile in $ZipFiles) {
#Get The Base Filename without the extension
$ZipFileActualName = [io.path]::GetFileNameWithoutExtension($ZipFile.FullName)
write-host File: $ZipFileActualName
$ZipFolder = $Shell.NameSpace($ZipFile.fullname)
$Location.Copyhere($ZipFolder.items(), 1040)
#Find and rename backups
$BackupFiles = Get-ChildItem $TempPath -Filter *backup*.$typeFilter -Recurse
$BackupFiles |% {Move-Item $_.Fullname $upzipPath/$ZipFileActualName'_backup'.$typefilter}
#Clear Temp Folder
Get-ChildItem -Path "$currentDirectory\Temp" -Include *.* -File -Recurse | foreach { $_.Delete()}
#Move Along to Next File
$FileCounter++
}
#Delete Temp Folder
Remove-Item "$currentDirectory\Temp" -Force -Recurse
#Clear Console
clear
#Read-Host -Prompt “Press Enter to exit”
#start .\
That did what I need to do. But how can I modify my script so it stores the backups in their respective folder? So the backups extracted from "FolderB" stay in "FolderB", etc? Is there something I can do?
UPDATE 2
Final code - Thanks to help from HAL9256:
#Current Directory of creatives
$fileLocation = read-host "Type/Paste location of creatives"
if (Test-Path \\server\path\* -PathType Leaf) {
$serverPathName = "\\server\path\"
$driveLetter = "D:\"
$fileLocation = ($fileLocation -replace [regex]::Escape($serverPathName),$driveLetter)
}
$fileLocation = Resolve-Path $fileLocation
Write-Output $fileLocation
$zipFilesPath = cd "$fileLocation"
$currentDirectory = pwd
#File type of backup
#Note: `n = new line
write-host "`nChoose Creative Backup File Type"
Write-Host "1. JPG"
Write-host "2. JPEG"
Write-Host "3. PNG"
Write-Host "4. GIF"
$typeFilter = Read-Host "`nType? 1/2/3/4"
if($typeFilter -eq '1'){
$typeFilter = 'jpg'
}
elseif($typeFilter -eq '2'){
$typeFilter = 'jpeg'
}
elseif($typeFilter -eq '3'){
$typeFilter = 'png'
}
elseif($typeFilter -eq '4'){
$typeFilter = 'gif'
}
else {
write-host "ERROR! Incorrect Input!"
Write-Host "Exiting Script..."
start-sleep -seconds 1.5
Exit
}
#Files Location
$ZipFilesPath = "$currentDirectory"
#Unzip To Same Location
$UnzipPath = "$currentDirectory"
#Check if Temp Folder exists
$TempCheck = Test-Path "$currentDirectory\Temp"
If ($TempCheck -eq $false) {
#Create Temp Folder
New-Item -ItemType directory -Path "$currentDirectory\Temp" -Force
}
$TempPath = "$currentDirectory\Temp"
$Shell = New-Object -com Shell.Application
$Location = $Shell.NameSpace($TempPath)
$ZipFiles = Get-Childitem $ZipFilesPath -Recurse -Include *.ZIP
$FileCounter = 1
#Clear Initilisation Vars from Console
clear
foreach ($ZipFile in $ZipFiles) {
#Get The Base Filename without the extension
$ZipFileActualName = [io.path]::GetFileNameWithoutExtension($ZipFile.FullName)
write-host File: $ZipFileActualName
$ZipFolder = $Shell.NameSpace($ZipFile.fullname)
$Location.Copyhere($ZipFolder.items(), 1040)
$DestinationDir = $ZipFile.DirectoryName.Replace($ZipFilesPath,$unzipPath)
#Find and rename backups
$BackupFiles = Get-ChildItem $TempPath -Filter *backup*.$typeFilter -Recurse
$BackupFiles |% {Move-Item $_.Fullname $DestinationDir/$ZipFileActualName'_backup'.$typefilter}
#Clear Temp Folder
Get-ChildItem -Path "$currentDirectory\Temp" -Include *.* -File -Recurse | foreach { $_.Delete()}
#Move Along to Next File
$FileCounter++
}
#Delete Temp Folder
Remove-Item "$currentDirectory\Temp" -Force -Recurse
#Clear Console
clear
#Read-Host -Prompt “Press Enter to exit”
#start .\
When you specify the path:
#Files Location
$ZipFilesPath = "$currentDirectory\*.zip"
Then trying to get the files:
$ZipFiles = Get-Childitem $ZipFilesPath -Recurse -Include *.ZIP
What you essentially are saying is Get-Childitem and get only *.zip files. Because the path parameter has the wildcard filter, it will only get all the *.zip files in that directory and will not get any folders. Since you have no folders matching the *.zip wildcard, Get-Childitem won't have any folders to continue to recurse through.
The solution is to only give a base folder to the path parameter for the Get-Childitem to recurse through, and, correctly, use the -Include to apply the filter for the type. e.g.:
#Files Location
$ZipFilesPath = "$currentDirectory"
...
$ZipFiles = Get-Childitem $ZipFilesPath -Recurse -Include *.ZIP
EDIT:
To move the file to the same folder structure, when inside the loop, you simply use the replace function to replace the source Directory path (the first part of the Directory Name) with your destination base path. Then the sub folders will remain the same. e.g.
...
$DestinationDir = $ZipFile.DirectoryName.Replace($ZipFilesPath,$upzipPath)
...
$BackupFiles |% {Move-Item $_.Fullname $DestinationDir/$ZipFileActualName'_backup'.$typefilter}
Related
I'm trying to copy files to a specific folder based on a file name.
For example:
Current Folder - C:\Stuff\Old Files\
The File- 206.Little Rock.map.pdf
Destination Folder - D:\Cleanup\206\Repository
So basically the leading number on the file (206) is part of the subfolder. The "\Repository" would stay constant. Only the leading number would change.
If the file was 207.Little Rock.map.pdf then the destination folder would be
D:\Cleanup\207\Repository
I started with a code I got from here but I'm not sure how to account for the change in number and how to make it create a folder if the folder doesn't exist. So 206\Repository would probably already exist, but I would need the script to create the folder if it doesn't.
$SourceFolder = "C:\Stuff\Old Files\"
$targetFolder = "D:\Cleanup\"
$numFiles = (Get-ChildItem -Path $SourceFolder -Filter *.pdf).Count
$i=0
clear-host;
Write-Host 'This script will copy ' $numFiles ' files from ' $SourceFolder ' to ' $targetFolder
Read-host -prompt 'Press enter to start copying the files'
Get-ChildItem -Path $SourceFolder -Filter *.PDF | %{
[System.IO.FileInfo]$destination = (Join-Path -Path $targetFolder -ChildPath $Name.Repository(".*","\"))
if(!(Test-Path -Path $destination.Directory )){
New-item -Path $destination.Directory.FullName -ItemType Directory
}
[int]$percent = $i / $numFiles * 100
copy-item -Path $_.FullName -Destination $Destination.FullName
Write-Progress -Activity "Copying ... ($percent %)" -status $_ -PercentComplete $percent -verbose
$i++
}
Write-Host 'Total number of files read from directory '$SourceFolder ' is ' $numFiles
Write-Host 'Total number of files that was copied to '$targetFolder ' is ' $i
Read-host -prompt "Press enter to complete..."
clear-host;
This should do mostly what you need. You might have to tweak the destination path a bit, but that should be fairly straight forward to figure out. I Highly recommend that use a '-' as the delimiter for your file prefix as opposed to a '.' as this will prevent accidentally moving EVERY FILE in a directory if you happen to execute it in the wrong place.
Also, when you write a script, do create functions to do individual units of work, and then call those functions at the end. It's much easier to modify, and debug that way.
<#
.SYNOPSIS
Moves files from source to destination based on FileName
Creates destination folder if it does not exist.
.DESCIPTION
The script expects files with a prefix defined by a hyphen '-' i.e. 200-<filename>.<ext>.
There is no filename validation in this script; it will *probably* skip files without a prefix.
A folder based on the prefix will be created in the destination.
If your file is name string-cheese.txt then it will be moved to $DestinationIn\string\string-cheese.txt
.PARAMETER SourceIn
Source Path (folder) where your files exist.
.PARAMETER DestinationIn
Target Path (folder) where you want your files to go.
.EXAMPLE
& .\CleanUp-Files.ps1 -SourceIn "C:\Users\User\Documents\Files\" -DestinationIn "C:\Users\User\Documents\Backup\" -Verbose
.NOTES
Author: RepeatDaily
Email: RepeatedDaily#gmail.com
This script is provided as is, and will probably work as intended. Good Luck!
https://stackoverflow.com/questions/50662140/copy-file-based-a-specified-folder-based-on-file-name-create-folder-if-it-doesn
#>
[CmdletBinding()]
param (
[string]$SourceIn,
[string]$DestinationIn
)
function Set-DestinationPath {
param (
[string]$FileName,
[string]$Target
)
[string]$NewParentFolderName = $FileName.SubString(0,$FileName.IndexOf('-'))
[string]$DestinationPath = Join-Path -Path $Target -ChildPath $NewParentFolderName
return $DestinationPath
}
function Create-DestinationPath {
[CmdletBinding()]
param (
[string]$Target
)
if (-not(Test-Path -Path $Target)) {
Try {
New-Item -ItemType Directory -Path $Target | Write-Verbose
}
catch {
Write-Error $Error[0];
}
}
else {
Write-Verbose "$Target exists"
}
}
function Move-MyFiles {
[CmdletBinding()]
param (
[string]$Source,
[string]$Destination
)
[array]$FileList = Get-ChildItem $Source -File | Select-Object -ExpandProperty 'Name'
foreach ($file in $FileList) {
[string]$DestinationPath = Set-DestinationPath -FileName $file -Target $Destination
Create-DestinationPath -Target $DestinationPath
try {
Move-Item -Path (Join-Path -Path $Source -ChildPath $file) -Destination $DestinationPath | Write-Verbose
}
catch {
Write-Warning $Error[0]
}
}
}
Move-MyFiles -Source $SourceIn -Destination $DestinationIn
Here is something you might try. The number for the directory is grabbed from a regex match, "(\d+)\..*.pdf". When you are confident that the correct file copies will be made, remove the -WhatIf from the Copy-Item cmdlet.
I did not try to address the Write-Progress capability. Also, this will only copy .pdf files that begin with digits followed by a FULL STOP (period) character.
I do not fully understand the need for all of the Write-Host and Read-Host usage. It is not very PowerShell. pwshic
$SourceFolder = 'C:/src/t/copymaps'
$targetFolder = 'C:/src/t/copymaps/base'
$i = 0
$numFiles = (
Get-ChildItem -File -Path $SourceFolder -Filter "*.pdf" |
Where-Object -FilterScript { $_.Name -match "(\d+)\..*.pdf" } |
Measure-Object).Count
clear-host;
Write-Host 'This script will copy ' $numFiles ' files from ' $SourceFolder ' to ' $targetFolder
Read-host -prompt 'Press enter to start copying the files'
Get-ChildItem -File -Path $SourceFolder -Filter "*.pdf" |
Where-Object -FilterScript { $_.Name -match "(\d+)\..*.pdf" } |
ForEach-Object {
$NumberDir = Join-Path -Path $targetFolder -ChildPath $Matches[1]
$NumberDir = Join-Path -Path $NumberDir -ChildPath 'Repository'
if (-not (Test-Path $NumberDir)) {
New-Item -ItemType Directory -Path $NumberDir
}
Copy-Item -Path $_.FullName -Destination $NumberDir -Whatif
$i++
}
Write-Host 'Total number of files read from directory '$SourceFolder ' is ' $numFiles
Write-Host 'Total number of files that was copied to '$targetFolder ' is ' $i
Read-host -prompt "Press enter to complete..."
clear-host;
Iv got an application that produces a ZIP file with a HTML document inside of it. However the extracted HTML file is not named the same as the zip file (for some strange reason that I have no control over).
I need to extract the zip file and rename the extracted file the same as the zip file name however I am unsure where this would slot in on my script some help would be appreciated please, script below:
#Files Location
$ZipFilesPath = "C:\Test\"
#Unzip To Same Location
$UnzipPath = "C:\Test\"
$Shell = New-Object -com Shell.Application
$Location = $Shell.NameSpace($UnzipPath)
$ZipFiles = Get-Childitem $ZipFilesPath -Recurse -Include *.ZIP
$FileCounter = 1
#Clear Initilisation Vars from Console
clear
foreach ($ZipFile in $ZipFiles) {
#Get The Base Filename without the Filepath
$ZipFileActualName = [io.path]::GetFileNameWithoutExtension($ZipFile.FullName)
write-host "File: " $ZipFileActualName
$ZipFolder = $Shell.NameSpace($ZipFile.fullname)
$Location.Copyhere($ZipFolder.items(), 1040)
#Move Along to Next File
$FileCounter++
}
Final Solution (With Added Piece From Nick Cox below)
#Location Of ZIP Files Defined Here
$ZipFilesPath = "C:\Test\";
#Unzip To Temp Folder Defined Here
$TempPath = "C:\Test\Temp"
#Create Our Temp File If It Doesnt Exist (Will Be Deleted Again)
If(!(test-path $TempPath))
{
New-Item -ItemType Directory -Force -Path $TempPath
}
$Shell = New-Object -com Shell.Application
$Location = $Shell.NameSpace($TempPath)
$ZipFiles = Get-Childitem $ZipFilesPath -Recurse -Include *.ZIP
$FileCounter = 1
#Clear Initilisation Vars from Console
clear
foreach ($ZipFile in $ZipFiles) {
#Get The Base Filename without the Filepath
$ZipFileActualName = [io.path]::GetFileNameWithoutExtension($ZipFile.FullName)
write-host "File: " $ZipFileActualName
$ZipFolder = $Shell.NameSpace($ZipFile.fullname)
$Location.Copyhere($ZipFolder.items(), 1040)
#Move Our Temp Files
$HtmlFiles = Get-ChildItem $TempPath *.html
$HtmlFiles |% {Move-Item $_.Fullname "$UnzipPath/$ZipFileActualName.html"}
#Move Along to Next File
$FileCounter++
}
#Remove Our .ZIP Folders
Get-ChildItem -Path $ZipFilesPath -Include *.zip* -File -Recurse | foreach { $_.Delete()}
#Remove Our Temp Folder
Remove-Item –path $TempPath –recurse
Why not extract to a temp location and copy from there to the destination?
#Files Location
$ZipFilesPath = "C:\Test\"
#Unzip To Same Location
$UnzipPath = "C:\Test\"
$TempPath = "C:\Test\Temp"
$Shell = New-Object -com Shell.Application
$Location = $Shell.NameSpace($TempPath)
$ZipFiles = Get-Childitem $ZipFilesPath -Recurse -Include *.ZIP
$FileCounter = 1
#Clear Initialisation Vars from Console
clear
foreach ($ZipFile in $ZipFiles) {
#Get The Base Filename without the Filepath
$ZipFileActualName = [io.path]::GetFileNameWithoutExtension($ZipFile.FullName)
write-host "File: " $ZipFileActualName
$ZipFolder = $Shell.NameSpace($ZipFile.fullname)
$Location.Copyhere($ZipFolder.items(), 1040)
$HtmlFiles = Get-ChildItem $TempPath *.html
$HtmlFiles |% {Move-Item $_.Fullname "$UnzipPath/$ZipFileActualName.html"}
#Move Along to Next File
$FileCounter++
}
By the way, if you're using PowerShell >= 5.0 you can unzip natively with Expand-Archive.
foreach ($ZipFile in $ZipFiles) {
#Get The Base Filename without the Filepath
$ZipFileActualName = [io.path]::GetFileNameWithoutExtension($ZipFile.FullName)
write-host "File: " $ZipFileActualName
$ZipFolder = $Shell.NameSpace($ZipFile.fullname)
$Location.Copyhere($ZipFolder.items(), 1041)
$HtmlFiles = Get-ChildItem $TempPath *.html
$HtmlFiles |% {Move-Item $_.Fullname "$UnzipPath/$ZipFileActualName.html"}
#Move Along to Next File
$FileCounter++
}
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
}
HI Everyone I am trying to write a script for my powershell practice to move a file from one folder to another based on user input. The script works fine but only if the file exists in the folder same as the script. Can someone please help me what i am doing wrong or try to help with logic
$destination = 'P:\Powershell practice\Movefolder'
$ListFile = "P:\Powershell practice\"
get-childitem $ListFile
$Filename = Read-host -prompt "Please Enter File to be moved"
$FileExists = test-path $Filename
If ($FileExists -eq $True) {
move-item $Filename $destination
Write-Host "File is moved to $destination "
}
else
{write-host "No File Found"}
You need to determine the full file path otherwise the test-path check whether the file exists at the current location. You can use the Join-Path cmdlet to join the pass:
$FilePath = Join-Path $ListFile $FileName
$FileExists = test-path $FilePath
If ($FileExists -eq $True) {
move-item $FilePath $destination
...
Offtopic:
You could also use a Grid-View where the user can select multiple files and press the ok button at the bottom to copy the files ;-):
$destination = 'P:\Powershell practice\Movefolder'
$ListFile = 'P:\Powershell practice\'
$filesToMove = get-childitem $ListFile | Out-GridView -OutputMode Multiple
$filesToMove | % { move-item $_.FullName $destination}
Incase if someone needs. Below is the correct working script for this
$destination = 'P:\Powershell practice\Movefolder'
$ListFile = 'P:\Powershell practice\'
get-childitem $ListFile
$Filename = Read-host -prompt "Please Enter File to be moved"
$FilePath = Join-Path $ListFile $FileName
$FileExists = test-path $FilePath
If ($FileExists -eq $True) {
move-item $FilePath $destination
Write-Host "File is moved to $destination "
}
else
{write-host "No File Found"}
I'm writing a script to delete pdf files older than 6 months in folder with the 'Email' prefix.
However, my second dir command within my foreach never runs, its code is blocked.
$Now = Get-Date;
$DaysTillDelete = "180";
$LastWrite = $Now.AddDays(-$DaysTillDelete);
$TargetFolder = "C:\Test EMDATA\EMDATA\";
$BackupPath = "\\SHPFS02\IT\EmPower Old";
$EmailFolders = #();
if(-Not(Test-Path -path ($TargetFolder + "\OldFiles" ))) {
mkdir -p ($TargetFolder +"\OldFiles");
}
$Network = Test-Path $BackupPath
#New-PSDrive -Name O -PSProvider FileSystem -Root "$BackupPath"; #-Credential $cred
Write-Host "Running Script"
dir $TargetFolder | %{
# Only delete files with the Email prefix
$name = $_.Name;
if ($_.Name.Length -le 5) {return;}
$id = $_.Name.SubString(0,5);
if ($id -eq "Email")
{
Write-Host "Found slip folder"
$EmailFolders += $TargetFolder + $_;
}
}
ForEach ($folder in $EmailFolders)
{
Write-Host $folder;
dir -path $folder -include *.pdf | %{
Write-Host "Checking" $name;
# Only select files older than 6 months
if( $_.LastWriteTime -le "$LastWrite")
{
$activeItem = Get-Item $TargetFolder + $_;
#Move files into oldfiles
Write-Host $TargetFolder
move-item -path $activeItem -destination ($TargetFolder + "OldFiles\");
if ($Network)
{
move-item -path $activeItem -destination "O:\";
}
Write-Host $_;
remove-item $activeItem;
Write-Host "Deleting" + $name;
}
}
}
The script works till line 31 but doesn't continue on past line 32 and being a fairly beginner PS user I can't see why.
Only use -include with the -recurse parameter.
http://technet.microsoft.com/en-us/library/hh849800.aspx
The Include parameter is effective only when the command includes the
Recurse parameter or the path leads to the contents of a directory,
such as C:\Windows*, where the wildcard character specifies the
contents of the C:\Windows directory.
What you want instead is the -filter parameter:
dir -path $folder -filter *.pdf