Dave
Dave

Reputation: 49

What is causing the error "You cannot call a method on a null-valued expression."

I am trying to create a script that will uninstall software listed in the variable $packages

When running my code i get the below error and cannot figure what is causing this.

You cannot call a method on a null-valued expression.
At line:7 char:3
+   $app.Uninstall()
+   ~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

some of the items within Packages will uninstall but not all and if i add an additional fake package to the start then they will all uninstall and produce the same error for that fake package which has left me a little confused as to why this happens.

My code is

$packages = @("Package 1 (Transport) TEST", "Package 2 TEST", "Package 3 TEST", "Package 4 
TEST", "Package 5 TEST", "Package 6 TEST", "Package 7 TEST", "Package 8 TEST", "Package 9 
TEST", "Package 10 TEST", "Package 11 TEST", "Package 12 TEST")
foreach($package in $packages){
$app = Get-WmiObject -Class Win32_Product | Where-Object {
$_.Name -match "$package"
}
$app.Uninstall()
}

any help would be greatly appreciated

Upvotes: 1

Views: 12597

Answers (2)

Dave
Dave

Reputation: 49

Mathias answer resolved my error issues however i had a further problem where one of the Packages was not being found for some reason. (I suspect this is due to Brackets in packages name)

I modified my Script as below, In my use case i want everything from the same vedor uninstalled so this works fine for me.

$app = Get-WmiObject -Class Win32_Product | Where-Object {$_.Vendor -match "[Vendor Name]"}
  $app.Uninstall()

Upvotes: 0

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174990

That error means that nothing is assigned to $app - in other words, there were no discoverable instance of Win32_Product that satisfied the Where-Object condition $_.Name -match "$package".

You can either rewrite your code slightly to check whether $app has a value or not:

foreach($package in $packages){
  $app = Get-WmiObject -Class Win32_Product | Where-Object {
    $_.Name -match "$package"
  }

  # Let's make sure we actually got something
  if($app){
    $app.Uninstall()
  }
}

Or, perhaps preferably, do another loop over the 0 or more objects that $app might contain (in the case where a package name matches multiple installed products):

foreach($package in $packages){
  $apps = Get-WmiObject -Class Win32_Product | Where-Object {
    $_.Name -match "$package"
  }

  # if `$apps` is empty/$null, the loop will simply run 0 times :) 
  foreach($app in $apps){
    $app.Uninstall()
  }
}

Upvotes: 1

Related Questions