Running command (scriptblock) at remote machine with runspaces - powershell

Hello I have a template with runspaces that runs command and gives output to outputbox. My big question is how to make it run on remote machine? If you run script now it gives you systeminfo of current machine but I need it on remote machines. Thanks in advance
$rs = [runspacefactory]::CreateRunspace()
https://pastebin.com/B91Dgz0a

As far as I know and used, Runspaces are for multithreading or parallel execution within the confines of a local machine. I am not aware of a way to start and manage the lifecycle of a thread on a remote machine. That is the job of the OS of the remote machine.
Scriptblock
However, Runspaces allow you to add scriptblocks to it using the AddScript() method as you have in your code. So all you have to do is change the code inside the scriptblock to something like
SystemInfo /s $remoteComputer.
You should also be able to use Invoke-command -ComputerName $remoteComputer -ScriptBlock {SystemInfo}
Passing the Argument
Now the question is of passing the $remoteComputer argument to the scriptblock. You can use the AddArgument() method of the Runspace like: (Using the variablename in your code)
$ps.Runspace.AddArgument($remoteComputer) method.
I hope it made sense.

Related

Programs running on Hyper-V with Invoke-Command hang

I'm trying to run my software on Hyper-V VM using powershell Invoke-Command, without success. Host OS -Windows 10. Guest OS - also Windows 10. VM Generation 1.
I did some simple experiments and found out this:
If I run
Invoke-Command -VMName MY_VM -Credential $Cred -ScriptBlock { calc }
then I can see launched calc.exe on the guest system right with UI.
But if I run mspaint or any non-Microsoft program, nothing happens. The program just hangs in the VM TaskManager without any effect.
I also tried to run several different programs using CLI calling Invoke-Command several ways, but got the same result.
What could be the problem?
The basic answer is that powershell remote connections (or any remote connection like rdp, ssh, etc) take place in a separate logon session, and can't really interact with each other.
There are two reasonable ways to do this:
Use PsExec - part of the microsoft sysinternals tools group.
# List sessions - note the session ID of the session you want the process to start in
quser /server:$computername
# Run a process remotely, specifying the logon ID
PsExec.exe -s -i $ID notepad.exe
Use a scheduled task that runs when you are logged in and is visible. You can do this with powershell's various New-ScheduledTask commands to create one, or follow this guide by Scripting Guy! using WMI Win32_ScheduledJob methods.
See use powershell to start a gui program on a remote machine for more details on both options, and a well-written description of why it's hard to do in windows.

Run script from Host onto PsSession Computer

I am trying to run the following code to run a script from my host computer onto a Vm that I have PSRemoted into (I am successfully remoted into the PSSession). Where am I going wrong?
Invoke-Command -FilePath C:\Script.ps1 -ComputerName PSRemoteComputer
You do not need to use both a PSSession and the Invoke-Command -ComputerName command as you have above. At that point, you'd be invoking C:\Script.ps1 on your VM and from your VM (which I assume doesn't exist, since C:\Script.ps1 exists on your machine).
If you exit your PSSession and run the command as you have typed it above, it should run correctly assuming PSRemoting is correctly enabled, and permissions for the script to run are set.
Keep in mind, objects are handled differently through PSRemoting, so if you are expecting a certain output you may be getting the deserialized version.

Difference between - command and ScriptBlock Powershell

ps1 is on remote machine . I am running below command from some other mahcine.
Is there any difference between using both below script ---
invoke-command -computer $MachineName -command { C:\hello.ps1 }
invoke-command -computer $MachineName -scriptblock{ C:\hello.ps1 }
Also, I am going to use for loop for multiple machine having same script name but having diff sequence of work that is located on each remote machine only . Want to understand the execution for second machine will go only if first get completed . Correct ?
Difference between -command and -scriptblock
There is no difference in execution. -commandis merely an alias for scriptblock. You can verify this by getting the parameter info for the invoke-command command
(Get-Command -Name Invoke-Command).Parameters.Values | select name, aliases
Sequential execution
Yes, the execution is sequential. The command you specify will execute on the second machine after the command has completed on the first machine.
According to the help
These commands run synchronously (one at a time). When the commands
complete, the output of the commands from all of the computers is
saved in the $version variable. The output includes the name of the
computer from which the data originated.
To answer your second question: Invoke-Command works in parallel. It runs what ever is mentioned in the script block to all the machines in parallel. By default, powershell will talk upto 32 computers at once. If you specify more than that, it will queue them up so that as one computer completes, the next one in line will begin. However, I believe, you can increase that number by specifying the -throttlelimit parameter of the Invoke-Command.

Start a program or filepath remotely

With XP machines and eventually win7 machines. I am trying to find a way to start a program remotely from the commandline or even powershell if possible. Right now we can kill tasks using the "taskkill" command, but there doesn't seem to be an easy way to start them without extra programs. I want to be able to do it without deploying anything. I tried that Psexec but that didnt work.
Invoke-Command -ComputerName server01 -ScriptBlock { yourprogram.exe }
Check out technet:
The Invoke-Command cmdlet runs commands on a local or remote computer and returns all output from the commands, including errors. With a single Invoke-Command command, you can run commands on multiple computers.
http://technet.microsoft.com/en-us/library/hh849719.aspx

Powershell tasks from local machine to remote machine

I am performing below tasks on remote machine from a local machine:
Creating/Deleting/Modifying some directory
Copying some folder from local to remote machine
Installing some .exe silently with noninteractive option
Exectuing some batch files
I want to write a script in PowerShell. Novice to PowerShell. I have done some basic investigation of terms like "PowerShell Remoting" etc.
What are the things I need to look for? Related exmple for this will help, where should I look for those?
Reading from docs on MSDN:
To run a single command on a remote computer, use the ComputerName parameter. To run a series of related commands that share data, use the New-PSSession cmdlet to create a PSSession (a persistent connection) on the remote computer, and then use the Session parameter of Invoke-Command to run the command in the PSSession. To run a command in a disconnected session, use the InDisconnectedSession parameter. To run a command in a background job, use the AsJob parameter.
So basically you should do something like:
$session = New-PSSession
Invoke-Command -Session $session -FilePath <PathToScript>
There is a good section on PowerShell remoting in the Getting Started with PowerShell 3.0 Virtual Academy class. If you don't want to start there, read the about_Remote help topic, then move on to the other remoting help topics listed at the bottom.