Powershell重新启动控制台问题

时间:2019-04-16 18:04:26

标签: powershell reboot login-script uptime

我有一个登录脚本,如果启动PC的时间超过允许的时间,它将重新启动PC。

我有一个PowerShell脚本,该脚本在登录期间运行,每周执行一次,以检查计算机的正常运行时间,如果> 48小时,则重新启动。该脚本允许用户请求扩展名,这样就不会立即将其踢出计算机。我有1、3、8小时的延长时间。只有1、3小时的延期工作。看来,如果您输入一个大于3的值,它将不接受它。有没有办法使此“扩展”工作时间超过3小时?

<#
.SYNOPSIS
    Script displays an interactive popup that display the reason for having the reboot the computer.
.DESCRIPTION
     The reboot script gives users the option to reboot now or delay the reboot for 1, 3, or 6 hours
.EXAMPLE
    Script executes from the login script
.INPUTS
    N/A
.OUTPUTS
    N/A
.NOTES
    General notes
#>

try {
    Add-Type -AssemblyName PresentationCore, PresentationFramework, WindowsBase, system.windows.forms
} 
catch {}

#Calculate the time since last reboot

$lastBootTime = Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object LastBootUpTime | ForEach-Object { Get-Date -Date $_.LastBootUpTime }
$Time = (Get-Date) - $lastBootTime

#if last reboot is less than 2 days exit the script.
if ($Time.TotalHours -lt 48) {
    exit
}

#if computer has a server os, exit
$version = (Get-CimInstance -ClassName Win32_OperatingSystem).caption

if($version -match "server")
{
    exit
}

<#
 # Set Sync hash
 #>
$Global:hash = [hashtable]::Synchronized(@{})
$Global:hash.Stopwatch = New-Object System.Diagnostics.Stopwatch
$Global:hash.Timer = New-Object System.Windows.Forms.Timer
$Global:hash.Timer.Enabled = $true
$Global:hash.Timer.Interval = 1000


<#
 # Form design XML
 #>
[xml]$xaml = @'
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Name="window" Height="340" Width="400" Title="Mandatory Reboot"  WindowStartupLocation="CenterScreen" Background="Transparent" AllowsTransparency="True"
ResizeMode="NoResize" ShowInTaskbar="True"  SizeToContent="Height" Topmost="True" WindowStyle="None">
    <Window.Resources>
        <SolidColorBrush x:Key="Brush_ChromeBackground" Color="#FFC8D1E0"/>
        <SolidColorBrush x:Key="Brush_ChromeBorder" Color="#FFA0A0A0"/>
    </Window.Resources>
    <Border x:Name="Border_Chrome"  BorderBrush="{StaticResource Brush_ChromeBorder}" BorderThickness="5"  CornerRadius="10"  Width="Auto" Background="#FFCD3232">
        <Grid Margin="15" >
            <Grid.RowDefinitions>
                <RowDefinition Height="120"></RowDefinition>
                <RowDefinition Height="60"></RowDefinition>
                <RowDefinition Height="60"></RowDefinition>
                <RowDefinition Height="60"></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="50"></ColumnDefinition>
                <ColumnDefinition Width="*"></ColumnDefinition>
                <ColumnDefinition Width="50"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <TextBlock TextWrapping="Wrap" Grid.Column="0" Grid.ColumnSpan="3" FontSize="14" Foreground="White">
                <Bold FontSize="16">Mandatory Reboot</Bold><LineBreak/>
                This computer exceeds the maximum allowed uptime. Your computer will be automatically rebooted unless manually restarted or an extension is requested.<LineBreak/>
            </TextBlock>
            <Button Name="RestartNowBtn" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="3" Width="240" Height="40" HorizontalContentAlignment="Center" HorizontalAlignment="Left">
                <StackPanel Orientation="Horizontal" >
                    <Label Content="Restart Now" FontWeight="Bold"></Label>
                </StackPanel>
            </Button>
            <StackPanel Orientation="Horizontal" Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="3" Margin="5,8" >
                <GroupBox Width="100" Header="Postpone">
                    <ComboBox Name="ScheduleValue" VerticalAlignment="Center" >
                        <ComboBoxItem Name="one" Selector.IsSelected="True">1</ComboBoxItem>
                        <ComboBoxItem Name="three">3</ComboBoxItem>
                        <ComboBoxItem Name="eight">8</ComboBoxItem>
                    </ComboBox>
                </GroupBox>
                <TextBlock Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10,0" FontWeight="Bold">Hour(s)</TextBlock>
                <Button Content="Request Extension" Name="scheduleBtn" Width="110" FontWeight="Bold"></Button>
            </StackPanel>
            <Grid Grid.Row="3" Grid.ColumnSpan="3" Margin="10">
                <ProgressBar Name="Time" Maximum="100" Value="100"></ProgressBar>
                <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">Time to Automatic Reboot (All unsaved work will be lost)</TextBlock>
            </Grid>
        </Grid>
    </Border>
