How to move folders from one location to another using PowerShell












0














So i have a directory full of folders that i want to move to another area, also i only want to move the folders that were created 30 days ago or more. I have a script that does what i need for files but it doesnt seem to work for folders. Script is below



Script for moving files



 param (
[Parameter(Mandatory=$true)][string]$destinationRoot
)

$path = (Get-Item -Path ".").FullName

Get-ChildItem -Recurse | ?{ $_.PSIsContainer }
Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-30)} |
Foreach-Object {
$content = $path + "" + $_.Name

$year = (Get-Item $content).LastWriteTime.year.ToString()
$monthNumber = (Get-Item $content).LastWriteTime.month
$month = (Get-Culture).DateTimeFormat.GetMonthName($monthNumber)

$destination = $destinationRoot + "" + $year + "" + $month

New-Item -ItemType Directory -Force -Path $destination

Move-Item -Path $content -Destination $destination -force

}


The Get-ChildItem portion does not seem to pull directories in like it should.










share|improve this question




















  • 1




    Please update your question to describe what, specifically, doesn't work.
    – mklement0
    Nov 12 at 15:09










  • what if a file thats less then 30 days is in a folder that is greater then 30 days?
    – ArcSet
    Nov 12 at 15:14






  • 1




    just use Get-ChildItem -Directory -Recurse. Honestly there are quite a few things that would make this script better. Let me see if i cant do a fast rewrite
    – ArcSet
    Nov 12 at 15:18








  • 1




    @mklement0 apologies for the name misspell. Was not intentional
    – Philip Loyer
    Nov 12 at 15:30






  • 1




    @mklement0 I think there is a flaw with gci recursing and in the foreach combining $path with the current name without taking into account that the current item might be a (sub-)subdir of $path - so $content points to a non existing folder.
    – LotPings
    Nov 12 at 15:33


















0














So i have a directory full of folders that i want to move to another area, also i only want to move the folders that were created 30 days ago or more. I have a script that does what i need for files but it doesnt seem to work for folders. Script is below



Script for moving files



 param (
[Parameter(Mandatory=$true)][string]$destinationRoot
)

$path = (Get-Item -Path ".").FullName

Get-ChildItem -Recurse | ?{ $_.PSIsContainer }
Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-30)} |
Foreach-Object {
$content = $path + "" + $_.Name

$year = (Get-Item $content).LastWriteTime.year.ToString()
$monthNumber = (Get-Item $content).LastWriteTime.month
$month = (Get-Culture).DateTimeFormat.GetMonthName($monthNumber)

$destination = $destinationRoot + "" + $year + "" + $month

New-Item -ItemType Directory -Force -Path $destination

Move-Item -Path $content -Destination $destination -force

}


The Get-ChildItem portion does not seem to pull directories in like it should.










share|improve this question




















  • 1




    Please update your question to describe what, specifically, doesn't work.
    – mklement0
    Nov 12 at 15:09










  • what if a file thats less then 30 days is in a folder that is greater then 30 days?
    – ArcSet
    Nov 12 at 15:14






  • 1




    just use Get-ChildItem -Directory -Recurse. Honestly there are quite a few things that would make this script better. Let me see if i cant do a fast rewrite
    – ArcSet
    Nov 12 at 15:18








  • 1




    @mklement0 apologies for the name misspell. Was not intentional
    – Philip Loyer
    Nov 12 at 15:30






  • 1




    @mklement0 I think there is a flaw with gci recursing and in the foreach combining $path with the current name without taking into account that the current item might be a (sub-)subdir of $path - so $content points to a non existing folder.
    – LotPings
    Nov 12 at 15:33
















0












0








0







So i have a directory full of folders that i want to move to another area, also i only want to move the folders that were created 30 days ago or more. I have a script that does what i need for files but it doesnt seem to work for folders. Script is below



Script for moving files



 param (
[Parameter(Mandatory=$true)][string]$destinationRoot
)

$path = (Get-Item -Path ".").FullName

Get-ChildItem -Recurse | ?{ $_.PSIsContainer }
Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-30)} |
Foreach-Object {
$content = $path + "" + $_.Name

$year = (Get-Item $content).LastWriteTime.year.ToString()
$monthNumber = (Get-Item $content).LastWriteTime.month
$month = (Get-Culture).DateTimeFormat.GetMonthName($monthNumber)

$destination = $destinationRoot + "" + $year + "" + $month

New-Item -ItemType Directory -Force -Path $destination

Move-Item -Path $content -Destination $destination -force

}


