i am trying to recursively rename files in a folder that contains a bunch of folders.
to better clarify, i have a parent folder with 10 child folders, each of the 10 child folders have 17 sound files.
i need to rename each of the 17 sound file 1,2,3...17
i managed to come up with the following code (which for now, writes the file name instead of actually changing it)
$files = gci -Path "D:\PARENT_FOLDER" -Recurse
$i = 1
foreach ($file in $files) {
$newName = 0
1..$i | % {$newName = $newName+1}
$i++
Write-Host "name is " $newName
}
but i cant figure out how to make it reset the count between folders.
right now the code outputs names from 1 to 180...
can anybody help me figure this out?
thanks in advance
ok so after a long day at work, i got home and tackled this from scratch and came up with a simpler solution:
i just nested "foreach" loops one inside the other to cycle thru all the folders inside the parent folder and all the files inside each folder.
if anybody is interested here is the code:
$path = "MASTER FOLDER PATH"
$list = Get-ChildItem -Path $path -Directory
foreach ($folder in $list)
{
Write-Host "working on Directory" $folder.FullName -ForegroundColor Green
foreach ($files in $folder)
{$files = Get-ChildItem -Path $path\$folder
$i=1
foreach ($file in $files) {
$newName = 0
1..$i | % {$newName = $newName+1}
$i++
Write-Host "Changing file " $file.FullName -NoNewline -ForegroundColor Yellow
Write-Host " ..." -ForegroundColor Yellow
Rename-Item -Path $file.FullName -NewName $newName
}
}
}
i appreciate your help.
:)
I'd recommend leaving out the -Recurse part for now and to do the recursive things manually (AKA in a loop).
$list = Get-ChildItem -Path $path -Name -Directory
for ($i=0;$i -le $list.Length-1;$i++) {
$list[$i] = $path + '\' + $list[$i]
}
Now you have an array of folders, which you can now individually adress.
$path = "(path)"
$list = Get-ChildItem -Path $path -Name -Directory
for ($i=0;$i -le $list.Length-1;$i++) {
$list[$i] = $path + '\' + $list[$i]
$temp = Get-ChildItem -Path $list[$i] -Name
for ($h=0;$h -le $temp.Length-1;$h++) {
$temp[$h] = $list[$i] + $temp[$h]
Rename-Item -LiteralPath $temp[$h] -NewName $h
}}
Thats what I came up with, hope it was helpful.
Here's another way. I don't see how to recurse and reset the number for each folder. This way I'm doing one folder at a time. Foreach with two script blocks will treat the first one as a "begin" script block.
foreach($dir in get-childitem parent) {
get-childitem parent\$dir | foreach {$i = 1} { rename-item $_.fullname $i -whatif; $i++ }
}
What if: Performing the operation "Rename File" on target "Item: C:\users\js\parent\foo\a Destination: C:\users\js\parent\foo\1".
What if: Performing the operation "Rename File" on target "Item: C:\users\js\parent\foo\b Destination: C:\users\js\parent\foo\2".
What if: Performing the operation "Rename File" on target "Item: C:\users\js\parent\foo\c Destination: C:\users\js\parent\foo\3".
What if: Performing the operation "Rename File" on target "Item: C:\users\js\parent\foo2\a Destination: C:\users\js\parent\foo2\1".
What if: Performing the operation "Rename File" on target "Item: C:\users\js\parent\foo2\b Destination: C:\users\js\parent\foo2\2".
What if: Performing the operation "Rename File" on target "Item: C:\users\js\parent\foo2\c Destination: C:\users\js\parent\foo2\3".
Related
This is my first post to Stack Overflow, and I avoided asking for help and tried to figure this out as much as I could on my own. I have very little scripting experience, but I'm looking to learn. I chose this project as a place to start, and felt like my goals for this script got out of hand rather quickly.
What I have is a functional, probably very bloated, script, that only does a fraction of what I wanted it to do for me.
Here is the task I have, that before we were doing 100% by hand - manually file by file:
I have MP3 files of high importance that need to get copied off of an SD card and eventually moved to a shared drive that is backed up regularly.
These files are in the file name format of MMDDYYYYHHMMSS_RC-700R.mp3
We store these files on our data share in its own directory, organized further by the month, leading me try to add that in as part of my script, but it is a less important feature.
My goal was to safely move these files off of the SD card, rename them - removing the TIME of the file, but if there were 2 (or more) files made on the same date to append an alphabetical iterative count up. I tried to comment out every step, not only for others to read, but to keep myself apprised of what I was trying to accomplish in each section of the code.
#Start by Clearing Host and Saving Transcript
Clear-Host
$date = Get-Date -Format 'dddd MM-dd-yyyy'
Start-Transcript -Path "F:\Script$date.txt" -NoClobber -Append
#Set locations - SD Card:Import
$Import = "C:\Users\Death\Desktop\Minutes"
$Source = "F:\Minutes\"
$Destination = "F:\Final\"
#Test if $Source Exists, if not Create directory for Files to be transferred to
if(!(Test-Path -Path $Source)) {
New-Item -ItemType directory -Path $Source
Write-Host "Folder path has been created successfully at: " $Source
}
else {
Write-Host "The given folder path $Source already exists";
}
#Test if $Destination exists and create if false
if(!(Test-Path -Path $Destination)) {
New-Item -ItemType directory -Path $Destination
Write-Host "Folder path has been created successfully at: $Destination "}
else {
Write-Host "The given folder path $Destination already exists";
}
#Copy Items from $Import location
Get-ChildItem -Path $Import -Filter *.mp3 | Copy-Item -Destination $Source
#Rename Files adding Dashes between MM DD YYYY and HHMMSS
Get-ChildItem -Path $Source -Filter *.mp3 | Rename-Item -NewName {$_.Name -Replace ('^\n*(\d{2})(\d{2})(\d{4})(\d{6}).(?:...)(\d{3})\w','TC $1-$2-$3-$4')}
#Move files into $Destination\Year\Month created - Need to add
#Move files into $NewPath\Year\Month created
#Running in to problems with moving the files after they have been renamed - Likely due to
Get-ChildItem -File -Path $Source -Filter '*.mp3' |
ForEach-Object {
$Year = $_.LastWriteTime.Year
$Month = $_.LastWriteTime.Month
$Monthname = (Get-Culture).DateTimeFormat.GetMonthName($Month)
$ArchDir = "$Destination\$Year\$Monthname\"
if (-not (Test-Path -Path $ArchDir)) { New-Item -ItemType "directory" -Path $ArchDir | Out-Null }
Move-Item -Path $Source\*.mp3 -Destination $ArchDir -Verbose
}
#Would like to add a list of files renamed and where they moved to instead of just Enter to exit
Read-Host -Prompt "Press Enter to exit"
I have had little parts of my goals working in other versions of this code, but this is my most functional one.
Problems that currently exist:
I haven't figured out how to safely iterate files created on the same day when renaming files and leaving off the TIME - So as it is currently functioning I have it leaving the TIME on the file and I am manually removing it and adding any letters when needed
It is throwing all of the files in to $Destination in the Month of the first file, and putting all the files in there (not a huge issue as this was extra)
I would like it to list every move operation as well as any errors. It is doing this now with the $Source & $Destination folders & the -Verbose on the final GCI - Move operation.
Until I demonstrate that the script is 100% functional I have all locations in the script on my local machine to keep my boss happy.
I am sorry for the wall of text & Thanks in advance for any assistance.
This looks way over-complicated.
For the file parts, it could be as simple as this...
As per your stated use case:
My goal was to safely move these files off of the SD card,
rename them - removing the TIME of the file,
Clear-Host
$SourcePath = 'C:\Temp'
$TargetPath = 'C:\Temp\TempChild'
Get-ChildItem -Path $SourcePath -Filter '*.mp3' |
ForEach {
$FileName = $PSItem
Try
{
If ((Get-Item -Path "$TargetPath\$($FileName.Name)" -ErrorAction Stop))
{
Rename-Item -Path "$TargetPath\$($PSItem.Name)" -NewName "$($FileName.Name -replace '\d+_')" -WhatIf
Move-Item -Path $FileName.FullName -Destination $TargetPath -WhatIf
}
}
Catch {Move-Item -Path $FileName.FullName -Destination $TargetPath -WhatIf}
}
# Results
<#
# When the file does not exists
What if: Performing the operation "Move File" on target "Item: C:\Temp\04122021143000_RC-M1234R.mp3 Destination: C:\Temp\TempChild\04122021143000_RC-M1234R.mp3".
# When the file exists
What if: Performing the operation "Rename File" on target "Item: C:\Temp\TempChild\04122021143000_RC-M1234R.mp3 Destination: C:\Temp\TempChild\RC-M1234R.mp3".
What if: Performing the operation "Move File" on target "Item: C:\Temp\04122021143000_RC-M1234R.mp3 Destination: C:\Temp\TempChild\04122021143000_RC-M1234R.mp3".
#>
You can create new paths, without using New-Item. Just use the -Force switch/parameter on the copy/move action.
Test-Path -Path "$TargetPath\test1"
# Results
<#
False
#>
Get-ChildItem -Path $SourcePath -Filter '*.mp3' |
Copy-Item -Destination "$TargetPath\test1" -Force -WhatIf
# Results
<#
What if: Performing the operation "Copy File" on target "Item: C:\Temp\04122021143000_RC-M1234R.mp3 Destination: C:\Temp\TempChild\test1".
#>
Get-ChildItem -Path $SourcePath -Filter '*.mp3' |
Copy-Item -Destination "$TargetPath\test1" -Force
Test-Path -Path "$TargetPath\test1"
Get-ChildItem -Path $TargetPath -Filter '*.mp3'
# Results
<#
True
Directory: C:\Temp\TempChild
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 4/8/2021 6:04 PM 39 04122021143000_RC-M12345R.mp3
-a---- 4/8/2021 6:04 PM 39 04122021143000_RC-M1234R.mp3
#>
As for
but if there were 2 (or more) files made on the same date to append an alphabetical iterative count up.
I am not sure why you use alpha vs numeric. Since alpha would limit you to 26 letters before you'd end up having to double that string. Numeric of course, you can just look at the number and increment by 1.
Here's what I mean, just using your file name vs file properties. Yet, you can do the same approach, by looking at the file properties in the mix.
Clear-Host
$SourcePath = 'C:\Temp'
$TargetPath = 'C:\Temp\TempChild'
Get-ChildItem -Path $SourcePath -Filter '*.mp3' |
ForEach {
$FileName = $PSItem
Try
{
If (
-Not ((Get-ChildItem -Path $TargetPath -Filter $FileName.Name) -match "(?<=RC-M\d+R\d)") -and
($FileName.Name -replace '_\.*') -match
((Get-ChildItem -Path $TargetPath -Filter $FileName.Name) -replace '_\.*')
)
{
Rename-Item -Path "$TargetPath\$($FileName.Name)" -NewName "$(
$FileName.Name -replace 'R\.', 'R1.'
)" -ErrorAction Stop -WhatIf
Move-Item -Path $FileName.FullName -Destination $TargetPath -Verbose -WhatIf
}
}
Catch
{
$FileToIncrement = (
Get-ChildItem -Path $TargetPath |
Where-Object -Property Name -Match ($FileName.BaseName -replace 'R\d+')
).FullName
if($FileToIncrement -match "(?<=RC-M\d+R)(?<bv>\d+)")
{
Rename-Item -Path $FileToIncrement -NewName (
$FileToIncrement -replace "(?<=RC-M\d+R)(\d+)",
("{0:0000}" -f (([int]::Parse($matches.bv)+1)))
) -Verbose -WhatIf
Move-Item -Path $FileName.FullName -Destination $TargetPath -Verbose -WhatIf
}
}
}
# Results - when incrementer does not exist for the matched time string
<#
VERBOSE: Performing the operation "Rename File" on target "Item: C:\Temp\TempChild\04122021143000_RC-M12345R.mp3 Destination: C:\Temp\TempChild\04122021143000_RC-M12345R1.mp3".
VERBOSE: Performing the operation "Move File" on target "Item: C:\Temp\04122021143000_RC-M12345R.mp3 Destination: C:\Temp\TempChild\04122021143000_RC-M12345R.mp3".
VERBOSE: Performing the operation "Rename File" on target "Item: C:\Temp\TempChild\04122021143000_RC-M1234R.mp3 Destination: C:\Temp\TempChild\04122021143000_RC-M1234R1.mp3".
VERBOSE: Performing the operation "Move File" on target "Item: C:\Temp\04122021143000_RC-M1234R.mp3 Destination: C:\Temp\TempChild\04122021143000_RC-M1234R.mp3".
#>
# Results - when incrementer exists for the matched time string
<#
What if: Performing the operation "Rename File" on target "Item: C:\Temp\TempChild\04122021143000_RC-M12345R1.mp3 Destination: C:\Temp\TempChild\04122021143000_RC-M12345R0002.mp3".
What if: Performing the operation "Move File" on target "Item: C:\Temp\04122021143000_RC-M12345R.mp3 Destination: C:\Temp\TempChild\04122021143000_RC-M12345R.mp3".
What if: Performing the operation "Rename File" on target "Item: C:\Temp\TempChild\04122021143000_RC-M1234R1.mp3 Destination: C:\Temp\TempChild\04122021143000_RC-M1234R0002.mp3".
What if: Performing the operation "Move File" on target "Item: C:\Temp\04122021143000_RC-M1234R.mp3 Destination: C:\Temp\TempChild\04122021143000_RC-M1234R.mp3".
#>
I'm trying to rename about 500 files in a single directory. Each file is .docx format similar to the below.
Apartment_7-9_01_92.docx
Apartment_7-9_02_192.docx
etc.
I want to remove the last two/three digits before the '.', including the '_' so that I end up with
Apartment_7-9_01.docx
Apartment_7-9_02.docx
Having never really used Powershell, the research I've done so far leads me to something like the below:
Get-ChildItem -File | ForEach-Object { $_ | Rename-Item -NewName -Replace $_.Name.SubString(0, $_.lastIndexOf('_')),".docx"}
I would have thought this would take everything, including and after the last '_' and replace it with '.docx', but it's telling me the lastIndexOf method doesn't exist in this case.
Thanks
I fixed your code, but I don't think it does what you want. $_ is a fileinfo object, and $_.name is a string, and .lastindexof() is a string method. I think you want to replace a substring location after the last "_", not before it.
Get-ChildItem -File | ForEach-Object { $_ | Rename-Item -NewName (
$_.name -Replace $_.Name.SubString(0, $_.Name.lastIndexOf('_')),".docx") -whatif}
What if: Performing the operation "Rename File" on target "Item:
/Users/js/Apartment_7-9_01_92.docx Destination: /Users/js/.docx_92.docx".
What if: Performing the operation "Rename File" on target "Item:
/Users/js/Apartment_7-9_02_192.docx Destination: /Users/js/.docx_192.docx".
This seems to work, and is close to what you were trying. Just specify where the substring starts.
Get-ChildItem -File | ForEach-Object { $_ | Rename-Item -NewName (
$_.name -Replace $_.Name.SubString($_.Name.lastIndexOf('_')),".docx") -whatif}
What if: Performing the operation "Rename File" on target "Item:
/Users/js/Apartment_7-9_01_92.docx Destination:
/Users/js/Apartment_7-9_01.docx".
What if: Performing the operation "Rename File" on target "Item:
/Users/js/Apartment_7-9_02_192.docx Destination:
/Users/js/Apartment_7-9_02.docx".
There's a way to pipe directly to rename-item too, like in the docs:
Get-ChildItem -File | Rename-Item -NewName {
$_.name -Replace $_.Name.SubString($_.Name.lastIndexOf('_')),".docx"} -whatif
You could first split the BaseName on "_", then take every item except the last and rejoin back on "_". An easy way to do that is with $array[0..($array.Length - 2)]. You could also just do $array[0..2] to take the first 3 items. You can then add the Extension at the end. From here you can simply rename the FullName with Rename-Item.
$Path = "PATH/TO/FILES"
Get-ChildItem -Path $Path -File | ForEach-Object {
$items = $_.BaseName -split "_"
$newFileName = ($items[0..($items.Length - 2)] -join "_") + $_.Extension
Rename-Item -Path $_.FullName -NewName $newFileName
}
I'm looking for help restructuring a large number of files within many subfolders.
Example source:
folderX
aaa.txt
bbb.txt
folderY
ccc.txt
folderZ
ddd.txt
eee.txt
Ideal result:
folderX_aaa.txt
folderX_aaa.txt
folderX_bbb.txt
folderY_ccc.txt
folderY_folderZ_ddd.txt
eee.txt
I hope that makes sense! I'm using Plex to manage some media and it doesn't like subfolders for certain uses (eg featurettes directory).
I'd like to use PowerShell because I'm already kinda familiar with it - but any techniques or suggestions are welcome.
Thanks in advance :)
Here's a single-pipeline solution:
$targetDir = Convert-Path '.' # Get the current (target) directory's full path.
Get-ChildItem -LiteralPath $targetDir -Directory | # Loop over child dirs.
Get-ChildItem -Recurse -File -Filter *.txt | # Loop over all *.txt files in subtrees of child dirs.
Move-Item -Destination { # Move to target dir.
# Construct the full target path from the target dir.
# and the relative sub-path with path separators replaced with "_" chars.
Join-Path $targetDir `
($_.Fullname.Substring($targetDir.Length + 1) -replace '[/\\]', '_')
} -Whatif
-WhatIf previews the move operations; remove it to perform actual moving.
Regex [/\\] matches / or \ as the path separator, so as to make the solution cross-platform.
while it would have been nice if you had shown what you have tried, i got interested ... [grin]
what the code does ...
sets some constants
creates some files & dirs to work with
grabs the files that match the target location & type
skips any file that is already in the $TopDir
derives the old file & dir names
uses the above to make a new full file name
moves the items
this only shows what WOULD happen. remove the -WhatIf to do it for real.
please note that the code DOES NOT check to see if there are same-named files in the destination.
the code itself ...
$TopDir = "$env:TEMP\PlexStuff"
$Delimiter = '_-_'
$Filter = '*.txt'
#region >>> create some files to test with
# remove this region after you have tested it
#(
[System.IO.FileInfo]"$TopDir\OneThing\aaa.txt"
[System.IO.FileInfo]"$TopDir\OneThing\bbb.txt"
[System.IO.FileInfo]"$TopDir\TwoThing\aaa.txt"
[System.IO.FileInfo]"$TopDir\ThreeThing\ccc.txt"
[System.IO.FileInfo]"$TopDir\ThreeThing\ddd.txt"
[System.IO.FileInfo]"$TopDir\eee.txt"
) |
ForEach-Object {
# the "$Null =" suppresses unwanted output from the commands
$Null = mkdir $_.Directory.FullName -Force -ErrorAction SilentlyContinue
$Null = New-Item -Path $_.Directory.FullName -Name $_.Name -ItemType File -ErrorAction SilentlyContinue
}
#endregion >>> create some files to test with
$FileList = Get-ChildItem -LiteralPath $TopDir -File -Recurse -Filter $Filter
foreach ($FL_Item in $FileList)
{
# skip files that are in the TopDir
if (-not ($FL_Item.DirectoryName -eq $TopDir))
{
$OldFileName = $FL_Item.Name
$OldDirName = $FL_Item.DirectoryName
$NewFileName = ($OldDirName, $OldFileName) -join $Delimiter
Move-Item -LiteralPath $FL_Item.FullName -Destination $NewFileName -WhatIf
}
}
output [slightly reformatted for readability] ...
What if: Performing the operation "Move File" on target "Item: C:\Temp\PlexStuff\OneThing\aaa.txt
Destination: C:\Temp\PlexStuff\OneThing_-_aaa.txt".
What if: Performing the operation "Move File" on target "Item: C:\Temp\PlexStuff\OneThing\bbb.txt
Destination: C:\Temp\PlexStuff\OneThing_-_bbb.txt".
What if: Performing the operation "Move File" on target "Item: C:\Temp\PlexStuff\ThreeThing\ccc.txt
Destination: C:\Temp\PlexStuff\ThreeThing_-_ccc.txt".
What if: Performing the operation "Move File" on target "Item: C:\Temp\PlexStuff\ThreeThing\ddd.txt
Destination: C:\Temp\PlexStuff\ThreeThing_-_ddd.txt".
What if: Performing the operation "Move File" on target "Item: C:\Temp\PlexStuff\TwoThing\aaa.txt
Destination: C:\Temp\PlexStuff\TwoThing_-_aaa.txt".
How do I copy files from one folder c:\t to other folder c:\t\1 based on date (files not older than three days will be copied)?
How do I modify this code to enter sourse folders?
ls -File | ?{
$_.CreationTime -ge $(Get-Date).AddDays(-3) -and
$_.LastWriteTime -ge $(Get-Date).AddDays(-3)
} | Copy-Item -destination C:\ps\1
this uses a slightly different approach. since folks often get date math reversed, this does the comparison on days old instead of directly comparing the date objects.
$SourceDir = $env:TEMP
$DestDir = 'D:\Temp'
# this gives you the date with the time set to midnite
$Today = (Get-Date).Date
$MinDaysOld = 3
$FileList = Get-ChildItem -LiteralPath $SourceDir -File
foreach ($FL_Item in $FileList)
{
$DaysOld = ($Today - $FL_Item.CreationTime.Date).Days
if ($DaysOld -gt $MinDaysOld)
{
'the file below is {0} days old.' -f $DaysOld
# remove the "-WhatIf" when you are ready to do it for real
Copy-Item -LiteralPath $FL_Item.FullName -Destination $DestDir -WhatIf
''
}
}
truncated output ...
the file below is 21 days old.
What if: Performing the operation "Copy File" on target "Item: C:\Temp\user2310119_append-csv-to-TXT-file.txt Desti
nation: D:\Temp\user2310119_append-csv-to-TXT-file.txt".
the file below is 49 days old.
What if: Performing the operation "Copy File" on target "Item: C:\Temp\vscode-inno-updater-1559095937.log Destinati
on: D:\Temp\vscode-inno-updater-1559095937.log".
[*...snip...*]
the file below is 34 days old.
What if: Performing the operation "Copy File" on target "Item: C:\Temp\vscode-inno-updater-1560382575.log Destinati
on: D:\Temp\vscode-inno-updater-1560382575.log".
the file below is 7 days old.
What if: Performing the operation "Copy File" on target "Item: C:\Temp\vscode-inno-updater-1562704735.log Destinati
on: D:\Temp\vscode-inno-updater-1562704735.log".
If you're looking to get a list of files that are less than 3 days old then just get the child items and pass it into a Where-Object:
$now = [DateTime]::Now
$files = Get-ChildItem -File *.* | ? {$now.Subtract($_.CreationTime).TotalDays -lt 3}
(Note: ? is an alias for Where-Object)
$files now contains all the files less than 3 days old.
You can now copy the files by passing the $files list into the ForEach-Object command:
$files | % {Copy-Item $_ -Destination c:\t\1}
(Note: % is an alias for ForEach-Object)
Putting this all together you get:
$now = [DateTime]::Now
$files = Get-ChildItem -File c:\t\*.* | ? {$now.Subtract($_.CreationTime).TotalDays -lt 3}
$files | % {Copy-Item $_ -Destination c:\t\1}
Or you can combine it like this, using piping:
$now = [DateTime]::Now
Get-ChildItem -File c:\t\*.* | ? {$now.Subtract($_.CreationTime).TotalDays -lt 3} | % {Copy-Item $_ -Destination c:\t\1}
I am trying to copy a file off a server and onto another, I want to keep the structure of the file like so C:\folder\folder\file! If the folder is there copy the file into it, if it is not then create the folders and then copy into it!
I would like it also to filter out the files that are still needed so I want to keep files for 30 days and then move them!
Blockquote
`[int]$Count = 0
$filter = (Get-Date).AddDays(-15).ToString("MM/dd/yyyy")
Get-WMIObject Win32_LogicalDisk | ForEach-Object{
$SearchFolders = Get-Childitem ($_.DeviceID + "\crams") -recurse
$FileList = $SearchFolders |
Where-Object {$_.name -like "Stdout_*" -and $_.lastwritetime -le $filter}
[int]$Totalfiles = ($FileList | Measure-object).count
write-host "There are a total of $Totalfiles found."
echo $FileList
start-sleep 30
[int]
ForEach ($Item in $FileList)
{$Count++
$File = $Item
Write-Host "Now Moving $File"
$destination ="C:\StdLogFiles\"
$path = test-Path (get-childitem $destination -Exclude "Stdout_*")
if ($path -eq $true) {
write-Host "Directory Already exists"
copy-item $File -destination $destination
}
elseif ($path -eq $false) {
cd $destination
mkdir $File
copy-Item $File -destination $destination
}
}
}`
Is what I have so far it has changed a lot due to trying to get it to work but the search works and so does the date part I can not get it to keep the structure of the file!
Okay I took out the bottom part and put in
ForEach ($Item in Get-ChildItem $FileList)
also tried get-content but path is null
{$Count++
$destination = "C:\StdLogFiles"
$File = $Item
Write-Host "Now Moving $File to $destination"
Copy-Item -Path $file.fullname -Destination $destination -force}}
it is copying everything that is in c into that folder but not the files I do not understand what it is doing now! I had it copying the files even wen back to an older version and can't get it to work again! I am going to leave it before I break it more!
Any help or thoughts would be appreciated
I think RoboCopy is probably a simpler solution for you to be honest. But, if you insist on using PowerShell you are going to need to setup your destination better if you want to keep your file structure. You also want to leave your filter date as a [DateTime] object instead of converting it to a string since what you are comparing it to (lastwritetime) is a [DateTime] object. You'll need to do something like:
$filter = (Get-Date).AddDays(-15)
$FileList = Get-WMIObject Win32_LogicalDisk | ForEach-Object{
Get-Childitem ($_.DeviceID + "\crams") -recurse | Where-Object {$_.name -like "Stdout_*" -and $_.lastwritetime -le $filter}
}
$Totalfiles = $FileList.count
For($i = 1;$i -le $TotalFiles; $i++)
{
$File = $FileList[($i-1)]
Write-Progress -Activity "Backing up old files" -CurrentOperation ("Copying file: " + $file.Name) -Status "$i of $Totalfiles files" -PercentComplete ($i*100/$Totalfiles)
$Destination = (Split-Path $file.fullname) -replace "^.*?\\crams", "C:\StdLogFiles"
If(!(Test-Path $Destination)){
New-Item -Path $Destination -ItemType Directory | Out-Null
}
Copy-Item $File -Destination $Destination
}
Write-Progress -Completed
That gathers all the files you need to move from all disks. Takes a count of them, and then enters a loop that will cycle as many times as you have files. In the loop is assigns the current item to a variable, then updates a progress bar based on progress. It then parses the destination by replacing the beginning of the file's full path (minus file name) with your target destination of 'C:\StdLogFiles'. So D:\Crams\HolyPregnantNunsBatman\Stdout04122015.log becomes C:\StdLogFiles\HolyPregnantNunsBatman. Then it tests the path, and if it's not valid it creates it (piped to out-null to avoid spam). Then we copy the file to the destination and move on to the next item. After the files are done we close out the progress bar.