</Window>
'@

$Global:hash.window = [Windows.Markup.XamlReader]::Load((New-Object -TypeName System.Xml.XmlNodeReader -ArgumentList $xaml))

#Connect to Control
$xaml.SelectNodes("//*[@Name]") | ForEach-Object -Process { 
    $Global:hash.$($_.Name) = $Global:hash.window.FindName($_.Name)
}

<#
 # Restart Now Button Even Handler
 #>
$Global:hash.RestartNowBtn.Add_Click( {
        #Stop the timer so that the auto reboot dosen't happen
        $Global:hash.Timer.Stop()
        #Force Reboot Now!
        cmd.exe /c shutdown.exe -r -d P:0:0 -t 60 -f
        $Global:hash.window.Close()
    })

<#
 # Schedule Button Click event handler
 #>
$Global:hash.ScheduleBtn.Add_Click( {

        switch ($Global:hash.ScheduleValue.SelectedItem.Name) {
            "one" {
                $rebootTime = (Get-Date).AddHours(1).TimeOfDay.TotalSeconds
            }
            "three" {
                $rebootTime = (Get-Date).AddHours(3).TimeOfDay.TotalSeconds
            }
            "eight" {
                $rebootTime = (Get-Date).AddHours(8).TimeOfDay.TotalSeconds
            }
        }

        $startTime = [Math]::Round(($rebootTime - (Get-Date).TimeOfDay.TotalSeconds), 0)

        #Stop the timer so that the auto reboot dosen't happen
        $Global:hash.Timer.Stop()

        cmd.exe /c shutdown.exe -r -d P:0:0 -t $startTime -f 

        $Global:hash.Window.Close()
    })

<#
 # Form Loaded Event Handler
 #>
$Global:hash.window.Add_Loaded( {

        $Global:hash.Stopwatch.Start()
        $Global:hash.Timer.Add_Tick( {
                [timespan]$secs = $Global:hash.Stopwatch.Elapsed

                if ($secs.TotalSeconds -gt 120) {
                    cmd.exe /c shutdown.exe -r -d P:0:0 -t 60 -f
                    $Global:hash.Timer.Stop()
                    $Global:hash.window.Close()
                    exit
                }

                $Global:hash.Time.Value = (100 - (($secs.TotalSeconds / 120) * 100))
            })

        $Global:hash.Timer.Start()
    })

<#
 # Start the form
 #>
$Global:hash.window.ShowDialog() | Out-Null

我希望允许延长8小时,但不允许> 3。

1 个答案:

答案 0 :(得分:1)

这是shutdown.exe可执行文件的限制。根据此处找到的文档:

https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/shutdown

/t <XXX>    Sets the time-out period or delay to XXX seconds before a restart or 
            shutdown. This causes a warning to display on the local console. You can 
            specify 0-600 seconds. If you do not use /t, the time-out period is 30 
            seconds by default.

如果要超出此范围,则必须在PowerShell中创建暂停,然后再执行shutdown.exe。这可以通过在8小时选项中添加start-sleep,休眠3小时然后指定最多600秒的计时器来完成。

编辑::该文档似乎已过时,并且关闭可以接受长达10年的任何内容(以秒为单位)。看,shutdown命令只需要几秒钟。您应该能够仅用秒x分钟x小时来计算,而不是您要尝试的所有奇特数学。一分钟60秒,一小时60分钟,因此唯一改变的是延迟的小时数。试试这个:

$Global:hash.ScheduleBtn.Add_Click( {

    $startTime = switch ($Global:hash.ScheduleValue.SelectedItem.Name) { 
        "one" { 1*60*60 } 
        "three" { 3*60*60 } 
        "eight" { 8*60*60}
    }
    $Global:hash.Timer.Stop()

    cmd.exe /c shutdown.exe -r -d P:0:0 -t $startTime -f 

    $Global:hash.Window.Close()
}