Solved

Reboot Script with Powershell

Posted on 2014-09-29
13
1,200 Views
Last Modified: 2016-11-09
We are deploying a software to users in our enterprise that will require a reboot to be fully functional.  The installation, however, will not prompt them to do this.  Is there a way with PowerShell to create a script that will prompt the users to perform a reboot, with the option to delay it up to 24 hours?  We would push this script separately through our software deployment tool.  Any assistance you could provide would be much appreciated.
0
Comment
Question by:myhelpermonkey
13 Comments
 
LVL 16

Expert Comment

by:Dale Harris
ID: 40350344
I would simply use a command before the restart command to either ask them or grab the amount of seconds.

$seconds = read-host "How many seconds would you like to wait before rebooting? (1-86400)"
shutdown.exe /r /t $seconds

Open in new window


You could also set up a cool menu, but ultimately, they could close out the script and you would have no way to track unless you wrote to a central log on a UNC File share or something.  You could make it write to the log before it prompts them ("User on Computer XXX has been asked to reboot", "User has specified XX seconds") and if there was no follow up log for how many seconds to reboot, you would know they didn't actually do the restart.

It all depends on how restricted or how many people you are having to push this out to.
0
 

Author Comment

by:myhelpermonkey
ID: 40350386
It will be pushed out to about 5 thousand plus users so I am not as concerned about the restrictive aspect.  I was hoping to just give them a button to hit to delay it or reboot immediately.  Is that something that can be done easily with PowerShell?
0
 
LVL 29

Accepted Solution

by:
becraig earned 500 total points
ID: 40351212
Ok so I took a few minutes and had some fun with this, it might be more than you need but I thought it was something to do with my spare time.


The concept is, it creates a popup on the user's computer and they have three options:
Reboot now
Postpone - select a window (default is 4 hours)
Cancel (which will reboot in 24 hours )

[void][System.Reflection.Assembly]::LoadWithPartialName( “System.Windows.Forms”)
[void][System.Reflection.Assembly]::LoadWithPartialName( “Microsoft.VisualBasic”)

$form = New-Object “System.Windows.Forms.Form”;
$form.Width = 500;
$form.Height = 150;
$form.Text = "Computer Reboot Notification";
$form.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen;

$DropDownArray = @("4:Hours", "8:Hours", "12:Hours", "24:Hours")
$DDL = New-Object System.Windows.Forms.ComboBox
$DDL.Location = New-Object System.Drawing.Size(140,10)
$DDL.Size = New-Object System.Drawing.Size(130,30)
ForEach ($Item in $DropDownArray) {
    $DDL.Items.Add($Item) | Out-Null
}
$DDL.SelectedIndex  = 0

$button1 = New-Object “System.Windows.Forms.button”;
$button1.Left = 40;
$button1.Top = 85;
$button1.Width = 100;
$button1.Text = “Reboot Now”;
$button1.Add_Click({$global:xinput = "Reboot";$Form.Close()})

$button2 = New-Object “System.Windows.Forms.button”;
$button2.Left = 170;
$button2.Top = 85;
$button2.Width = 100;
$button2.Text = “Postpone”;
$button2.Add_Click({$global:xinput = "Postpone:" + $DDL.Text;$Form.Close()})

$button3 = New-Object “System.Windows.Forms.button”;
$button3.Left = 290;
$button3.Top = 85;
$button3.Width = 100;
$button3.Text = “Cancel”;
$button3.Add_Click({$global:xinput = "Postpone24";$Form.Close()})


$form.KeyPreview = $True
$form.Add_KeyDown({if ($_.KeyCode -eq "Enter") 
    {$x=$textBox1.Text;$form.Close()}})
$form.Add_KeyDown({if ($_.KeyCode -eq "Escape") 
    {$form.Close()}})



$eventHandler = [System.EventHandler]{ 
$button1.Click;
$DropDownArray.Text;
$form.Close();};

$button.Add_Click($eventHandler) ;
$form.Controls.Add($button1);
$form.Controls.Add($button2);
$form.Controls.Add($button3);
$form.Controls.Add($DDL);
$form.Controls.Add($textLabel1)
$ret = $form.ShowDialog();

