1
Get-CimInstance -ComputerName $pc -Class Win32_UserProfile | Where-Object { $_.LocalPath.split('\')[-1] -eq $compare } | Remove-CimInstance

Because some system profiles have empty values for LocalPath, I get the following:

You cannot call a method on a null-valued expression. At line:52 char:88

Where-Object { $_.LocalPath.split('')[-1] -eq $compare })

Any way either first check for empty value and skip to next?

ty

mklement0
  • 382,024
  • 64
  • 607
  • 775
user1245735
  • 43
  • 1
  • 9

1 Answers1

2

In PowerShell (Core) 7.1 and above, you can use the null-conditional operator, ?.:

Get-CimInstance -ComputerName $pc -Class Win32_UserProfile | 
  Where-Object { $_.LocalPath?.split('\')[-1] -eq $compare } | 
  Remove-CimInstance

As a general caveat:

  • While ?. works as expected with properties, with variables it unfortunately and unexpectedly requires the variable name to be enclosed in {...}, because - surprisingly - ? is a legal character in a variable name.
  • For instance, Set-StrictMode -Version 2; $foo = $null; ${foo}?.ToUpper() works, but using $foo?.ToUpper() instead does not, because PowerShell looks for a variable named $foo? (sic), which doesn't exist. Requesting that this counterintuitive behavior be changed - even though it is technically a breaking change - is the subject of GitHub issue #14025.

In Windows PowerShell you can use PowerShell's implicit to-Boolean conversion rules:

Get-CimInstance -ComputerName $pc -Class Win32_UserProfile | 
  Where-Object { $_.LocalPath -and $_.LocalPath.split('\')[-1] -eq $compare } | 
  Remove-CimInstance
  • Due to use of $_.LocalPath as an operand with the -and operator, it is implicitly coerced to a Boolean, and $null is coerced to $false; similarly, an empty string would yield $false - see the bottom section of this answer for a summary of PowerShell's to-Boolean conversion rules.

  • Since -and short-circuits (as does -or), the RHS expression is never evaluated if $_.LocalPath yields $false, thereby avoiding the error.

  • Note that -eq has higher precedence than -and (and -or), so no parentheses are needed around the RHS expression - see the conceptual about_Operator_Precedence help topic

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • If you're working with a string, you can also use `[string]::isNullOrEmpty($path)` to check if the path is, well, null or empty. – Guy S Aug 19 '22 at 00:43
  • 1
    @GuyS, yes, but `$path` (in an _implied_ Boolean context, else use `[bool] $path`) is much simpler than `[string]::IsNullOrEmpty($path)` - and, as bonus for PowerShell users , they then don't have to learn about (clumsy) static methods such as `IsNullOrEmpty()`. If there's a chance that `$path` is a type other than a string , `$path -like ''` will do. Note that `[string]`-typed variables and parameters in PowerShell are never `$null` (try `[string] $foo = $null; '' -eq $foo`, which yields `$true`, because `$null` was converted to `''`) - only object properties / values rom APIs can be. – mklement0 Aug 19 '22 at 01:05
  • 1
    Alternative way for PS 5.x, that avoids naming `$_.LocalPath` twice: `"$($_.LocalPath)".split('\')[-1] -eq $compare` – zett42 Aug 20 '22 at 19:38