I'm trying to delete some old files in an archive folder and my script works fine until it gets to the last section where it removes the empty folders (testing using -whatif initially). I get the following error:
Remove-Item : Cannot bind argument to parameter 'Path' because it is null.
At C:\ArchiveDelete.ps1:13 char:39
+ $dirs | Foreach-Object { Remove-Item <<<< $_.fullname -whatif }
+ CategoryInfo : InvalidData: (:) [Remove-Item], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.RemoveItemCommand
Tried to find a suitable answer on here but can't find a solution (I know I may be using an older version of Powershell)
#Days older than
$HowOld = -900
#Path to the root folder
$Path = "C:\SharedWorkspace\ArchiveDSAgile"
#Deletion files task
get-childitem $Path -recurse | where {$_.lastwritetime -lt (get-date).adddays($HowOld) -and -not $_.psiscontainer} |% {remove-item $_.fullname -force -whatif}
#Deletion empty folders task
do {
$dirs = gci $Path -recurse | Where { (gci $_.fullName -Force).count -eq 0 -and $_.PSIsContainer } | select -expandproperty FullName
$dirs | Foreach-Object { Remove-Item $_ -whatif }
} while ($dirs.count -gt 0)
None of your loops are necessary.
You can feed the output of Where-Object right into Remove-Item
$AgeCap = (Get-Date).AddDays(-900)
$Path = "C:\SharedWorkspace\ArchiveDSAgile"
Get-ChildItem $Path -Recurse -File | Where-Object LastWriteTime -lt $AgeCap | Remove-Item -WhatIf
The -File parameter for Get-ChildItem available in PowerShell 3.0 (I believe) and higher. The Workaround for PowerShell 2.0 would be checking against $_.PSIsContainer in Where-Object, as you did in your sample code.
Finally got it working:
#Days older than
$HowOld = -900
#Path to the root folder
$Path = "C:\SharedWorkspace\ArchiveDSAgile"
#Deletion files task
get-childitem $Path -recurse | where {$_.lastwritetime -lt (get-date).adddays($HowOld) -and -not $_.psiscontainer} |% {remove-item $_.fullname -force -whatif}
#Deletion empty folders task
Get-ChildItem $Path -Recurse | Where-Object {$_.lastwritetime -lt (get-date).adddays($HowOld) -and -not !$_.psiscontainer} | Remove-Item -recurse -WhatIf
Thanks for your help
Related
I am trying to recursively search for files on a windows 7 machine + network drives attached to it while excluding certain folders i.e. C:\windows & all recursive folders in this such as system32.
I know this question has been asked before but following the answers has not helped and I am still left with a blank variable.
Here are the combinations I have tried:
$AllDrives = Get-PSDrive
$files=#("*.xml",*.txt)
foreach ($Drive in $AllDrives) {
if ($Drive.Provider.Name -eq "FileSystem") {
$filenames = Get-ChildItem -recurse $drive.root -include ($files) -File | Where-Object {$_.PSParentPath -notlike "*Windows*" -and $_.PSParentPath -notlike "*Microsoft*"
}
}
I have also tried these combinations:
$filenames = Get-ChildItem -recurse $drive.root -include ($files) -File | Where-Object {$_.PSParentPath -notmatch "Program Files|Users|Windows"}
$exclude_pattern = $drive.root + "Windows"
$filenames = Get-ChildItem -Force -Recurse -path $drive.root -Include $files -Attributes !Directory+!System -ErrorAction "SilentlyContinue" | Where-Object { $_.PSIsContainer -eq $false } | Where-Object { $_.FullName -notmatch $exclude_pattern }
Unfortunately, after an amount of time has elapsed, when I type $filename into the terminal nothing has been assigned to it.
I wrote a simple script that will run as a scheduled task every weekend. This script cleans up files older than # days and you can give the name of a folder for exclusion as a parameter. This folder should not be cleaned up by the script. But somehow the script still deletes some files from the excluded folder. But in a strange way no files matching the conditions of the parameter.
For example I run the script to delete files older than 15 days and exclude the folder NOCLEANUP. but some files still get deleted from that folder, but there are still files older than 15 days in the NOCLEANUP folder.
Code below
Thanks in advance and apologies for the dirty code. Still new to PS.
Function CleanDir ($dir, $days, $exclude, $logpath)
{
$Limit = (Get-Date).AddDays(-$days)
$Path = $dir
#Folder to exclude
$ToExclude = $exclude
#Log location
$Log= $logpath
$Testpath = Test-Path -PathType Container -Path $Log
if ($Testpath -ne $true)
{
New-Item -ItemType Directory -Force -Path $Log
}
#Logs deleted files
cd $Log
Get-ChildItem -Path $Path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.LastwriteTime -lt $Limit } | Where-Object { $_.fullname -notmatch $ToExclude} | Where-Object { $_.fullname -notmatch '$RECYCLE.BIN'} | Out-File -FilePath CLEANUPLOG.TXT
# Delete files older than the $Limit.
Get-ChildItem -Path $Path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.LastwriteTime -lt $Limit } | Where-Object { $_.fullname -notlike $ToExclude} | Remove-Item -Force -Recurse
#Goes into every folder separately and deletes all empty subdirectorys without deleting the root folders.
$Folder = Get-ChildItem -Path $Path -Directory
$Folder.fullname | ForEach-Object
{
Get-ChildItem -Path $_ -Recurse -Force | Where-Object {$_.PSIsContainer -eq $True} | Where-Object {$_.GetFiles().Count -eq 0} | Remove-Item -Force -Recurse
}
}
I have the following code to keep on top of old folders which I no longer want to keep
Get-ChildItem -Path $path -Recurse -Force -EA SilentlyContinue|
Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } |
Remove-Item -Force -EA SilentlyContinue
Get-ChildItem -Path $path -Recurse -Force -EA SilentlyContinue|
Where-Object { $_.PSIsContainer -and (Get-ChildItem -Path
$_.FullName -Recurse -Force | Where-Object { !$_.PSIsContainer })
-eq $null } | Remove-Item -Force -Recurse -EA SilentlyContinue
It deletes anything older than a certain number of days ($limit) including files and folders.
However, what I am after is ONLY deleting old folders and their contents.
For example, a day old folder may have file within that is a year old but I want to keep that folder and the old file. The code above keeps the folder but deletes the file. All I want to do is delete folders (and their contents) within the root that are older than the $limit else leave the other folders and content alone.
Thanks in advance.
Well look at this bit:
Get-ChildItem -Path $path -Recurse -Force -EA SilentlyContinue|
Where-Object { !$_.PSIsContainer -and $_.CreationTime -ge $limit } |
Remove-Item -Force -EA SilentlyContinue
It's basically saying "everything not a folder and older than specified is removed". So your first step is to remove that.
The second part is just deleting empty folders, you can keep it as-is or you could add to the Where statement to include the CreationTime:
Get-ChildItem -Path $path -Recurse -Force -EA SilentlyContinue|
Where-Object { $_.PSIsContainer -and $_.CreationTime -lt $limit -and (Get-ChildItem -Path
$_.FullName -Recurse -Force | Where-Object { $_.CreationTime -lt $limit })
-eq $null } | Remove-Item -Force -Recurse -EA SilentlyContinue
The second Where statement returns a list of files and folders newer than $limit, and only deletes the folder if that is null.
I'm trying to create a PowerShell script that will move XML files of a certain age to a network drive to be archived. The script thus far:
$qaprocessedpath = "Y:\SFTPSHARE\SFTPYMSQ\YS42C1Processed"
$qabackup = “\\servername\S$\xmlbackup\qa"
$max_age_qa = "-1"
$curr_date = Get-Date
$del_date_q = $curr_date.AddDays($max_age_qa)
Get-ChildItem -include *.xml $qaprocessedpath | Where-Object {$_.LastWriteTime -lt $del_date_q } | Foreach-Object {Copy-Item -Path $_.FullName -Destination $qabackup} {Remove-Item $_.FullName}
This code leads to the following error:
Copy-Item : Cannot bind argument to parameter 'Path' because it is null.
At Y:\SFTPSHARE\SFTPYMSP\XMLBackup.ps1:52 char:132
+ Get-ChildItem -include *.xml $qaprocessedpath | Where-Object { $_.LastWriteTime -lt $del_date_q } | Foreach-Object {Copy-Item -Path <<<< $_.FullName -Destination $qabackup} {Remove-Item $_.FullName}
+ CategoryInfo : InvalidData: (:) [Copy-Item], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.CopyItemCommand
Not sure where the issue is. I'm a novice scripter, so I'm sure it's something obvious...
In this line
Get-ChildItem -include *.xml $qaprocessedpath | Where-Object {$_.LastWriteTime -lt $del_date_q } | Foreach-Object {Copy-Item -Path $_.FullName -Destination $qabackup} {Remove-Item $_.FullName}
Why do you have two scriptblocks following the Foreach-Object?
Try separating the copy-item and remove-item with semicolons (in the same scriptblock) if you want them both to run. As you wrote it, the two scriptblocks are getting bound to the -Process parameter (as usual) and the -Begin parameter.
I am having trouble with the following script, which liberally makes use of pipelines:
$date = Get-Date -date "12/31/2010 00:00 AM" -format MM-dd-yyyy
$TDrive = "C:\Users\xxxx\Desktop"
(get-childitem -path $Tdrive -recurse -force -ErrorAction SilentlyContinue) |
?{ $_.fullname -notmatch "\\Alina_NEW\\?" } |
?{ $_.fullname -notmatch "\\!macros\\?" } |
?{ $_.fullname -notmatch "\\DO_NOT_DELETE\\?" } |
Where-Object {$_.LastAccessTime -lt $date} |
Remove-Item $_
I am getting the following error when I run this, meaning that the $_ is null:
Remove-Item : Cannot bind argument to parameter 'Path' because it is null.
At line:13 char:13
+ Remove-Item $_
+ ~~
+ CategoryInfo : InvalidData: (:) [Remove-Item], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.R
emoveItemCommand
What I am not understanding is, why would the path ever be null? This is all one fluid pipeline, and the value of $_ should persist through the entire pipeline, should it not?
My only thought is that when the where-object finds a file that is not less than that date, it returns null through the rest of the pipeline. I believe this error happens pre-execution, however, so there is a more fundamental problem here.
The point of this script is to delete all files not in the directories listed, that are older than 12/31/2010.
Two things. First, you'll want to Remove-Item Foreach of the files gci finds. Second, Remove-Item takes a path. Try something like this:
$date = Get-Date -date "12/31/2010 00:00 AM" -format MM-dd-yyyy
$TDrive = "C:\Users\xxxx\Desktop"
(get-childitem -path $Tdrive -recurse -force -ErrorAction SilentlyContinue) |
?{ $_.fullname -notmatch "\\Alina_NEW\\?" } |
?{ $_.fullname -notmatch "\\!macros\\?" } |
?{ $_.fullname -notmatch "\\DO_NOT_DELETE\\?" } |
Where-Object {$_.LastAccessTime -lt $date} |
% {Remove-Item $_.FullName -WhatIf}