Skip to content

Instantly share code, notes, and snippets.

@JohnLBevan
Created April 2, 2020 13:29
Show Gist options
  • Select an option

  • Save JohnLBevan/66a6886a7393c41cfa19fdce380c65ab to your computer and use it in GitHub Desktop.

Select an option

Save JohnLBevan/66a6886a7393c41cfa19fdce380c65ab to your computer and use it in GitHub Desktop.
Take a remote computer out of safe mode (with networking) / put it back into normal mode.
Function Repair-RemoteSafeModeBoot {
[CmdletBinding()]
Param (
[Parameter(Mandatory = $true)]
[string]$ComputerName
)
if (-not (Test-Connection -ComputerName $ComputerName -Quiet -Count 1 -ErrorAction 'Stop')) {
throw "Could not ping $ComputerName; no attempt made to fix it"
}
$os = Get-WmiObject -ComputerName $ComputerName -Class 'Win32_OperatingSystem' -ErrorAction 'Stop'
Write-Verbose "Computer $ComputerName last rebooted at $($os.ConvertToDateTime($os.LastBootUpTime))"
$cs = Get-WmiObject -ComputerName $ComputerName -Class 'Win32_ComputerSystem' -ErrorAction 'Stop'
Write-Verbose "Computer $ComputerName bootup state is $($cs.BootupState)"
if ($cs.BootupState -eq 'Normal boot') {
Write-Warning "$ComputerName is not in safe mode; no attempt to fix it was made"
return # we don't want to proceed if the remote device is already in normal mode as we may do more harm than good (unlikely to have any impact tbh; but why risk it)
}
if ($cs.BootupState -ne 'Fail-safe with network boot') {
Write-Warning "$ComputerName has boot up state $($cs.BooupState). I've never tested with these states, so can't say what will happen. Please read up on this & if acceptable to proceed amend this script to enable it for your scenario."
return # probably safe to remove this & continue; but I don't want to be responsible for that decision... Comment this statement out at your own risk
}
# run a command on the remote computer to take it out of safe mode: https://superuser.com/a/706664/156700
$rv = Invoke-WmiMethod –ComputerName $ComputerName -Class 'win32_process' -Name 'create' -ArgumentList 'bcdedit /deletevalue {default} safeboot' -ErrorAction 'Stop' | Select-Object -ExpandProperty ReturnValue
if ($rv -ne 0) {
throw "Attempted to run bcdedit, but received return value $rv implying that the command was unsuccessful"
}
Start-Sleep -Seconds 5 # probably not required; but added to be safe. It's not like 5 seconds is much to ask if you're in this scenario.
#restart the remote computer
$rv = $os.Reboot() | Select-Object -ExpandProperty ReturnValue
if ($rv -ne 0) {
throw "Attempted to reboot the remote device, but received return value $rv, implying that the command was unsuccessful"
}
Write-Information "$ComputerName updated to normal mode & restarted. Wait a few minutes whilst the reboot occurs then try to log in. If you still have issues try rerunning this command with the -Verbose flag enabled to check whether the boot time or mode have changed."
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment