Programs running on Hyper-V with Invoke-Command hang - powershell

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.

Related

How to remotely execute an remote script in PowerShell

First off: This is not a duplicate of How to remote execute an ELEVATED remote script in PowerShell.
My scenario is similar but different in a certain way. What I want to do is the following:
Invoke-Command -UseSSL -ComputerName "$COMPUTER" -FilePath \\script.example.com\secretshare$\install_test.ps1 -ArgumentList 'U'
As the called script performs an installation and manipulates firewall rules, it needs elevated privileges. Irritatingly the error I get is an access error on the share mentioned above.
When I use this suggestion where I use PowerShell DSC, which is run as SYSTEM, it works. But only on Servers running Windows Management Framwork 4.0. So obviously I need a solution for Windows Server 2008 (R2) systems.
I hope someone can point me to the right direction so I can update this question to help other admins aswell.

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.

Windows - remotely running executable or cmd using WMI or powershell, and logging the output

This is incredibly difficult to do. I can't believe it. It should be so easy.
Anyway, using WMI (with both vbscript and perl) I'm able to start a process on a remote machine that runs a .exe, but I cannot get the output to write to a log. This is driving me nuts. I have to use WMI or powershell because I can't install anything additional on the remote machines, which are all Windows 2003 or newer. I also cannot assume that powershell remoting is enabled on all target machines, so I may not even be able to use powershell. This can cause a problem with powershell.
Here is what I'm trying to do in psuedo code:
servers = server1, server2, server3
for each server in servers
run command on remote server >> log.txt
next
I'm assuming you have powershell remoting enabled on all the servers and that you want the results saved in a local log file (ie not on each server)...
$Servers = "server1", "server2","server3"
Invoke-Command -ComputerName $Servers -ScriptBlock { ping.exe www.stackoverflow.com } >> c:\localfile.txt
This also assumes that your exe outputs to stdout, I think there will be issues capturing other streams.

Starting a process remotely in Powershell, getting %ERRORLEVEL% in Windows

A bit of background:
I'm trying to start and stop some performance counters remotely at the start of a test, then stop them at the end of the test. I'm doing this from an automated test framework from a Win2003 machine, the test framework executes commands without launching a console, some of the system under test is running Win2008. I've written scripts to choose the performance counters based on roles assigned to the servers.
My problem(s):
logman can't start or stop counters on machines that run a later version of the OS.
psexec can be used to run logman remotely, but psexec likes to hang intermittently when run from the test framework. It runs fine manually from the command line. I'm guessing that this is because the calling process doesn't provide a console, or some similar awkwardness. There's not much I can do about this (GRRRR)
I wrote a PowerShell script that executes logman remotely using the WMI's win32_process and called it from a batch script, this works fine. However, the test framework decides pass and fail scenarios based on the %ERRORLEVEL% and the content of stderr, but WMI's win32_process does not give me access to either. So if the counters fail to start, the test will plough on anyway and waste everyone's time.
I'm looking for a solution that will allow me to execute a program on a remote machine, check the return code of the program and/or pipe stderr back to the caller. For reasons of simplicity, it needs to be written in tools that are available on a vanilla Win2k3 box. I'd really prefer not to use a convoluted collection of scripts that dump things into log files then reading them back out again.
Has anyone had a similar problem, and solved it, or at least have a suggestion?
For reasons of simplicity, it needs to
be written in tools that are available
on a vanilla Win2k3 box. I'd really
prefer not to use a convoluted
collection of scripts that dump things
into log files then reading them back
out again.
PowerShell isn't a native tool in Windows 2003. Do you still want to tag this question PowerShell and look for an answer? Anyway, I will give you a PowerShell answer.
$proc = Invoke-WmiMethod -ComputerName Test -Class Win32_Process -Name Create -ArgumentList "Notepad.exe"
Register-WmiEvent -ComputerName test -Query "Select * from Win32_ProcessStopTrace Where ProcessID=$($proc.ProcessId)" -Action { Write-Host "Process ExitCode: $($event.SourceEventArgs.NewEvent.ExitStatus)" }
This requires PowerShell 2.0 on the system where you are running these scripts. Your Windows 2003 remote system does not really need PowerShell.
PS: If you need a crash course on WMI and PowerShell, do read my eGuide: WMI Query Language via PowerShell