Copying PDFs while keeping folder structure - powershell

So I am trying to copy all the folders and keep the structure that only contain pdf's. I am not sure if there is a way to do this, I have managed to get some of the script to work.
However, when I run it, it copies all the folders even if they don't have PDFs in them. Also I have noticed that my script fails to check the folder and creates in the next directory down. For example:
C:\temp copied once shows C:\temp.
If I was to run the script again it now shows C:\temp\temp
Below is my Code:
$Criteria = *.pdf
$Trial = c:\temp\folders.txt
$Server = \\file
$Path = homedrives\home
$des = $Path
$safe = Get-Content $Trial
$safe | ForEach-Object {
#find drive-delimeter
$first = $_.IndexOf("\\");
if ($first -eq 1) {
#stripe it
$newdes = Join-Path -Path $des -ChildPath #($_.Substring(0,1)+$_.Substring(2))[0]
} else {
$newdes = Join-Path -Path $des -ChildPath $_
}
$err = 0
$fr = 0
$folder = Split-Path -Path $newdes -Parent
#check if folder exists"
$void = Get-Item $folder -ErrorVariable err -ErrorAction SilentlyContinue
if ($err.Count -ne 0) {
#create when it doesn't
$void = New-Item -Path $folder -ItemType Directory -Force
}
#$void = Copy-Item -Path $_ -destination $newdes -Force -Verbose
$void = Copy-Item -Path $_ -destination $newdes -Filter $Criteria -Recurse -Force -ErrorVariable fr -ErrorAction SilentlyContinue
$CR = "`r`n"
$RR = $fr[0].CategoryInfo.TargetName.ToString()
"List of PDF's that Failed To Copy" + $CR + "--------------------------------------------------------------" + $CR + $RR | Out-file -Append $Er
Write-Host $_
}
Write-Host $newdes

