Welcome › Forums › General PowerShell Q&A › Assistance with Invoke-Command ScriptBlock error.
- This topic has 3 replies, 3 voices, and was last updated 1 month, 1 week ago by
Participant.
-
AuthorPosts
-
-
December 11, 2020 at 12:15 pm #278886
Hello All,
What I am trying to accomplish is for this script to take a list of remote servers and find the “Service Name” of a service, and then convert that into a PID that will be used later for process termination. This is only a snippet of a script that will take a list of servers, ask the user for the “Service Name” of a service and kill that task. For a single server, I have it working.
Here is the issue, the script below is as far as I gotten toward my goal with a list of servers. This particular version seems the best, but gives an error “Get-Process: Cannot find a process withthe name “whatever”. I have verified the process exists with the name provided. In fact, the process that I am testing with has the same name as the Service Name except the process has ‘exe’ appended. Didn’t matter however.
It appears that Invoke-Command has trouble with multiple commands in the ScriptBlock, but I don’t know another way to make this happen.
I am limited to PoSH 5.1 and Get-Process and Get-WMIObject can’t accept the $server variable in the -ComputerName parameter of Invoke-Command. They only work if thier -ComputerName parameter is used.
Any assistance would be appreciated.PowerShell12345678910$ServerList = 'server01','server02'$SvcName = 'whatever'$ted = ForEach ($Server in $ServerList){Invoke-Command -ScriptBlock {$ProcID = Invoke-Command -ScriptBlock {(Get-Process -ComputerName $server -name $SvcName).Id};$ProcObj = Invoke-command -ScriptBlock {Get-WmiObject Win32_Process -ComputerName $server | ?{ $_.ProcessId -match $ProcID }}}} -
December 11, 2020 at 1:31 pm #278913
Variables defined outside of the Invoke-Command script block cannot be referenced inside the Invoke-Command script block. So in your case line 7, $SvcName does not exist ($null). To “fix” this you would need to preface $using: or pass the object in as an argument to a parameter. Either way I would change the approach. Based on what your requirements are per the post here’s what I would do:
PowerShell1234567891011$ServerList = 'server01','server02'$ted = Invoke-Command -ComputerName $ServerList -ScriptBlock {$SvcName = 'whatever'$PID = Get-CimInstance -ClassName win32_service |Where-Object {$_.Name -eq $SvcName} |Select-Object -ExpandProperty ProcessID#Do whatever you want to the process here. Just reference $PID for the pid} #invoke-command script blockNote the computername parameter of invoke-command will take an array so no need for the foreach loop. Any objects returned from the remote script block will be assigned to $ted with a new property of PSComputerName that will tell you which server it came from.
-
This reply was modified 1 month, 1 week ago by
Mike R..
-
This reply was modified 1 month, 1 week ago by
-
December 11, 2020 at 1:38 pm #278919
There are numerous issues. This is invoking a command locally, to invoke a command locally again to make a remote call from the local server to the remote server. WMI and Get-Process (which in the background is using WMI) can make RPC calls to the server with DCOM:
PowerShell1234567$ServerList = 'server01','server02'$SvcName = 'whatever'$ted = ForEach ($Server in $ServerList){$ProcID = (Get-Process -ComputerName $server -name $SvcName).Id$ProcObj = Get-WmiObject Win32_Process -ComputerName $server | ?{ $_.ProcessId -match $ProcID }}If you want to use PS Remoting with WSMAN, then you can do it like this to execute the commands remotely on the server. To pass a local variable to the remote session, you need to use the ‘Using:’ keyword:
PowerShell123456789$ServerList = 'server01','server02'$SvcName = 'whatever'$ted = ForEach ($Server in $ServerList){Invoke-Command -ComputerName $server -ScriptBlock {$ProcID = (Get-Process -name $using:SvcName).Id$ProcObj = Get-WmiObject Win32_Process | ?{ $_.ProcessId -match $ProcID }}}Also, keep in mind that this is assuming there is 1 returned value. Using -match is a regex, a better comparison would be using -eq (equals) for a straight comparison.
-
December 11, 2020 at 1:50 pm #278925
Yea, I had a feeling that I was on a bad path with this one, but couldn’t sort out exactly what. Thank you for the guidance.
-
-
AuthorPosts
- You must be logged in to reply to this topic.