Running PowerShell from MSdeploy runcommand does not exit - powershell

Im am trying to get MSDeploy to execute a PowerShell script on a remote server. This is how i execute MSDeploy:
msdeploy \
-verb:sync \
-source:runCommand='C:\temp\HelloWorld.bat', \
waitInterval=15000,waitAttempts=1 \
-dest:auto,computername=$WebDeployService$Credentials -verbose
HelloWorld.bat contains:
echo "Hello world!"
powershell.exe C:\temp\WebDeploy\Package\HelloWorld.ps1
echo "Done"
The HelloWorld.ps1 only contains:
Write-Host "Hello world from PowerShell!"
However, it seems like PowerShell never terminates. This is the output from running the msdeploy:
Verbose: Performing synchronization pass #1.
Verbose: Source runCommand (C:\temp\HelloWorld.bat) does not match destination (C:\temp\HelloWorld.bat) differing in attributes (isSource['True','False']). Update pending.
Info: Updating runCommand (C:\temp\HelloWorld.bat).
Info:
Info: C:\temp>echo "Hello world!"
"Hello world!"
C:\temp\WebDeploy>powershell.exe C:\temp\HelloWorld.ps1
Info: Hello world from Powershell!
Info:
Warning: The process 'C:\Windows\system32\cmd.exe' (command line '/c "C:\Users\peter\AppData\Local\Temp\gaskgh55.b2q.bat
"') is still running. Waiting for 15000 ms (attempt 1 of 1).
Error: The process 'C:\Windows\system32\cmd.exe' (command line '/c "C:\Users\peter\AppData\Local\Temp\gaskgh55.b2q.bat"'
) was terminated because it exceeded the wait time.
Error count: 1.
Anyone knows a solution?

Your scenario and problem look similar to this reported issue:
PowerShell.exe can hang if STDIN is redirected
If this is the case then try this workaround: use -inputformat none:
powershell.exe -inputformat none C:\temp\WebDeploy\Package\HelloWorld.ps1
I have tried this with "a fake msdeploy" program that calls the .bat file like this:
using System.Diagnostics;
class Program
{
static void Main(string[] args)
{
ProcessStartInfo si = new ProcessStartInfo();
si.FileName = "cmd.exe";
si.Arguments = "/c " + args[0];
si.RedirectStandardInput = true;
si.UseShellExecute = false;
var process = Process.Start(si);
process.WaitForExit();
}
}
This demo does have the same problem that you describe and the workaround helps. If msdeploy calls the .bat file in the same or similar way then hopefully this is a solution.

powershell.exe -file ScriptFile.ps < CON
This solve the problem without resorting to undocumented features.

Related

Execute external powershell script in jenkins pipleline

I was trying to execute powershell script in a remote machine via jenkins pipeline.my script location ex: $server_vm_name\d$\scripts\testscript.ps1 . and I need to pass parameter to the testscript.ps1 as parameter name -clientpath. for the client path u have used this external path ex:
\${client_vm_name}\d$\Client\Application . I have used the network paths for both script location and parameter
I have write the following code snippet to get the work done. but its not working. anyone have idea what i have done in wrong way?.
error msg :
*
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 885: unexpected char: '\' # line 885, column 49.
rshell script: "\\$db_vm_name\d$\script
stage('Installation') {
agent{
label PS_AGENT_LABEL
}
steps{
script{
powershell script: "\\$server_vm_name\d$\scripts\testscript.ps1 -clientPath \\${client_vm_name}\d$\Client\Application"
}
}
}

AWS Lambda deployment

I'm trying to deploy my lambdas (.NET Core 2.0) into AWS by using AWS CLI + TeamCity + Powershell script. I have some steps , including deploy step and applying new aliase number step.
While deploy step I don't get alias number (lambda version). A script returns me something like "function = ", but it should be like "result = 44 (or any other lambda version)".
Here's a script (mix of Powershell + AWS CLI commands).
FOR ( /F "tokens=* delims=" %%%A IN ('dotnet lambda deploy-function MyLambda --profile default --region my-server-region --configuration Release --function-publish true') DO ( set result=%%%A )){
FOR ( /F "tokens=1,2,3,4,5,6 delims= " %%%A IN ('echo %%%result%%%') DO ( set result=%%%F )){
#echo on
echo %env.MyLambdaVersion%
#echo off
echo "##teamcity[setParameter name='env.MyLambdaVersion' value='%%result%%']"
}
}
I actually don't know what I do wrong, actually this script was written before I started to work on this project. Any advice or any link will be helpfull, thanks :)
EDIT
I expect this kind of respinse, where i can get MyLambda version
Succesfull build scrinshot1: https://i.stack.imgur.com/bOIGr.jpg
But instead of it I'm getting this result.
Invalid response
EDIT 2
Output of the script in text format
Step 17/36: Deploying new version of Lambda "MyLambda" (Command Line) (3m:16s)
[13:27:03][Step 17/36] Starting: C:\BuildAgent\temp\agentTmp\custom_script1964828788270486366.cmd
[13:27:03][Step 17/36] in directory: C:\BuildAgent\work\3f3a1ea85ff2ff09
[13:30:10][Step 17/36]
[13:30:11][Step 17/36] C:\BuildAgent\work\3f3a1ea85ff2ff09\Proj\Lambda\Proj.Lambda.MyLambda>echo
[13:30:12][Step 17/36] ECHO is on.
[13:30:16][Step 17/36] "
[13:30:16][Step 17/36] ##teamcity[setParameter name='env.MyLambdaVersion' value='function: ']
[13:30:16][Step 17/36] "
[13:30:20][Step 17/36] Process exited with code 0

Troubles with wget called by script started by Task Scheduler

I need to load a https file. I use wget with option --no-check-certificate. It runs perfectly if started by the ISE-debugger. It even runs perfectly if I started in the cmd-console: ./myScript.ps1. But as soon as I set the Task Scheduler to start my script I get:
--2016-02-07 19:44:01-- https://www.dailyfx.com/calendar/
Resolving www.dailyfx.com... 104.87.22.147
Connecting to www.dailyfx.com|104.87.22.147|:443... connected.
WARNING: cannot verify www.dailyfx.com's certificate, issued by `/C=US/O=GeoTrust Inc./CN=GeoTrust SSL CA - G3':
Unable to locally verify the issuer's authority.
WARNING: certificate common name `fxcm.com' doesn't match requested host name `www.dailyfx.com'.
HTTP request sent, awaiting response... 403 Forbidden
2016-02-07 19:44:01 ERROR 403: Forbidden.
Before calling I set the $ArgList and then I call wget:
$urlDFx = "https://www.dailyfx.com/calendar/"
$argList = "$urlDFx -O $rawDFx -o $logDFx --no-check-certificate"
$wg = Start-Process wget -wait -NoNewWindow -PassThru -ArgumentList $argList
The other variables are various local files.
Again, it works in the ISE and the CMD console but not if started by the Task Scheduler. The other part of the scripts are executed without any problem: I did another http-file and parse it.
What can I do?
I have found a solution even if I don't understand why this now works!
I set:
$argList = "$urlDFx -O $rawDFx -o $logDFx --no-check-certificate --verbose "
1) It works even if the task-scheduler has started the script.
2) The log-file of wget contains absolutely the same as before.
(May be now --verbose is skipped??)

