Restarting Jenkins Agent after VM Snapshot Recovery - powershell

I am working on a desktop version of Continious Integration Testing. I am using HyperV for Testinf Enviroment VMs. Those VMs have Snapshots, that are restored after every testrun. However i am stuck on the point where i need to restart the Jenkins agent on the recovered VM.
My best attempt was to inject a powershell command to restart the agent, which actually starts the agent. But it will immediatly close after the injection since there is no valid session that will keep it up.
The command I used to test this:
Invoke-Command -VMName VMName -Scriptblock {Start-Process -FilePath "C:\Jenkins\JenkinsAgentStart.bat"} -credential $credential
I also tried starting this as a new process. The result remains the same. I can see the Java RAM going up for a second and dropping immediatly whilst seeing the connection result of my Jenkins agent in the injected powershell window.
Is there a way to start the Jenkins Agent using the HyperV Host AND keeping it up after resetting the VMs Snapshot?

Related

Get-Service on remote machine got 'Cannot find any service with service name' error after change to Prod using Jenkins

We are using Jenkins to deliver our new windows machine. During deployment, I have a code running on the Jenkins machine to get-service status from a remote server. It works fine in testing environment. However, after it moves to production environment, always complains
'Cannot find any service with service name '...''
But when I log into the machine, the service is there. What's the possible reason it throw this error?
Here is my code:
$status = Get-Service -Computer $server -Name $servicename | %{$_.Status}
Before Get-Service, I connect to the remote machine using:
net use \\$server\c$ $password /USER:$username
This step looks fine which means Jenkins can connect to remote server.
Anyone can help? Thanks!
make sure that the user that is used to run the scheduled task is part of the administrator group in the remote server as well

Quickest way to enable PSRemoting after a reboot? Long delay with WMI Method

In our environment I often need to reboot a computer and then send commands to it via Invoke-Command. For this, I obviously need to have PSRemoting enabled on the target machine.
It is enabled by default on all our machines, however after a reboot it takes a while to kick in by itself.
I'm using Invoke-WmiMethod to force enable it as soon as the computer pings instead of waiting.
That works well but it sometimes takes over 30-40 seconds to kick in. It's still faster than the 2-5 minutes it can take if I just let it start by itself.
The command I'm using is:
Invoke-WmiMethod -ComputerName $poste -Path Win32_Process -Name create -ArgumentList "powershell.exe -command Enable-PSRemoting -SkipNetworkProfileCheck -Force"
My questions are:
Why does it take so long before it actually is enabled after that command runs?
Is there a better way you would suggest to enable PSRemoting via WMI or something else?
tldr;
All you are really doing when running Enable-PSRemoting is starting the WinRM service, everything else that the command does is skipped as you've already configured it.
The WinRM service is set to Automatic Delayed Start - to make it start faster change this to Automatic.
The 'delay' you are referring to is the delay in Windows starting the WinRM service.
Services that start at bootup have two options:
Automatic will start the service asap after Windows itself loads
Automatic Delayed Start will start the service after a short delay
The reason for the two types is resource contention - having every service start at the same time will use a huge amount of resources and the end-user will notice this as a slow-down.
To manage resources effectively Services that are essential to Windows will be set to Automatic and start simultaneously. This consumes lots of system resources, but the user has no choice as these services are generally required for Windows to work properly.
But for Services that are not essential, Delayed Start is the better option. These start "shortly after boot" when all the Automatic services have started. These are generally service for secondary functionality - eg an updater service.
The WinRM service is set to Automatic Delayed Start - to make it start faster change this to Automatic. You will take a performance hit for this so test this before making mass changes.
IMO - don't change the service startup, use code to deal with this delay...
For example, Restart-Computer with the Wait param will restart a remote computer and wait for connectivity before continuing:
Restart-Computer -ComputerName "Server01" -Wait -For PowerShell -Timeout 300 -Delay 2

How to run a script on a new Hyper-V Windows VMM virtual machine

I use a powershell script, triggered by teamcity, to spin up new Windows Server VMs. Currently, when the machine is up and running, I need to log in via the VMM console to make a couple of configuration changes (enable file sharing, network discovery, msdeploy and remoting over winrm) in order to allow other teamcity jobs to be able to deploy enterprise apps to the VM.
I haven't found any way to run my config setup scripts on the new VM other than by using the GUI console in VMM. For VMHosts, there is Invoke-SCScriptCommand, but this doesn't work for virtual machines themselves. Am I missing something or do I have to alter the template that my VM's are built from, in order to get the required config on the VMs?
One way you could achieve what you require is by putting all your config changes in a powershell script sitting inside VM template and adding it to VM's startup scripts.
The script's first step is checks whether the config changes have been applied in the past by checking some kind of a flag(ie. a file c:\deployed.flag) and last step is to create the flag.
if(Test-Path c:\deployed.flag){
## deployment script run already, do nothing
}
else{
## your config changing code block
New-Item c:\deployed.flag -Type f
}
In VMWare/PowerCLI you can run Invoke-VMScript which executes command directly on a VM via VMWare tools but alas Hyper-V Integration Services don't have such functionality.

