Powershell – Windows startup procedure monitoring - powershell

I want to conduct some specific actions right after Windows startup (when user is logged on) via PowerShell script. However, I do not want to do it by adding my PowerShell script to Windows Startup because in this way my script will run in the middle of Windows Startup procedure. Therefore, some services and applications may not be started yet.
I want to run the script when ALL Windows Services are started, all applications from Windows Startup section are run and HDD is not heavily loaded. Is it possible to detect such Windows state using PowerShell?
I would be grateful for any kind of help, because I am running out of ideas…

Create a Powershell startup script. Set it to monitor system via Perfmon counters and wait untill the system is idle enough. Like so,
$epsilon = 0.2
do { # sleep and loop untill cpu load is low enough
start-sleep -seconds 5
$counter = Get-Counter "\\computer\Process(Idle)\% Processor Time"
} while ($counter.CounterSamples.CookedValue -ge $epsilon)
# The system is now idle enough
# Start the real work after the loop
The proper counter set depends on what you are after. Current disk queue might be of interest too.
The same approach can be used to check service state, running processes and so on.

Related

Determine if users can RDP after Windows Update

I'm automating windows updates for a set of SQL servers, mostly running on Windows Server 2016. Typically after you install updates you have to reboot, and there is a period of time after rebooting where the server is applying updates and users can't remote into the server. In my automation, I would like to wait until that period of time is over before reporting a successful update. Is there an indicator that I can check remotely through powershell that will determine whether a user can remote in?
I've checked the main RDP services (termservice, SessionEnv and UmRdpService) during this period and they are all running, so if there's some sort of indicator, it isn't them. Maybe there is a field somewhere that states that windows is applying updates? All of the servers are virtualized through VMWare if it matters.
Thanks for reading!
How about testing the port that the remote desktop service listens on?
test-netconnection server -port 3389
I didn't have any luck on ServerFault either, but I did eventually find a solution myself, posting here in case anyone finds this thread looking for help.
The isn't actually a service that changes states when you can RDP back into a server; that's probably determined somewhere in the windows code and there's no way you could find the flag. However, the TIWorker program runs after a reboot to install windows, and in my experience recently, when that exe completes, you can RDP 100% of the time, which is good enough for my automation.
I loop over this piece of code in 5 second intervals until it returns 0 rows, then finish.
Get-Process -ComputerName $server | ? {$_.ProcessName -match 'TiWorker'}

Quickest way to enable PSRemoting after a reboot? Long delay with WMI Method

In our environment I often need to reboot a computer and then send commands to it via Invoke-Command. For this, I obviously need to have PSRemoting enabled on the target machine.
It is enabled by default on all our machines, however after a reboot it takes a while to kick in by itself.
I'm using Invoke-WmiMethod to force enable it as soon as the computer pings instead of waiting.
That works well but it sometimes takes over 30-40 seconds to kick in. It's still faster than the 2-5 minutes it can take if I just let it start by itself.
The command I'm using is:
Invoke-WmiMethod -ComputerName $poste -Path Win32_Process -Name create -ArgumentList "powershell.exe -command Enable-PSRemoting -SkipNetworkProfileCheck -Force"
My questions are:
Why does it take so long before it actually is enabled after that command runs?
Is there a better way you would suggest to enable PSRemoting via WMI or something else?
tldr;
All you are really doing when running Enable-PSRemoting is starting the WinRM service, everything else that the command does is skipped as you've already configured it.
The WinRM service is set to Automatic Delayed Start - to make it start faster change this to Automatic.
The 'delay' you are referring to is the delay in Windows starting the WinRM service.
Services that start at bootup have two options:
Automatic will start the service asap after Windows itself loads
Automatic Delayed Start will start the service after a short delay
The reason for the two types is resource contention - having every service start at the same time will use a huge amount of resources and the end-user will notice this as a slow-down.
To manage resources effectively Services that are essential to Windows will be set to Automatic and start simultaneously. This consumes lots of system resources, but the user has no choice as these services are generally required for Windows to work properly.
But for Services that are not essential, Delayed Start is the better option. These start "shortly after boot" when all the Automatic services have started. These are generally service for secondary functionality - eg an updater service.
The WinRM service is set to Automatic Delayed Start - to make it start faster change this to Automatic. You will take a performance hit for this so test this before making mass changes.
IMO - don't change the service startup, use code to deal with this delay...
For example, Restart-Computer with the Wait param will restart a remote computer and wait for connectivity before continuing:
Restart-Computer -ComputerName "Server01" -Wait -For PowerShell -Timeout 300 -Delay 2

Running Windows Powershell script always from task scheduler

This might be a very basic question. I have FileWatcher script in windows powershell which I want to run always so that it keeps watching a particular location for files. when I run it from Windows Powershell IDE its run perfectly fine. I understand that I can schedule a task in windows task scheduler for that but what's happening is that the task runs and then comes back in "Ready" status. This is NOT working. I think it should be in "Running" state always. I might be missing something. Please kindly help with your valuable suggestions.
You can do this with TaskSchedule…
Running PowerShell scripts as a “service” (Events: Prologue)
but this is also what permanent Event Subscriptions are for or setting up as user10675448 suggest, make it a real service.
How to run a PowerShell script as a Windows service
Windows PowerShell - Writing Windows Services in PowerShell
This article presents the end result of that effort: A novel and easy
way to create Windows Services, by writing them in the Windows
PowerShell scripting language. No more compilation, just a quick
edit/test cycle that can be done on any system, not just the
developer’s own.
There is also this approach...
PowerShell and Events: Permanent WMI Event Subscriptions
Unlike the temporary event, the permanent event is persistent object
that will last through a reboot and continue to operate until it has
been removed from the WMI repository.
There are multiple ways of setting up the WMI events and I will be
covering 3 of those ways (as they deal with PowerShell) in this
article.

How do I (administrator) gracefully close a window process running in another user session using powershell on Windows 2008 R2 Remote Desktop Services

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.

Powershell scripting

I want to automate test using powershell. I want to write a script to shutdown the computer, wait for 3minutes and then power on the computer. Is it possible using Powershell? I know that reboot is possible, but I want the system to remain in shutdown stage for 3min and then power on.
If you mean a "real computer" (not a Virtual Machine) so it's not possible. But you can achieve that using Virtual Machine setup. Take look at this documentation: https://technet.microsoft.com/en-us/library/hh848589.aspx
You can shutdown computer with Stop-Computer command
Wait with Start-Sleep
But to poweron PC you need something more complex, take a look at WOL. However there are some difficulties:
It would work only with PCs that allow to be awakened with magic packets
You need to know MAC-address of machine
Target machine should be in the current network subnet of the caller.