How do I get topshelf to return error code when command fails?

I am trying to start my service with powershell but currently it fails. I don't know why it fails but that is not the point here. When trying to start the host all I don't get the correct exit code so my automatic deploy fails silently.
What I'm trying to do is:
$cmd = "$folder" + "\MyService.exe"
try
{
& $cmd stop
& $cmd uninstall
& $cmd install
& $cmd start
}
catch
{
Write-Host "Error: Update of service failed"
exit 1
}
The start command fails with the following messge:
Topshelf.Hosts.StartHost Error: 0 : The service failed to start., System.InvalidOperationException: Cannot start service MyService on computer '.'. ---> System.ComponentModel.Win32Exception: The service cannot be started, either because it is disabled or because it has no enabled devices associated with it
--- End of inner exception stack trace ---
at System.ServiceProcess.ServiceController.Start(String[] args)
at System.ServiceProcess.ServiceController.Start()
at Topshelf.Runtime.Windows.WindowsHostEnvironment.StartService(String serviceName)
at Topshelf.Hosts.StartHost.Run()
and I never get into the catch statement of my powershell script.
UPDATE:
Note that I am asking for how to get the method to the catch statement and not the solution to the actual exception. I have solved the actual exception but I want better feedback in the future if it fails, and that is want the catch statement to be executed which it isn't in case of error.
try/catch in PowerShell doesn't work with exe.
After myservice.exe calls you need to check the automatic variable $LastExitCode.
Try something like this:
$out = & $cmd start
if ($LastExitCode -ne 0) # if exe returns 0 on success, if not change the condition accordingly
{
"ERROR: $out"
return # to exit script or do something else.
}

Powershell remoting and page file

I wrote a powershell script that connects to a remote machine with the intent of executing a software rollout on said machine. Basically it connects, maps a drive, copies the rollout from the mapped drive to the target machine, then executes a perl script to install the rollout. If I do those steps manually everything works fine. When I try using my script, the perl script fails on the remote machine saying, "The paging file is too small for this operation to complete".
Can someone explain the considerations I need to take into account when operating remotely? I've tried monitoring memory usage and I don't see anything out of the ordinary. Is the page file OS wide or is there some type of per user configuration my script should be setting when it connects?
I can post snippets of my script if needed, but the script is 426 lines so I think it would be overwhelming to post in its entirety.
I found that the remote shells are managed differently than logging onto the box and executing a powershell session. I had to increase the maximum amount of memory available using one of the commands below:
Set-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB 1024
winrm set winrm/config #{MaxMemoryPerShellMB="1024"}
The default is 150MB which didn't cut it in my case. I can't say that I recommend 1GB, I'm just a developer. I tried upping it until I found what worked for me.
I tried this code to run the puppet client as an administrator but the framework still complains with "Access Denied"
Exe (C:\Users\lmo0\AppData\Local\Temp\Microsoft .NET Framework 4 Setup_4.0.30319\Windows6.1-KB958488-v6001-x64.msu) failed with 0x5 - Access is denied. .
using System;
using System.Diagnostics;
namespace RunAsAdmin
{
class Program
{
static void Main(string[] args)
{
Process proc = new Process();
Process p = new Process();
p.StartInfo.FileName = #"powershell.exe";
p.StartInfo.Arguments = #"invoke-command -computername vavt-pmo-sbx24 -ScriptBlock {&'C:\Program Files (x86)\Puppet Labs\Puppet\bin\puppet.bat' agent --test --no-daemonize --verbose --logdest console}";
p.StartInfo.Verb = "runas";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
p.Start();
while (p.HasExited == false) {
Console.WriteLine(p.StandardOutput.ReadLine());
}
Console.ReadLine();
p.WaitForExit();
p.Close();
}
}
}