powershell - unable to exclude folders during recursive copy - powershell

I am new to powershell and am running into a problem while trying to exclude certain directories during recursive copy. Any help is appreciated!
Thanks in advance.
$Date = Get-Date
$Date = $Date.adddays(-1)
$destPath = "\\destination\test"
$srcPath = "H:\program files\symphony\Save"
$srcPathRemits = “H:\program files\symphony\files"
$destDrive = "X:"
$User = "user"
$Password = "password"
$exclude = #('H:\program files\symphony\files\Temp\*','H:\program files\symphony\files\Other\*','H:\program files\symphony\files\etc\*','H:\program files\symphony\files\ParsedXML\*')
$net = new-object -ComObject WScript.Network
$net.MapNetworkDrive($destDrive, $destPath, $false, $User, $Password)
gci -recurse -path $srcPathRemits -Exclude $exclude | ? {!($_.psiscontainer) -AND $_.lastwritetime -gt $Date} | % { write-host $_.fullname; Copy-Item -path $_.fullname -destination $destDrive}
$net.RemoveNetworkDrive($destDrive,"true","true")

You didn't say what the problem was, but I'll assume that the directories ($exclude) were not properly excluded. Try this instead, for the gci line:
Get-Item -Path H:\program files\symphony\files\* -Exclude Temp, Other, etc, ParsedXML | Get-ChildItem -recurse | ? {!($_.psiscontainer) -AND $_.lastwritetime -gt $Date} | % { write-host $_.fullname; Copy-Item -path $_.fullname -destination $destDrive}

Related

I am trying to get the files in zip format which were newly created around two days ago using powershell and I am not getting any output

$Servers = Get-content 'D:\utils\Backup\SBX servers.txt'
foreach($Path in $Servers){
$Path = "E:\Backup"
$result = Get-ChildItem E:\Backup\*_DB.zip -Recurse -Force -File |Format-Wide| Where-Object { $_.LastWriteTime -gt (get-date).AddDays(-1)}
$result
}
you were not far from the solution, but there are multiple problem with your syntax. First you should not "filter" (where-object), after "formating" (Format-wide).
foreach($Path in $Servers){
$Path = "E:\Backup"
$result = Get-ChildItem E:\Backup*DB.zip -Recurse -Force -File | Where-Object { $_.LastWriteTime -gt (get-date).AddDays(-1)}
$result | Format-Wide
}
you were missing the "underscore" in your filter too: "$." -> "$_."

How can I get Powershell to generate logs after moving files?

Hi this is the first time I create a program using powershell, I created a powershell script to move old files that are not in use to a NAS, the code works as what I want, but I need a Log.txt file for find out what files have been moved. can someone please help me?
$Date = Get-Date -UFormat %d-%m-%Y
$Source = 'C:\Source\'
$Temp = 'C:\Backup-Temp\'
$Nas = 'D:\Destination\'
$Ext = "*.zip","*.rar"
$SetTime = '-5'
New-Item -Path $Temp -Name "Backup-$Date" -ItemType "directory"
Foreach ($Ext in $Ext) {
get-childitem -Path "$Source" -Recurse |
Where-object {$_.LastWriteTime -lt (get-date).AddDays($SetTime) -and $_.name -like "$Ext"} |
Move-item -destination "$Temp\Backup-$Date" |
Compress-Archive -Path "$Temp\Backup-$Date" -DestinationPath "$Nas\Backup-$date.Zip"
}
$Date = Get-Date -UFormat %d-%m-%Y
$Source = 'C:\Source\'
$Temp = 'C:\Backup-Temp\'
$Nas = 'D:\Destination\'
$Ext = "*.zip","*.rar"
$SetTime = '-5'
$LogFileFullName = 'c:\tmp\log.txt'
function Write-Log([string]$msg){
Out-File -FilePath $LogFileFullName -InputObject "$([DateTime]::Now): $msg" -Append
}
New-Item -Path $Temp -Name "Backup-$Date" -ItemType "directory"
Foreach ($Ext in $Ext) {
get-childitem -Path "$Source" -Recurse |
Where-object {$_.LastWriteTime -lt (get-date).AddDays($SetTime) -and $_.name -like "$Ext"} |
ForEach-Object {
Move-item $_.FullName -destination "$Temp\Backup-$Date" |
Compress-Archive -Path "$Temp\Backup-$Date" -DestinationPath "$Nas\Backup-$date.Zip"
Write-Log $_.FullName
}
}
You could just add the following to your chain of piped commands:
Add-Content $logfile "$_.name`n"
where $logfile is set to a static filename prior.
I may be old-fashioned, but having so many commands in one chain is prone to failure. It would be more resilient to break-up the chain so that you can include some error checking along the way.
A better but less desirable option would be to put your chain within a try/catch block.
Best of luck.

Copy everything except files on the list

