Alternative to Thread. Sleep with different hardware - powershell

I am writing a autologin script in Powershell. With main purpose of doing autologon with keystrokes on remote clients in our environment after installation, with the desired AD and password entered.
Works fine on my i9. But most people using Tablets and Elitebooks so using
Thread Sleep
Works bad since i would need to have custom timing on Every hardware, or very high default numbers for lower end clients using my script
Is there any way adding an "wait for row above to completed" Before continuation to next.

I don't have enough on your current code to produce a more accurate answer but the idea, in all cases, remains the same.
You should periodically wake up the thread to check whether or not the machine is in the state you want it in and from there, you either go back to sleep or exit the loop and continue.
The delay is up to you but you want to find a sweet spot to have great performance and reactivity.
Example (based on your description)
$IsLoggedIn = $false
while (! $IsLoggedIn) {
$IsLoggedIn = 'Custom Logic returning $true if the user is logged in'
if ($IsLoggedIn) { break }
Start-Sleep -Milliseconds 100
}
You just need to figure out the thing you want to use as the check to validate the computer is in the correct state you need it in before proceeding further.

Related

Tcl/Tk - How to keep other buttons useable while separate function still running?

I'm very new to Tcl/Tk and have been dealing with an issue for the last couple of days. Basically I have a server written in C and a client GUI written in Tcl/Tk. So far it doesn't do a ton. To test it, I start up the server so that it's listening for connections, then run my GUI. When I click one of the buttons, the GUI should open up a separate toplevel window with a text widget embedded in it. (This part works.) Then, my client connects to the server and gives it a couple of settings, and through this the server decides what info to send back. The server's response is what gets printed to that second window's text widget.
What I'm trying to add in now is a Stop button. Right now, my server is set up to wait a couple of seconds, then write the same message to the client. This is set up inside a loop that is waiting to hear a "Stop" command from my client. I have a Stop button in the GUI with a command set up to write that command to the server when clicked. However, all of my buttons get frozen as soon as I hit the begin button and messages are written to the client.
Basically, how can I keep allowing my server to write to my client while still keeping the rest of my GUI usable? I want my client to write a new line to the text widget on my separate window whenever it receives a new message from the server, but I still want the main GUI window that has all my command buttons to behave independently.
In general, it depends on whether what you are doing is CPU-intensive (where reading from a plain file counts as CPU-intensive) or I/O-intensive (where running things in another process counts as I/O-intensive; database calls often count as CPU-intensive here despite not really needing to). I'm only going to mention summaries of what's going on as you aren't quite providing enough information.
For I/O-intensive code, you want to structure your code to be event-driven. Tcl has good tools for this, in that fileevent works nicely on sockets, terminals and pipelines on all supported platforms. The coroutine system of Tcl 8.6 can help a lot with preventing the callbacks required from turning your code into a tangled mess!
For CPU-intensive code, the main option is to run in another thread. That thread won't be able to touch the GUI directly (which in turn will be free to be responsive), but will be able to do all the work and send messages back to the main thread with whatever UI updates it wants done. (Technically you can do this with I/O-intensive code too, but it's more irritating than using a coroutine.) Farming things out to a subprocess is just another variation on this where the communications are more expensive (but much isolation is enforced by the OS).
If you're dealing with sockets, you're probably I/O-intensive. Assume that until you show otherwise. Here's a simple example:
proc gets_async {sock} {
set sock [lindex $args end]
fileevent $sock readable [info coroutine]
while {[gets $sock data] < 0 && [fblocked $sock]} {
yield
}
fileevent $sock readable {}
return $data
}
proc handler {socket} {
set n 0
while {![eof $socket]} {
# Write to the server
puts $socket "this is message [incr n] to the server"
# Read from the server
puts [gets_async $socket]
}
close $socket
}
proc launchCommunications {host port} {
set sock [socket $host $port]
fconfigure $sock -blocking 0 -encoding utf-8
coroutine comms($host:$port) handler $socket
}
Note that gets_async is much like coroutine::util gets in Tcllib.