The Get-ChildItem portion does not seem to pull directories in like it should.










share|improve this question















So i have a directory full of folders that i want to move to another area, also i only want to move the folders that were created 30 days ago or more. I have a script that does what i need for files but it doesnt seem to work for folders. Script is below



Script for moving files



 param (
[Parameter(Mandatory=$true)][string]$destinationRoot
)

$path = (Get-Item -Path ".").FullName

Get-ChildItem -Recurse | ?{ $_.PSIsContainer }
Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-30)} |
Foreach-Object {
$content = $path + "" + $_.Name

$year = (Get-Item $content).LastWriteTime.year.ToString()
$monthNumber = (Get-Item $content).LastWriteTime.month
$month = (Get-Culture).DateTimeFormat.GetMonthName($monthNumber)

$destination = $destinationRoot + "" + $year + "" + $month

New-Item -ItemType Directory -Force -Path $destination

Move-Item -Path $content -Destination $destination -force

}


The Get-ChildItem portion does not seem to pull directories in like it should.







powershell






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 12 at 15:29

























asked Nov 12 at 14:56









Philip Loyer

3961317




3961317








  • 1




    Please update your question to describe what, specifically, doesn't work.
    – mklement0
    Nov 12 at 15:09










  • what if a file thats less then 30 days is in a folder that is greater then 30 days?
    – ArcSet
    Nov 12 at 15:14






  • 1




    just use Get-ChildItem -Directory -Recurse. Honestly there are quite a few things that would make this script better. Let me see if i cant do a fast rewrite
    – ArcSet
    Nov 12 at 15:18








  • 1




    @mklement0 apologies for the name misspell. Was not intentional
    – Philip Loyer
    Nov 12 at 15:30






  • 1




    @mklement0 I think there is a flaw with gci recursing and in the foreach combining $path with the current name without taking into account that the current item might be a (sub-)subdir of $path - so $content points to a non existing folder.
    – LotPings
    Nov 12 at 15:33
















  • 1




    Please update your question to describe what, specifically, doesn't work.
    – mklement0
    Nov 12 at 15:09










  • what if a file thats less then 30 days is in a folder that is greater then 30 days?
    – ArcSet
    Nov 12 at 15:14






  • 1




    just use Get-ChildItem -Directory -Recurse. Honestly there are quite a few things that would make this script better. Let me see if i cant do a fast rewrite
    – ArcSet
    Nov 12 at 15:18








  • 1




    @mklement0 apologies for the name misspell. Was not intentional
    – Philip Loyer
    Nov 12 at 15:30






  • 1




    @mklement0 I think there is a flaw with gci recursing and in the foreach combining $path with the current name without taking into account that the current item might be a (sub-)subdir of $path - so $content points to a non existing folder.
    – LotPings
    Nov 12 at 15:33










1




1




Please update your question to describe what, specifically, doesn't work.
– mklement0
Nov 12 at 15:09




Please update your question to describe what, specifically, doesn't work.
– mklement0
Nov 12 at 15:09












what if a file thats less then 30 days is in a folder that is greater then 30 days?
– ArcSet
Nov 12 at 15:14




what if a file thats less then 30 days is in a folder that is greater then 30 days?
– ArcSet
Nov 12 at 15:14




1




1




just use Get-ChildItem -Directory -Recurse. Honestly there are quite a few things that would make this script better. Let me see if i cant do a fast rewrite
– ArcSet
Nov 12 at 15:18






just use Get-ChildItem -Directory -Recurse. Honestly there are quite a few things that would make this script better. Let me see if i cant do a fast rewrite
– ArcSet
Nov 12 at 15:18






1




1




@mklement0 apologies for the name misspell. Was not intentional
– Philip Loyer
Nov 12 at 15:30




@mklement0 apologies for the name misspell. Was not intentional
– Philip Loyer
Nov 12 at 15:30




1




1




@mklement0 I think there is a flaw with gci recursing and in the foreach combining $path with the current name without taking into account that the current item might be a (sub-)subdir of $path - so $content points to a non existing folder.
– LotPings
Nov 12 at 15:33