ok, so looks like I have cracked it, for future reference, my code actually uses user input to determine locations, it then selects the criteria the user requested and then copies only files with the extensions defined. It copies the folder structure without duplicating and although the filename limitations of windows still exist, there is an error log that is produced that shows the files that have failed to copy. Thanks for all your assistance in this matter.
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null -ErrorAction Stop
$Server = "\\" + [Microsoft.VisualBasic.Interaction]::InputBox("Please choose a Server to search", "Server Choice")
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null -ErrorAction Stop
$Choice = [Microsoft.VisualBasic.Interaction]::InputBox("Please choose a File Path to search", "File Path Choice") + "\"
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null -ErrorAction Stop
$Ext = [Microsoft.VisualBasic.Interaction]::InputBox("Please choose a File type i.e. *.PST", "Location Choice")
#$Ext.ToUpper()
$Criteria = "*." + $Ext
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null -ErrorAction Stop
#$FPath = [Microsoft.VisualBasic.Interaction]::InputBox("Please choose a path to copy to", "Location Choice")
$Path = [Microsoft.VisualBasic.Interaction]::InputBox("Please choose a folder to store the data", "Path Choice") + "\"
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null -ErrorAction Stop
#$Name = [Microsoft.VisualBasic.Interaction]::InputBox("Please choose a filename", "File Name Choice")
$Search = $Server +"\"+ $Choice
$FileName = $Path
$Info = $Path + "FileCopy.txt"
$Trial = $Path + "Folders.txt"
$Type = $Path + "$Ext's.txt"
$Er= $Path + "Failed Copying.txt"
$Trial2 = $Path + "Folders.txt"
#$Server2 = "\" + $Server
#$File = $Path + $Name
if( -Not (Test-Path -Path $Path ) )
{
New-Item -ItemType directory -Path $Path |out-null
}
Else{
[System.Windows.MessageBox]::Show('The directory already exists','Error','Ok','Error')
-ErrorAction SilentlyContinue
}
$properties = #(
'Directory'
' '
'Name'
' '
#{
Label = 'Size'
Expression = {
if ($_.Length -ge 1GB)
{
'{0:F2} GB' -f ($_.Length / 1GB)
}
elseif ($_.Length -ge 1MB)
{
'{0:F2} MB' -f ($_.Length / 1MB)
}
elseif ($_.Length -ge 1KB)
{
'{0:F2} KB' -f ($_.Length / 1KB)
}
else
{
'{0} bytes' -f $_.Length
}
}
}
$result = Get-ChildItem -Path $Search -Recurse -Include $Criteria -ErrorAction SilentlyContinue
) | Out-Null
$Result
#Get-ChildItem -Path $Search -Recurse -Include *.pst -ErrorAction SilentlyContinue |
$Folders = (get-childitem -Path $Search | where-object { $_.PSIsContainer }).Count
If (Test-Path $Search) {
<#Write-Host
Write-Host "Listing All Found In $Path" -ForegroundColor "Yellow"
Write-Host "=========================================" -ForegroundColor "Yellow"#>
Add-Type -assembly System.Windows.Forms
## -- Create The Progress-Bar
$ObjForm = New-Object System.Windows.Forms.Form
$ObjForm.Text = "Progress-Bar of searched folders"
$ObjForm.Height = 100
$ObjForm.Width = 500
$ObjForm.BackColor = "White"
$ObjForm.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedSingle
$ObjForm.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
## -- Create The Label
$ObjLabel = New-Object System.Windows.Forms.Label
$ObjLabel.Text = "Starting. Please wait ... "
$ObjLabel.Left = 5
$ObjLabel.Top = 10
$ObjLabel.Width = 500 - 20
$ObjLabel.Height = 15
$ObjLabel.Font = "Tahoma"
## -- Add the label to the Form
$ObjForm.Controls.Add($ObjLabel)
$PB = New-Object System.Windows.Forms.ProgressBar
$PB.Name = "PowerShellProgressBar"
$PB.Value = 0
$PB.Style="Continuous"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 500 - 40
$System_Drawing_Size.Height = 20
$PB.Size = $System_Drawing_Size
$PB.Left = 5
$PB.Top = 40
$ObjForm.Controls.Add($PB)
## -- Show the Progress-Bar and Start The PowerShell Script
$ObjForm.Show() | Out-Null
$ObjForm.Focus() | Out-NUll
$ObjLabel.Text = "Starting. Please wait ... "
$ObjForm.Refresh()
Start-Sleep -Seconds 1
Out-Null
## -- Execute The PowerShell Code and Update the Status of the Progress-Bar
$result = Get-ChildItem -Path $Search -Recurse -Include $Criteria -ErrorAction SilentlyContinue
$Counter = 0
ForEach ($Item In $Result) {
## -- Calculate The Percentage Completed
$Counter++
[Int]$Percentage = ($Counter/$Result.Count)*100
$PB.Value = $Percentage
$ObjLabel.Text = "Scanning $Folders Folders For $Criteria in $Search"
#$ObjLabel.Text = "Found $counter $Criteria in $Search"
$ObjForm.Refresh()
Start-Sleep -Milliseconds 150
# -- $Item.Name
#"`t" + $Item.Path
}
$ObjForm.Close()
#Write-Host "`n"
}
Else {
#Write-Host
#Write-Host "`t Cannot Execute The Script." -ForegroundColor "Yellow"
#Write-Host "`t $Search Does Not Exist in the System." -ForegroundColor "Yellow"
#Write-Host
}
Out-Null
Sort-Object -Property DirectoryName |
Format-Table -Property $properties |
out-file $Info
$Search| out-file -Append $Trial
#$Search | Out-File -Append $Trial2
$result | out-file -Append $Info
$result | Select Name | out-file -Append $Type
$CR = "`r`n"
"List of PDF's that Failed To Copy" + $CR + $CR + "--------------------------------------------------------------" | Out-file $Er
$des = $Path
#$PDFs= get-content $Type
$safe = Get-Content $Trial
#$Ten = #($Criteria)
$safe | ForEach-Object{
#find drive-delimeter
$first=$_.IndexOf("\\");
if($first -eq 0){
#stripe it
$newdes=Join-Path -Path $des -ChildPath #($_.Substring(0,1)+$_.Substring(2))[0]
}
$newdes=Join-Path -Path $des -ChildPath $_
$err=0
$fr=0
$folder=Split-Path -Path $newdes -Parent
$folders=Split-Path -Path $newdes -leaf
#$fy = $folder + "\" +$folders
#check if folder exists"
$void=Get-Item $newdes -ErrorVariable err -ErrorAction SilentlyContinue #-verbose
If(!(Test-Path -Path $newdes) ){
$err=1
}
if($err.Count -ne 0){
#create when it doesn't
$void=New-Item -Path $folder -ItemType Directory #-verbose
}
#$void=Copy-Item -Path $_ -destination $newdes -Force -Verbose
$void=Copy-Item -Path $_ -destination $folder -Filter $Criteria -Recurse -Container -Force -ErrorVariable fr -ErrorAction SilentlyContinue -verbose
write-host "------------------------------------------------------- Break -------------------------------------------------------" -ForegroundColor Green
foreach($re in $fr){
$RR = $re[0].CategoryInfo.TargetName.ToString()
$X5 = $re[0].CategoryInfo.Reason.ToString()
$X6 = $re[0].TargetObject.DirectoryName.ToString()
$X6 + $CR + $X5 + "---" + $RR + $CR | Out-file -Append $Er
}
write-host "`n" $_
}
write-host "`n------------------------------------------------------- End of Script -------------------------------------------------------" -ForegroundColor Blue`

Related

For loop with list not working as expected Powershell

I'm trying to create a powershell script which checks a log file for lines of text and if the line exists restarts a service and resets/archives the log. I got it working before with 1 "checkstring" if you will, but I've been struggling to get it to work with a list of strings. Could anyone help me figure out where I'm going wrong?
This is the code I'm currently using:
$serviceName = "MySQL80"
$file = "test.txt"
$pwd = "C:\tmp\"
$checkStrings = New-Object System.Collections.ArrayList
# Add amount of checkstrings
$checkStrings.add("Unhandled error. Error message: Error retrieving response.")
$checkStrings.add("Unhandled error. Error message: Error retrieving response. Second")
$logName = "ServiceCheck.log"
$backupFolder = "Archive"
$logString = (Get-Date).ToString("ddMMyyyyHHmmss"), " - The service has been reset and the log moved to backup" -Join ""
Set-Location -Path $pwd
if(Test-Path -Path $file) {
if(Test-Path -Path $backupFolder) {
} else {
New-Item -Path $pwd -Name $backupFolder -ItemType "director"
}
foreach ($element in $checkStrings) {
$containsWord = $fileContent | %{$_ -match $element}
if ($containsWord -contains $true) {
Restart-Service -Name $serviceName
$backupPath = $pwd, "\", $backupFolder, "\", $date, ".log" -join ""
$currentFile = $pwd, "\", $file -join ""
Copy-Item $currentFile -Destination $backupPath
Get-Content $currentFile | select-string -pattern $checkString -notmatch | Out-File $currentFile
if(Test-Path -Path $logName) {
Add-Content $logName $logString
} else {
$logString | Out-File -FilePath $logName
}
}
}
}

Powershell loop is only running once file per filename, even if the filename exists with multiple extensions

I'll be the first to admit that PowerShell isn't my strong suit, but I've pieced together the following after an evening of digging around on the internet. The end goal is to organize a huge drive of images by the DateTaken, as well as sidecar XMP files if they exist. It's probably not the most elegant code, but it almost works.
The last issue, which I can't figure out, is that the foreach loop only executes once per filename, regardless of extension. For example, only DSC00001.arw, DSC00001.xmp, or DSC00001.jpg would be processed.
Any points in the right direction would be appreciated.
Thanks!
$Folders = (Get-ChildItem -Path F:\ -Recurse -Directory -Force).FullName
$objShell = New-Object -ComObject Shell.Application
$Folders | % {
$objFolder = $objShell.namespace($_)
foreach ($File in $objFolder.items()) {
if (($File | Split-Path -Extension) -in ".arw",".gif",".tiff",".jpg",".png",".nef") {
Write-Host $File.Name`t -NoNewline -ForegroundColor Green
try {
$DateTaken = ($objFolder.getDetailsOf($File,12) -replace [char]8206) -replace [char]8207
$DateTaken = [DateTime]::ParseExact($DateTaken, "g", $null)
$Year = $DateTaken.ToString('yyyy')
$Date = $DateTaken.ToString('yyyy-MM-dd')
Write-Host $Date`t -ForegroundColor Blue -NoNewline
}
catch {
$Year = 'Other'
$Date = 'Other'
Write-Host $Date`t -ForegroundColor DarkRed -NoNewline
}
finally {
$DatePath = (Join-Path (Join-Path F:\ $Year ) $Date)
}
write-Host $File.Path -> (Join-Path $DatePath ($File | Split-Path -Leaf))-NoNewline
#Move-Item $File.Path (Join-Path $DatePath ($File | Split-Path -Leaf))
Write-Host Completed`n -NoNewline
if (Test-Path (Join-Path ($File | Split-Path) (($File | Split-Path -LeafBase) + '.xmp'))) {
Write-Host XMP:`t -ForegroundColor Magenta -NoNewLine
Write-Host (Join-Path ($File | Split-Path) (($File | Split-Path -LeafBase) + '.xmp')) -> (Join-Path ($DatePath) (($File | Split-Path -LeafBase) + '.xmp'))
#Move-Item (Join-Path ($File | Split-Path) (($File | Split-Path -LeafBase) + '.xmp')) (Join-Path ($DatePath) (($File | Split-Path -LeafBase) + '.xmp'))
}
}else {
Write-Host $File.Name is not an image `n -NoNewline -ForegroundColor DarkYellow
}
}
}
I'm not sure why $objFolder.items() doesn't actually return all expected files, but I would suggest using PowerShell's built-in file system provider to discover the actual files in each folder and then use $objFolder.ParseName() to obtain a reference you can pass to GetDetailsOf():
$Folders = (Get-ChildItem -Path F:\ -Recurse -Directory -Force).FullName
$objShell = New-Object -ComObject Shell.Application
$Folders | % {
$objFolder = $objShell.NameSpace($_)
foreach ($FileInfo in Get-ChildItem -LiteralPath $_ -File -Force) { # <-- trick is right here, use Get-ChildItem to discover the files in the folder
if($FileInfo.Extension -in ".arw",".gif",".tiff",".jpg",".png",".nef"){
$File = $objFolder.ParseName($FileInfo.Name) # <-- here we resolve the corresponding file item with shell app
# ... resolve and parse dateTaken here, just like before
# *.xmp file path might be easier to construct like this
$xmpPath = $FileInfo.FullName -replace "$($FileInfo.Extension)`$",'.xmp'
if(Test-Path -LiteralPath $xmpPath){
# ...
}
}
}
}

