I have this script where i want to move files from one path to another:
$logArchieveDirectory='C:\LogArchieve\'+$archiveTillDate.Day+$archiveTillDate.Month+$archiveTillDate.Year;
$sourcePathServer = 'C:\DDS\Server\LOGS';
$destPathServer=$logArchieveDirectory+'\Server';
#Create Directories
New-Item -ItemType directory -Path $logArchieveDirectory;
New-Item -ItemType directory -Path $destPathServer;
#Moving Logs to new temporary log archieve directories
foreach( $item in (Get-ChildItem $sourcePathServer | Where-Object { $_.CreationTime -le $archiveTillDate }) )
{
Move-Item $item $destPathServer -force;
}
However, i have specified both paths fine But i keep getting this error when i run this script.
Move-Item : Cannot find path 'C:\DDS\WorkFolder\WebAdapter' because it does not exist.
At C:\DDS\WorkFolder\powerShellScript08062014.ps1:38 char:11
+ Move-Item <<<< $item $destPathController;
+ CategoryInfo : ObjectNotFound: (C:\DDS\WorkFolder\WebAdapter:String) [Move-Item], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.MoveItemCommand
The C:\DDS\WorkFolder\ is actually the folder where my script file is located. But what i am not understanding is why it is looking for the folder here and not where the path is given i.e. $sourcePathServer?
Your script passes relative paths to Move-Item and it defaults to the working directory. An easy solution is to pass absolute paths using .FullName property:
foreach ($item in (Get-ChildItem $sourcePathServer `
| Where-Object { $_.CreationTime -le $archiveTillDate })) {
Move-Item $item.FullName $destPathServer -force
}
Also using foreach in conjunction with pipelines doesn't look very elegant because of all the parentheses. You can get rid of it:
Get-ChildItem $sourcePathServer `
| Where-Object { $_.CreationTime -le $archiveTillDate } | Foreach-Object {
Move-Item $_.FullName $destPathServer -Force
}
Related
I have to move files from a folder corresponding to a CSV column like that :
id
name
1a
file1
2b
file2
3c
file3
4d
file4
So if in my folder I have a file named file1 I need to create a folder named 1a and put file1 inside.
I have the following script
$CsvId = Import-Csv './test.csv'
$sourcePath= "C:\Users\olong\Desktop\object"
$dirPath = "C:\Users\olong\Desktop\dir"
$files = Get-ChildItem -Path $sourcePath | ForEach-Object -Process {[System.IO.Path]::GetFileNameWithoutExtension($_)}
$pattern = '(?<=_).*(?=_)'
ForEach ($item In $CsvId) {
$objectID = $item.'id'
$docID = $item.'name'
$location = $dirPath+ "\" + $objectID
Foreach ($file in $files) {
if($file -contains $docID) {
if (-not (Test-Path -Path $location)) {
mkdir -Path $location
}
Move-Item ($file.FullName) -Destination $location -Verbose -Force
}
}
}
But it gives me that error :
Move-Item : Cannot bind argument to parameter 'Path' because it is null.
At C:\Users\olong\Desktop\scriptMove.ps1:19 char:15
+ Move-Item ($file.FullName) -Destination $location -Verbose -Force
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Move-Item], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.MoveItemCommand
With PowerShell's debugger $file is not null and with or without parenthesis on $file.FullName does nothing
I think what you want to do is to get the file(s) as mentioned in the csv under header 'name' having any extension into a subfolder as mentioned in field 'id' and create that subfolder first if it does not already exist.
If my assumtion is correct, you can try below:
$sourcePath = "C:\Users\olong\Desktop\object"
$destinationPath = "C:\Users\olong\Desktop\dir"
Import-Csv -Path './test.csv' | ForEach-Object {
$targetDirectory = Join-Path -Path $destinationPath -ChildPath $_.id
# create the output subfolder if it does not already exist
$null = New-Item -Path $targetDirectory -ItemType Directory -Force
# next use the file basename from the $_.name column as filter and move the file(s)
Get-ChildItem -Path $sourcePath -Filter "$($_.name).*" -File | Move-Item -Destination $targetDirectory
}
I have the below script which is working fine for what we need thus far however running into an error as the file names have changed.
With the below script it is providing a Cannot Find Path error as the filenames have changed.
Where am i going wrong with this one?
## Add ShareFile PowerShell Snap-in
Add-PSSnapin ShareFile
## Create new authentiation file
#New-SfClient -Name "C:\Sharefile\SVCACC.sfps" -Account midl
## Variables ##
$OutputAppReqFID = "fo4a3b58-bdd6-44c8-ba11-763e211c183f"
$Project = 'M000'
$LocalPath = "\\file.server.au\$project\DATA\DATA CUSTODIAN\OUTPUT\"
$sfClient = Get-SfClient -Name C:\sharefile\SVCACC.sfps
$OutputAppReqFID_URL = (Send-SfRequest $sfClient -Entity Items -id $OutputAppReqFID).Url
## Create PS Drive ##
New-PSDrive -Name "sfDrive-$($project)" -PSProvider ShareFile -Client $sfClient -Root "\" -RootUri $OutputAppReqFID_URL
## Copy all files from folders to ShareFile
foreach ($file in Get-ChildItem -Path $LocalPath -Recurse -Force | Where-Object {$_.Mode -ne "d-----"} | Select FullName -ExpandProperty FullName) {
Get-ChildItem $file -Recurse | Rename-Item -NewName { $_.Directory.Name+'_'+$_.Name}
Copy-SfItem -Path $file -Destination "sfDrive-$($project):"
#remove-item $file
}
<## Remove all folders from UNC directory
foreach ($folder in Get-childitem -Path $LocalPath -Recurse | Where-Object {$_.Mode -eq "d-----"} | Select-Object -ExpandProperty FullName) {
remove-item $folder
}
#>
## Remove PS Drive ##
Remove-PSDrive "sfdrive-$($project)"
Error recieved is below:
Copy-SfItem : Cannot find path '\\file.server.au\M000\DATA\DATA CUSTODIAN\OUTPUT\New Text Document.txt' because it does not exist.
At line:43 char:6
+ Copy-SfItem -Path $file -Destination "sfDrive-$($project):"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (\\file.serve...xt Document.txt:String) [Copy-SfItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,ShareFile.Api.Powershell.CopySfItem
The problem is that you are renaming $file and then trying to Copy-SfItem -Path $file in the very next line. This reference to $file is still pointing to the old name before the rename. You need to instead capture the path to the newly renamed filepath and then reference that in your Copy-SfItem command
foreach ($file in Get-ChildItem -Path $LocalPath -Recurse -Force |
Where-Object { $_.Mode -ne 'd-----' } |
Select-Object -ExpandProperty FullName) {
# capture reference to the new file name by using -PassThru switch with
# the Rename-Item cmdlet and saving in a variable ($renamedFile)
$renamedFile = Get-ChildItem $file -Recurse |
Rename-Item -NewName { $_.Directory.Name + '_' + $_.Name } -PassThru
# Now we copy using our $newFile reference
Copy-SfItem -Path $renamedFile -Destination "sfDrive-$($project):"
# followed by removing the file if needed
# remove-item $renamedFile
}
This can be cleaned up some as well.
Adding the -File switch to Get-ChildItem will give us only files removing the need for | Where-Object {$_.Mode -ne "d-----"}
Taking off the | Select-Object -ExpandProperty FullName from the end of the foreach will eliminate the need to calling Get-ChildItem again in the first foreach loop.
foreach ($file in Get-ChildItem -Path $LocalPath -Recurse -Force -File ) {
# capture reference to the new file name by using -PassThru switch with
# the Rename-Item cmdlet and saving in a variable ($newFile)
$renamedFile = $file | Rename-Item -NewName { $_.Directory.Name + '_' + $_.Name } -PassThru
# Now we copy using our $newFile reference
Copy-SfItem -Path $renamedFile -Destination "sfDrive-$($project):"
# followed by removing the file if needed
# remove-item $renamedFile
}
Updates based on your comments
foreach ($file in Get-ChildItem -Path $LocalPath -Recurse -Force -File ) {
$file = if ($file.Directory.FullName -ne $LocalPath) {
# capture reference to the new file name by using -PassThru switch with
# the Rename-Item cmdlet and saving in a variable ($file)
$file | Rename-Item -NewName { $_.Directory.Name + '_' + $_.Name } -PassThru
}
else {
#Pass thru $file with no changes
$file
}
# Now we copy using our $file reference
Copy-SfItem -Path $file -Destination "sfDrive-$($project):"
# followed by removing the file if needed
# remove-item $file
}
I am trying to copy latest 30days files to the folder by this code:
$month = (get-date).AddDays(-30).ToString("yyyMM")
$lastmonthfiles = Write-Host (-join('DCP_', $month,"*.csv"))
Copy-Item -Path Write-Host (-join ("C:\DC+\History\", $lastmonthfiles)) -Destination C:\DC+\History\Backup
but I am having a problem in path in copy-item instruction, which is
Copy-Item : A positional parameter cannot be found that accepts argument 'C:\DC+\History\'.
At line:5 char:1
+ Copy-Item -Path Write-Host (-join ("C:\DC+\History\", $lastmonthfiles ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Copy-Item], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.CopyItemCommand
I am new in PowerShell, and programming so, I could not understand, how can I update and achieve a goal.
Try this:
$Source = Get-Item "C:\Games"
$Destination = "E:\Backup"
$LogFile = "C:\Copy-LogFile.txt"
Copy-Item -Path $( $Source | Where LastWriteTime -LE (Get-Date).AddDays(-30) ) -Destination $Destination -Recurse -PassThru |
Out-File $LogFile -Force
This takes care of your copy function and generates an output log.
Sorry, but your code makes no sense to me...
If it is your aim to copy files to a subfolder in a backup path, try this:
# get the date to use as subfolder to copy to and also to filter the last 30 days files
$refDate = (Get-Date).AddDays(-30).Date # .Date sets it to midnight
# set this variable to the folder where the csv are to be found
$sourceFolder = 'X:\Path\To\Where\The\Files\Are'
# create a destination path to copy to (just a string)
$destination = Join-Path -Path 'C:\DC+\History\Backup' -ChildPath ($refDate.ToString("yyyMM"))
# create this destination folder
$null = New-Item -Path $destination -ItemType Directory -Force
# get the files and copy them to the destination folder
Get-ChildItem -Path $sourceFolder -Filter '*.csv' -File | # filter on CSV fies only
Where-Object { $_.LastWriteTime -ge $refDate } | # filter on date 'last 30 days'
Copy-Item -Destination $destination -Force
I've got this function, that move a directory to inside another directory, but always gives me the access denied error.
Any idea what am i doing wrong?
Get-ChildItem C:\Scripts\MetadataExport -Directory | ForEach-Object {
# this will look for a 4-12 digit number in the directory name
If ($_.Name -match '(?:\b|\D)(\d{4,12})(?:\b|\D)') {
$destPath = Join-Path $_.Parent.Fullname $Matches[1]
If (-not (Test-Path -LiteralPath $destPath)) {
New-Item $destPath -ItemType Directory
}
Move-Item -LiteralPath $_.Fullname -Destination $destPath -Force
}
}
the error:
Move-Item : Access to the path 'C:\Scripts\MetadataExport\kwakwala-rosenblum-0172' is denied.
At C:\Users\User\Documents\ScripsPS1\MetadataExport.ps1:170 char:9
Move-Item -LiteralPath $_.Fullname -Destination $destPath -Fo ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : WriteError: (C:\Scripts\Meta...-rosenblum-0172:DirectoryInfo) [Move-Item], IOException
+ FullyQualifiedErrorId : MoveDirectoryItemIOError,Microsoft.PowerShell.Commands.MoveItemCommand
So, the goal is to move every folder that part of the name matches with another folder with numeric name.
Ex:
The 'kwakwala-rosenblum-0172' folder needs to move to inside '0172' folder.
Just move if the Literal-Path is the same as folder's name.
I am not sure what you are trying to do but you effectively try to move a folder to a folder with the same name:
$Null = New-Item -Path .\0172 -ItemType Directory -Force
$Null = New-Item -Path .\kwakwala-rosenblum-0172 -ItemType Directory -Force
Get-ChildItem -Directory | Foreach-Object {
if ($_.Name -Match '(?:\b|\D)(\d{4,12})(?:\b|\D)') {
$destPath = Join-Path $_.Parent.Fullname $Matches[1]
Write-Host $_.Fullname '-->' $destPath
}
}
C:\..\0172 --> C:\..\0172
C:\..\kwakwala-rosenblum-0172 --> C:\..\0172
Which is the same as doing this:
Move-Item -LiteralPath .\0172 -Destination .\0172 -force
Move-Item: The process cannot access the file because it is being used by another process.
Meaning that this would likely "resolve" the issue:
if ($_.Fullname -ne $destPath) {
Move-Item -LiteralPath $_.Fullname -Destination $destPath -Force
}
But, I am not sure what your expectation is.
You might want to explain (in the question) how you expect the subfolders to be (re)named.
I want to remove bak files after zip from all subfolder for given path, so all duplicate files with extension .bak will be removed,i run below script but getting error.
$filePath = "d:\Test\"
$Afiles = Get-ChildItem -Recurse -Path $filePath | Where-Object {$_.Extension -eq ".bak"}
$Bfiles = Get-ChildItem -Recurse -Path $filePath | Where-Object {$_.Extension -eq ".7z"}
$Alist = #()
$Blist = #()
foreach( $A in $Afiles) {
$Alist += $A.baseName
}
foreach( $B in $Bfiles) {
$Blist += $B.baseName
}
foreach($A in $Alist) {
if($Blist -contains $a)
{
rm ("$A.bak")
}
}
I am receiving below error :
Remove-Item : Cannot find path 'C:\Users\******\Desktop\master_backup_2015_08_21_013722_8370267.bak' because it does not exist.
At C:\Users\*****\Desktop\duplicatedelete1.ps1:26 char:10
+ rm <<<< ("$A.bak")
+ CategoryInfo : ObjectNotFound: (C:\Users\****....722_8370267.bak:String) [Remove-Item], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand
You're receiving error because you're not specifying full path for rm command and PowerShell tries to delete file in your current directory.
Try this:
$Path = 'D:\Test'
Get-ChildItem -Path $Path -Recurse -Filter '*.7z' | ForEach-Object {
$BackupFile = Join-Path -Path (Split-Path $_.FullName -Parent) -ChildPath ($_.BaseName + '.bak')
if(Test-Path -Path $BackupFile){
Remove-Item -Path $BackupFile
}
}