@mklement0 I think there is a flaw with gci recursing and in the foreach combining $path with the current name without taking into account that the current item might be a (sub-)subdir of $path - so $content points to a non existing folder.
– LotPings
Nov 12 at 15:33














1 Answer
1






active

oldest

votes


















1














So looking at the script i decided to change some things up



Function Move-FilesByAge(){
param (
[Parameter(Mandatory=$true)][string]$Source,
[Parameter(Mandatory=$true)][string]$Destination,
[Parameter(Mandatory=$true)][timespan]$AgeLimit
)

Get-ChildItem $Source -Directory -Recurse | ?{
$($_.CreationTimeUtc.Add($AgeLimit)) -lt $((Get-Date).ToUniversalTime())
} | %{
$Dpath = $Destination + "" + $_.CreationTimeUtc.ToString("yyyy") + "" + $_.CreationTimeUtc.ToString("MMMM")
New-Item -ItemType Directory -Force -Path $Dpath
Move-Item $_ -Destination $Dpath -Force
}
}

Move-FilesByAge -Source C:Test -Destination C:Test2 -AgeLimit (New-TimeSpan -days 30)


This can lead to a major issue. If a folder with the same name exists then it will pop a error that folder exists.



Since you are new to powershell lets go over some basics about this script. In Powershell we love Piping | which you did well in the original. We also a big fan of aliases Where-Object ?{}, Foreach-Object %{}.



Get-ChildItem has a built in switch for just returning directories -directory.



You are also using last LastWriteTime when you should be using CreationTime. CreationTimeUtc allows you to standardize your time across timezones by providing a base timezone.



Date.ToString(Date Format Here). IS a great way to shorten how you parse the date as a string. .ToString("yyyy") gets you the year in 4 numbers like 2018. .ToString("MMMM") will get the month by name like March.






share|improve this answer























  • Worked like a charm, thanks so much for your help
    – Philip Loyer
    Nov 12 at 16:12










  • You could simplify things with the -format operator: $Dpath = "{0}{1:yyyy\MMMM}" -f $Destination,$_.CreationTimeUtc to include a literal character in a format string ` which has a meaning it needs to be escaped `.
    – LotPings
    Nov 12 at 16:12










  • good point @LotPings
    – ArcSet
    Nov 12 at 16:12










  • Hmm backticks and backslashes don't play together nicely in a comment: To include a literal character in a format string which has a meaning it needs to be escaped \
    – LotPings
    Nov 12 at 16:16











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53264748%2fhow-to-move-folders-from-one-location-to-another-using-powershell%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














So looking at the script i decided to change some things up



Function Move-FilesByAge(){
param (
[Parameter(Mandatory=$true)][string]$Source,
[Parameter(Mandatory=$true)][string]$Destination,
[Parameter(Mandatory=$true)][timespan]$AgeLimit
)

Get-ChildItem $Source -Directory -Recurse | ?{
$($_.CreationTimeUtc.Add($AgeLimit)) -lt $((Get-Date).ToUniversalTime())
} | %{
$Dpath = $Destination + "" + $_.CreationTimeUtc.ToString("yyyy") + "" + $_.CreationTimeUtc.ToString("MMMM")
New-Item -ItemType Directory -Force -Path $Dpath
Move-Item $_ -Destination $Dpath -Force
}
}

Move-FilesByAge -Source C:Test -Destination C:Test2 -AgeLimit (New-TimeSpan -days 30)


This can lead to a major issue. If a folder with the same name exists then it will pop a error that folder exists.



Since you are new to powershell lets go over some basics about this script. In Powershell we love Piping | which you did well in the original. We also a big fan of aliases Where-Object ?{}, Foreach-Object %{}.



Get-ChildItem has a built in switch for just returning directories -directory.



You are also using last LastWriteTime when you should be using CreationTime. CreationTimeUtc allows you to standardize your time across timezones by providing a base timezone.



Date.ToString(Date Format Here). IS a great way to shorten how you parse the date as a string. .ToString("yyyy") gets you the year in 4 numbers like 2018. .ToString("MMMM") will get the month by name like March.






