Ok, here is my situation.
Once I’m done using my home PC for the day, I shutdown my Windows 10 PC as I normally would from the Start menu. The next morning, while I’m away at work, my son comes along, presses a few keys on my keyboard, and my PC switches on back to life. My PC remains on for the whole day until I come back home from work.
Sounds familiar? Well, that is what I faced, and I was looking for an automated solution: once my PC turns on, wait for several minutes, then check if someone is logged in. If no one is logged in, shutdown the PC. And here is what I finally ended up with.
I wanted something which will work and log what happens as well. And being that PowerShell is sort of the “replacement” of VBS and CMD files, this would be in PowerShell as well.
First things first, how do i detect if someone is logged in to the machine? Turns out, this can be quite complicated. The first Google link I found was on the Spiceworks Forum. That did not work. Then I tried a few more links. All seemed far too complicated, although it would eventually work. I think.
Eventually, I found a technique to check users running Explorer. This seemed like a good solution, and I recall at work, we had used something similar, and it worked pretty well.
With that sorted, next was logging. Event Viewer seems like a good bet, but I found out, I needed to create a new event source in the Application log if I wanted to separate out my shutdown script from the rest of the noise.
New-EventLog –LogName Application –Source "Shutdown Script"
With that done, it was time go combine everything together as 1 script.
##This script is schedule to run on every system start-up.
$loggedOnUsers = 0
##Wait 2 minutes
$waitMinutes = 2
$waitSeconds = 60 * $waitMinutes
$elapsed = [System.Diagnostics.Stopwatch]::StartNew()
#Write something to event log
Write-EventLog -LogName Application -Source "Shutdown Script" -EntryType Information -EventId 1 -Message "Machine startup detected. Waiting for $waitSeconds seconds"
sleep $waitSeconds
#is there any users logged on?
Write-EventLog -LogName Application -Source "Shutdown Script" -EntryType Information -EventId 1 -Message "Finished waiting, checking for logged on users"
$explorerprocesses = @(Get-WmiObject -Query "Select * FROM Win32_Process WHERE Name='explorer.exe'" -ErrorAction SilentlyContinue)
if ($explorerprocesses.Count -eq 0)
{
Write-Host "No explorer process found / Nobody interactively logged on"
}
else
{
$loggedOnUsers = $explorerprocesses.Count
foreach ($i in $explorerprocesses)
{
$Username = $i.GetOwner().User
$Domain = $i.GetOwner().Domain
$message = "$Domain\$Username logged on since: " + ($i.ConvertToDateTime($i.CreationDate))
Write-EventLog -LogName Application -Source "Shutdown Script" -EntryType Information -EventId 1 -Message $message
}
}
if ($loggedOnUsers -eq 0)
{
Write-EventLog -LogName Application -Source "Shutdown Script" -EntryType Information -EventId 1 -Message "No users logged on. Shutting down..."
Stop-Computer
}
All you need to do next, create a new Task Scheduler entry to run this script at startup, and you are good to go!
Open Task Scheduler and create a new Task. In the Actions tab, click New.
Choose Start a program. Put in the path to PowerShell.exe. For the arguments, use:
-ExecutionPolicy Bypass '[Full Path To]\ShutdownOnNoLogin.ps1'
You need to also have 2 triggers. One for the system startup, and one for waking up from sleep
Why 2? Well, Windows 10 (and i believe Windows 8 and 8.1 as well) do not really fully shutdown when you choose Shutdown from the Start Menu. Instead, it enters a sleep mode. The second trigger is to detect when the PC wakes up from sleep (the trigger of my son banging on my keyboard).
A trigger with the settings below is what you need to configure as the second trigger.
Hope this was useful.
you are a hero!