How to amend a string with a variable?

I am trying to copy PDFs from one server to another preserving the folder structure, I have come up with the following script.
I am trying to find the data contained in the variable $Server in another variable $newdes and remove it. However, this fails to happen. If you inspect the variable $newdes you will see that it contains the data stored in $Server, which I need to remove in order for the copy to commence.
As it stands the variable of $newdes contains
C:\Temp\ \file\homedrives\home
It might not show but I see double \ as a UNC file path.
I need it to read C:\temp\homedrives\home.
I am guessing because of the \ \file this fails to start the copy, if this is the case, somebody advise how to get this working.
Amended as requested:
$Criteria = *.pdf
$Trial = c:\temp\folders.txt
$Server = \\file
$Path = homedrives\home
$des = $Path
$safe = Get-Content $Trial
$safe | ForEach-Object {
# find drive-delimeter
$first = $_.IndexOf("\\");
if ($first -eq 1) {
# stripe it
$newdes = Join-Path -Path $des -ChildPath #($_.Substring(0, 1) + $_.Substring(2))[0]
} else {
$newdes = Join-Path -Path $des -ChildPath $_
}
$err = 0
> $folder = Split-Path -Path $newdes -Parent
$err = 0
# check if folder exists"
$void = Get-Item $folder -ErrorVariable err -ErrorAction SilentlyContinue
if ($err.Count -ne 0) {
# create when it doesn't
$void = New-Item -Path $folder -ItemType Directory -Force -Verbose
}
$void = Copy-Item -Path $_ -Destination $des -Force -Verbose
#$void = Copy-Item -Path $_ -Include $Criteria -Destination $Path $Choice -Recurse -Container
#$void = Copy-Item -Path $Files -Include $Criteria -Destination $newdes -Force -Verbose -Recurse -ErrorAction SilentlyContinue
Write-Host $_
}
Write-Host $newdes
Why you don't use the -Recurse switch?
$source = 'C:\source'
$dest = 'C:\dest'
$extensions = #('*.pdf')
Copy-Item -Path $source -Destination $dest -Include $extensions -Force -Recurse
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/copy-item?view=powershell-6
ok, thanks for the assistance, I have now solved the issue, but it has presented another. Will post another question.
The solution to the above is to use
-filter "*.pdf"
Below is a copy of my code
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")
Function Select-Server
{
param([string]$Description="Select Folder",[string]$RootFolder="Desktop")
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
$objForm = New-Object System.Windows.Forms.FolderBrowserDialog
$objForm.Rootfolder = $Server
$objForm.Description = $Description
$objForm.ShowNewFolderButton = $false
$Show = $objForm.ShowDialog()
If ($Show -eq "OK")
{
Return $objForm.SelectedPath + "\"
}
Else
{
Write-Error "Operation cancelled by user."
}
}
Function Select-FolderDialog
{
param([string]$Description="Select Folder",[string]$RootFolder="Desktop")
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
$objForm = New-Object System.Windows.Forms.FolderBrowserDialog
$objForm.Rootfolder = $RootFolder
$objForm.Description = $Description
$objForm.ShowNewFolderButton = $false
$Show = $objForm.ShowDialog()
If ($Show -eq "OK")
{
Return $objForm.SelectedPath
}
Else
{
Write-Error "Operation cancelled by user."
}
}
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null
$Server = "\\" + [Microsoft.VisualBasic.Interaction]::InputBox("Please choose a Server to search", "Server Choice")
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null
$Choice = [Microsoft.VisualBasic.Interaction]::InputBox("Please choose a File Path to search", "File Path Choice") + "\"
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null
$Ext = [Microsoft.VisualBasic.Interaction]::InputBox("Please choose a File type i.e. *.PST", "Location Choice")
#$Ext.ToUpper()
$Criteria = "*." + $Ext
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null
#$FPath = [Microsoft.VisualBasic.Interaction]::InputBox("Please choose a path to copy to", "Location Choice")
$Path = [Microsoft.VisualBasic.Interaction]::InputBox("Please choose a folder to store the data", "Path Choice") + "\"
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null
#$Name = [Microsoft.VisualBasic.Interaction]::InputBox("Please choose a filename", "File Name Choice")
$Search = $Server +"\"+ $Choice
$FileName = $Path
$Info = $Path + "FileCopy.txt"
$Trial = $Path + "Folders.txt"
$Trial2 = $Path + "Ammended Folders.txt"
$Type = $Path + "$Ext's.txt".ToUpper()
#$Server2 = "\" + $Server
#$File = $Path + $Name
if( -Not (Test-Path -Path $Path ) )
{
New-Item -ItemType directory -Path $Path |out-null
}
Else{
[System.Windows.MessageBox]::Show('The directory already exists','Error','Ok','Error')
}
$properties = #(
'Directory'
' '
'Name'
' '
#{
Label = 'Size'
Expression = {
if ($_.Length -ge 1GB)
{
'{0:F2} GB' -f ($_.Length / 1GB)
}
elseif ($_.Length -ge 1MB)
{
'{0:F2} MB' -f ($_.Length / 1MB)
}
elseif ($_.Length -ge 1KB)
{
'{0:F2} KB' -f ($_.Length / 1KB)
}
else
{
'{0} bytes' -f $_.Length
}
}
}
$result = Get-ChildItem -Path $Search -Recurse -Include $Criteria -ErrorAction SilentlyContinue
) | Out-Null
$Result
#Get-ChildItem -Path $Search -Recurse -Include *.pst -ErrorAction SilentlyContinue |
$Folders = (get-childitem -Path $Search | where-object { $_.PSIsContainer }).Count
If (Test-Path $Search) {
<#Write-Host
Write-Host "Listing All Found In $Path" -ForegroundColor "Yellow"
Write-Host "=========================================" -ForegroundColor "Yellow"#>
Add-Type -assembly System.Windows.Forms
## -- Create The Progress-Bar
$ObjForm = New-Object System.Windows.Forms.Form
$ObjForm.Text = "Progress-Bar of searched folders"
$ObjForm.Height = 100
$ObjForm.Width = 500
$ObjForm.BackColor = "White"
$ObjForm.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedSingle
$ObjForm.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
## -- Create The Label
$ObjLabel = New-Object System.Windows.Forms.Label
$ObjLabel.Text = "Starting. Please wait ... "
$ObjLabel.Left = 5
$ObjLabel.Top = 10
$ObjLabel.Width = 500 - 20
$ObjLabel.Height = 15
$ObjLabel.Font = "Tahoma"
## -- Add the label to the Form
$ObjForm.Controls.Add($ObjLabel)
$PB = New-Object System.Windows.Forms.ProgressBar
$PB.Name = "PowerShellProgressBar"
$PB.Value = 0
$PB.Style="Continuous"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 500 - 40
$System_Drawing_Size.Height = 20
$PB.Size = $System_Drawing_Size
$PB.Left = 5
$PB.Top = 40
$ObjForm.Controls.Add($PB)
## -- Show the Progress-Bar and Start The PowerShell Script
$ObjForm.Show() | Out-Null
$ObjForm.Focus() | Out-NUll
$ObjLabel.Text = "Starting. Please wait ... "
$ObjForm.Refresh()
Start-Sleep -Seconds 1
Out-Null
## -- Execute The PowerShell Code and Update the Status of the Progress-Bar
$result = Get-ChildItem -Path $Search -Recurse -Include $Criteria -ErrorAction SilentlyContinue
$Counter = 0
ForEach ($Item In $Result) {
## -- Calculate The Percentage Completed
$Counter++
[Int]$Percentage = ($Counter/$Result.Count)*100
$PB.Value = $Percentage
$ObjLabel.Text = "Scanning $Folders Folders For $Criteria in $Search"
#$ObjLabel.Text = "Found $counter $Criteria in $Search"
$ObjForm.Refresh()
Start-Sleep -Milliseconds 150
# -- $Item.Name
#"`t" + $Item.Path
}
$ObjForm.Close()
#Write-Host "`n"
}
Else {
#Write-Host
#Write-Host "`t Cannot Execute The Script." -ForegroundColor "Yellow"
#Write-Host "`t $Search Does Not Exist in the System." -ForegroundColor "Yellow"
#Write-Host
}
Out-Null
Sort-Object -Property DirectoryName |
Format-Table -Property $properties |
out-file $Info
$Search | out-file -Append $Trial
#$Search | Out-File -Append $Trial2
$result | out-file -Append $Info
$result | Select Name | out-file -Append $Type
$des = $Path
#$PDFs= get-content $Type
$safe = Get-Content $Trial
#$Ten = #($Criteria)
$safe | ForEach-Object{
#find drive-delimeter
$first=$_.IndexOf("\\");
if($first -eq 1){
#stripe it
$newdes=Join-Path -Path $des -ChildPath #($_.Substring(0,1)+$_.Substring(2))[0]
}
else{
$newdes=Join-Path -Path $des -ChildPath $_
}
$err=0
$folder=Split-Path -Path $newdes -Parent
$err=0
#check if folder exists"
$void=Get-Item $folder -ErrorVariable err -ErrorAction SilentlyContinue
if($err.Count -ne 0){
#create when it doesn't
$void=New-Item -Path $folder -ItemType Directory -Force -Verbose
}
$void=Copy-Item -Path $_ -destination $newdes -Filter $Criteria -recurse -Container -Force -Verbose -ErrorAction SilentlyContinue
write-host $_
}
write-host $newdes
$void=Copy-Item -Path $_ -destination $newdes -Filter $Criteria -recurse -Container -Force -Verbose -ErrorAction SilentlyContinue

