Reboot Script with Powershell

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.
myhelpermonkeyAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Dale HarrisProfessional Services EngineerCommented:
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
myhelpermonkeyAuthor Commented:
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
becraigCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Making Bulk Changes to Active Directory

Watch this video to see how easy it is to make mass changes to Active Directory from an external text file without using complicated scripts.

Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
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
myhelpermonkeyAuthor Commented:
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
becraigCommented:
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
myhelpermonkeyAuthor Commented:
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
becraigCommented:
you can simply call it as a command

powershell -executionpolicy bypass c:\path-to-script\script..ps1
0
myhelpermonkeyAuthor Commented:
Awesome, thanks again for your help
0
becraigCommented:
Happy to help.

I thought it was a bit of an overkill but I liked the approach.
0
Blake OursoCommented:
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
Jeremy KingCommented:
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
Cameron RohslerCommented:
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.