share|improve this answer























  • Worked like a charm, thanks so much for your help
    – Philip Loyer
    Nov 12 at 16:12










  • You could simplify things with the -format operator: $Dpath = "{0}{1:yyyy\MMMM}" -f $Destination,$_.CreationTimeUtc to include a literal character in a format string ` which has a meaning it needs to be escaped `.
    – LotPings
    Nov 12 at 16:12










  • good point @LotPings
    – ArcSet
    Nov 12 at 16:12










  • Hmm backticks and backslashes don't play together nicely in a comment: To include a literal character in a format string which has a meaning it needs to be escaped \
    – LotPings
    Nov 12 at 16:16
















1














So looking at the script i decided to change some things up



Function Move-FilesByAge(){
param (
[Parameter(Mandatory=$true)][string]$Source,
[Parameter(Mandatory=$true)][string]$Destination,
[Parameter(Mandatory=$true)][timespan]$AgeLimit
)

Get-ChildItem $Source -Directory -Recurse | ?{
$($_.CreationTimeUtc.Add($AgeLimit)) -lt $((Get-Date).ToUniversalTime())
} | %{
$Dpath = $Destination + "" + $_.CreationTimeUtc.ToString("yyyy") + "" + $_.CreationTimeUtc.ToString("MMMM")
New-Item -ItemType Directory -Force -Path $Dpath
Move-Item $_ -Destination $Dpath -Force
}
}

Move-FilesByAge -Source C:Test -Destination C:Test2 -AgeLimit (New-TimeSpan -days 30)


This can lead to a major issue. If a folder with the same name exists then it will pop a error that folder exists.



Since you are new to powershell lets go over some basics about this script. In Powershell we love Piping | which you did well in the original. We also a big fan of aliases Where-Object ?{}, Foreach-Object %{}.



Get-ChildItem has a built in switch for just returning directories -directory.



You are also using last LastWriteTime when you should be using CreationTime. CreationTimeUtc allows you to standardize your time across timezones by providing a base timezone.



Date.ToString(Date Format Here). IS a great way to shorten how you parse the date as a string. .ToString("yyyy") gets you the year in 4 numbers like 2018. .ToString("MMMM") will get the month by name like March.






share|improve this answer























  • Worked like a charm, thanks so much for your help
    – Philip Loyer
    Nov 12 at 16:12










  • You could simplify things with the -format operator: $Dpath = "{0}{1:yyyy\MMMM}" -f $Destination,$_.CreationTimeUtc to include a literal character in a format string ` which has a meaning it needs to be escaped `.
    – LotPings
    Nov 12 at 16:12










  • good point @LotPings
    – ArcSet
    Nov 12 at 16:12










  • Hmm backticks and backslashes don't play together nicely in a comment: To include a literal character in a format string which has a meaning it needs to be escaped \
    – LotPings
    Nov 12 at 16:16














1












1








1






So looking at the script i decided to change some things up



Function Move-FilesByAge(){
param (
[Parameter(Mandatory=$true)][string]$Source,
[Parameter(Mandatory=$true)][string]$Destination,
[Parameter(Mandatory=$true)][timespan]$AgeLimit
)

Get-ChildItem $Source -Directory -Recurse | ?{
$($_.CreationTimeUtc.Add($AgeLimit)) -lt $((Get-Date).ToUniversalTime())
} | %{
$Dpath = $Destination + "" + $_.CreationTimeUtc.ToString("yyyy") + "" + $_.CreationTimeUtc.ToString("MMMM")
New-Item -ItemType Directory -Force -Path $Dpath
Move-Item $_ -Destination $Dpath -Force
}
}

Move-FilesByAge -Source C:Test -Destination C:Test2 -AgeLimit (New-TimeSpan -days 30)


This can lead to a major issue. If a folder with the same name exists then it will pop a error that folder exists.



Since you are new to powershell lets go over some basics about this script. In Powershell we love Piping | which you did well in the original. We also a big fan of aliases Where-Object ?{}, Foreach-Object %{}.



Get-ChildItem has a built in switch for just returning directories -directory.



You are also using last LastWriteTime when you should be using CreationTime. CreationTimeUtc allows you to standardize your time across timezones by providing a base timezone.



Date.ToString(Date Format Here). IS a great way to shorten how you parse the date as a string. .ToString("yyyy") gets you the year in 4 numbers like 2018. .ToString("MMMM") will get the month by name like March.






