0

We have an application server running as a service, when some configuration is loaded it starts a bat script which has to run the powershell command Stop-ClusterGroup DRMSERVICES and then start it again. The bat file works flawless when I manually execute it by dobbelt clicking. But when the service is running the bat, it does not finish, or execute the powershell command.

Bat file looks as follows

@echo off

powershell -command Stop-ClusterGroup DRMSERVICES

powershell -command Start-ClusterGroup DRMSERVICES

The service runs the bat file in silent mode, as a main difference. I have tried with various switches including the -ExecutionPolicy Unrestricted and START /wait etc Creating a seperate ps1 file and have the bat execute this instead. All with the same output: Manually executing the bat works When the service executes the bat, it does not work.

I know the bat file is executed by the service, as inserting NET STOP servicename is working correct.

In the powershell event viewer I can also see event of the powershell commands take place. The difference between manually executing and have the service execute the command in the event viewer, is event id 800 which states info about 'execution pipe' this is not present when the service is executing the bat.

The service does not wait for the powershell, and thus it does not have time to stop the cluster before exiting.

I'm lost whether this is a permission issue, syntax error or whatever.

Hopefully somebody can help

UPDATE: I have tried with all proposed solutions, all with same result, the bat file works when double clicked, but the service does not execute the powershell command. Pure cmd is executed, as I can pipe to a txt file. I even got to a point when trying runas that the output log text wrote "insert administrator password"

I even managed to have our software guy change our software to call a powershell directly instead of a bat, same result. Powershell won't execute the command, this tells me it probably is permission, but everything have been set to log in as admin and run as admin for the sake of success, but still nothing.

  • 1
    Why does the configuration loader need to involve a batch file? Can it not run the PowerShell code without involving cmd.exe at all? – Compo Oct 23 '20 at 21:47
  • Is it really a service or a scheduled task? If a scheduled task, is it running with Admin privileges? Also if CMD works in general you could use the `cluster.exe` command to do this `cluster group DRMSERVICES /Offline` and `cluster group DRMSERVICES /Online` – Ben Personick Oct 24 '20 at 03:50
  • This software is made in the late 90's by our self, and simply change the software is not an option. – Morten Brask Jensen Oct 24 '20 at 06:12
  • I will try with the cluster.exe tool and update – Morten Brask Jensen Oct 24 '20 at 06:15
  • The reason for not trying with the cluster.exe tool, was to avoid using an obsolete tool. – Morten Brask Jensen Oct 24 '20 at 06:26
  • Your tool is obsolete, `This software is made in the late 90's by our self`, so there seems little reason to exclude `cluster.exe` for being `an obsolete tool`. – Compo Oct 25 '20 at 13:47
  • @Compo our software is old, but OS version independent, so when running server 2016, cluster.exe becomes obsolete, as it is not supported any more, not our software – Morten Brask Jensen Oct 25 '20 at 14:47
  • Not being supported, and actually working, are two different things; the important question is, does `cluster.exe` work on [tag:windows-server-2016]? _You said you would "try with the cluster.exe tool and update"_. Also, you did not answer my question in the opening comment. – Compo Oct 25 '20 at 14:53
  • @Compo I said the software cannot be changed, and having the service invoke powershell instead of a bat, requires a software change. I cannot try with cluster.exe until tomorrow, Monday, and I expect it to work actually, as that would not require opening a powershell. But as I stumbled upon this issue, I would rather solve it by using powershell, as this will become an issue when cluster.exe is actually obsolete. And powershell does not seem to dissappear soon – Morten Brask Jensen Oct 25 '20 at 15:06
  • Perhaps now would be a good time to have your 20+ year old software rewritten too, instead of trying to create workarounds for ever evolving Operating Systems. _(After all, a compiled application which relies on scripting technologies, was not very well written in the first place)_. Also you haven't made clear to us whether your application is running a separate service, or whether your application is itself the service. You also didn't explain, in response to the already provided answer, whether you have implemented a delay, or check, betweern the `stop`, and `start`, commands. – Compo Oct 25 '20 at 16:23
  • @Compo I'm not sure whether you are trying to help, or just pointing out everything else which does not have anything to do with the problem. Boiled down, the problem is that an application running as a service is not executing a bat file which calls a powershell command probably. The application runs as a service, so it is a service, which is already stated above. And as I do not go to work during weekends, so I cannot update anything until I have tried it out. The software is not the problem. – Morten Brask Jensen Oct 25 '20 at 16:41
  • We'll wait for your update tomorrow then! _since you're clearly not providing feedback to the already supplied answer, or to my question about whether you've implemented it._ – Compo Oct 25 '20 at 16:44
  • @BenPersonick I expected the cluster.exe tool to work, as it does not have to start a powershell. Again, double clicking the bat works as expected, but the service states the system cannot find the path specified. Echo'ing %cd% shows windows\system32 And cluster.exe is indeed installed by adding feature, and exists in system 32 folder as cluster.exe – Morten Brask Jensen Oct 26 '20 at 13:33
  • @MortenBraskJensen So, this points to a permissions issue on the service, or variables missing from the environment of the service account. Have you tried explicitly writing all of the paths needed into the `cmd` scrip? Alternatively can you put this as a `scheduled task` set to run on demand, and test that it works in the task? If it does try having the service call task scheduler (`schtasks`) and start the task on demand. – Ben Personick Oct 26 '20 at 14:54

2 Answers2

0

I think i have dealt with this kind of issue before, after the,

powershell -command Stop-ClusterGroup DRMSERVICES

you need to have cmd wait for a certain number of seconds, and then test if the DRMSERVICES is now stopped, if it is stopped then to start the DRMSERVICES again. This way cmd will keep waiting, and then check if the service has stopped. After a certain number of tries, maybe have a way to stop checking and exit the script, for example it is trying to stop the service, and has run into a problem.

There is a timeout command in cmd

Shaqil Ismail
  • 1,794
  • 1
  • 4
  • 5
  • I did as proposed, and created a bat that executes the powershell, and puts it in a file, then look in the file for offline, and online during timeout, but works perfectly when double click on the bat. But not when the service is executing the bat – Morten Brask Jensen Oct 26 '20 at 13:28
  • Can be used to query services instead of looking into as file, https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-service?view=powershell-7 which user are you running the task as? – Shaqil Ismail Oct 26 '20 at 13:51
  • What user are you running the bat script with?, Have you set the service, to use the account you want to run the script with, if it is not your account, then you need to check the permissions, for the script and the folders, where the script is located, and allow the specific user to run this. – Shaqil Ismail Oct 26 '20 at 14:01
  • I have tried with the service to log on as administrator as well. Still won't execute – Morten Brask Jensen Oct 26 '20 at 14:20
  • I think this is relevant to your scenario, http://woshub.com/run-powershell-script-as-windows-service/ talking about servany.exe does not control a powershell execution state. You need to delete the service, and when you create this new service, allow the user which has access to the script, maybe put this in a folder, and then copy the folder to c:\ for example, and then check the permissions, for the user, who will be running the script and then create the service, using the powershell command new-service and using the credential parameter. – Shaqil Ismail Oct 26 '20 at 14:55
  • Can it be a problem that it is a 32bit service trying to execute the bat, when the system, the windows server is 64 bit? As the errorlevel returned is the cmd stating that it does not recognize Stop-clusterService, even when the command is written as powershell -command "& {stop-clusterservice}" – Morten Brask Jensen Oct 26 '20 at 18:56
  • If your software, PowerShell communicates with is 32 bit, then both 64 bit and 32 bit PowerShell versions should be able to run the commands. – Shaqil Ismail Oct 26 '20 at 19:34
  • Can you tell me the exact command and parameters you used to create the service? – Shaqil Ismail Oct 26 '20 at 19:42
  • The service we are running is a server for an application, when a new config is loaded, this service is to be restarted in order to load the new config. It is setup as generic service in a failover cluster. When the user through a gui loads a config, the service starts a bat, which is supposed to restart the cluster service. – Morten Brask Jensen Oct 26 '20 at 19:42
  • the software is a build, and compiled c++ application which runs as a service. And this service "old" restart mechanism was calling a bat which simply called "net stop $servicename" and restarted it again. Now I simply want to change the bat to run the powershell command Stop-clustergroup instead – Morten Brask Jensen Oct 26 '20 at 19:46
  • And this simply does not work no matter how I write my command. It can execute when double clicked. And partially by the service, as the i can write output to a file, but the stop-cluster command does not execute when the service is calling the bat, only when double clicked – Morten Brask Jensen Oct 26 '20 at 19:48
  • When the powershell code is run in the .bat file, can you retrieve the output, when you modify the .bat file, when you are running the service? – Shaqil Ismail Oct 26 '20 at 20:20
  • Yes, and no, I can retrieve the output from the powershell to a txt file when doubleclicking, but when the service is calling the bat it is not outputting anything from the powershell command. Instead, it states that the Stop-clustergroup is not an internal function recognized – Morten Brask Jensen Oct 26 '20 at 20:25
  • https://stackoverflow.com/questions/26890393/run-a-powershell-script-inside-a-windows-service. https://stackoverflow.com/questions/59530375/how-do-i-run-a-powershell-script-as-a-service. Most examples are going for the NSSM tool seeing as service control manager is not available in powershell – Shaqil Ismail Oct 27 '20 at 10:18
0

I solved the problem. Because the service is a 32bit process, it will execute a 32bit powershell. FailoverClusters module only exists as a 64bit module. By using %SystemRoot%\sysnative\WindowsPowershell\v1.0\powershell.exe The service is able to open a 64bit session, and thus use the failover cluster module.

As a side note, the sysnative folder is only visible from a 32bit session, therefore it cannot be found via browsing in a 64bit os.