I am trying to copy all files recursively from a:\ to b:\, except those whose metadata is present in a:\list.txt. The list.txt pattern is LastWriteTimeYYYY-MM-DD HH:MM:SS,size,.fileextension, for example:
2001-01-31 23:59:59,12345,.doc
2001-01-31 23:59:59,12345,.txt
2001-01-31 23:59:00,456,.csv
...so any and all files, anywhere in the a:\ dir tree, matching these metadata should not be copied.
I seem to be having trouble with the Where-Object in order to exclude the items on the list.txt, but copy everything else:
$Source = "C:\a"
$Target = "C:\b"
$List = Import-Csv list.txt -Header LastWriteTime,Size,Name
$Hash = #{}
ForEach ($Row in $List){
$Key = ("{0},{1},.{2}" -F $Row.LastWriteTime,$Row.Size,$Row.Name.Split('.')[-1].ToLower())
IF (!($Hash[$Key])) {$Hash.Add($Key,$Row.Name)}
}
$Hash | Format-Table -Auto
Get-Childitem -Path $Source -Recurse -File | Where-Object {$Hash -eq $Hash[$Key]}| ForEach-Object {$Key = ("{0},{1},{2}" -F ($_.LastWriteTime).ToString('yyyy-MM-dd HH:mm:ss'),$_.Length,$_.Extension.ToLower())
#$Key
If ($Hash[$Key]){
$Destination = $_.FullName -Replace "^$([RegEx]::Escape($Source))","$Target"
If (!(Test-Path (Split-Path $Destination))){MD (Split-Path $Destination)|Out-Null}
$_ | Copy-Item -Destination $Destination
}
}
I propose you a simplification of your code :
$Source = "C:\a\"
$Target = "C:\b\"
New-Item -ItemType Directory $Target -Force | Out-Null
$List = Import-Csv list.txt -Header LastWriteTime,Length,Extension
Get-Childitem $Source -Recurse -File | %{
$File=$_
$exist=$List | where {$_.LastWriteTime -eq $File.LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') -and $_.Length -eq $File.Length -and $_.Extension -eq $File.Extension} | select -first 1
if ($exist -ne $null) {continue}
New-Item -ItemType Directory $File.DirectoryName.Replace($Source, $Target) -Force | Out-Null
Copy-Item $File.FullName $File.FullName.Replace($Source, $Target) -Force
}

How can I delete files older than x days?

I want to delete files older than x days, 5 in the below example. I tried to use below, but its not working nor its throwing an error.
Get-ChildItem –Path “E:\del” –Recurse | Where-Object{$_.CreationTime –lt(Get-Date).AddDays(-5)} | Remove-Item
Here is an approach you could take.
$Path = E:\del
$DaysBack = "-5"
$CurrentDate = Get-Date
$DatetoDelete = $CurrentDate.AddDays($DaysBack)
#delete files from $Path directory that are older than $Daysback
Get-ChildItem -Path $Path -Include * -Recurse | Where-Object {$_.LastWriteTime -lt $DatetoDelete} | Remove-Item -ErrorAction SilentlyContinue -Recurse -Force
Try this:
$cleanup_days = 5
$cleanup_lastWrite = $now.AddDays(-$cleanup_days)
Get-ChildItem -Path "E:\del" | Where-Object { $_ -is [System.IO.FileInfo] } | ForEach-Object {
If ($_.LastWriteTime -lt $cleanup_lastWrite)
{
Remove-Item $("E:\del\" + $_)
}
}

Delete files which are not locked (in use)

I'm trying to delete all files (not folders) in %TEMP% which are older than 30 days. The problem is that some files are in use by a program so they can not be deleted. I tried to solve the problem as follow:
function IsFileLocked($filePath){
#write-host $filePath
Rename-Item $filePath $filePath -ErrorVariable errs -ErrorAction SilentlyContinue
$errs.Count
if ($errs.Count -ne 0)
{
return $true #File is locked
}
else
{
return $false #File is not locked
}
}
$Path= "$env:temp"
if ((Test-Path -Path $Path) -ieq $true)
{
$Daysback = '-30'
$CurrentDate = Get-Date
$DatetoDelete = $CurrentDate.AddDays($Daysback)
get-childitem $Path -recurse | Where-Object {$_.LastWriteTime -lt $DatetoDelete } |
Where-Object {$_.PSIsContainer -eq $False }| Where-Object {(IsFileLocked -filePath "($_)") -eq $false }# | remove-item -force #-WhatIf
}
The problem is that (IsFileLocked -filePath "($_)") -eq $false doesn't return any element.
Is it possible that get-childitem blocks the files, so that all of them are locked when I run get-childitem?
Any other ideas how to solve this problem?
How about just removing files older than 30 days and ignore the errors:
$old = (Get-Date).AddDays(-30)
Get-ChildItem $env:TEMP -Recurse |
Where-Object {!$_.PSIsContainer -and $_.LastWriteTime -lt $old } |
Remove-Item -Force -ErrorAction SilentlyContinue