Author Posts

July 21, 2015 at 11:25 am

I have a simple script to rename some files
#cls
cd e:\scripts\br
Get-ChildItem -Filter "13615*.pdf" -Recurse | Rename-Item -NewName {$_.name -replace '136150','0' }
Get-ChildItem -Filter "11111*.pdf" -Recurse | Rename-Item -NewName {$_.name -replace '111110','0' }
#Write-Output -Recurse | {$_.name}
if ( $_.name.contains("-01") -ne "True" ) {
Get-ChildItem -Filter "*.1.pdf" -Recurse | Rename-Item -NewName {$_.name -replace '.1.pdf','-01x.1.pdf' }
}
Write-Output Done

what i get when i run it is
Done
PS E:\scripts\br> powershell.exe .\renamer.ps1
You cannot call a method on a null-valued expression.
At E:\scripts\br\renamer.ps1:6 char:6
+ if ( $_.name.contains("-01") -ne "True" ) {
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
so clearly $_name.contains("-01") isnt working the way I expect...any ideas on where I am going wrong?

July 21, 2015 at 11:31 am

You're misusing $_.

You've probably seen it used in commands like ForEach-Object and Where-Object, which is where it's made to be used (mostly). But $_ can only be used in specific situations where PowerShell knows to look for it, and you're not in one of those situations.

For example, what you're doing with -NewName is also not legal. Write-Output doesn't have a -Recurse parameter. In the specific place where you're getting the error, $_ has literally no meaning. Therefore, it doesn't have a Name property, therefore, the Contains() method is being called for a null-valued expression, which is the error.

You might be able to rewrite things.

Get-ChildItem -Filter "13615*.pdf" -Recurse | ForEach-Object {
  Rename-Item -NewName ($_.Name -replace '136150','0′)
  if ($_.name.contains("-01")) {
  }
}

Within those outermost {} of ForEach-Object, PowerShell will replace $_ with the current pipeline object.