Solved

Reboot Script with Powershell

Posted on 2014-09-29
13
1,401 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Best Practices: Disaster Recovery Testing

Besides backup, any IT division should have a disaster recovery plan. You will find a few tips below relating to the development of such a plan and to what issues one should pay special attention in the course of backup planning.

Question has a verified solution.

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

The Nano Server Image Builder helps you create a custom Nano Server image and bootable USB media with the aid of a graphical interface. Based on the inputs you provide, it generates images for deployment and creates reusable PowerShell scripts that …
A quick Powershell script I wrote to find old program installations and check versions of a specific file across the network.
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…

730 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