Windows service deployment with a parameter

I'm trying to deploy a windows service to remote machine with a parameter being used at service start-up.
I have two issues:
How to actually use the Invoke-WmiMethod (powershell) to pass service with parameters
Starting a service on Windows Server 2012 with a parameter.
ad1) I am publishing service currently like this:
Invoke-WmiMethod -class Win32_process -name Create -ArgumentList ("C:\PathToService\ServiceExecutable.exe install") -ComputerName RemoteComputer.local
This is done in this way as this is self-installable/uninstallable service. What I tried so far is getting the service object after installing the service like this
$(Get-Service -ComputerName RemoteComputer.local -Name ServiceName)
but failed to see how I could attach/modify the startup parameters on it.
ad2) This one completely baffles me;
This is a normal Service dialog since I can remember. Whatever you put into the start parameters should be passed to the service as args.
This just doesn't happen for me on Windows Server 2012 only!.
If I run it under Windows 8 - all is well.
If I run it in a console - all is well.
If I run it under Windows Server 2012 through service manager - logs show it fails to get the args.
Does not make any difference if I use different accounts (network, admin,...).
I would recommend using a local app.config instead.
That way you can specify all configuration you need, without needing to resort to startup parameters.

powershell remoting Win2008R2 "The WSMan service could not launch a host process to process the given request"

I've recently upgraded a number of servers from 2003 to 2008R2. Since the upgrade I've started to see the following error:
[servername] Connecting to remote server failed with the following error message : The WSMan service could not launch a host process to process the given request. Make sure the WSMan provider host server and proxy are properly registered. For more information, see the about_Remote_Troubleshooting Help topic.
The error is seemingly random. The script will work and then fail. The command to create the session is in a loop (create session, remove session) and is called numerous times as part of a set of deployment scripts. When the script fails, it fails at different points.
I've checked the event log on the local workstation (win7) destination server (win2008R2) but there are no errors that I can see.
This is the lines that randomly fails:
$session = New-PSSession -ComputerName $serverName -Credential $credential
I did not see this issue on Win2003. The scripts have not changed. I'm assuming the problem is on the destination server but cannot find any errors or logs to look at. It will work once and then fail so my deployment scripts will sometimes succeed and then fail at different points.
Any guidance on tracking down this problem would be much appreciated.
You can get this error when trying to connect to localhost with an account that's not an administrator.
It used to be possible to use accounts that weren't an administrator, but a Windows Update in January 2019 disabled the functionality for security reasons. From the patch notes:
By default, PowerShell remoting only works with administrator accounts, but can be configured to work with non-administrator accounts. Starting with this release, you cannot configure PowerShell remote endpoints to work with non-administrator accounts. When attempting to use a non-administrator account, the following error will appear:“New-PSSession: [computerName] Connecting to remote server localhost failed with the following error message: The WSMan service could not launch a host process to process the given request. Make sure the WSMan provider host server and proxy are properly registered. For more information, see the about_Remote_Troubleshooting Help topic.”
You need to be setting the WSMan TrustedHosts. If you want, you can set it to everything using wildcards (*).
You can do it via PowerShell: Set-Item WSMan:\localhost\Client\TrustedHosts -Value *.
Keep in mind that you also need to enable the Windows Remote service. Use the native winrm qc command for this. Enable-PSRemoting -Force might do it as well.
You can also use the PSExec Tools from Sysinternals. Keep in mind that these tools will likely be blocked by your EndPoint Security, so don't forget to white list it.
Is there a specific reason you migrate your old OSes to a newer, but still EOL OS? You can do a lot via PowerShell in 2008R2, but it's still pretty limited. IMO, Using PowerShell is best starting from 2012R2 and onwards.
Are you hitting the number of processes limit by creating pssessions that are crashing and leaving processes open?
Default limit is 15. I'd agree with the above comment and not use sessions, instead use invoke-command like:
invoke-command -scriptblock $scriptBlock -ArgumentList $args -computername $compName -Credential $encodedRemoteCredentials
to Check your limit:
PS C:\aws> ls WSMan:\localhost\Shell
WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\Shell
Name Value
---- ----
MaxProcessesPerShell 15
As a quick and dirty test - next time your pssession version of your script fails, increase the maxProcessesPerShell limit using set-item cmdlet to 50 and retry. If the script no longer fails, you know that's the issue (and should consider moving to invoke-command!).