Powershell Invoke-Command very slow to connect on one computer - performance

So I'm trying to use Invoke-Command to run a command on a remote server in Azure. To test, I'm using a super simple script:
Invoke-Command -ComputerName MyServer -ScriptBlock { Write-Output "HI"}
I've run this command on a whole bunch of other servers that are configured identically (as far as I can tell), and they all run in a second or less. For this particular server, it takes 2 minutes or more. I can't figure out why. It does eventually execute properly, but it takes forever to establish the remote pssession.
Some things I've tried/verified:
Powershell version is identical on this machine and others (5.1.14393). OS version is the same.
I've tried completely disabling Windows firewall, no luck
I've tried using explicit credentials instead of Kerberos
Network adapter settings/IP 4 settings are identical on all machines. It doesn't matter if the servers are on the same subnet or not.
FROM the problem machine I can Invoke-Command remotely to other machines just fine (< 1 second execution). On the problem machine, invoke-command to itself takes 2+ minutes
I've tried setting PSSessionOptions with options as described here.
Tried using ISE vs command line, no difference
Tried using enter-pssession, no difference
Tried using psexec on this and other servers. It works, takes about 20-30 seconds, but is consistent across all servers, including the problem server.
I've restarted the WinRM service, rebooted the machine, redeployed the machine in Azure, no dice.
DISM and SFC to repair image and installed files
As far as I can tell, the machine is identical to its "brother" that was set up at a similar time, in the same way, on the same subnet, with the same routing rules. The only difference is the machine size, but I've queried other machines of different sizes and they work as expected.
I'm out of ideas. Thoughts?

I had similar issues to this: the commands seemed to just hang. Turns out it was the proxy.
Use the following line in your script to bypass it:
netsh winhttp reset proxy

Related

Copy files from remote Windows machines with command-line, through RDP

Our team has ~80 Windows development machines, and activities of each developer are logged as text files on the local storage of those machines.
To analyze the logged activities, I want to gather all log files from those machines. Additionally, the log files are updated constantly, so It is desirable to gather files with the command-line from my machine.
I’ve searched and found some solutions, but all of those are not suitable for our situation:
We cannot use PsExec, because tcp/135 and tcp/445 are both closed (countermeasure for WannaCry).
Administrative share is disabled.
telnet service is not up and is banned by security reasons.
WinRM is disabled on those machines by default.
It is difficult to install new software like OpenSSH on those machines (because of the rule of this project)
RDP is the only way to connect those machines. (I have an account on all machines)
How can I copy files from remote Windows machines with command-line through RDP?
Or, at least, is there any way to execute a command on remote Windows machines with command-line through RDP?
I think you can do this, though it is very hacky :)
For a basic setup, which just copies files once, what you would need to do is
Run a script in the remote session when it logs in. I can think of three ways to do this:
Use the "Alternate Shell" RDP file property. This runs a specified program in place of explorer.exe on login; you can use it to run "cmd.exe /c [your script]" for instance.
If that doesn't work (e.g. the remote machine doesn't respect it), you might be able to use a scheduled task that runs the script on login, but perhaps only for a specified user, or maybe the script could check the WinStation type to make sure this is actually an RDP connection before doing anything.
It's also possible to do this by connecting in RemoteApp mode and using the script as your "application", but that only works for Server and Enterprise editions of Windows.
Enable either drive redirection or clipboard redirection on the RDP connection, to give you a way to get data out.
Drive redirection is much simpler to script; you just have the remote script copy files to e.g. "\\tsclient\C\logs".
Clipboard redirection is theoretically possible - you have the remote script copy, then a local script paste - but would probably be a pain to get working in practice. I'm only mentioning it in case drive redirection isn't available for some reason.
You would probably want to script to then log the session off afterward.
You could then launch that from command-line by running "mstsc.exe [your RDP file]". The RDP files could be programmatically generated if needed (given you're working with 80 machines).
If you want a persistent connection you can execute commands over, that's more complicated, but still technically possible. Two ways I can think of:
Use the previous method to run a program on logon, but this time create a custom application that receives commands using a transport that isn't blocked and executes them in the session. I've done this with WCF over HTTP, for instance; it's not secure, of course.
Develop and install a service on the remote machine that opens an RDP virtual channel, and a corresponding RDP client plugin that communicates with it. You can then do whatever you want across the connection. While this solution would be the most likely to work, it's also the most heavyweight and time-consuming to implement so it's probably a last resort.

How can I remotely detect if a Windows server is ready for login

In order to build an automated deployment pipeline, I need to be able to clone and deploy Windows Server virtual machines, sysprep them, and then perform various customisation tasks on them.
Some steps, such as sysprep, require a reboot, so I currently simply wait for the reboot to happen, and once the machine comes online again I can execute the customisation on it.
The problem with this is that sysprep performs various actions after the reboot, and as far as I can tell, everything on the machine becomes available during the time when "preparing Windows" is still showing on the machine. This means I can use PowerShell Remoting to start changing things, but I don't want to do my customisations which could reboot the machine, while the first-boot stuff is still happening.
How can I remotely detect that a machine is "fully" booted, or at least past any deployment stages so it's in a state ready to log into? Is there some service that only starts when the login is available? Maybe a registry key to indicate that the boot process was completely fully?
This loop does the trick pretty well for me.
while (-not (Test-Path \\machineName\c$)) {
Start-Sleep 1
Write-Host "Waiting..."
}
From what I've experienced, the file system is accessible a couple seconds after the login screen appears, so I'd assume the system is "fully" booted.
make a loop and wait for following registry key to become IMAGE_STATE_COMPLETE
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\State
IMAGE_STATE_COMPLETE represents fully completed sysprep after reboot.

Ansible - Managing Windows 2003 and WinRM connection timeout

I'm trying to implement Ansible in our company.
I have 2 huge problems that may cause us to leave this product, but before we give up I thought maybe someone could help us.
Some overall information - We installed ansible 2.1 on RHEL 6.5. We tried to use Ansible Tower but we gave up because of the complexity (most of our use is for ad-hoc commands).
The first issue is managing Windows server 2003. When we want to manage windows servers, we need to run the pre-script, but it only works with PowerShell v.3 and above, while Windows server 2003 is not supporting PowerShell v.3 (it's almost impossible to install this version).
In our company (unfortunately) there still dozens of Windows server 2003 machines.
Is there a way to make Ansible being able to manage those servers?
The second issue is the timeout of the WinRM. When we running an ad-hoc command on windows servers, there are machines that Ansible succeed to make a WinRM connection, but its hang out waiting the command to run (for example, even simple "hostname" commands).
We reduced the ansible timeout, but it's still hang out, so we assuming that it succeed making the WinRM connection but hang after.
There ia a way to configure the time out of ALL the process of ansible per machine, or otherwise configure the WinRM to have timeout after the connection succeeded?
Thanks,
Afik
Basically, no- due to major shortcomings of Powershell 2 for things we need to do, and the incredibly low number of Server 2003 installs left out there, we made PS3 the minimum required version.
There's been a little bit of work done by community folks to make a PS2-friendly version of the WinRM connection plugin to at least get basic Ansible connectivity working there (so "raw" will work, and modules can be transferred/run), but pretty much all the existing modules rely on Powershell cmdlets that don't exist in PS2/S2003. So you'd be back to "raw" for everything, which isn't much more useful than Powershell remoting (other than being able to blast commands to multiple machines at a time). If you want to see that, it's at
https://github.com/elum/ansible and
https://github.com/elum/ansible-modules-core
but we're unlikely to accept this into the core product or support it in any way.

psexec fails with error Could not start PsExec service on NTDB2UT02:

We recently moved from a Windows 2003 server to Windows 2008 R2 server and now I see that all my psexec jobs fail.
thsi is how they are coded to run:
c:\shell\psexec.exe \NTDB2UT02 -u conseco\plat -i cmd.exe
I then get prompted for a password and as soon as I enter the password I get the error message below
PsExec v1.31 - execute processes remotely
Copyright (C) 2001-2002 Mark Russinovich
www.sysinternals.com
Password:
Could not start PsExec service on NTDB2UT02:
The system cannot find the file specified.
So I went back to the Windows 2003 server that we were using earlier and I know it worked there because I have proof that it ran, and now I get the same message from the old Windows 2003 server too.
I read on a few posts that I could use the cmdkey to add a cached credential and I even tried doing that on both servers, but it didnt help at all.
I am going to try using a newer version of psexec, but I doubt that this will change anything at all.
Any tips or if anyone has successfully figured out a solution to this (or even a workaround), sharing that will be greatly appreciated.
thanks,
Mike
I have struggled with this on 2003 server and found that when I turned off firewall everything worked, then when turning firewall back on it didn't. I found the problem under firewall exceptions "File and Printer Sharing". When you go to edit the service, there are 4 entries, and when you check the scope they are set for your network subnet only. My problem was/is that we use multiple subnets and this machine did not match to the other machines trying to access it. If you find this is also your problem, and not the admin$ share issue (you can search against that), update the network subnets in a custom list (or if you're daring to attacks, allow any computer - bad idea). You only need to update ports 139 and 445 Hope this helps someone.

psexec inside visual studio

I've been trying to get psexec to run executables on remote machines from custom build tasks in visual studio. All of these commands work from the command line but running it from an application seems to be a problem. Some commands work, on other psexec hangs and consequently so do msbuild and visual studio 2005. I'm calling SharePoint's stsadm.exe in this case, but this problem occurs with a lot of programs, when running psexec from an application. There are lots of people having this problem, but there seems to be no solution, so my question is: Does anyone know a working alternative to psexec?
I've experienced 'hangs' when executing PSEXEC against a remote system, but I always attributed it to the security context in which the remote process was running under.
From PSEXEC help:
If you omit a username the remote
process runs in the same account from
which you execute PsExec, but because
the remote process is impersonating it
will not have access to network
resources on the remote system. When
you specify a username the remote
process executes in the account
specified, and will have access to any
network resources the account has
access to. Note that the password is
transmitted in clear text to the
remote system.
If your executing a process remotely, that then needs to access the database (stsadm.exe), then it could be failing trying to access the network resource, depending on how PSEXEC was executed. If thats the case, I'd imagine it would eventually time out and give some sort of resource unavailable message.
There are two things that generally done when executing deployment steps against a remote machine to prevent the behavior your describing:
Like rifferte mentioned, make sure all assets needed to
deploy are local to the remote
machine (copy files, etc) before
using PSEXEC to execute the script (*.bat, *.vbs, *.ps, etc) -
so that everything runs 'local' to
the remote machine.
Run PSEXEC using
a domain username/password when
executing it - note that this
information is passed in clear text
to the remote server.
There's always RCE.
RemCom is a small (10KB upx packed)
remoteshell / telnet replacement that
lets you execute processes on remote
windows systems, copy files on remote
systems, process there output and
stream it back. It allows execution of
remote shell commands directly with
full interactive console without
having to install any client software.
On local machines it is also able to
impersonate so can be used as a silent
replacement for Runas command.
You can try to have psexec call a bat program that executes what you need on the remote machine. I ran into this issue with installutil.exe. A simple bat file on the remote machine resolved it.
You should also share your experience on the sysinternals board. There may be something they can do in a future revision.

Resources