Click here to Skip to main content
15,867,568 members
Articles / Programming Languages / PowerShell
Article

Reboot and Resume PowerShell Script

Rate me:
Please Sign up or sign in to vote.
4.71/5 (9 votes)
8 Jul 2011CPOL3 min read 119.9K   2.8K   15   12
A first step in creating that magic "Developer PC Setup Script".

Introduction

Gone are the days where daily reboots of Windows were needed. However, when dealing with system maintenance or installing multiple applications from script, rebooting is sometimes unavoidable. This article will describe a PowerShell script capable of running through a number of steps, rebooting the computer, and continuing the script at another step. Simple, yet very useful.

Background

The ideas shown in this article stem from a real life script for setting up a developer PC with everything from the right version of the .NET Framework, enabling the right features in IIS, installing Visual Studio and MS SQL Server locally, plus a lot more. The advantages of setting up a developer PC in this way are many:

  • It is a lot faster than letting every developer go through the steps themselves
  • It is a lot more flexible than using a disc image
  • It documents very clearly which technologies are used
  • It can be used for updating existing developer PCs as well as installing from scratch

The main disadvantage of the above mentioned setup script is the upfront time investment in getting such a script in place. This article will however help you to get started and you should really take up the challenge and try creating your own script - you will be impressed with just how powerful PowerScript really is.

Running the Test Script

The simple test script covered in this article is shown below:

param($Step="A")
# -------------------------------------
# Imports
# -------------------------------------
$script = $myInvocation.MyCommand.Definition
$scriptPath = Split-Path -parent $script
. (Join-Path $scriptpath functions.ps1)


Clear-Any-Restart

if (Should-Run-Step "A") 
{
    Write-Host "A"
    Wait-For-Keypress "The test script will continue after a reboot, press any key to reboot..." 
    Restart-And-Resume $script "B"
}

if (Should-Run-Step "B") 
{
    Write-Host "B"
}

if (Should-Run-Step "C") 
{
    Write-Host "C"
}

Wait-For-Keypress "Test script Complete, press any key to exit script..."

The script will execute step A through C, only when done with step A, it will reboot, and then continue at step B. Below are two screenshots showing what to expect:

Script running step A and then reboots

Script continues the script starting at step B

Making the Script Step Aware

Making a PowerShell script to execute in sequential steps can be done in a number of ways. The only thing required in this example is that the starting step must be specified on the command line, as in:

>.\testscript.ps1 -Step B

As seen from the test script above, we declare a script parameter $Step for taking in the starting step from the command line. We then create a simple guard method Should-Run-Step which will return false until the starting step specified on the command line is encountered, and from there on, it will return true:

$global:started = $FALSE
$global:startingStep = $Step

function Should-Run-Step([string] $prospectStep) 
{
    if ($global:startingStep -eq $prospectStep -or $global:started) {
        $global:started = $TRUE
    }
    return $global:started
}

This stepping mechanism could of course be way more sophisticated, including endpoints and step ranges, but that is not really the focus of the article and hence left as an exercise for the reader.

A Few Registry Helper Functions

As much as I like the super general ???-ItemProperty functions of PowerShell, I tend to think these methods can clutter the scripts and make them less readable. Therefore I will introduce four simple helper methods for dealing with the Registry:

function Test-Key([string] $path, [string] $key)
{
    return ((Test-Path $path) -and ((Get-Key $path $key) -ne $null))   
}

function Remove-Key([string] $path, [string] $key)
{
    Remove-ItemProperty -path $path -name $key
}

function Set-Key([string] $path, [string] $key, [string] $value) 
{
    Set-ItemProperty -path $path -name $key -value $value
}

function Get-Key([string] $path, [string] $key) 
{
    return (Get-ItemProperty $path).$key
}

Rebooting from PowerShell

Restarting a computer from PowerShell is done simply with the command Restart-Computer. Making Windows execute a command on startup is handled via the Registry key "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run". Putting this information together leads us to define a Restart-And-Run function which will reboot and then launch whatever is passed in the $run parameter.

$global:RegRunKey ="HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
function Restart-And-Run([string] $key, [string] $run) 
{
    Set-Key $global:RegRunKey $key $run
    Restart-Computer
    exit
}

If you do not want to launch the command specified every time you start Windows, you better remember to clear that Registry key. As we plan to resume our script, we can easily do that in a dedicated function which is to be placed at the top of our script.

$global:restartKey = "Restart-And-Resume"
function Clear-Any-Restart([string] $key=$global:restartKey) 
{
    if (Test-Key $global:RegRunKey $key) {
        Remove-Key $global:RegRunKey $key
    }
}

As you may have noticed, the Clear-Any-Restart function takes a default key of "Restart-And-Resume", and resuming the script was what this article set out to accomplish. Guess what, all we need to do is restart PowerShell with the wanted step parameter:

$global:powershell = (Join-Path $env:windir "system32\WindowsPowerShell\v1.0\powershell.exe")
function Restart-And-Resume([string] $script, [string] $step) 
{
    Restart-And-Run $global:restartKey "$global:powershell $script -Step $step"
}

That is it, we are all done, you are now ready to make your own setup scripts. Enjoy, and please do let me know what you think and what crazy things you use this for.

Troubleshooting

If you are having trouble executing the script, make sure you have not specified the restricted execution policy:

>Set-ExecutionPolicy RemoteSigned

History

  • July 08, 2011: Initial version.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Denmark Denmark
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questionawesome script Pin
PSK464-Aug-20 1:08
PSK464-Aug-20 1:08 
QuestionReally nice script. Helped me a lot! Pin
Member 1291739121-Dec-16 22:58
Member 1291739121-Dec-16 22:58 
QuestionDoesn't work on Client computer - Need admin rights without UAC. Pin
Guillaume T.23-Feb-16 2:39
Guillaume T.23-Feb-16 2:39 
QuestionThe Reboot and Resume Powershell Script runs the next step after logging in to the server. I want the script to keep running without actually logging in. Pin
Member 1204286513-Oct-15 21:44
Member 1204286513-Oct-15 21:44 
QuestionResume Script Under Different Login? Pin
Member 1074273611-Apr-14 7:41
Member 1074273611-Apr-14 7:41 
AnswerRe: Resume Script Under Different Login? Pin
Member 1074273611-Apr-14 7:54
Member 1074273611-Apr-14 7:54 
QuestionAny way to jump to specific steps? Pin
Member 958706019-Feb-14 4:55
Member 958706019-Feb-14 4:55 
QuestionUAC Pin
rome777720-Nov-12 10:43
rome777720-Nov-12 10:43 
GeneralMy vote of 5 Pin
hermiodinator30-Apr-12 10:51
hermiodinator30-Apr-12 10:51 
QuestionJust wanted to say thanks Pin
Marin Marušić26-Nov-11 10:58
Marin Marušić26-Nov-11 10:58 
AnswerRe: Just wanted to say thanks Pin
Lasse W28-Nov-11 8:36
Lasse W28-Nov-11 8:36 
GeneralMy vote of 5 Pin
Member 432084415-Jul-11 12:27
Member 432084415-Jul-11 12:27 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.