How can I prevent a user from killing powershell process which ends the action of the script. and how can I restart powershell by a piece of code to resume its action?
If the script is being run under the users account, you can't stop them from being able to kill the process.
To get around this, you could have the script run as another user (as a service, or invoking as another user) which will launch the Powershell session under their credentials, in which case only admins will be able to kill the process.
Speaking from experience here:
In our environment we run SCCM, we have several powershell scripts that open a verbose window to let the user know that something is running. This script is running as SYSTEM. The user can still close the window even if they're not a member of the administrators group.
To get around crucial scripts that can't be closed I would suggest running the script silently, so that way it runs without the user even knowing. Or, if you indeed need a GUI, use VB.NET / C# to create a form and use the form closing event to prevent the user from closing it until you're well and ready.
Related
I am trying to run a powershell script to upgrade enterprise software. However since if someone singed-in to the computer it is hard to find time to run this script.
Therefore, I have make the script to wait until user logged-out.
I know how to find out if someone is logged into the pc. I need to know how to make powershell script wait until the user logged out.
You can (and should) do this using Scheduled Tasks, the event ID for logout should be 4647. Tie your script to this event and it will run when the user logs out.
https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4647
I have a long running powershell script. It kicks off at login via GPO, connects to Exchange with the user's current credentials then goes back to sleep. It does this every half hour or so and continues until the user logs out.
The issue occurs if the user changes their password during this time. The next time the script attempts to connect to Exchange it fails. I assume this is because the credentials stored within the powershell session are no longer valid.
Is there a way to refresh/update the scripts's credentials from the O/S?
The only other way I thought to work around this was to restart the script in a new powershell instance, hence grabbing a new set of credentials. This sounds problematic as I believe the context will be passed on to the new session if it's initiated from the running script. Triggering a scheduled task that calls the script may work though I haven't tried it and it seems overly convoluted.
Any thoughts? I don't want to use Get-Credential as that requires a prompt. I also don't want to store a password in a file.
[System.Security.Principal.WindowsIdentity] may provide a way? Not quite sure where to start.
Update:
I'm using EWS as per: https://devblogs.microsoft.com/scripting/learn-to-use-the-exchange-web-services-with-powershell/
You can use the credentials stored in the current powershell session as per:
$exchService.UseDefaultCredentials = $true
So I didn't work out how to update the stored credentials in a running powershell session... surely it's possible... anyway, here is what I did.
Script runs, connects to Exchange successfully, sleeps
User changes Windows password
Script wakes up, connection to Exchange fails
Trap error via try/catch, create Scheduled task to Run in 5 seconds from now with Schedule.Service COMObject
Quit script
Task fires and relaunches powershell script with the updated credentials. Connection to Exchange succeeds. Script sleeps
Task autodeletes itself via Settings.deleteExpiredTaskAfter = 'PT0S' - which is immediately. You also need to set the .EndBoundary on the trigger
Works fairly neatly but it's a bit of a hack. Love to see a more elegant solution from someone.
If I run the following command in my session...
(Get-Process -Id $pid).CloseMainWindow()
I am able to gracefully shut down a process (no modal windows or other popups arise).
If, however, the pid is in another user's session on the same machine (running RDS), the process does not close, and CloseMainWindow() returns FALSE (it returns TRUE if it's running in my own session). It also works if I run the powershell from the other user's session.
I specifically need a way to gracefully shut down the program as the program has a few important cleanup actions required to keep its database in order. So stop-process or process.kill() will not work.
After lengthy research, it does not seem possible to do this. There is, however, a solution which met at least some of my requirements.
You can create a Windows Scheduled Task which is triggered on session disconnect. This allows you to run a cleanup job as the user, rather than as the administrator, which allows programs to exit gracefully.
It has two major drawbacks....
It is called even if the user just has a minor network interruption (so you have to build a wait() function in the script to sleep for a bit and then check if it is still disconnected - not a clean solution.
It isn't called during a log-off event. For that you need to use a logoff script triggered by GPO.
Hope this helps someone in the future.
I am looking for a way to run a job on a schedule and also alert the user to that running job. Specifically, I am using PowerShell to manage a computer lab scenario, and between sessions I want to refresh the environment, clean off the desktop, reset shortcuts pinned to the task bar for the next session, etc. But I want to warn anyone sitting at the machine that this is about to happen. However, my scripts that use Balloontips very successfully as regular scripts don't work as scheduled jobs. They run, and I have verified they run as the user in question, by creating a Scheduled Job that rights a text file to the user desktop. But Balloon Tips don't actually appear. Is there some secret to getting this to work, or is this a form of "interaction" that a scheduled job just can't do?
I also tried an alternative approach, launching the browser with a web page warning of the impending cleanup. That also didn't work. Suggesting some limits to what can be done as a Scheduled Job.
I would much rather go the very "integrated with the OS" route of the balloon tips, but for the life of me it seems like that just isn't an option. So, any other suggestions for providing user info by way of a scheduled job?
Since this runs in Session 0 where GUI interaction doesn't exist you must resort to some other mechanism.
You say this happens between sessions. You could show your ballon via another "notification script" that is executed from within your ScheduledJob. You have options here. For example:
Add entry to registry Run key that will self delete on run. Shows popup when user logs in (session change ? ). Entry executes posh script which parameters you could craft, i.e. (powershell -File notify.ps1 -ArgumentList "Operation bla bla..")
Add ScheduledTask that doesn't run in Session 0 (regular task). You need to do that only once. Every next time you run this job to show notification to the user from within main script via schtasks run or ScheduledTasks module depending on your system.
Add a ScheduledTask that check periodically EventLog for the input of your main script. The task would start on logon and subscribe to event log notifications. I don't like this as the script must run non-stop.
Hello Folks,
I have a powershell MTA (GUI script using winForms), which works well, lets take the script name to be "ENDUserMTA.ps1" which does invoke certain commands and does something which really needs admin rights. this works fine when run manually or via task scheduler or when set via [registry] RunOnce or Run or whatever when there is admin rights..
The problem is i want to invoke this script on the END users laptop and make them to work with it [interactively]
Options that i have tried so far:
Tried Scheduling the "ENDUserMTA.ps1" in Task Manager SYSTEM account [using When running the task, use the following user account] - this starts and run NOT INTERACTIVE [since system account does not have interactive session]
Tried Scheduling the "ENDUserMTA.ps1" in Task Manager with Different user account which has admin rights [using When running the task, use the following user account] - This again starts but the GUI is not shown to the End User who has logged without admin rights, rather shown to only the user who was set under the option [When running the task, use the following user account]
My situation is not possible to create PSSessions or Delegated Remoting. I am now is middle of forest and no where to go!!!
Not sure how to invoke the script as admin to a user who has logged into a machine without admin rights..
WHat i exactly need or similar solution: When scheduling this script, i schedule the script to start atlogon[any user], after the script completes it will delete the scheduled task
Pls help..
Balaji
Begining on Vista Microsoft has started to separate UI stacks for security reasons.
My advise for your problem is to change the architecture of your code in order to create two scripts.
The first one with no UI will be scheduled with administrative rights
The second one with UI will be started with the user rights and will be a client of the first one.
You can use Inter-Process Communication between the two scripts, but you will met a security issue, you server part vill need particular ACLs to allow the client part to connect.
It exists other way to communicate between scripts, but it's not so easy with an asynchronous UI architecture on one side. It would be simple using managed code (.NET code) or native code(unmanaged code). For me, you are on the limit of the scripting place even if scripting capacities are very large as far as PowerShell is built on the top of .NET.