if ($global:xinput -eq "Reboot") {write-host "shutdown -r -f /t 600"}
if ($global:xinput -like "Postpone:*:Hours") {
$hval = (([int]$global:xinput.split(":")[1])*60*60)
write-host "shutdown -r -f /t $hval"}
if ($global:xinput -eq "Postpone24") {write-host "shutdown -r -f /t 86400"}

Open in new window


Again it is a lot of code for a simple thing but it is an option :~)
1
Does Powershell have you tied up in knots?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

 
LVL 69

Expert Comment

by:Qlemo
ID: 40352025
There is nothing native, so some of the available options are:
Build a script assembling a form allowing for "reboot now" and "postpone in X minutes/hours", as becraig showed. The script nags und runs until reboot.
Same, but let the script be called by Scheduled Task if postponed, with one task scheduled for 24 hours after installation (and removed if not postponed).
Let PS call shutdown.exe with the warning text and a grace period, and if aborted call it again after x minutes/hours.
0
 

Author Comment

by:myhelpermonkey
ID: 40352614
Hey becraig,

Thanks a lot of your help with this...your script was pretty much exactly what I was looking for.  My only question is that it does not seem to be creating the shutdown event, regardless of the option I select.  Here is the output:

PS C:\Users\khiggi03\Desktop> .\rebootscript.ps1
You cannot call a method on a null-valued expression.
At C:\Users\Kevin Higgins\Desktop\rebootscript.ps1:55 char:1
+ $button.Add_Click($eventHandler) ;
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

shutdown -r -f /t 86400
PS C:\Users\khiggi03\Desktop> shutdown -a
Unable to abort the system shutdown because no shutdown was in progress.(1116)
PS C:\Users\khiggi03\Desktop>
0
 
LVL 29

Expert Comment

by:becraig
ID: 40352620
You need to change it from being "write-host"


I only inserted a write-host so you could see the command.

Change the following block:
if ($global:xinput -eq "Reboot") { shutdown -r -f /t 600 }
if ($global:xinput -like "Postpone:*:Hours") {
$hval = (([int]$global:xinput.split(":")[1])*60*60)
shutdown -r -f /t $hval}
if ($global:xinput -eq "Postpone24") { shutdown -r -f /t 86400 }

Open in new window

0
 

Author Comment

by:myhelpermonkey
ID: 40352636
That did the trick.  One last thing, is there a way to force the set-executionpolicy to allow this script to be ran?  Most systems will likely block the script from running.
0
 
LVL 29

Expert Comment

by:becraig
ID: 40352648
you can simply call it as a command

powershell -executionpolicy bypass c:\path-to-script\script..ps1
0
 

Author Comment

by:myhelpermonkey
ID: 40352664
Awesome, thanks again for your help
0
 
LVL 29

Expert Comment

by:becraig
ID: 40352671
Happy to help.

I thought it was a bit of an overkill but I liked the approach.
0
 

Expert Comment

by:Blake Ourso
ID: 41550362
Is there any way to disable the X (Close) button on this, or just make the script start over thus prompting the box again, on close?

Also, I was more curious bout a defer option instead of a "reboot in 8/12/24 hour" choice, the middle button.

Trying to make this more of a more user-controlled reboot until they reach the 36 hour mark, in which it will force them b/c we don't want them deferring all year long.
0
 

Expert Comment

by:Jeremy King
ID: 41560328
becraig awesome script thanks for sharing!!  Is there a way to display a timer or countdown of when the reboot will happen on the users screen when this is run?
0
 

Expert Comment

by:Cameron Rohsler
ID: 41880092
Today I was doing some searching around and I came across this reboot script.

I am just curious, how can I get this to run across a list of systems at 1 time? Lets say I have 4000 users and a .txt file with all of the hostnames. Is there a way for that to happen?

I am also receiving the following error:

You cannot call a method on a null-valued expression.
At C:\Scripts\Incirlik Reboot\RebootScript.ps1:58 char:1
+ $button.Add_Click($eventHandler) ;
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull


I made sure to have the correct block mentioned in the comments so that it doesn't say "Write-Host" anymore.
I really appreciate any help! Thanks!
0

Featured Post

Problems using Powershell and Active Directory?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Active Directory replication delay is the cause to many problems.  Here is a super easy script to force Active Directory replication to all sites with by using an elevated PowerShell command prompt, and a tool to verify your changes.
This script can help you clean up your user profile database by comparing profiles to Active Directory users in a particular OU, and removing the profiles that don't match.
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…

831 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question