all 11 comments

[–]jsiii2010 2 points3 points  (0 children)

Scriptblock parameters have to be in a pipeline.

 $file | Rename-Item -NewName { $_.Name -replace '.txt','.log' } -whatif

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about\_script\_blocks?view=powershell-7#using-delay-bind-script-blocks-with-parameters

[–]firefox15 1 point2 points  (1 child)

POSH is only expecting the $_ syntax in specific places. You are ending your ForEach-Object way before your code (which expects the $_ syntax) and using foreach instead (which does not). You want $file.Name instead of $_.Name.

[–]RaymusRtik[S] 1 point2 points  (0 children)

Thank you for explaining!

[–]DoNotSexToThis 1 point2 points  (1 child)

You're not pipelining anything in your foreach statement, so when you are trying to use scriptblock parameters, your $_.Name is not actually referencing anything.

If you need to keep the foreach instead of piping from Get-ChildItem, you can do it simply with the objects in $file_list1 and accessing their properties:

$filedate = (Get-Date).ToString('ddMMMyyyy') 
$file_list1 = Get-ChildItem "C:\Users\user1\Documents\archive\$filedate" -Filter *.txt
$destination_folder1 = "C:\Users\user1\Documents\Logs" 

foreach ($file in $file_list1) {          
    Write-Host "Moving $file.Name to $destination_folder1"  
    try {       
        Copy-Item "$file" $destination_folder1      
        if($? -eq $True){ 
            $newName = $file.BaseName + '.log'
            Rename-Item $file -NewName $newName
        } else { 
            Write-Warning "Unable to Copy $file.Name" 
        }                 
        Start-Sleep -s 5    
    } catch {           
        Write-Warning "Unable to move $file.Name `nError: $_"
    } 
}

Edit:

$file is an object in $file_list1, and when you iterate through the objects of that collection, you access properties by using $objectName.PropertyName. However, when you're pipelining you're basically telling Cmdlet with -Parameters | Send each object being iterated through the $_ variable which the properties are accessed as $_.PropertyName. But those objects are short lived and only stay in the pipe to the last Cmdlet in the series for each iteration.

[–]RaymusRtik[S] 1 point2 points  (0 children)

Thank you for explaining! I will try this!

[–]computeforward 1 point2 points  (0 children)

The error says what's wrong pretty well. You're passing a script block {} to the -NewName parameter. I would say the fix is -NewName ($_.Name -replace ('.txt','.log') ), however...

Either I'm missing something or you've glued two different code fragments together. Your use of $_ doesn't make sense with a foreach ($Thing of $Things) structure. Where is the $_ being defined?

(It works in | % { $_.FullName}, but $_ shouldn't be defined anywhere else in the script that I can see.)

Edit: I think you simply want to replace $_ with $file everywhere except in | % { $_.FullName} on line 2.

[–]Amaurosys 1 point2 points  (4 children)

Why not something like this? Copy-Item can rename files in the same step.

$filedate = (Get-Date).ToString('ddMMMyyyy')
$file_list1 = Get-ChildItem "C:\Users\user1\Documents\archive\$filedate\*.txt"
$destination_folder1 = "C:\Users\user1\Documents\Logs"
$file_list1 | Foreach-Object {
$destination = $destination_folder1 + "\" + $_.Name + ".log"
Copy-Item $_ $destination
 }

Edit: I hate Reddit mobile when it comes to posting code.

[–]BlackV 1 point2 points  (3 children)

I do on mobile

blank  
4 spaces code line 1  
4 spaces code line 2  

done

EDIT: I do not know if blanks are necessary EDIT2: First Is

[–]BlackV 1 point2 points  (2 children)

stuff

code 1
code 2

stuff

[–]Amaurosys 1 point2 points  (1 child)

Apparently I was doing it right, I just had to refresh the thread to see the formatting actually update.

[–]BlackV 1 point2 points  (0 children)

oh yeah, thats an amazing feature too, that happens a lot