Unable to delete zip folders older than 14 days

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
}

"A device attached to the system is not functioning " error when using robocopy to move folder in sharepoint

We are using Sharepoint 2010. There is a requirement to archive folders/Subfolders from a given folder to Archive folder which is part of document library. So we used Robocopy from powershell environment. But we're getting error "A device attached to the system is not functioning". ERROR 31 (0x0000001F) Changing File Attributes
Can any one help me what I have to do fix the above error.
Here is my code
$sourceDir = "\\labserver\sites\XXX\YYY Accounts Documents"
$targetDir = "\\labserver\sites\XXXX\Archived YYY Accounts Documents"
$FilePath = "C:\InactiveAccount_SharepointFolder.xlsx"
$sourceDir1= "\\labserver\sites\xxx\yyy Accounts Documents"
$SheetName = "Sheet1"
# Create an Object Excel.Application using Com interface
$objExcel = New-Object -ComObject Excel.Application
# Disable the 'visible' property so the document won't open in excel
$objExcel.Visible = $false
# Open the Excel file and save it in $WorkBook
$WorkBook = $objExcel.Workbooks.Open($FilePath)
$strSheetName = "sheet1"
# Load the WorkSheet 'BuildSpecs'
if ($strSheetName -eq "")
{
$worksheet = $WorkBook.sheets.item(1)
}
else
{
$worksheet = $WorkBook.sheets.item($strSheetName)
}
try {
$intRowMax = ($worksheet.UsedRange.Rows).count
for($intRow = 2 ; $intRow -le $intRowMax ; $intRow++)
{
$isFodlerExists = $worksheet.cells.item($intRow,3).value2
if($isFodlerExists -match "Yes")
{
$accountName = $worksheet.cells.item($intRow,1).value2
#[system.io.directory]::CreateDirectory($tempSource + $accountName)
#write-host $accountName
$sFolder = $sourceDir + "\" + $accountName
$sFolder1 = $sourceDir1 + "\" + $accountName
write-host $sFolder
$tFolder = $targetDir
Add-Content -Path $ErrorLog -Value $sFolder
if((Test-path -Path $sFolder1) -eq $TRUE)
{
try {
#Copy-Item -Path $sFolder -Destination $tFolder -Recurse -force
robocopy $sFolder $tFolder /e /r:2 /log:$ErrorLog /tee
}
Catch {
Add-Content -Path $ErrorLog -Value "Exception write"
$DateTime = (Get-Date).ToShortDateString() + " " + (Get-Date).ToShortTimeString()
$Target = $_.TargetObject
$e = $_
Add-Content -Path $ErrorLog -Value "$DateTime - $e $Target"
#Write-Host "$e $Target"
$ErrorActionPreference = "Continue"
}
if($?)
{
add-content -path $ErrorLog -value ($?)
}
else
{
add-content -path $ErrorLog -value ($?)
}
}
}
#write-host $accountName
}
}
Catch {
Add-Content -Path $ErrorLog -Value "Exception write"
$DateTime = (Get-Date).ToShortDateString() + " " + (Get-Date).ToShortTimeString()
$Target = $_.TargetObject
$e = $_
Add-Content -Path $ErrorLog -force -Value "$DateTime - $e $Target"
#Write-Host "$e $Target"
$ErrorActionPreference = "Continue"
}
$WorkBook.close()
$objExcel.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($objExcel)
Can any one help me what I have to do fix the above error.