How can I detach process from Elixir System.cmd/2 before command ends?

I'm trying to run this (script.exs):
System.cmd("zsh", ["-c" "com.spotify.Client"])
IO.puts("done.")
Spotify opens, but "done." never shows up on the screen. I also tried:
System.cmd("zsh", ["-c" "nohup com.spotify.Client &"])
IO.puts("done.")
My script only halts when I close the spotify window. Is it possible to run commands without waiting for it to end?
One should not spawn system tasks in a blind hope they would work properly. If the system task crashes, some actions should be taken in the calling OTP process, otherwise sooner or later it’ll crash in production and nobody would know what had happened and why.
There are many possible scenarios, I would go with Task.start_link/1 (assuming the calling process traps exits,) or with Task.async/1 accompanied by an explicit Task.await/1 somewhere in the supervision tree.
If despite everything explained above you don’t care about robustness, use Kernel.spawn/1 like below
pid = spawn(System, :cmd, ~w|zsh -c com.spotify.Client|)
# Process.monitor(pid) # yet give it a chance to handle errors
IO.puts("done.")

(Laravel 5) Monitor and optionally cancel an ALREADY RUNNING job on queue

I need to achieve the ability to monitor and be able to cancel an ALREADY RUNNING job on queue.
There's a lot of answers about deleting QUEUED jobs, but not on an already running one.
This is the situation: I have a "job", which consists of HUNDREDS OF THOUSANDS rows on a database, that need to be queried ONE BY ONE against a web service.
Every row needs to be picked up, queried against a web service, stored the response and its status updated.
I had that already working as a Command (launching from / outputting to console), but now I need to implement queues in order to allow piling up more jobs from more users.
So far I've seen Horizon (which doesn't runs on Windows due to missing process control libs). However, in some demos seen around it lacks (I believe) a couple things I need:
Dynamically configurable timeout (the whole job may take more than 12 hours, depending on the number of rows to process on the selected job)
Ability to CANCEL an ALREADY RUNNING job.
I also considered the option to generate EACH REQUEST as a new job instead of seeing a "job" as the whole collection of rows (this would overcome the timeout thing), but that would give me a Horizon "pending jobs" list of hundreds of thousands of records per job, and that would kill the browser (I know Redis can handle this without itching at all). Further, I guess is not possible to cancel "all jobs belonging to X tag".
I've been thinking about hitting an API route, fire the job and decouple it from the app, but I'm seeing that this requires forking processes.
For the ability to cancel, I would implement a database with job_id, and when the user hits an API to cancel a job, I'd mark it as "halted". On every loop I would check its status and if it finds "halted" then kill itself.
If I've missed any aspect just holler and I'll add it or clarify about it.
So I'm asking for an advice here since I'm new to Laravel: how could I achieve this?
So I finally came up with this (a bit clunky) solution:
In Controller:
public function cancelJob()
{
$jobs = DB::table('jobs')->get();
# I could use a specific ID and user owner filter, etc.
foreach ($jobs as $job) {
DB::table('jobs')->delete($job->id);
}
# This is a file that... well, it's self explaining
touch(base_path(config('files.halt_process_signal')));
return "Job cancelled - It will stop soon";
}
In job class (inside model::chunk() function)
# CHECK FOR HALT SIGNAL AND [OPTIONALLY] STOP THE PROCESS
if ($this->service->shouldHaltProcess()) {
# build stats, do some cleanup, log, etc...
$this->halted = true;
$this->service->stopProcess();
# This FALSE is what it makes the chunk() method to stop looping
return false;
}
In service class:
/**
* Checks the existence of the 'Halt Process Signal' file
*
* #return bool
*/
public function shouldHaltProcess() :bool
{
return file_exists($this->config['files.halt_process_signal']);
}
/**
* Stop the batch process
*
* #return void
*/
public function stopProcess() :void
{
logger()->info("=== HALT PROCESS SIGNAL FOUND - STOPPING THE PROCESS ===");
$this->deleteHaltProcessSignalFile();
return ;
}
It doesn't looks quite elegant, but it works.
I've surfed the whole web and many goes for Horizon or other tools that doesn't fit my case.
If anyone has a better way to achieve this, it's welcome to share.
Laravel queue have 3 important config:
1. retry_after
2. timeout
3. tries
See more: https://laravel.com/docs/5.8/queues
Dynamically configurable timeout (the whole job may take more than 12
hours, depending on the number of rows to process on the selected job)
I think you can config timeout + retry_after about 24h.
Ability to CANCEL an ALREADY RUNNING job.
Delete job in jobs table
Delete process by process id in your server
Hope it help you :)

