I have the following script for renaming a bunch of files in a directory, adding the name of the directory to the start of them:
$s = "Y:\Teknisk Arkiv\Likeretter 111-Å1\E2_Kretsskjema\02_Likeretter styring\3AJJ000302-222"
Get-ChildItem -Path $s -Exclude $_.Directory.Name* | rename-item -NewName { $_.Directory.Name + '_' + $_.Name }
Before running the script the files in the folder looks something like this
after like this
As you can see it does more or less what I want, except that -exclude $_.DirectoryName*
doesn't prevent files which already have the foldername as a prefix from being renamed. What am I doing wrong here?
$_
in a pipeline is only defined inside a script block used in a non-initial pipeline segment, where it refers to the input object at hand, so in your Get-ChildItem
command it is effectively undefined.
Even if $_.Directory.Name
did have a value, $_.Directory.Name*
wouldn't work as expected, because it would be passed as 2 arguments (you'd have to use "$($_.Directory.Name)*"
or ($_.Directory.Name + '*')
.
You instead want to extract the directory name from the $s
input path, which you can do with Split-Path -Leaf
, and then append '*'
.
In order for -Exclude
to be effective, the input path must end in \*
, because -Include
and -Exclude
filters - perhaps surprisingly - operate on the leaf component of the -Path
argument, not on the child paths (unless -Recurse
is also specified).
To put it all together:
Get-Item -Path $s\* -Exclude ((Split-Path -Leaf $s) + '*') |
Rename-Item -NewName { $_.Directory.Name + '_' + $_.Name }
I've switched to Get-Item
, since \*
is now being used to enumerate the children, but Get-ChildItem
would work too.