question

MSmith-4367 avatar image
0 Votes"
MSmith-4367 asked MotoX80 commented

PS script running as a service

Trying to get a script to run as a service using NSSM, following this guide
Service appears to be installed.

PS C:\powershell> Get-Service $servicename

Status Name DisplayName
Stopped PMimagewatcher PMimagewatcher

When I try to start it, get this error
PS C:\powershell> Start-Service $servicename
Start-Service : Failed to start service 'PMimagewatcher (PMimagewatcher)'.
At line:1 char:1
+ Start-Service $servicename
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (System.ServiceProcess.ServiceController:ServiceController) [Start-Service], S
erviceCommandException
+ FullyQualifiedErrorId : StartServiceFailed,Microsoft.PowerShell.Commands.StartServiceCommand


I should add, I'm only looking for someway to ensure that this script runs continually when the server is up. A service seems like the logical choice, but if there is some other way to do this then I'm open to it.


windows-server-powershell
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

MotoX80 avatar image
0 Votes"
MotoX80 answered MotoX80 commented

Check the system eventlog to see if there is an entry with more information about why the service did not start. Look in Services.msc. Is the service set to run as the system account? Does it need to run as some user account? If you try to start it from there, do you get a different error message?

In the Powershell code, add a Start-Transcript cmdlet to write to a log file. That will at least let you know that NSSM/Powershell is launching the script.

If you don't get a transcript, there must be something wrong calling Powershell. Download and run Process Monitor. Start the procmon capture, start the service, and then stop the capture. It will capture a lot of events. Then look for nssm.exe and powershell.exe and see if there are any access denied errors and if Powershell.exe is being launched with the correct parameters.




· 6
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Service is set to run as Local System account. I do get the same results when I set it to run under my account, which is how it's running in the shell.

Starting from services.msc returns;
Windows could not start the PMimagewatcher service on Local Computer.
The service did not return an error. This could be an internal Windows error or an internal service error.
If the problem persists, contact your system administrator.

The application log shows it starting and then 'exited with return code 0'

Added Start-Transcript and tested running the script manually. Log appears ok.
After I attempt to start the service there are additional transcript entries identical to the manual run.

0 Votes 0 ·

What does the script do? If you want it to run as a service, then it can't end. Do you have some loop with a sleep command inside while it waits for something to do?

0 Votes 0 ·

Actually it's using Register-ObjectEvent to watch for files being created. So it does not loop or keep running.

 $watcher = New-Object System.IO.FileSystemWatcher
    
 $watcher.Path = 'F:\Image Files'
 $watcher.IncludeSubdirectories = $true
 $watcher.EnableRaisingEvents = $true
 $watcher.Filter = '*.jpg'
    
 $action =
 {
     $path = $event.SourceEventArgs.FullPath
     $changetype = $event.SourceEventArgs.ChangeType
     Write-Host "$path was $changetype at $(get-date)"
     "$(get-date) #INS $path " | Out-File $logfile -Append
     Copy-Item $path -Destination $dest_inscards
     if(-not $?) {$error[0].exception.message | Out-File $logfile -Append}
     else {"Copy Success" | Out-File $logfile -Append}
 }
    
 Register-ObjectEvent $watcher 'Created' -Action $action
0 Votes 0 ·
Show more comments

So I added a while loop with a start-sleep -seconds 60 at the end of the script. Now when I start the service it does keep running and no errors from the shell or in the event log.
So that fixed it. Thanks for your help.

What's odd to me is that the action from my Register-ObjectEvent now appears to be delayed by the while loop.
I guess this makes sense. Would it be a problem to reduce the sleep to say 1 second?

Or is there some way to keep the script running without using the while loop?

Again I appreciate your help.

0 Votes 0 ·
Show more comments
YoungYang-MSFT avatar image
0 Votes"
YoungYang-MSFT answered MSmith-4367 commented

From the error message, the service you want to start cannot be started. But according to the explanation of the command, If a service is already running, the message is ignored without error. It is recommended that you check again whether the service you want to start exists.

· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

If it does not exist wouldn't the Get-Service command return some error?

If I try to start a service that does not exist like Start-Service blah the error returned is
Start-Service : Cannot find any service with service name 'blah'.

0 Votes 0 ·