Search code examples
powershellinvoke-command

Invoke-Command to clear Internet Explorer Cache


Using specific input of the user logon name and computername I would like to delete the Temporary internet files for that user on a remote machine. I can almost get it to work but when I try and pass the filepath as a variable it fails with either being empty, or not including the username. I have googled and tried to fix it myself for hours now. I have played with powershell for a while but my 'scripting' is me defining variables and just piping commands. Anything beyond that will probably just confuse me although, any help would be appreciated. Below is what I have so far. The redundancy is just me checking that my variables are being passed until the -Scriptblock, which is where things go wrong.

$User = Read-Host -Prompt 'Please input the user logon name.'
$CompName = Read-Host -Prompt 'Please enter the target computername.'
$UNC = "C:\Users\$User\AppData\Local\Microsoft\Windows\Temporary Internet Files"
$Block = { Remove-Item $UNC -Recurse -Force -EA Continue }
Invoke-Command -ComputerName $CompName -ScriptBlock {$Block} 

Solution

  • This gets asked a lot. You are invoking a new session or runtime environment where the contents of $UNC does not exist. You need to pass that value from the calling script to the called invoke. You do it with -ArgumentList. The syntax for Invoke-Command and Invoke-Expression are the same for this parameter. Here is a full example:

    Cannot bind parameter to argument 'command' beacuse it is null. Powershell

    Also, I would change this: Invoke-Command -ComputerName $CompName -ScriptBlock {$Block} to this: Invoke-Command -ComputerName $CompName -ScriptBlock $Block

    the meaning is very different. {$Block} would run a script that outputted the value (blank) of $Block. Whereas without the {} you are passing a scriptblock variable to be parsed.


    Here is a working example:

    $OutsideVar = "Hello World!"
    
    invoke-command -ArgumentList $OutsideVar -ScriptBlock {
        param( $InsideVar )
        Write-Host $InsideVar
    }
    

    The key to understanding what is happening here is understanding scope. $OutsideVar exists at the top processes scope. When you start a new scope with Invoke-Command $OutsideVar no longer exists. Just like you can call an .EXE file with arguments, you can call this new scope with arguments. You have to tell the inner scope how to handle those arguments and that is what the param() block is doing. It says: "You are going to get 1 argument, store it in $InsideVar". Now you have that value in the inner scope. You can pass multiple values by adding more params like this:

    invoke-command -ArgumentList $OutsideVar, $OutsideVar2, $OutsideVar3 -ScriptBlock {
        param( $InsideVar, $InsideVar2, $InsideVar3 )
    }