Moving files older than into subfolders - powershell

I'm trying to move old files into folders based on creation date. The setup is that the script should check a folder for files older than 5 years and then put them in folders sorted by year with subfolders for each month.
$SourceDir = "C:\Test"
$DestinationDir = "C:\Archive\Test\"
$limit = (Get-Date).AddYears(-5)
$files = Get-ChildItem $SourceDir * | Where-Object {
!$_.PSIsContainer -and $_.CreationTime -lt $limit
}
foreach ($file in $files) {
$Directory = $DestinationDir + "" + $file.CreationTime.Date.ToString('yyyy') + "\" + $file.CreationTime.Date.ToString('MM-MMM')
if (!(Test-Path $Directory)) {
New-Item $directory -Type Directory
}
Move-Item $file.FullName $Directory
I get this error
PS C:\Scripts> .\SortIntoMonths5Year.ps1
You cannot call a method on a null-valued expression.
At C:\Scripts\SortIntoMonths5Year.ps1:11 char:69
+ $Directory = $DestinationDir + "" + $file.CreationTime.Date.ToString <<<< ('yyyy') + "\" + $file.CreationTime.Date.ToString('MM-MMM')
+ CategoryInfo : InvalidOperation: (ToString:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Test-Path : Cannot bind argument to parameter 'Path' because it is null.
At C:\Scripts\SortIntoMonths5Year.ps1:13 char:16
+ if (!(Test-Path <<<< $Directory))
+ CategoryInfo : InvalidData: (:) [Test-Path], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.TestPathCommand
Move-Item : Cannot bind argument to parameter 'Path' because it is null.
At C:\Scripts\SortIntoMonths5Year.ps1:17 char:10
+ Move-Item <<<< $file.FullName $Directory
+ CategoryInfo : InvalidData: (:) [Move-Item], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.MoveItemCommand

Fixed it myself
$SourceDir = "C:\Test"
$DestinationDir = "C:\Archive\Test\"
$files = get-childitem $SourceDir * | Where-Object {$_.LastWriteTime -lt (Get-Date).AddYears(-5)}
#$files = get-childitem $SourceDir *
foreach ($file in $files)
{
$Directory = $DestinationDir + "" + $file.LastWriteTime.Date.ToString('yyyy') + "\" + $file.LastWriteTime.Date.ToString('MM-MMM')
if (!(Test-Path $Directory))
{
New-Item $directory -type directory
}
Move-Item $file.fullname $Directory
}

Related

Is it possible to use Compress-Archive using a PSDrive in the -Path and -DestinationPath?

I am using a PSDrive for Compress-Archive but I come across this error:
Compress-Archive : The path 'Z:\' either does not exist or is not a valid file system path.
At C:\Users\user\somefolder\script.ps1:34 char:5
+ Compress-Archive -Path ($ZDrive + $fileName + $csvExt) -Destinati ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (Z:\:String) [Compress-Archive], InvalidOperationException
+ FullyQualifiedErrorId : ArchiveCmdletPathNotFound,Compress-Archive
The PSDrive code and codes at line 33 and 34 are these:
New-PSDrive -Name "Z" -Root $OutputDirectoryPath -PSProvider FileSystem;
$ZDrive = "Z:\";
query($CustomQuery) | Export-Csv -Path ($ZDrive + $fileName + $csvExt) -NoTypeInformation;
Compress-Archive -Path ($ZDrive + $fileName + $csvExt) -DestinationPath ($ZDrive + $fileName + $zipExt) -Force;

Remove-item varibale for path from csv

i have to delete folders based on a excel list, so i have tried to import the execl with import csv but it dosent work.
The import doesnt fill the variable in the correct format.
This is the code i tried to use:
$folders = import-csv G:\Book1.csv foreach ($folder in $folders) {Remove-Item -Path $folder -Recurse -Force}
The error is this:
Remove-Item : Cannot find drive. A drive with the name '#{Foldername=G' does not exist.
At line:4 char:5
+ Remove-Item -Path $folder -Recurse -Force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (#{Foldername=G:String) [Remove-Item], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand
Remove-Item : Cannot find drive. A drive with the name '#{Foldername=G' does not exist.
At line:4 char:5
+ Remove-Item -Path $folder -Recurse -Force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (#{Foldername=G:String) [Remove-Item], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand
Remove-Item : Cannot find drive. A drive with the name '#{Foldername=G' does not exist.
At line:4 char:5
+ Remove-Item -Path $folder -Recurse -Force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (#{Foldername=G:String) [Remove-Item], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand
In the CSV in the 1.Line heading stands foldername in line 2-4 are the name of the folders (a, b, c).
This is the CSV:
Foldername
G:\Test\a
G:\Test\b
G:\Test\c
The directory is G:\Test\a , b, c
I have found a Solution, the CSV file was a Problem and the import so i had to modify the CSV File:
"Foldername"
"G:\Test\a"
"G:\Test\b"
"G:\Test\c"
the powershell code is this now:
$folders = import-csv .csv | ForEach-Object {
write-host $($_.Foldername)
Remove-Item -Path $($_.Foldername) -Recurse -Force
}

Find & Replace text from multiple specific files from sub folders dynamically using powershell

I am working on azure CD pipeline, i want to change content of multiple files which exist in following folder structure.
MainFolder => SubFolder1 => myFile1.txt
SubFolder2 => myFile2.txt
SubFolder3 => myFile3.txt
I want to achieve my above requirement using powershell, and i have tried the following code.
$filepath = 'C:\Users\ashishjain06\Desktop\MainFolder'
$mydata = Get-ChildItem $filepath -include *.txt -recurse | Select-Object fullName
$totalRecords = $mydata.Count
for($x = 0; $x -lt $totalRecords; $x++)
{
((Get-Content -path $mydata[$x] -Force) -replace 'oldText','newText') | Set-Content -Path $mydata[$x]
}
When i run above code it's give me following output.
Get-Content : Cannot find drive. A drive with the name '#{FullName=C' does not exist.
At line:6 char:7
+ ((Get-Content -path $mydata[$x] -Force) -replace 'oldText ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (#{FullName=C:String) [Get-Content], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.GetContentCommand
Get-Content : Cannot bind argument to parameter 'Path' because it is null.
At line:6 char:25
+ ((Get-Content -path $mydata[$x] -Force) -replace 'oldText ...
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-Content], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.GetContentCommand
Get-Content : Cannot bind argument to parameter 'Path' because it is null.
At line:6 char:25
+ ((Get-Content -path $mydata[$x] -Force) -replace 'oldText ...
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-Content], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.GetContentCommand
Get-Content : Cannot bind argument to parameter 'Path' because it is null.
At line:6 char:25
+ ((Get-Content -path $mydata[$x] -Force) -replace 'oldText ...
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-Content], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.GetContentCommand
Get-Content : Cannot bind argument to parameter 'Path' because it is null.
At line:6 char:25
+ ((Get-Content -path $mydata[$x] -Force) -replace 'oldText ...
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-Content], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.GetContentCommand
I am newbie on powershell, Please help me out to resolve this issue.
Get-ChildIItem returns (an array of) FileInfoObjects with a bunch of properties,
Select-Object drops all but the selected one, but it is still an object with one property FullName.
See $mydata | Get-Member
One method is Select-Object -ExpandProperty FullName,
another one is the property dereference operator . used in the following script.
To have the script work on any user don't include a fixed path, either use $Env:USERPROFILE or better yet, let the system evaluate current users Desktop folder (which might be relocated).
Instead of iterating the arrray $mydata by index let powershell do that with a foreach:
$filepath = Join-Path ([environment]::GetFolderPath('Desktop')) 'MainFolder'
$files = (Get-ChildItem $filepath -Filter *.txt -Recurse).FullName
foreach($file in $files){
(Get-Content -path $file -Force) -replace 'oldText','newText' | Set-Content -Path $file
}
It's still an object with a property unless you do this:
select-object -expandproperty fullname
Replace Select-Object with ForEach-Object, i.e.:
$filepath = 'C:\Users\ashishjain06\Desktop\MainFolder'
#$mydata = Get-ChildItem $filepath -include *.txt -recurse | Select-Object fullName
$mydata = Get-ChildItem $filepath -include *.txt -recurse | ForEach-Object fullName
$totalRecords = $mydata.Count
for($x = 0; $x -lt $totalRecords; $x++)
{
((Get-Content -path $mydata[$x] -Force) -replace 'oldText','newText') | Set-Content -Path $mydata[$x]
}

cannot rename because item does not exist

Trying to search a folder for files not already ending in *.txt which have not been modified in 1 day and rename the extension to .txt
$app_files = get-childitem "C:\Users\adm.aross\Desktop\Rename DHL files - TKT0087521\Test" -recurse -exclude *.txt | where-object {$_.LastWriteTime -lt (Get-Date).AddDays(-1)}
foreach ( $file in $app_files ) {
$newfile = $file.Name + ".txt"
Rename-Item -Literalpath "C:\Users\adm.aross\Desktop\Rename DHL files - TKT0087521\Test\$file" $newfile
}
Rename-Item : Cannot rename because item at
'C:\Users\adm.aross\Desktop\Rename DHL files -
TKT0087521\Test\C:\Users\adm.aross\Desktop\Rename DHL files -
TKT0087521\Test\01-06-2019.log' does not exist. At line:5 char:9
+ Rename-Item -Literalpath "C:\Users\adm.aross\Desktop\Rename D ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Rename-Item], PSInvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.RenameItemCommand
Rename-Item : Cannot rename because item at
'C:\Users\adm.aross\Desktop\Rename DHL files -
TKT0087521\Test\C:\Users\adm.aross\Desktop\Rename DHL files -
TKT0087521\Test\01-07-2019.log' does not exist. At line:5 char:9
+ Rename-Item -Literalpath "C:\Users\adm.aross\Desktop\Rename D ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Rename-Item], PSInvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.RenameItemCommand
Rename-Item : Cannot rename because item at
'C:\Users\adm.aross\Desktop\Rename DHL files -
TKT0087521\Test\C:\Users\adm.aross\Desktop\Rename DHL files -
TKT0087521\Test\08-05-2019.log.log' does not exist. At line:5 char:9
+ Rename-Item -Literalpath "C:\Users\adm.aross\Desktop\Rename D ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Rename-Item], PSInvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.RenameItemCommand
$RootFolder = 'C:\Users\adm.aross\Desktop\Rename DHL files - TKT0087521\Test'
$CheckDate = [DateTime]::UtcNow.AddDays(-1)
Get-ChildItem -LiteralPath $RootFolder -Exclude #('*.txt') -Recurse:$true |
Where-Object { $_.psIsContainer -eq $false } | # Check is file, not a directory
Where-Object { $_.LastWriteTimeUtc -lt $CheckDate } |
Where-Object { $_.CreationTimeUtc -lt $CheckDate } |
Where-Object { ( Test-Path -LiteralPath "$($_.FullName).txt" -PathType Any ) -ne $true } | # Check if there is no .txt file already
ForEach-Object { Rename-Item -LiteralPath $_.FullName -NewName "$($_.Name).txt" }
Check WriteTime and CreationTime. There can be situations when file
is created AFTER written ( when file is copied from another source,
WriteTime is copied, and CreationTime is not )
Check you can rename the file (the target name not exist )
Check it is a file

Get-ChildItem : A parameter cannot be found that matches parameter name 'Directory' [duplicate]

This question already has answers here:
A parameter cannot be found that matches parameter name 'directory'
(2 answers)
Closed last year.
I am getting Get-ChildItem : *A parameter cannot be found that matches parameter name 'Directory'* error message , below is the script used, kindly help me in finding the issue?
Script:
Function Clear-ReadOnlyFiles([string]$path)
{
"Clearing readonly attribute from files in $path"
New-Variable -Name read_only -Value 1 -Option readonly
Get-ChildItem -Path $path |
Where-Object { $_.attributes -match 'readonly' } |
ForEach-Object {
$_.attributes = $_.attributes -Bxor $read_only }
}#end Clear-ReadonlyFiles
$ZipCmd = "{0}\7za.exe" -f $BackupDir
$ZipCmdArgs = "-sdel"
# Grab Directories in Location
$Directories = Get-ChildItem -Path $BackupDir -Directory
# Cycle Through and Launch 7za to Compress
# Check if Archive Exists - If yes, delete source folder
ForEach ($Directory in $Directories)
{
$Source = "{0}\{1}" -f $BackupDir,$Directory.Name
$Archive = "{0}.7z" -f $Source
# Clear Read-Only Attribute on Folder
$SubFiles = Get-ChildItem -Path $Directory -Recurse -ReadOnly
ForEach ($SubFile in $SubFiles) {
$SubFile.IsReadOnly = $False
}
#If ($Directory.IsReadOnly -eq $True) { $Directory.set_IsReadOnly($False) }
$AllArgs = #('a', $ZipCmdArgs, $Archive, $Source);
& $ZipCmd $AllArgs
}
Error message:
Get-ChildItem : A parameter cannot be found that matches parameter name 'Directory'.
At C:\Play\BackupCompress.ps1:35 char:57
+ $Directories = Get-ChildItem -Path $BackupDir -Directory <<<<
+ CategoryInfo : InvalidArgument: (:) [Get-ChildItem], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
Get-ChildItem : A parameter cannot be found that matches parameter name 'ReadOnly'.
At C:\Play\BackupCompress.ps1:45 char:66
+ $SubFiles = Get-ChildItem -Path $Directory -Recurse -ReadOnly <<<<
+ CategoryInfo : InvalidArgument: (:) [Get-ChildItem], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
Property 'IsReadOnly' cannot be found on this object; make sure it exists and is settable.
At C:\Play\BackupCompress.ps1:47 char:18
+ $SubFile. <<<< IsReadOnly = $False
+ CategoryInfo : InvalidOperation: (IsReadOnly:String) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound
I believe that the Directory switch was added in PowerShell 3.0. In older versions you will need to check the PSIsContainer property of each child item, which will be true if the item is a directory:
$Directories = Get-ChildItem -Path $BackupDir | Where-Object { $_.PSIsContainer }
-Directory is a conditional parameter and only works on paths whose provider is "FileSystem". It's present on this page: Get-ChildItem for FileSystem, but not on the generic one.
Make sure that the correct provider appears when you type the following:
Get-Item $BackupDir | Select-Object -Property PSProvider