≡ Menu

Gracefully shutdown (or restart) remote computer using powershell

Want to know how to shutdown/restart a remote computer using Powershell? Well, this post is for same purpose. Powershell has built-in cmdlets to shutdown/restart remote computers –i.e shutdown-computer, restart-computer. They servers most purpose, but the problem is that these cmdlets doesn’t provide a way to give shutdown or restart comments and the timeout.

Having the ability to provide comments (or reason for shutdown/restart) is important and useful since we can track how has initiated the reboot.

Now let us jump on to the coding part.

[cmdletbinding()]            

param (            

 [parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]            
 [string[]]$ComputerName = $env:computername,            
 $Timeout = 30,            
 [switch]$Reboot            

)            

begin {            
 $Username = $env:username            
 if($reboot) { $flag = 2 } else { $flag = 1 }             
 if($reboot) {            
  $comment  = "Reboot initiated by $Username using $($MyInvocation.InvocationName). Timeout is $Timeout"            
 } else {            
  $comment  = "Reboot initiated by $Username using $($MyInvocation.InvocationName). Timeout is $Timeout"            
 }            
}            

process {            
 foreach($Computer in $ComputerName) {            
  Write-Verbose "Working on $Computer"            
  if(Test-Connection -ComputerName $Computer -Count 1 -ea 0) {            
   $OS  = Get-WMIObject -Class Win32_OperatingSystem -ComputerName $Computer            
   if( -not $OS.Win32ShutdownTracker($timeout, $comment, 0, $flag)) {            
    $Status  = "FAILED"            
   } else {            
    $Status  = "SUCCESS"            
   }            
  $OutputObj = New-Object -TypeName PSobject             
  $OutputObj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Computer            
  $OutputObj | Add-Member -MemberType NoteProperty -Name Status -Value $status            
  $OutputObj | Add-Member -MemberType NoteProperty -Name Timeout -Value $timeout            
  $OutputObj            
  }            
 }            
}            

end {            
}

This script uses WMI class Win32_OperatingSystem to shutdown the computer. This class has a method Win32ShutdownTracker which is available in Vista, Windows 7, Windows 2008(and R2) operating systems that allows us to provide a comment and timeout for the shutdown and restart. This script provides a default timeout of 30s for shutdown/restart operations but you can reduce or increase it by using -Timeout parameter. Setting this parameter to 0(zero) will trigger the graceful shutdown immediately.

You can read more about the implementation of Win32_OperatingSystem at http://msdn.microsoft.com/en-us/library/windows/desktop/aa394239%28v=vs.85%29.aspx and Win32ShutdownTracker method at http://msdn.microsoft.com/en-us/library/windows/desktop/aa394057%28v=vs.85%29.aspx

 

Usage:

Copy the above script into a file and save it as shutdown-Computer.ps1

  • To shutdown a single computer : Shutdown-Computer.ps1 -ComputerName MyPC1
  • To shutdown multiple computers : Shutdown-Computer.ps1 -ComputerName MyPC1, MyPC2
  • To trigger the shutdown immediately: Shutdown-Computer.ps1 -ComputerName MyPC1 -Timeout 0
  • To trigger restart: Shutdown-Computer -ComputerName.ps1 -Restart

Output:

I welcome your comments….

Comments on this entry are closed.

  • PS4 News February 16, 2012, 3:38 am

    What’s up colleagues, how is everything, and what you wish for to say on the topic of this article, in my view its in fact amazing in support of me.

  • Steve September 23, 2014, 12:40 am

    I would like to use SCCM 2012 to remotely execute this script on a system and force reboot the system (localhost). Can I do this with this script? If so, how?

    Thanks,
    Steve