wake-up-neo.com

PowerShell - Skript neu starten und fortsetzen

Ich suche nach einer Möglichkeit, ein Powershell-Skript an der Stelle fortzusetzen, an der es nach dem Aufrufen eines Neustarts im Skript aufgehört hat. Zum Beispiel baue ich ein DC über Powershell-Automatisierung und muss nach dem Umbenennen des PCs in TESTDC01 neu starten, aber nach dem Neustart fahren Sie mit dem Skript fort, um mit dcpromo usw. fortzufahren.

Ist das möglich?

Prost!

27
PnP

Es gibt einen großartigen Artikel über TechNet aus der Reihe Hey, Scripting Guy, der sich mit einer Situation befasst, die Ihrer Beschreibung sehr ähnlich ist: Umbenennen eines Computers und Fortsetzen des Skripts nach dem Neustart. Die Magie besteht darin, die neuen Workflows zu verwenden, die Teil von Version 3 sind:

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

Sobald der Workflow deklariert wurde (Sie weisen ihn keiner Variablen zu), können Sie ihn wie ein reguläres Cmdlet aufrufen. Die wahre Magie ist das -Wait -Parameter im Cmdlet "Restart-Computer".

Rename-And-Reboot PowerShellWorkflows

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

Wenn PowerShell v3 oder höher nicht verfügbar ist, können Sie Ihr vorhandenes Skript in mehrere kleinere Skripts aufteilen und ein Masterskript ausführen, das beim Start einen gespeicherten Status (Datei, Registrierung usw.) prüft und dann mit der Ausführung von beginnt neues Skript, um gegebenenfalls fortzufahren. Etwas wie:

$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" }
}

Denken Sie jedoch daran, Ihren Status beim Durchlaufen Ihrer kleineren Skripte entsprechend festzulegen.

26
Goyuix

Die obige Antwort ist richtig, gilt jedoch nur für die Remote-Ausführung von Powershell-Skripten. Laut Windows-Webportal kann das lokal ausgeführte Skript an der Stelle fortgesetzt werden, an der es nach dem Neustart des lokalen Computers aufgehört hat:

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

Notiere dass der [System.Management.Automation.Remoting.PSSessionConfigurationData]::IsServerManager flag sollte nur dann auf true gesetzt werden, wenn die Workflow-Aktionen nach dem Neustart lokal ausgeführt werden sollen.

15
adaml

Testen Sie PS 3.0 mit Workflows. Ich habe noch nicht mit ihnen gearbeitet, aber sie sollen sich von Neustarts erholen.

5
E.V.I.L.

Wenn dies jemandem hilft, starte ich den Server neu und wiederhole, bis \\server\c$ Offline geht. Als nächstes schleife ich While (-not(Test-path "\\$server\c$")), um zu bestätigen, dass der Server wieder online ist, und setze einfach mein Skript fort.

Dieser Code funktioniert, könnte aber definitiv verbessert werden. Es wird ein CSV-Protokoll der neu gestarteten Server erstellt. Es sollte auch in PowerShell v2 und neuer funktionieren.

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

Machen Sie es aus der Ferne:

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

Und fahren Sie mit Ihrem Skript fort. 8)

1
icey