I want to write a vbscript that will wait for windows shutdown and intercept to carry out proper action before shutting down. I want this to be in vbscript since am using it for administration.
Much easier than that, ever since Windows 2000 you can use the Group Policy setting (or Local Policy even if you're not in a domain) to set the Shutdown Script which will be called, as the name implies, when someone is trying to shutdown the computer. For more info, check out MSKB #198642.
Related
In my usecase i need to send API call upon Windows machine shutdown/reboot.
The script i created works as expected from the PowerShell console, but not when defined in gpedit.msc's shutdown scripts location.
I am assuming this is because WiFi adapter somehow gets down before the script gets executed. Added some debug prints and seems that it is a corect observation.
To prove it more i re-defined the same script in user login scripts location - and it worked as expected indeed.
My question is whether it is really correct that a WiFi adapter disconnects before the shutdown script steps into the process, and if yes - is there any way to outsmart it with PowerShell script?
(My theory is that trapping/delaying a WiFi adapter in a shutdown could adress the case, but even if i knew how to do that i smell the same issue here - the adapter will go down before the trap pops up...)
EDIT: the thing is definitely with the adapter power on shutdown call. If i define the User Logoff script - the script works even if i do reboot or shut down.
So despite i didn't find a way to intercept the NW adapter power supply on shutdown (as well as no comprehensive technical documentation of this feature), i definitely found out a way to acheive my usecase - define the user logoff scripts instead of shutdown scripts.
I have got a custom GINA (Windows Server 2003 R2) that is launching a modal window within WlxLoggedOnSAS and WlxLoggedOffSAS that contains all my workflow. It chains to MS GINA.
When I try to execute a remote script using telnet (like shutdown), it fails. Does any one know why this happens? And is there a way to handle this? Possibly handle an event in the GINA?
I have been hunting for a solution for a while and haven't found any.
I managed to figure this out. Just answering my own question for the benefit of anyone else running into the same scenario. Basically, I have classified GINA in 3 states -
Secure Access Seq (CAD) Screen : This is the one which prompts users to type in Ctrl-Alt-Del. Remote telnet commands will work here.
WlxLoggedOffSAS Screen : This is the login state where the custom GINA UI or MS GINA UI gets created. Generally, this thread is blocked. At this point, remote shutdown commands won't work. To deal with this situation, read on.
WlxLoggedOnSAS Screen : This is the desktop lock state where the custom GINA UI or MS GINA UI gets created. At this point, the shutdown command will work with the /f switch (force shutdown).
To get around state 2, you can do one of two things:
Use something like Windows Task Scheduler to initiate the restart.
Add a new method to your custom GINA DLL that essentially switches to the CAD screen (state 1). You can invoke that DLL method using rundll32.exe. One switched to state 1, just invoke the shutdown and it will work.
I'm trying to deploy a patch to a service I created and replace the service file.
For that reason I need to stop the service so the file will be released.
I'm using sc \\remote stop svcname, then I query the service using sc \\remote query svcname until I see that it's state is STOPPED.
At this point the service file should be unlocked, and to be on the safe side I also delete the service using sc \\remote delete svcname.
Still, it doesn't seem to release the file and any deletion or change attempt fails.
I know one solution might be polling the file repeatedly, but I want to avoid this method.
Any suggestions?
Windows don't ensure the process providing the service terminates when the service is stopped (the process may provide more than one service). It just considers the service stopped when it handles the message sent to it.
So if the service process has a bug and does not properly release resources, they may still be locked. I would probably wait a little and than simply terminate the process.
There is also a tool from Microsoft called handle.exe (this is command-line version, they also have a GUI-one) that can list which processes hold the file open. It should be possible to get the same information programmatically, but I am not sure of the exact calls to make (and you need administrator privileges; you have to give them to the tool too). That way you can check whether the file is open, by which process and wait for it to terminate or force-terminate it if you didn't know which one it is.
I have developed a C# Windows Forms application that runs in the background as a systray icon and does some stuff when it's clicked. It is supposed to launch when Windows starts and run continously, and a normal user without administrator rights shall not be allowed to shut it down.
What is the best way to do this? I initially intended to run it on the LocalSystem account through Task Scheduler, but then I learned (the hard way) about Session 0 isolation (i.e. the application will run but its UI elements do not show). When I run it with the logged in user, even if it runs elevated, the user can still shut it down through task manager (without requiring elevation).
Is there any way to give a process from LocalSystem access to the UI? I have a winlogon and a csrss process from LocalSystem running in session 1, so I guess it can be done, I just don't know how. Or is there maybe an easier way to disallow users to shut down a process of their own through the task manager? The only other option I can think of is to create an extra Windows Service that keeps polling if the app is running, and immediately launches it again if someone kills it - but that seems incredibly clumsy (also, I want it to stay dead when it crashed by itself, to avoid a single bug causing infinite loops of process creation).
Deponds on why they can't shut it down.
The natural way to go would to have created a service, started by a high priv account, and then had the desktop app just show what it was doing.
If there's something that they should see, but don't becasue they aren't running the service monitor app. (and acknowledge message back to the service), send them an email, send their boss an email, send yourself one and then go shout at them.....
Be a lot easier than trying to get the lid back on this tin of worms.
A nice way to make sure the desktop app is ruuning, would be simply to schedule it to run every X, but drop out immediately if it already is or the somethingwenthorriblywrong flkag is set.
Not worth writing a service to check if it's still there, as they could kill that as well, unless you want to make that a service they can't kill. :(
You are trying to be too draconian with this. Add some sort of auditing so you can see it dies or was shutdown, monitor that and deal with any adverse reports. It's a heck of a lot easier, and gives manage something to do...
You can run an administrative process in the user's logon session. One method would be to for a master process (a system service) to duplicate its own token, use SetTokenInformation to change the session associated with the token, and then call CreateProcessAsUser. The lpStartupInfo parameter can be used to associate the process with a particular window station and desktop. It may be necessary to explicitly change the permissions on the window station and desktop first.
HOWEVER, this is a bad idea from a security standpoint, because GUI applications are vulnerable to malicious messages sent from other processes on the same desktop ("shatter attacks").
It would be safer to run the process in the user's own context but apply an ACL to it. This can be done using the lpProcessAttributes parameter to CreateProcess or CreateProcessAsUser, or with the SetSecurityInfo function. I've never tried this, but it should in theory prevent the user from using task manager to close the process.
If you are creating the process from the user's context, then the user will be the owner, so a sufficiently knowledgeable person could change the permissions back in order to terminate the process. If you need to block this hole, using CreateProcessAsUser from a privileged master process (the token can be duplicated from one of the existing processes in the user's session) should (again, in theory) mean that the user is not the process owner.
Another potential issue: if you listen for messages indicating that the user is logging out (in order to exit) such a message could be faked. If you don't then you need to find some other way of exiting when the user logs out. You may need to experiment here, I'm not sure how the system will react.
I have a windows Service always running once PC started, how would i detect using .NET 3.5 or WMI, when the user or some other application/process has requested a shutdown or reboot in windows.
I do not want to stop it, just log the time and who initiated the shutdown (user or process is fine, don't really need to know which process)
Thank you
Use the Microsoft.Win32.SystemEvents.SessionEnding event.
However, note that you are in a Windows Service, and this event won't fire for you unless you create a hidden form in your service. You can get one of these for free by enabling the "Interact with Desktop" option on the service.
You're looking for the SystemEvents.SessionEnding event.
Occurs when the user is trying to log
off or shut down the system.
Win32.SessionEnded event gets fired when the system is being shut down. You should attach to this in your program.