• Schedule a Powershell script while PC sleeps

    Home » Forums » Developers, developers, developers » DevOps Lounge » Schedule a Powershell script while PC sleeps

    Author
    Topic
    #496771

    Hi, I would like to run a Powershell script while my PC sleeps (actually the script checks for the battery level and whether the PC is plugged or not, if battery is low and PC not plugged, it will stop the PC to save the remaining battery).
    I have written the corresponding Powershell script. I can set up a schedule task that will launch the script. It works as long as I tick the “Run only when user is logged on” box. But in this case, it won’t launch when my PC is at sleep.
    When I tick the “Run whether user is logged on or not”, the task will start, but won’t run Powershell. From looking up on different sites, my understanding is that when this box is ticked, tasks will not run interactively, and that may prevent Powershell from launching.
    So my question is: is there a way to launch Powershell in the background.
    Or can you think of a different way of doing this ?

    Thanks a lot in adavance for your help

    Viewing 9 reply threads
    Author
    Replies
    • #1470259

      Danio,

      Maybe a combination of Start-Job (run in background) and Start-Sleep (put job to sleep) command-lets could be used to accomplish the desired task. HTH :cheers:

      P.S. I moved the thread so It will get more exposure to those who may have input.

      May the Forces of good computing be with you!

      RG

      PowerShell & VBA Rule!
      Computer Specs

    • #1470260

      Many thanks for your answer and for moving the post. I must say I am not familiar with Powershell (just discovered it a few days ago !) and wrote my current script thanks to one you have proposed on another post. In my different searches, I came across the Start-job and Start-Sleep command-lets, but haven’t yet figured out how to use them properly.
      I will try to have a closer look at this and will come back then. Thanks again.

    • #1470643

      Try this – go to the Advance Power Option, expand Sleep > Allow Wake Timers and make sure that On Battery is Enabled. This setting is supposed to enable Windows to wake up from sleep when a scheduled event is set. And I am assuming that you are running your PowerShell script as a scheduled event.

    • #1470820

      Thanks for your input. You are right that I try to run my Powershell script as a scheduled event. But I am in fact facing different problems. One is that I am not sure that my PC will wake from sleep for a scheduled event, and I am sure you’re right, I should enable the “Allow wake Timers on Battery”. The problem being that in my Adavance Power Option, there is no Sleep menu ! So that will probably be a problem.
      But before that, my other problem, which I tried to explain in first post, is that when then Powerscript is launched, it starts Powershell. This works fine if I am logged on the computer. But for this to work during sleep, I guess I should tick the “Run whether user is logged on or not” box. But if I do so, the script won’t mork. The scheduled task starts, but Powershell is not launched and nothing happens. From what I read, I think this is because tasks ran with the “Run whether user is logged on or not” option can not use GUI. But I thus don’t know how to run my Powershell script during sleep. I tried adding option to launch Powershell in background but this didn’t work either.

    • #1470842

      Danio,

      From my testing I can’t find a way to trigger a scheduled event via the Sleep event. It seems that once Sleep is triggered it’s too late to catch the event status change.

      So it would seem that you have to start your program with task scheduler by testing switch to battery or on bootup.

      Would you mind posting your script so I could do more testing? HTH :cheers:

      May the Forces of good computing be with you!

      RG

      PowerShell & VBA Rule!
      Computer Specs

    • #1470994

      Hi, not sure I understood your answer. Sorry :confused:
      Here is the script I would like to run while my PC is at sleep. For testing purposes, I have used [console]::Beep(500,500) instead of what would be Stop-Computer.

      Code:
      $MyBattery = `
       Get-WmiObject -class BatteryStatus -ComputerName LocalHost -NameSpace  rootWMI
      
      if (($MyBattery.RemainingCapacity -lt 150000) -and $MyBattery.Discharging) {    [console]::Beep(500,500) }

      Thanks again for your time and help.

    • #1471095

      Danio,

      Anyone who has never made a mistake has never tried anything new.

      – Albert Einstein

      Boy did I try a lot of new things today!37551-headbang

      Thought I had it solved until I realized the computer wasn’t sleeping it had just turned the display off! Back to almost square one.
      Ok here’s something that may work you or may not!

      As I stated earlier I couldn’t trap the Sleep event to start the PS.
      Thus I changed to the On Start event in task scheduler with 5 Minute (minimum allowed) repeat time.
      It takes a while (after the 5 minute wait for the task for PS to fire up test and start the shutdown, this will be reflected is the log message’s time stamps.

      I threw in a couple of PS start-up switches to speed the process:
      -nologo -NonInteractive -WindowStyle Minimized.

      You could also experiment with the -hidden if you wish.

      I also switched your code from the WMI BatteryStatus class to the Win32_Battery class because it has the EstimatedChargeRemaining property which returns a percentage that is easier to work with IMHO.
      Note: Status 1 = On Battery 2 = Charging

      You can also eliminate the writing of status messages as you see fit.

      Items highlighted in RED need your Values!
      Start-SaveBattery.ps1

      Code:
      Add-Type -AssemblyName System.Windows.Forms
      
      $LogFN ="[B][COLOR="#FF0000"]d:path[/COLOR][/B]BatteryStatus.txt"
      $PrtMsg = $true
      
      Do
      {
        $MyBattery = Get-WmiObject -class Win32_Battery `
                                 -ComputerName $env:ComputerName 
      
        if (($MyBattery.EstimatedChargeRemaining -lt [B][COLOR="#FF0000"]97[/COLOR][/B]) -and `
           ($MyBattery.BatteryStatus -eq 1) -And $PrtMsg) {
          "`nSystem Shutdown at: $(Get-Date)`n" >> $LogFN
          $PrtMsg = $false
           Stop-Computer 
        }
        Else {
           "Process Started: $(Get-Date)`n " + `
           "Status: $($MyBattery.BatteryStatus) " + `
           "Percent: $($MyBattery.EstimatedChargeRemaining)" `
                >> $LogFN
         [System.Windows.Forms]::SetSuspendState("Suspend",$false,$true)
         Break    
        }
        
      } while ($true)  #Need endless loop so Stop-Computer can finish!

      BatteryStatus.txt {Log File Output}

      Code:
      Process Started: 10/14/2014 20:27:45
       Status: 1 Percent: 94
      
      System Shutdown at: 10/14/2014 20:33:39
      
      Process Started: 10/14/2014 20:39:52
       Status: 2 Percent: 94
      Process Started: 10/14/2014 20:44:48
       Status: 2 Percent: 95
                            {Wall power turned off here}
      System Shutdown at: 10/14/2014 20:49:59
      
      Process Started: 10/14/2014 21:09:39
       Status: 1 Percent: 98
      Process Started: 10/14/2014 21:14:34
       Status: 1 Percent: 97
      
      System Shutdown at: 10/14/2014 21:19:34
      
      Process Started: 10/14/2014 21:19:35
       Status: 1 Percent: 96
      Process Started: 10/14/2014 21:25:37
       Status: 1 Percent: 97
      
      System Shutdown at: 10/14/2014 21:30:33
      
      Process Started: 10/14/2014 21:30:33
       Status: 1 Percent: 96   {Wall power turned on here}
      Process Started: 10/14/2014 22:00:05
       Status: 2 Percent: 97
      

      Scheduled Task: YourName.ps1

      After fixing the items in RED you should be able to import this task after saving it to a file with a type of .xml.

      Code:
      
        
          2014-10-13T08:58:37.8150333
          [B][COLOR="#FF0000"]computer nameUserID[/COLOR][/B]
        
        
          
            
              PT5M
              P1D
              false
            
            P3D
            true
          
        
        
          
            [B][COLOR="#FF0000"]computer nameUserID[/COLOR][/B]
            InteractiveToken
            LeastPrivilege
          
        
        
          IgnoreNew
          false
          false
          true
          true
          false
          
            true
            false
          
          true
          true
          false
          false
          false
          false
          true
          PT1H
          7
        
        
          
            C:WindowsSystem32WindowsPowerShellv1.0powershell.exe
            -NoLogo -NonInteractive -WindowStyle "Minimized" [B][COLOR="#FF0000"]d:path[/COLOR][/B]ScriptsStart-SaveBattery.ps1
          
        
      
      

      HTH :cheers:

      Update: read next post for new & improved version w/o spurious messages, ability to easily turn off logging, reliable sleep operation.

      May the Forces of good computing be with you!

      RG

      PowerShell & VBA Rule!
      Computer Specs

    • #1471157

      Hey Y’all,

      There were some problems with the previous post that I missed or ignored…bad me. Well, I’ve exhaustively tested this version and it works. That said I’m sure someone will make a liar of me. 😆

      Program: Start-SaveBattery.ps1

      Code:
      
      param (
             [Switch]$LogMsgs
            ) 
      
      Set-StrictMode –Version latest
      
      Function Sleep-Computer {
      Sleep-Computer -WhatIf
      What if: Performing operation "Sleep-Computer" on Target 
               "SushiHangover-MacBookPro".
      .EXAMPLE
      c:PS>Sleep-Computer -Confirm -Force
      Confirm
      Are you sure you want to perform this action?
      Performing operation "Sleep-Computer" on Target "V-RONEES-W8MBP".
      [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help 
         (default is "Y"):
      .LINK
      http://sushihangover.blogspot.com
      .LINK
      https://github.com/sushihangover
      #>
        [cmdletbinding(SupportsShouldProcess=$True,ConfirmImpact="Low")]
        param (
               [parameter(mandatory=$false)][switch]$Force
              )
        if ($pscmdlet.ShouldProcess($env:COMPUTERNAME)) {
          if ($Force.IsPresent) {
            if ($pscmdlet.ShouldProcess("Turning off hibernation")) {
              & powercfg -hibernate off
            }
          }
            $rundll = Join-Path -Path ($env:windir) `
                -ChildPath "System32rundll32.exe"
            & ($rundll) powrprof.dll,SetSuspendState 0,1,0
        }
      } #End Sleep-Computer
      
      #MAIN
      
      $ErrorActionPreference = 'Stop'
      $LogFN ="G:BEKDocsBatteryStatus.txt"
      $PrtMsg = $true
      $StatusDesc = @(' ','On Battery','On Mains')
      
      Do
      {
        $MyBattery = Get-WmiObject -class Win32_Battery `
                                 -ComputerName $env:ComputerName 
      
         If (($MyBattery.EstimatedChargeRemaining -lt 90) -and `
           ($MyBattery.BatteryStatus -eq 1)) {
           If ($PrtMsg -and ($LogMsgs.ispresent)) {
             "`nSystem Shutdown at: $(Get-Date)`n" >> $LogFN
             $PrtMsg = $false
           Stop-Computer 
           }
        }
        Else {
            If ($LogMsgs.ispresent) {
              "Process Started: $(Get-Date)`n " + `
              "Status: $($StatusDesc[$($mybattery.BatteryStatus)]) " + `
              "Percent: $($MyBattery.EstimatedChargeRemaining)" `
              >> $LogFN
            }
          Sleep-Computer -Force  
          Break 
        }
        
      } while ($true)  #Need endless loop so Stop-Computer can finish!
      

      Test run results:

      Code:
      Process Started: 10/14/2014 22:52:50
       Status: 2 Percent: 95
      
      System Shutdown at: 10/14/2014 22:57:47
      
      --------End First Test Run On Battery Under Test Value (97)
      
      
      System Shutdown at: 10/14/2014 23:16:28
      
      --------End of Second Run On Battery Under Test Value (97)
      
      Process Started: 10/15/2014 06:30:13
       Status: 1 Percent: 97
      
      System Shutdown at: 10/15/2014 06:35:07
      
      --------End of third Run On Battery w/full charge! ------
      
      Process Started: 10/15/2014 08:12:18
       Status: On Battery Percent: 98
      Process Started: 10/15/2014 08:12:20
       Status: On Battery Percent: 98
      Process Started: 10/15/2014 08:17:21
       Status: On Battery Percent: 97
      Process Started: 10/15/2014 08:22:21
       Status: On Battery Percent: 97
      Process Started: 10/15/2014 08:27:21
       Status: On Battery Percent: 97
      Process Started: 10/15/2014 08:32:22
       Status: On Battery Percent: 96
      Process Started: 10/15/2014 08:37:22
       Status: On Battery Percent: 96
      [B][COLOR="#B22222"]--- lines deleted for brevity ---[/COLOR][/B]
      Process Started: 10/15/2014 09:22:27
       Status: On Battery Percent: 90
      Process Started: 10/15/2014 09:27:27
       Status: On Battery Percent: 90
      
      System Shutdown at: 10/15/2014 09:32:28
      
      ------End of test w/ Pct (90) and updated Messages & Sleep function!
      
      Process Started: 10/15/2014 12:07:35
       Status: On Mains Percent: 88
      Process Started: 10/15/2014 12:18:32
       Status: On Battery Percent: 90
      
      System Shutdown at: 10/15/2014 12:25:02
      
      --- End of final test switching from Mains power to Battery ---
      
      Process Started: 10/15/2014 12:35:47
       Status: On Mains Percent: 91
      Process Started: 10/15/2014 12:40:44
       Status: On Mains Percent: 92
      Process Started: 10/15/2014 13:04:29
       Status: On Mains Percent: 97
      --- Stopped Task via Task Manager ---
      

      Of course I also tested with the -LogMsgs switch absent but nothing is logged so it doesn’t show which it shouldn’t.

      Note: The logging function can be useful for setting the time interval in your scheduled task as it will show you how fast your computer uses battery power in sleep mode. If you notice above five minutes doesn’t always use 1% of battery so it is probably too short of an interval.

      Changes to previous post:

      If you want to run the program w/o logging the task XML above will work as is. However, if you want logging you need to change as follows:

      Code:
        
          
            C:WindowsSystem32WindowsPowerShellv1.0powershell.exe
            -NoLogo -NonInteractive -WindowStyle "Minimized" [B][COLOR="#FF0000"]"d:pathStart-SaveBattery.ps1 -LogMesgs"[/COLOR][/B]
          
        
      

      Note: the double quotes around the program name and switch parameter are necessary to keep the switch from being interpreted as belonging to PowerShell rather than the program!

      May the Forces of good computing be with you!

      RG

      PowerShell & VBA Rule!
      Computer Specs

    • #1472027

      Hey Y’all,

      I don’t know what happened to the OP but I’ve been working on this for quite a
      while now and I believe I’ve got it working reasonably well with reasonably
      clean organized code. I hope some of Y’all will find this useful.

      I’ve added parameters to make the code easier to control w/o editing the code!
      -LogMsgs {Switch parameter if present activity is written to the log file
      located in the Root Directory of your Documents/MyDocuments folder.}
      -PctTrigger nn {where: nn = percent of batter power remaining. When the remaining
      power level falls BELOW this number the machine will be shut down
      if it is on Battery Power. If you fail to specify this parameter
      it will DEFAULT to 25, e.g. 25%}

      Sample calling seq: Start-PSBatterySave.ps1 -LogMsgs -PctTrigger 33

      Actions: Messages will be written to the log file and the machine will be shut down
      when the battery level falls below 33% while on battery power.

      Note: The program is set to place the computer to sleep ONLY if it was sleeping AND
      it was awakened by the PSBatterySave task! If you are actively working on
      battery power, the program will run at it’s scheduled interval but will NOT
      interrupt your work with undesired sleep states!

      Note2: Remember that in your Scheduled task the entire Add arguments (optional): value:

      d:pathStart-SaveBattery.ps1 -LogMsgs -PctTrigger nn

      MUST be enclosed in double quotes!

      Version 5.0 of the code:

      Code:
      param (
             [parameter(mandatory=$false)][Int]$PctTrigger = 25,         
             [Switch]$LogMsgs
            ) 
      
      Set-StrictMode –Version latest
      
      Function Sleep-Computer {
      Sleep-Computer -WhatIf
      What if: Performing operation "Sleep-Computer" on Target 
               "SushiHangover-MacBookPro".
      .EXAMPLE
      c:PS>Sleep-Computer -Confirm -Force
      Confirm
      Are you sure you want to perform this action?
      Performing operation "Sleep-Computer" on Target "V-RONEES-W8MBP".
      [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help 
         (default is "Y"):
      .LINK
      http://sushihangover.blogspot.com
      .LINK
      https://github.com/sushihangover
      #>
        [cmdletbinding(SupportsShouldProcess=$True,ConfirmImpact="Low")]
        param (
               [parameter(mandatory=$false)][switch]$Force
              )
        if ($pscmdlet.ShouldProcess($env:COMPUTERNAME)) {
          if ($Force.IsPresent) {
            if ($pscmdlet.ShouldProcess("Turning off hibernation")) {
              & powercfg -hibernate off
            }
          }
            $rundll = Join-Path -Path ($env:windir) `
                -ChildPath "System32rundll32.exe"
            & ($rundll) powrprof.dll,SetSuspendState 0,1,0
        }
      } #End Sleep-Computer
      
      #MAIN  -------------------------------------------------------
      
      $ErrorActionPreference = "Continue"
      $LogFN = [environment]::GetFolderPath("MyDocuments") + `
                              "BatteryStatus.log"
      $StatusDesc = @(' ','On Battery','On Mains')
      
      #-------------- Determine if PSBatterySave Task Woke Computer ---------- 
      
      $Temp = powercfg -lastwake
       
      if ($Temp[4] -match "Wake Timer") {
        if ($Temp[6] -match "\PSBatterySave") {
          $SleepSwitch = $true
        }
        Else {
          $SleepSwitch = $false
        }
      }
      Else {
        $SleepSwitch = $false
      }
      
        $MyBattery = Get-WmiObject -class Win32_Battery `
                                   -ComputerName $env:ComputerName 
      
        $StatusMsg = "Process Started: $(Get-Date)" + `
                     " Status: $($StatusDesc[$($MyBattery.BatteryStatus)])" + `
                     " Percent: $($MyBattery.EstimatedChargeRemaining)" + `
                     " Trigger: $($PctTrigger)" 
      
      
         If ($MyBattery.BatteryStatus -eq 2) {
           #--- Mains Power ---#
           If ($LogMsgs.IsPresent) {
              $StatusMsg >> $LogFN
           }
           If ($SleepSwitch) {
             Sleep-Computer -Force 
           }
         }
         #--------------------End on Mains Power ----------------------
      
         Else {
             #--- On Battery Power ---#
             If ($MyBattery.EstimatedChargeRemaining -lt $PctTrigger) {
               If ($LogMsgs.IsPresent) {
                 $StatusMsg + "`n  System Shutdown at: $(Get-Date)`n" >> $LogFN
               }
               Stop-Computer
               Start-Sleep -Seconds 30
               
             }  #--- ON Battery Power ---#
             Else {
                 If ($LogMsgs.IsPresent) {
                   $Statusmsg >> $LogFN
                 } #--- If ($LogMsgs.IsPresent) ---@
             }
             If ($SleepSwitch) {
               Sleep-Computer -Force 
             }
         }  #Else #--- Battery Power ---#
      

      Test Log File Entries:

      Code:
      Process Started: 10/20/2014 20:30:16 Status: On Battery Percent: 82 Trigger: 88
        System Shutdown at: 10/20/2014 20:30:16
      
      Process Started: 10/20/2014 22:12:43 Status: On Battery Percent: 92 Trigger: 88
      Process Started: 10/20/2014 22:18:57 Status: On Battery Percent: 90 Trigger: 88
      Process Started: 10/20/2014 22:19:25 Status: On Battery Percent: 90 Trigger: 91
        System Shutdown at: 10/20/2014 22:19:25
      
      Process Started: 10/20/2014 22:22:37 Status: On Mains Percent: 91 Trigger: 88
      Process Started: 10/20/2014 22:22:56 Status: On Battery Percent: 91 Trigger: 88
      Process Started: 10/20/2014 22:30:16 Status: On Battery Percent: 90 Trigger: 88
      Process Started: 10/20/2014 22:40:17 Status: On Battery Percent: 90 Trigger: 88
      Process Started: 10/20/2014 22:50:17 Status: On Battery Percent: 90 Trigger: 88
      Process Started: 10/20/2014 23:00:18 Status: On Battery Percent: 89 Trigger: 88
      Process Started: 10/20/2014 23:10:19 Status: On Battery Percent: 89 Trigger: 88
      Process Started: 10/20/2014 23:20:19 Status: On Battery Percent: 88 Trigger: 88
      Process Started: 10/20/2014 23:30:20 Status: On Battery Percent: 88 Trigger: 88
      Process Started: 10/20/2014 23:40:20 Status: On Battery Percent: 88 Trigger: 88
      Process Started: 10/20/2014 23:50:20 Status: On Battery Percent: 87 Trigger: 88
        System Shutdown at: 10/20/2014 23:50:20
      

      As you can see from the entries above 10 minutes is too often to check the
      status since it is taking about 30 minutes to use 1% of the battery power.
      You can use the message log to tune your machine for the optimal settings
      for your computer and then adjust the Task Scheduler task to the appropriate
      Repeat Task value.

      IMPORTANT NOTE: This code turns Hibernation OFF!!!

      HTH :cheers:

      May the Forces of good computing be with you!

      RG

      PowerShell & VBA Rule!
      Computer Specs

    • #1472089

      Addendum,

      Change the Trigger event from “At Startup” to “At Log on”!

      See this post for information on Trigger Events.

      May the Forces of good computing be with you!

      RG

      PowerShell & VBA Rule!
      Computer Specs

    Viewing 9 reply threads
    Reply To: Schedule a Powershell script while PC sleeps

    You can use BBCodes to format your content.
    Your account can't use all available BBCodes, they will be stripped before saving.

    Your information: