重启和恢复 PowerShell 脚本
创建神奇的“开发者 PC 设置脚本”的第一步。
引言
每天都需要重启 Windows 的时代已经过去了。然而,当处理系统维护或从脚本安装多个应用程序时,重启有时是不可避免的。 本文将介绍一个 PowerShell 脚本,该脚本能够运行多个步骤,重启计算机,并在另一步骤继续脚本。 简单但非常有用。
背景
本文中展示的想法源于一个真实的脚本,用于设置开发者 PC,其中包含从正确版本的 .NET Framework、在 IIS 中启用正确的功能、本地安装 Visual Studio 和 MS SQL Server 等。 以这种方式设置开发者 PC 的优势有很多
- 它比让每个开发人员自己完成这些步骤要快得多
- 它比使用磁盘映像更灵活
- 它非常清楚地记录了使用的技术
- 它可用于更新现有的开发人员 PC 以及从头开始安装
上述设置脚本的主要缺点是前期投入的时间,用于获得这样的脚本。 但是,本文将帮助您入门,您应该真正接受挑战,尝试创建自己的脚本 - 您会对 PowerScript 的强大功能印象深刻。
运行测试脚本
本文中介绍的简单测试脚本如下所示
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..."
脚本将执行步骤 A 到 C,只有在完成步骤 A 后,它才会重启,然后继续执行步骤 B。 以下是两个屏幕截图,显示了预期结果
使脚本了解步骤
可以通过多种方式使 PowerShell 脚本按顺序执行。 此示例中唯一的要求是,必须在命令行上指定起始步骤,如下所示
>.\testscript.ps1 -Step B
从上面的测试脚本中可以看出,我们声明了一个脚本参数 $Step
,用于从命令行获取起始步骤。 然后我们创建一个简单的 guard 方法 Should-Run-Step
,该方法将返回 false,直到在命令行上遇到指定的起始步骤,从那时起,它将返回 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
}
当然,此步骤机制可以更加复杂,包括端点和步骤范围,但这并不是本文的重点,因此留给读者作为练习。
一些注册表辅助函数
虽然我喜欢 PowerShell 的超级通用的 ???-ItemProperty
函数,但我倾向于认为这些方法会使脚本变得混乱,降低可读性。 因此,我将介绍四个简单的辅助方法来处理注册表
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
}
从 PowerShell 重启
使用命令 Restart-Computer
即可从 PowerShell 简单地重启计算机。 使 Windows 在启动时执行命令是通过注册表项 "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" 处理的。 将这些信息放在一起,我们可以定义一个 Restart-And-Run
函数,它将重启然后启动在 $run
参数中传递的任何内容。
$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
}
如果您不想在每次启动 Windows 时都启动指定的命令,最好记住清除该注册表项。 由于我们计划恢复脚本,因此我们可以很容易地在一个专用的函数中执行此操作,该函数应放置在脚本的顶部。
$global:restartKey = "Restart-And-Resume"
function Clear-Any-Restart([string] $key=$global:restartKey)
{
if (Test-Key $global:RegRunKey $key) {
Remove-Key $global:RegRunKey $key
}
}
您可能已经注意到,Clear-Any-Restart
函数采用默认键 "Restart-And-Resume",并且恢复脚本正是本文旨在实现的目标。 猜猜怎么着,我们所要做的就是使用所需的步骤参数重新启动 PowerShell
$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"
}
就这样,我们都完成了,您现在可以制作自己的设置脚本了。 尽情享受,请让我知道您的想法以及您对此的使用情况。
故障排除
如果您在执行脚本时遇到问题,请确保您没有指定 restricted
执行策略
>Set-ExecutionPolicy RemoteSigned
历史
- 2011 年 7 月 8 日:初始版本。