The reason you cannot just use $count++
in your script block in order to increment the sequence number directly is:
Delay-bind script blocks - such as the one you passed to Rename-Item -NewName
- and script blocks in calculated properties run in a child scope.
Therefore, attempting to modify the caller's variables instead creates a block-local variable that goes out of scope in every iteration, so that the next iteration again sees the original value from the caller's scope.
- To learn more about scopes and implicit local-variable creation, see this answer.
Workarounds
A pragmatic, but potentially limiting workaround is to use scope specifier $script:
- i.e., $script:count
- to refer to the caller's $count
variable:
$directory = 'C:\Temp'
[int] $count=71
gci $directory | sort -Property LastWriteTime |
rename-item -newname { '{0}_{1}' -f $script:count++, $_.Name } -whatif
This will work:
in an interactive session (at the command prompt, in the global scope).
in a script, as long as the $count
variable was initialized in the script's top-level scope.
- That is, if you moved your code into a function with a function-local
$count
variable, it would no longer work.
A flexible solution requires a reliable relative reference to the parent scope:
There are two choices:
- conceptually clear, but verbose and comparatively slow, due to having to call a cmdlet:
(Get-Variable -Scope 1 count).Value++
gci $directory | sort -Property LastWriteTime |
rename-item -newname { '{0}_{1}' -f (Get-Variable -Scope 1 count).Value++, $_.Name } -whatif
- somewhat obscure, but faster and more concise:
([ref] $count).Value++
gci $directory | sort -Property LastWriteTime |
rename-item -newname { '{0}_{1}' -f ([ref] $count).Value++, $_.Name } -whatif
[ref] $count
is effectively the same as Get-Variable -Scope 1 count
(assuming that a $count
variable was set in the parent scope)
Note: In theory, you could use $global:count
to both initialize and increment a global variable in any scope, but given that global variables linger even after script execution ends, you should then also save any preexisting $global:count
value beforehand, and restore it afterwards, which makes this approach impractical.