$command = Start-Process -NoNewWindow -FilePath "C:\Program Files\McAfee\Agent\cmdagent.exe" -ArgumentList "/e /l C:\temp"
This doesn't define a command for later execution with Invoke-Command
, it instantly executes the Start-Process
command, which is not your intent, and it is the reason it runs locally.
To fix that, you'd have to define it as a script block ({ ... }
):
$command = { Start-Proces ... }
, and then pass it as-is to Invoke-Command
's -ScriptBlock
parameter (Invoke-Command -ComputerName $computer -ScriptBlock $command
) (don't enclose it in { ... }
again).
Additionally, I suggest taking advantage of Invoke-Command
's ability to target multiple computers at once, in parallel, and to avoid using Start-Process
for synchronous invocation of an external program in the same window.
To put it all together:
$machines = Get-Content -Path "C:\server_list.txt"
Write-host "Executing Events on the following computers: $machines" -b "yellow" -foregroundcolor "red"
# Define the command as a script block, which is a piece of PowerShell code
# you can execute on demand later.
# In it, execute cmdagent.exe *directly*, not via Start-Process.
$command = { & "C:\Program Files\McAfee\Agent\cmdagent.exe" /e /l C:\temp }
# Invoke the script block on *all* computers in parallel, with a single
# Invoke-Command call.
Invoke-Command -ComputerName $machines -ScriptBlock $command
Note the need to use &
, the call operator, to invoke the cmdagent.exe
executable, because its path is quoted (of necessity, due to containing spaces).
Alternatively, you can define the script block directly in the Invoke-Command
call:
Invoke-Command -ComputerName $machines -ScriptBlock {
& "C:\Program Files\McAfee\Agent\cmdagent.exe" /e /l C:\temp
}
A notable pitfall when targeting remote computers is that you cannot directly reference local variables in the (remotely executing) script block, and must instead explicitly refer to them via the $using:
scope; e.g., $using:someLocalVar
instead of $someLocalVar
- see this answer for more information.