Waiting for an process to quit in PowerShell

Is there a possibility to wait for an process to quit, without it needs to running?
I know there is the keyword WaitForExit, but to use this the process needs to run.
My second question is, if there is a possibility to use an else-Statement in an while loop.
Tried it already, but it always said that there isnt an function called else.
Do Until
Do {
Sleep 5
} Until (Get-Process iexplore);
Will wait until iexplore is found
While
While (Get-Process iexplore) {
Sleep 5
}
Will wait until iexplore is no longer running
Else after while
You cannot use an else statement after a while loop.
It needs to come after an if.
if there is a possibility to use an else-Statement in an while loop.
If you mean something like:
while (cond) {
} else {
}
?
Then NO. (how would the content of the else block be any different to code immediately following the while block?)
Is there a possibility to wait for an process to quit,
Yes. There are different ways of doing this, depending on the nature of the target process. Is it one created by the same script? Is the same session? A service? Or just an arbitrary process?
Does it seems to fits your needs (1st question) ? http://technet.microsoft.com/library/hh849813.aspx
You can use wait-process cmdlet.
Check link for details http://ss64.com/ps/wait-process.html
Example: wait-process -name notepad.exe

powershell - How to wait for user input

I am trying to prevent users from shutting down the computer in certain situations. I am displaying a confirm message to do that. This is how my script looks like:
$sysevent = [microsoft.win32.systemevents]
Register-ObjectEvent -InputObject $sysevent -EventName "SessionEnding" -Action $OnShutdown -SourceIdentifier "ExecuteOnShutdown"
$OnShutdown =
{
Write-Host -ForeGround Green $event.SourceEventArgs.Reason
$OUTPUT= [System.Windows.Forms.MessageBox]::Show("Do you really want to shutdown the computer?." , "confirm" , 4)
Write-Host $OUTPUT
}
This works fine but i dont know how do i suspend the shutdown command till user clicks "yes" or "no". Is there a way to prevent the system shutdown and wait for the user to click "yes" or "no" and then shutdown the server based on the answer?
In your event handler scriptblock there are a number of automatic variables defined one of which is $EventArgs. In this case there will be a Cancel property on this object you can set to $true but the docs warn:
When set to true, this property requests that the session continue to
run. It provides no guarantee that the session will not end.
There is also another variable defined in this context - $Sender. Execute man about_automatic_variables for more info.
Consider deploying your script via group policy or a local policy shutdown / logoff script which should prevent shutdown until your condition is met. You might need to wrap your messagebox call in conditional sleep loop (which is what I did for something similar in VBScript years ago!), maybe not.
If you choose to use this method, you may also want to include a preferred default selection for your messagebox (perhaps after a specified timeout period has elapsed?); a user may not hang around to see your mesaagebox as it will be drawn after the interactive desktop has unloaded.
Here's a link to a Technet article about how to Use Startup, Shutdown, Logon, and Logoff Scripts.
I'm not sure if this answers your question as this won't prevent the shutdown, it just stops it until your condition is met.