share|improve this answer














So looking at the script i decided to change some things up



Function Move-FilesByAge(){
param (
[Parameter(Mandatory=$true)][string]$Source,
[Parameter(Mandatory=$true)][string]$Destination,
[Parameter(Mandatory=$true)][timespan]$AgeLimit
)

Get-ChildItem $Source -Directory -Recurse | ?{
$($_.CreationTimeUtc.Add($AgeLimit)) -lt $((Get-Date).ToUniversalTime())
} | %{
$Dpath = $Destination + "" + $_.CreationTimeUtc.ToString("yyyy") + "" + $_.CreationTimeUtc.ToString("MMMM")
New-Item -ItemType Directory -Force -Path $Dpath
Move-Item $_ -Destination $Dpath -Force
}
}

Move-FilesByAge -Source C:Test -Destination C:Test2 -AgeLimit (New-TimeSpan -days 30)


This can lead to a major issue. If a folder with the same name exists then it will pop a error that folder exists.



Since you are new to powershell lets go over some basics about this script. In Powershell we love Piping | which you did well in the original. We also a big fan of aliases Where-Object ?{}, Foreach-Object %{}.



Get-ChildItem has a built in switch for just returning directories -directory.



You are also using last LastWriteTime when you should be using CreationTime. CreationTimeUtc allows you to standardize your time across timezones by providing a base timezone.



Date.ToString(Date Format Here). IS a great way to shorten how you parse the date as a string. .ToString("yyyy") gets you the year in 4 numbers like 2018. .ToString("MMMM") will get the month by name like March.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 12 at 15:56

























answered Nov 12 at 15:47









ArcSet

3,0581925




3,0581925












  • Worked like a charm, thanks so much for your help
    – Philip Loyer
    Nov 12 at 16:12










  • You could simplify things with the -format operator: $Dpath = "{0}{1:yyyy\MMMM}" -f $Destination,$_.CreationTimeUtc to include a literal character in a format string ` which has a meaning it needs to be escaped `.
    – LotPings
    Nov 12 at 16:12










  • good point @LotPings
    – ArcSet
    Nov 12 at 16:12










  • Hmm backticks and backslashes don't play together nicely in a comment: To include a literal character in a format string which has a meaning it needs to be escaped \
    – LotPings
    Nov 12 at 16:16


















  • Worked like a charm, thanks so much for your help
    – Philip Loyer
    Nov 12 at 16:12










  • You could simplify things with the -format operator: $Dpath = "{0}{1:yyyy\MMMM}" -f $Destination,$_.CreationTimeUtc to include a literal character in a format string ` which has a meaning it needs to be escaped `.
    – LotPings
    Nov 12 at 16:12










  • good point @LotPings
    – ArcSet
    Nov 12 at 16:12










  • Hmm backticks and backslashes don't play together nicely in a comment: To include a literal character in a format string which has a meaning it needs to be escaped \
    – LotPings
    Nov 12 at 16:16
















Worked like a charm, thanks so much for your help
– Philip Loyer
Nov 12 at 16:12




Worked like a charm, thanks so much for your help
– Philip Loyer
Nov 12 at 16:12












You could simplify things with the -format operator: $Dpath = "{0}{1:yyyy\MMMM}" -f $Destination,$_.CreationTimeUtc to include a literal character in a format string ` which has a meaning it needs to be escaped `.
– LotPings
Nov 12 at 16:12




You could simplify things with the -format operator: $Dpath = "{0}{1:yyyy\MMMM}" -f $Destination,$_.CreationTimeUtc to include a literal character in a format string ` which has a meaning it needs to be escaped `.
– LotPings
Nov 12 at 16:12












good point @LotPings
– ArcSet
Nov 12 at 16:12




good point @LotPings
– ArcSet
Nov 12 at 16:12












Hmm backticks and backslashes don't play together nicely in a comment: To include a literal character in a format string which has a meaning it needs to be escaped \
– LotPings
Nov 12 at 16:16




Hmm backticks and backslashes don't play together nicely in a comment: To include a literal character in a format string which has a meaning it needs to be escaped \
– LotPings
Nov 12 at 16:16


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53264748%2fhow-to-move-folders-from-one-location-to-another-using-powershell%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Bressuire

Vorschmack

Quarantine