web-dev-qa-db-ja.com

Powershell-再起動してスクリプトを続行

スクリプトで再起動を呼び出した後、PowerShellスクリプトを中断したところから続行する方法を探しています。たとえば、Powershellオートメーションを使用してDCを作成しています。PCの名前をTESTDC01に変更した後、再起動する必要がありますが、再起動後はdcpromoなどに進むスクリプトを続行します。

これは可能ですか?

乾杯!

27
PnP

Hey、Scripting GuyシリーズのTechNetには、説明している内容と非常によく似た状況に関するすばらしい記事があります。コンピューターの名前を変更し、再起動後にスクリプトを再開します。魔法は、バージョン3の一部である新しいワークフローを使用することです。

workflow Rename-And-Reboot {
  param ([string]$Name)
  Rename-Computer -NewName $Name -Force -Passthru
  Restart-Computer -Wait
  Do-MoreStuff
}

ワークフローが宣言されたら(変数に割り当てないで)、通常のコマンドレットであるかのように呼び出すことができます。本当の魔法は、Restart-Computerコマンドレットの-Waitパラメーターです。

Rename-And-Reboot PowerShellWorkflows

ソース: http://blogs.technet.com/b/heyscriptingguy/archive/2013/01/23/powershell-workflows-restarting-the-computer.aspx

PowerShell v3以降を選択できない場合は、既存のスクリプトを複数の小さなスクリプトに分割し、起動時に実行され、保存された状態(ファイル、レジストリなど)を確認するマスタースクリプトを作成してから、必要に応じて続行する新しいスクリプト。何かのようなもの:

$state = Get-MyCoolPersistedState
switch ($state) {
  "Stage1" { . \Path\To\Stage1.ps1 ; break }
  "Stage2" { . \Path\To\Stage2.ps1 ; break }
  "Stage3" { . \Path\To\Stage3.ps1 ; break }
  default { "Uh, something unexpected happened" }
}

小さなスクリプトを移動するときは、状態を適切に設定することを忘れないでください。

26
Goyuix

上記の答えは正しいですが、powershellスクリプトのリモート実行にのみ適用されます。 windows web portal によると、ローカルマシンの再起動後に中断したところからローカルで実行中のスクリプトを再開する方法は次のようになります。

workflow Resume_Workflow
{
    .....
    Rename-Computer -NewName some_name -Force -Passthru
    Restart-Computer -Wait
    # Do some stuff
    .....
}
# Create the scheduled job properties
$options = New-ScheduledJobOption -RunElevated -ContinueIfGoingOnBattery -StartIfOnBattery
$secpasswd = ConvertTo-SecureString "Aa123456!" -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential ("WELCOME\Administrator", $secpasswd)
$AtStartup = New-JobTrigger -AtStartup

# Register the scheduled job
Register-ScheduledJob -Name Resume_Workflow_Job -Trigger $AtStartup -ScriptBlock ({[System.Management.Automation.Remoting.PSSessionConfigurationData]::IsServerManager = $true; Import-Module PSWorkflow; Resume-Job -Name new_resume_workflow_job -Wait}) -ScheduledJobOption $options
# Execute the workflow as a new job
Resume_Workflow -AsJob -JobName new_resume_workflow_job

[System.Management.Automation.Remoting.PSSessionConfigurationData]::IsServerManagerフラグは、ワークフローアクションが再起動後にローカルで実行されることを意図している場合にのみtrueに設定する必要があります。

15
adaml

ワークフローを備えたPS 3.0をご覧ください。私はまだ彼らと仕事をしていませんが、彼らは再起動から回復することを想定しています。

5
E.V.I.L.

これが誰かを助けるなら、私はサーバーを再起動してから_\\server\c$_がオフラインになるまでループします。次に、While (-not(Test-path "\\$server\c$"))をループして、サーバーが再びオンラインに戻ったことを確認し、単にスクリプトを続行します。

このコードは機能していますが、間違いなく改善される可能性があります。再起動中のサーバーのCSVログを生成します。 PowerShell v2以降でも動作するはずです。

_Param([Parameter(Mandatory=$true)][string]$server)
 $ErrorActionPreference = "SilentlyContinue"

Try{
 $LastReboot = Get-EventLog -ComputerName $server -LogName system | Where-Object {$_.EventID -eq '6005'} | Select -ExpandProperty TimeGenerated | select -first 1

 (Invoke-WmiMethod -ComputerName $server -Path "Win32_Service.Name='HealthService'" -Name PauseService).ReturnValue | Out-Null

Restart-Computer -ComputerName $server -Force

#New loop with counter, exit script if server did not reboot.
$max = 20;$i = 0
 DO{
 IF($i -gt $max){
        $hash = @{
             "Server" =  $server
             "Status" = "FailedToReboot!"
             "LastRebootTime" = "$LastReboot"
             "CurrentRebootTime" = "FailedToReboot!"
          }
$newRow = New-Object PsObject -Property $hash
 $rnd = Get-Random -Minimum 5 -Maximum 40
 Start-Sleep -Seconds $rnd
 Export-Csv D:\RebootResults.csv -InputObject $newrow -Append -Force
    "Failed to reboot $server"
    exit}#exit script and log failed to reboot.
    $i++
"Wait for server to reboot"
    Start-Sleep -Seconds 15
}#end DO
While (Test-path "\\$server\c$")

$max = 20;$i = 0
 DO{
 IF($i -gt $max){
        $hash = @{
             "Server" =  $server
             "Status" = "FailedToComeOnline!"
             "LastRebootTime" = "$LastReboot"
             "CurrentRebootTime" = "FailedToReboot!"
          }
$newRow = New-Object PsObject -Property $hash
 $rnd = Get-Random -Minimum 5 -Maximum 40
 Start-Sleep -Seconds $rnd
Export-Csv D:\RebootResults.csv -InputObject $newrow -Append -Force
    "$server did not come online"
    exit}#exit script and log failed to come online.
    $i++
    "Wait for [$server] to come online"
    Start-Sleep -Seconds 15
}#end DO
While (-not(Test-path "\\$server\c$"))

$CurrentReboot = Get-EventLog -ComputerName $server -LogName system | Where-Object {$_.EventID -eq '6005'} | Select -ExpandProperty TimeGenerated | select -first 1
    $hash = @{
             "Server" =  $server
             "Status" = "RebootSuccessful"
             "LastRebootTime" = $LastReboot
             "CurrentRebootTime" = "$CurrentReboot"
              }

$newRow = New-Object PsObject -Property $hash
 $rnd = Get-Random -Minimum 5 -Maximum 40
 Start-Sleep -Seconds $rnd
Export-Csv D:\RebootResults.csv -InputObject $newrow -Append -Force

}#End Try.

Catch{
 $errMsg = $_.Exception
 "Failed with $errMsg"
}
_
1
user4317867

リモートで実行:

Rename-Computer -ComputerName $computer -NewName "TESTDC01" -DomainCredential $domain\$username -Force -Restart

そして、その8)からスクリプトを続けます

1
icey