Powershell - script error: "You cannot call a method on a null-valued expression."

Discussion in 'Scripting' started by strotee, Dec 23, 2021.

  1. strotee

    strotee MDL Member

    Jan 30, 2011
    229
    204
    10
    #1 strotee, Dec 23, 2021
    Last edited: Dec 23, 2021
    So I have this Powershell script that I execute that clears out my Quick Access pinned items and adds several custom paths. I'm trying to make it generic to where I can execute it on my host machine as well as a VM. I run into trouble when I have different usernames between host or VM. I'm getting this error:
    Code:
    You cannot call a method on a null-valued expression.
    At C:\Users\test\Desktop\quick_access.ps1:10 char:3
    +   $qa.NameSpace($array[$i]).Self.InvokeVerb("pintohome")
    It works when I hard-code in my username for $name.
    Code:
    #$ErrorActionPreference = 'SilentlyContinue'
    $qa = New-Object -ComObject shell.application
    $okItems = @("")
    #remove
    ($qa.Namespace("shell:::{679f85cb-0220-4080-b29b-5540cc05aab6}").Items() | where {$_.name -notin $okItems}).InvokeVerb("unpinfromhome");
    #add
    $name=powershell -c "(Get-ChildItem Env:\USERNAME).Value"
    $array = @('C:\users\$name\desktop','C:\Windows\System32\drivers\etc')
    for($i=0;$i -lt $array.Length;$i++) {
      $qa.NameSpace($array[$i]).Self.InvokeVerb("pintohome")
    }
    Any pointers would be greatly appreciated.

    Edit: It works when I replace
    Code:
    $array = @('C:\users\$name...
    with
    Code:
    $array = @('C:\users\test...
     
  2. abbodi1406

    abbodi1406 MDL KB0000001

    Feb 19, 2011
    16,197
    84,762
    340
    Code:
    $array = @('C:\users\' + $name + '\desktop','C:\Windows\System32\drivers\etc')
    That's how to expand or include variable when you declare a string
     
  3. strotee

    strotee MDL Member

    Jan 30, 2011
    229
    204
    10
    Of course, concatentation, that'll teach me to wake up at 2am. I ended up using a slight change but this appears to be final:
    Code:
    $ErrorActionPreference = 'SilentlyContinue'
    $QA = New-Object -ComObject shell.application
    $okItems = @("")
    #remove
    ($QA.Namespace("shell:::{679f85cb-0220-4080-b29b-5540cc05aab6}").Items() | where {$_.name -notin $okItems}).InvokeVerb("unpinfromhome");
    #add
    $UserName=powershell -c "(Get-ChildItem Env:\USERNAME).Value"
    $Desktop = [System.String]::Concat("C:\Users\",$UserName,"\Desktop")
    $array = @($Desktop,'Z:\2.8','Z:\Plex','Z:\Torrents','Z:\Media','Z:\Projects','Z:\Projects\OS\Windows\10','C:\Windows\System32\drivers\etc','Z:\Media\webm\boram\resources\app')
    for($i=0;$i -lt $array.Length;$i++) {
      $qa.NameSpace($array[$i]).Self.InvokeVerb("pintohome")
    }
    
    Hopefully, someone else finds this useful for when your Quick Access pins gets wiped (via scripts or user error). Thanks and Merry Christmas.
     
  4. AveYo

    AveYo MDL Expert

    Feb 10, 2009
    1,836
    5,693
    60
    'single quotes treat the content literally, for example $pid is $pid'
    "
    double quotes would replace $pid here with the process id"
    old-fashion concatenation is usually safer, since paths can contain special powershell characters such as $ or @
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  5. strotee

    strotee MDL Member

    Jan 30, 2011
    229
    204
    10
    Thanks, I updated the code:
    Code:
    $UserName=[System.Security.Principal.WindowsIdentity]::GetCurrent().Name.split("\")[1]
    $Desktop = 'C:\Users\' + $UserName + '\Desktop'
    
     
  6. strotee

    strotee MDL Member

    Jan 30, 2011
    229
    204
    10
    This is the FINAL version (I swear). Use it as to how you like: https:// pastebin.com/raw/SyFiTbmi