How to create a service in powershell to execute .exe? - windows

I have powershell script. I need to run it as a service. I try this way to make it as a service.
Start-Process -FilePath C:\Users\xx\Downloads\nssm-2.24\win32\nssm.exe -ArgumentList 'install AgentService "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "-command "& { . D:\SERVICE\Script.ps1}"" ' -NoNewWindow
Then I open run.exe and type services.msc. The service exist. And I try to start it. It show like this picture.
But I see the powershell script is not running. Because in my powershell script I use infinity loop to do some process, like copy and rename file. But It does not work.
Anyone can give me idea plese. Thank you.

A ordinary EXE executable, by default, is not ready to be run as a Windows Service.
A service process needs to register with the Service Control Manager on startup and listen for commands from the SCM. All the details you need are here:
C++: https://learn.microsoft.com/en-us/windows/win32/services/services
C# and .NET: https://learn.microsoft.com/en-us/dotnet/framework/windows-services/
However, if it helps, there are pre-built services that will launch and manage the process lifetime of any ordinary EXE. Google for run any windows exe as a service. One that I've personally used before is SrvStart.

Related

Powershell on ansible-playbook remote host

I have a PowerShell script ex1.ps1 which takes user inputs and ex1.ps1 has commands to open a new PowerShell to execute an exe file:
Start-Process -FilePath "$PSHOME\powershell.exe" -ArgumentList "-command C:\APPLICATION1.exe`
I want to execute ex1.ps1 on a remote host. I am trying to call ex1.ps1 using Ansible-playbook as:
# ansible-playbook script
- name: Run basic PowerShell script
win_powershell:
script: |
powershell.exe -ExecutionPolicy ByPass -File C:/Users/ex1.ps1
It is executing fine but in remote host there is no PowerShell prompt open to get the inputs.
You shouldn't be expecting manual input when deploying with a tool like Ansible. I don't know the actual program you are trying to run but the best solution here is to figure out the required parameters for the program to install/start/run without user interaction.
If you are able to provide the name of the program (and it's not something internal to your organization) a more complete answer may be able to be provided.
Unrelated to your question, unless you've over-generalized your code for this question there isn't a reason to call powershell.exe from within PowerShell just to run an executable. You can either use Start-Process or the call operator & directly with the exe path in question.
I have an answer here that goes over Start-Process and the usage of & in a bit more detail.

Task scheduler Windows Server 2019 - Task not running ONSTART

I am trying to build an AWS AMI for a gitlab runner for building our .NET application.
I am using packer for building the image based one the official Windows Server 2019 base AWS AMI.
I am using WinRM, with HTTPS, not changing any password.
Here are the powershell commands to configure the virtual machine :
"Creating desktop directory"
mkdir C:\Windows\SysWOW64\config\systemprofile\Desktop
"Installing ntrights tools"
mkdir tools
Invoke-WebRequest -Uri "https://download.microsoft.com/download/8/e/c/8ec3a7d8-05b4-440a-a71e-ca3ee25fe057/rktools.exe" -OutFile "tools\tools.exe" -UseBasicParsing
Start-Process "tools\tools.exe" -ArgumentList "/T:$pwd\tools\ /C" -Wait
Start-Process "msiexec.exe" -ArgumentList "/i $pwd\tools\rktools.msi /qn" -Wait
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
Remove-Item tools -Recurse
"Setting rights of service logon to $Env:WINRMUSER"
ntrights.exe ntrights +r SeServiceLogonRight -u $Env:WINRMUSER
# Git lab runner
$path = ".\gitlab-runner.exe"
If(!(test-path $path))
{
"Downloading Gitlab Runner"
Invoke-WebRequest -Uri "https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-windows-386.exe" -OutFile $path -UseBasicParsing
}
"Scheduling runner to start at startup of the system"
schtasks.exe /create /tn "Gitlab Runner service start" /RU $Env:WINRMUSER /RP `"$Env:WINRMPASS`" /Sc ONSTART /tr "powershell -Command $pwd\register-gitlabrunner.ps1 -ExecutionPolicy Bypass"
There are obviously more scripts executed (install msbuild, install .net sdk 4.7.2, nugget, and git) I can provide them if relevant. Here I focus on the powershell code I came up with for the gitlab runner problem.
I want the virtual machine to start the runner on start so we just have to launch instances of the AMI to scale up.
To explain a bit more what I did try :
You can see I am trying to create the desktop directory in order for windows to get that it can run interactive things... Not working
I am setting up the SeServiceLogonRight in order to avoid the "failed to logon" error
The user is Administrator, and the password is the right password
The scheduled tasks is created and ready to run. Won't run on start, won't run If i start it through schtasks /Run (the last run time is never updated and show a value in 19XX)
Tried to cmd /c the task command, everything work as expected
I don't find any logs anywhere, event log seems to be empty of problem from Application, System and Powershell. The file in c:\Windows\Tasks\SchlogU (or something like that), does not exist (but the folder exists)
I have no UI for the scheduler, I use a light version of windows so all I can do is play with the schtasks.exe
Default folder is : c:\Users\Administrator
The powershell script is pushed by packer onto the server and is located in c:\Users\Administrator (as for the gitlab-runner.exe)
I connect directly through RDP to try debugging the situation.
Here is the script that should be started
Set-Location $PSScriptRoot
$path = ".\gitlab-runner.exe"
"Stopping runner"
Invoke-Expression "$path stop"
"Unregistering previous configuration"
Invoke-Expression "$path unregister --all-runners"
"Uninstalling runner"
Invoke-Expression "$path uninstall"
"Installing runner"
Invoke-Expression "$path install"
"Registering Gitlab Runner"
Invoke-Expression "$path register --non-interactive --url 'https://URL_HERE/' --registration-token 'TOKEN HERE' --executor shell"
"Starting the runner"
Invoke-Expression "$path start"
I can install the runner only once in the configuration using the user and password but this is not the problem here since the task never runs...
Answer the question with what I came up thanks :
I was told by so many docs and answers everywhere that the task scheduler is the way to go when you need to start scripts at startup or logon.
As I always worked with windows servers with GUIs, the Task Scheduler was working fine until now. Maybe I did something wrong somewhere, maybe not.
Anyway, after trying using powershell commands to create the task (with improvements but no sufficient solutions), I tried to put a command file in the C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp, did not work either.
the file look like this thanks to this link
PowerShell -Command "Set-ExecutionPolicy Unrestricted"
PowerShell -Command "c:\Users\Administrator\register-gitlabrunner.ps1" >> c:\startup.log.txt
I tried to delay the start of the script to 5 minutes after startup. Was to test if it was a problem with a slow initialization of network or something else. Still not working.
There is something preventing the script to be executed when it's launched at startup using this methods.
From there I added a persistent "user_data" script on my EC2 launch template in order to start what I was expecting on start. It works.
I don't feel it's the best way since I need to configure the template and not only the AMI but at least it works.
The script in user_data looks like this :
<script>
cmd /c "C:/ProgramData/Microsoft/Windows/Start Menu/Programs/StartUp/startup.cmd"
</script>
<persist>true</persist>
I kept the installation and registering in the startup script since I got logon errors when I install gitlab runner through WinRM using the account credentials (--user --password)
I still don't understand what is up with this issue. I guess it's a problem with the account used to start the script (localsystem or something like that, that would conflict with the gitlab runner service).
Since I have no GUI (the docs are mostly on GUI) and limited time, I won't investigate more for the moment and feel it's enough at least for the moment.
Hope this can help someone that will encounter the same situation

Window opened via psexec is blank when using PowerShell Direct, but is OK when psexec starts locally

I am trying to build a simple environment to take screenshots automatically. I have several Hyper-V VMs and I need to use PowerShell Direct to run commands on them in a special sequence. When I run psexec to open notepad.exe via PowerShell Direct, Notepad's window opens, but it is blank. I can blindly click controls on the window (e.g., on the toolbar) and it appears that they work, but nothing is actually displayed besides a blank window.
The only simple option to open Windows in an existing session I see now is to run psexec (any other suggestions would be greatly appreciated because my attempts to stick to PowerShell-only approach hits a roadblock, see Starting a GUI application on a guest VM with PowerShell Direct).
I run psexec on one of the virtual machines to start notepad.exe in session 2. This PowerShell snippet runs on a host VM, it contacts guest VM via PowerShell Direct.
Invoke-Command -VMName 'client1.example.com' -Credential $credential -ScriptBlock {
C:\bin\psexec.exe \\client1.example.com -i 2 "notepad.exe"
}
notepad.exe starts, but the window is blank. Is this a bug in psexec?
Please see the screenshot:
The problem does not occur when I run psexec directly in a guest VM.
C:\bin\psexec.exe \\client1.example.com -i 2 "notepad.exe"
Solved by adding the -s option. I don't understand why the problem occurs in the first place and how running it "in the system account" helps.
-s Run the remote process in the System account.
The problem does not occur when I start explorer.exe, BTW.

Running PowerShell in Task Scheduler

I am using PowerShell for downloading data from email.
I want to run this process by PowerShell. When I run script like this:
D:\script.ps1
in powershell.exe it works fine.
When I schedule it in Task Scheduler nothing happens.
I tried it to Set it like Program/script:
powershell
Powershell.exe
powershell.exe
Add arguments:
-executionpolicy bypass -file D:\script.ps1
-file D:\script.ps1
-file "D:\script.ps1"
And nothing works. I'm using Windows 2008 R2.
Troubleshooting scheduled tasks is a pain in the rear, because you can't really see what's going on. These are some things you may want to check:
Check that your commandline works in principle, e.g. by running it from CMD (in your case try running powershell.exe -File "D:\script.ps1"). If that gives you any errors you need to fix those first.
If you intend to run the task as a particular user, start CMD as that user and run the same commandline to check if the user has all the permissions required for whatever the script is doing.
Check if your task actually terminated or if the process is still running (via Process Explorer, Get-Process, Task Manager, …).
Check the Last Run Result for the exit code of the command.
Enable the history for your scheduled tasks (Action → Enable All Tasks History). That will give you at least some information about what the task is doing, whether it starts at all, and if/which errors occurred. You need administrative rights to enable the task history.
Check the eventlog for errors/warnings correlating with the task run.
Add logging statements to the script you're running to record progress information. Personally I prefer logging to the eventlog, because that avoids filesystem permissions issues.
Write-EventLog -LogName Application -Source EventSystem -EventID 100 -EntryType Information -Message 'Your log message.'
If you have admin privileges on the system you can register an event source of your own and use that in the above log statement instead of abusing an existing source like EventSystem:
New-EventLog -Source MyEventSource -LogName Application
Further help will depend heavily on the findings you got following these steps as well as your actual script code.
I found this site that was quite useful:
http://www.microsoftpro.nl/2011/07/07/how-to-schedule-a-powershell-script-using-scheduled-tasks-in-windows-server-2008-r2/
I also changed Secure option property and it helped.
I didnt check: Do not store password and now it runs without me being logged into network.
Peace
Few major observations which I had faced:
Instead of giving only powershell.exe , try giving the full PS path C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe.
Permission is one more concern. The user through which you are running the task might not have the permission to run that.
Execution Policy: Make sure you are bypassing the execution policy using -ExecutionPolicy Bypass.
Make sure you are running the task with Highest Privileges.
Finally, through analysis of logs.

remote execution(PowerShell) of cmd file doesn't complete

Current PS script:
Invoke-Command -ComputerName RemoteServer007.FQDN.com -ScriptBlock {
Set-Variable -Name WOWCONFIG -value "d:\ABCs\WOWzers" `
| Start-Process "d:\da-folder\Do-It-NOW-Pleez.cmd"
}
If I log on locally to the server(RemoteServer007.FQDN.com) and execute the cmd file, it runs through all of the lines(commands) within the cmd file.
When I execute it remotely, it gets about 30% of the way through the commands within the cmd file, the PS execution ends without error, but not all of the lines/commands in the cmd file had been executed.
This was discovered by simply configuring each line of the cmd file to output to txt files.
I even tried re-ranging the commands in the cmd file, thinking that perhaps there was a specific command that was causing it to exit, but that is not the case.
I'm wondering if there is some timeout or response that PowerShell is not getting? and just quitting almost immediately after starting?
Any ideas or help would be greatly appreciated.
There are a couple of things you can do here:
You may have a memory issue. Increasing the value of MaxMemoryPerShellMB might help
set-item WSMan:\$target\Shell\MaxMemoryPerShellMB -Value 0 -Force
You'd need to run this once on the remote machine before you execute your commands again.
You can also see possible error logs in the windows event viewer. There are categories for powershell and for Windows Remote Management which you should look at.
Finally, you can just run this process asynchronously, using the task scheduler for instance. I had a similar problem with windows in the past, and running the process from the task scheduler, outside the powershell session, fixed it. There's an example of how we did this in Cloudify here:
https://github.com/CloudifySource/cloudify/blob/master/esc/src/main/resources/clouds/ec2-win/upload/bootstrap-management.ps1#L220

Resources