Powershell - перезагрузка и продолжение Script
Я ищу способ продолжить работу с Powershell script, после чего он отключился после вызова перезагрузки в script. Например, я создаю DC через автоматизацию Powershell, и после переименования ПК в TESTDC01 необходимо перезагрузить компьютер, но после перезагрузки продолжите с помощью script, чтобы перейти к dcpromo и т.д.
Возможно ли это?
Ура!
Ответы
Ответ 1
Существует отличная статья о TechNet из серии Hey, Scripting Guy, которая описывает ситуацию, очень похожую на то, что вы описываете: переименование компьютера и возобновление script после перезагрузки. Магия заключается в использовании новых рабочих процессов, которые являются частью версии 3:
workflow Rename-And-Reboot {
param ([string]$Name)
Rename-Computer -NewName $Name -Force -Passthru
Restart-Computer -Wait
Do-MoreStuff
}
Как только рабочий процесс объявлен (вы не назначаете его переменной), вы можете назвать его, как если бы это был обычный командлет. Реальная магия - это параметр -Wait
в командлете Restart-Computer.
Rename-And-Reboot PowerShellWorkflows
Источник: http://blogs.technet.com/b/heyscriptingguy/archive/2013/01/23/powershell-workflows-restarting-the-computer.aspx
Если PowerShell v3 или более поздняя версия не является доступным выбором, вы можете разбить существующий script на несколько меньших скриптов и иметь мастер script, который запускается при запуске, где-то (где-то в каком-либо сохраненном состоянии).), затем начинает выполнение нового script, чтобы продолжить, когда это необходимо. Что-то вроде:
$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" }
}
Просто не забудьте вспомнить, как правильно настроить ваше состояние, когда вы перемещаете свои маленькие скрипты.
Ответ 2
Вышеприведенный ответ верен, но он применим только к удаленному выполнению сценариев powershell.
В соответствии с веб-портал Windows способ возобновления вашего локального запуска script резюме с момента его останова после перезапуска локального компьютера
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, только если действия рабочего процесса предназначены для выполнения локально после перезапуска.
Ответ 3
Проверьте PS 3.0 с рабочими потоками. Я еще не работал с ними, но они полагаются на восстановление после перезапуска.
Ответ 4
Если это помогает кому-то, то я делаю перезагрузку сервера, а затем цикл до \\server\c$
переходит в автономный режим. Затем я зациклирую While (-not(Test-path "\\$server\c$"))
, чтобы подтвердить, что сервер снова подключен к сети и просто продолжит мой script.
Этот код работает, но определенно может быть улучшен. Он генерирует журнал 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"
}
Ответ 5
Сделайте это удаленно:
Rename-Computer -ComputerName $computer -NewName "TESTDC01" -DomainCredential $domain\$username -Force -Restart
И продолжай свой сценарий с этого 8)